This JavaScript code appears to be part of a parser or tree-traversal function that handles tasks such as special character handling, filtering object properties, and converting a tree-like data structure to a string representation. The main function, treeToStr
, recursively traverses the tree, extracting information from statement objects and using parser objects to resolve rule names and input strings.
npm run import -- "antlr to html"
var importer = require('../Core');
var {selectDom} = importer.import("select tree")
//TODO: remove \u200b characters
var specialChars = (str) => {
var special = {
'&':'&',
'<':'<',
'>':'>',
'"':'"',
"'":'''
}
Object.keys(special).forEach(s => {
str = (str || '').replace(new RegExp(s, 'ig'), special[s])
})
return str
}
function filterObject(obj) {
let result = {}
for(var i in obj) {
if(i == 'children' || i == 'parentCtx') {
continue
}
result[i] = obj[i]
}
return result
}
function treeToStr(statement, parent, parser) {
var {type, ruleIndex, start, stop, exception, strdata} = statement;
if(typeof start == 'object') {
statement['start'] = start.start
statement['line'] = start.line
}
if(typeof stop == 'object') {
statement['stop'] = stop.stop
}
if(!parser)
parser = (statement.parentCtx ? statement.parentCtx.parser : statement.parser)
if(typeof type == 'number') {
type = parser.ruleNames[type]
} else
if(typeof ruleIndex == 'number') {
type = parser.ruleNames[ruleIndex]
statement.type = type
}
if(exception) {
return ''
}
if(!strdata && statement.start && statement.stop && statement.type) {
statement.strdata = parser.input.substring(statement.start, statement.stop + 1)
}
var result = ``, attrs = ``;
var isList = true;
for(var i in statement) {
if(parseInt(i) + '' === i + '') {
result += treeToStr(statement[i], parent, parser)
continue;
}
if(i == 'parentCtx' || i == 'parser' || i[0] == '_' || i == 'exception' || i == 'source') {
continue
}
if(i == 'strdata') {
statement[i] = statement[i].split('\n')[0]
}
if(i == 'type' && typeof statement[i] == 'number') {
statement[i] = parser.ruleNames[statement[i]]
}
isList = false;
var jsType = typeof statement[i];
if(jsType === 'object' && statement[i]) {
jsType = Object.getPrototypeOf(statement[i]).constructor.name;
}
if(i == 'symbol' && jsType == 'vt') {
continue
}
// if the property is an Object, print out as a child
// TODO: replace this type property when converting other trees
// should be like getEl() treeToStr(() => el.type)
if(statement[i] && typeof statement[i].type !== 'undefined'
// or if the property is an Array,
// print them out as child elements
|| (Array.isArray(statement[i]) /* && statement[i].length
&& typeof statement[i][0].type !== 'undefined' */)
) {
// print out the other keys just for fun matching
attrs += `
${i}="" ${i}-type="${jsType}"`;
result += `
${treeToStr(statement[i], i, parser)}`
// output as child element and <-attr> elements
// for posterity, only child elements are return on the select,
// but attr elements can still be matched
} else {
// if the property is not an object, i.e. native types
if(typeof statement[i] == 'object' && statement[i] !== null) {
attrs += `
${i}="${specialChars(JSON.stringify(filterObject(statement[i])))}" ${i}-type="${jsType}"`
} else if(typeof statement[i] !== 'string') {
attrs += `
${i}="${specialChars(JSON.stringify(statement[i]))}" ${i}-type="${jsType}"`
} else {
attrs += `
${i}="${specialChars(statement[i])}" ${i}-type="${jsType}"`
}
}
}
return isList ? result : `
<${type}${attrs}${parent ? `
parent-attr="${parent}"`: ``}>${result}</${type}>`
}
function treeToHtml(tree) {
var body = treeToStr(tree);
require('fs').writeFileSync('text.html', body)
return selectDom('//BODY', '<BODY>' + body + '</BODY>');
}
module.exports = {treeToHtml}
const importer = require('../Core');
const { selectDom } = importer.import('select tree');
// Function to remove special characters from a string
const removeSpecialChars = (str) => {
const specialCharsRegex = /&|<|>|"|'|/g;
return str.replace(specialCharsRegex, (match) => {
switch (match) {
case '&':
return '&';
case '<':
return '<';
case '>':
return '>';
case '"':
return '"';
case "'":
return ''';
default:
return match;
}
});
};
// Function to filter out unwanted properties from an object
const filterObject = (obj) => {
return Object.fromEntries(Object.entries(obj).filter(([key, value]) => key!== 'children' && key!== 'parentCtx'));
};
// Function to convert a tree statement to a string
const treeToStr = (statement, parent, parser) => {
const { type, ruleIndex, start, stop, exception, strdata } = statement;
if (typeof start === 'object') {
statement['start'] = start.start;
statement['line'] = start.line;
}
if (typeof stop === 'object') {
statement['stop'] = stop.stop;
}
const parserNames = parser.ruleNames;
if (!parser) {
parser = statement.parentCtx?.parser?? statement.parser;
}
if (typeof type === 'number') {
type = parserNames[type];
} else if (typeof ruleIndex === 'number') {
type = parserNames[ruleIndex];
statement.type = type;
}
if (exception) {
return '';
}
if (!strdata && statement.start && statement.stop && statement.type) {
statement.strdata = parser.input.substring(statement.start, statement.stop + 1);
}
const result = [];
const attrs = {};
let isList = true;
for (const [key, value] of Object.entries(statement)) {
// Recursively convert child elements
if (parseInt(key) + '' === key + '') {
result.push(treeToStr(value, parent, parser));
continue;
}
if (key === 'parentCtx' || key === 'parser' || key.startsWith('_') || key === 'exception' || key ==='source') {
continue;
}
if (key ==='strdata') {
statement[key] = statement[key].split('\n')[0];
}
if (key === 'type' && typeof statement[key] === 'number') {
statement[key] = parserNames[statement[key]];
}
isList = false;
const jsType = typeof value;
if (jsType === 'object' && value) {
jsType = Object.getPrototypeOf(value).constructor.name;
}
if (key ==='symbol' && jsType === 'Function') {
continue;
}
// Convert objects and arrays to HTML
if (statement[key] && typeof statement[key].type!== 'undefined' ||
(Array.isArray(statement[key])) // TODO: uncomment this line
) {
attrs[key] = { type: jsType };
// Recursively convert child elements
result.push(treeToStr(statement[key], key, parser));
// Output as child element and <-attr> elements
// TODO: uncomment this line
} else {
// Convert native types to HTML
if (typeof value === 'object' && value!== null) {
attrs[key] = { type: jsType };
attrs[key].value = specialChars(JSON.stringify(filterObject(value)));
} else if (typeof value!=='string') {
attrs[key] = { type: jsType };
attrs[key].value = specialChars(JSON.stringify(value));
} else {
attrs[key] = { type: jsType };
attrs[key].value = specialChars(value);
}
}
}
// Output as child element or element with attributes
if (isList) {
return result.join('');
}
return `<${type}${Object.keys(attrs).map((key) => `${key}="${attrs[key].value}" ${key}-type="${attrs[key].type}""`).join('')}${parent? ` parent-attr="${parent}"`: ``}>${result.join('')}</${type}>`;
};
// Function to convert a tree to HTML
const treeToHtml = (tree) => {
const body = treeToStr(tree);
const fs = require('fs');
fs.writeFileSync('text.html', body);
return selectDom('//BODY', `<BODY>${body}</BODY>`);
};
module.exports = { treeToHtml };
Code Breakdown
This code appears to be a part of a parser or a tree-traversal function. It's written in JavaScript and uses Node.js's require
function to import other modules. Here's a brief explanation of the code:
var importer = require('../Core');
var {selectDom} = importer.import('select tree')
This code imports a module from ../Core
and extracts the selectDom
function from it.
var specialChars = (str) => {
var special = {
'&':'&',
'<':'<',
'>':'>',
'"':'"',
"'":'''
}
Object.keys(special).forEach(s => {
str = (str || '').replace(new RegExp(s, 'ig'), special[s])
})
return str
}
This function takes a string as input and replaces special characters with their HTML entity equivalents. This is likely used to escape special characters in text data.
function filterObject(obj) {
let result = {}
for(var i in obj) {
if(i == 'children' || i == 'parentCtx') {
continue
}
result[i] = obj[i]
}
return result
}
This function takes an object as input and returns a new object with some properties filtered out. Specifically, it ignores properties named 'children'
and 'parentCtx'
.
function treeToStr(statement, parent, parser) {
//...
}
This is the main function of interest. It takes a statement object, an optional parent object, and a parser object as input. It appears to recursively traverse a tree-like data structure, converting each statement to a string representation.
The function performs several tasks:
This function seems to be used to serialize a tree-like data structure into a human-readable string representation.