import { html, type TreeAdapter, type TreeAdapterTypeMap, type Token } from 'parse5';
function getSerializedTreeIndent(indent: number): string {
return '|'.padEnd(indent + 2, ' ');
}
function getElementSerializedNamespaceURI(
element: T['element'],
treeAdapter: TreeAdapter
): string {
switch (treeAdapter.getNamespaceURI(element)) {
case html.NS.SVG: {
return 'svg ';
}
case html.NS.MATHML: {
return 'math ';
}
default: {
return '';
}
}
}
function serializeNodeList(
nodes: T['node'][],
indent: number,
treeAdapter: TreeAdapter
): string {
let str = '';
for (let node of nodes) {
str += getSerializedTreeIndent(indent);
if (treeAdapter.isCommentNode(node)) {
str += `\n`;
} else if (treeAdapter.isTextNode(node)) {
str += `"${treeAdapter.getTextNodeContent(node)}"\n`;
} else if (treeAdapter.isDocumentTypeNode(node)) {
const publicId = treeAdapter.getDocumentTypeNodePublicId(node);
const systemId = treeAdapter.getDocumentTypeNodeSystemId(node);
str += `\n';
} else {
const tn = treeAdapter.getTagName(node);
str += `<${getElementSerializedNamespaceURI(node, treeAdapter) + tn}>\n`;
let childrenIndent = indent + 2;
const serializedAttrs = treeAdapter.getAttrList(node).map((attr: Token.Attribute) => {
let attrStr = getSerializedTreeIndent(childrenIndent);
if (attr.prefix) {
attrStr += `${attr.prefix} `;
}
attrStr += `${attr.name}="${attr.value}"\n`;
return attrStr;
});
str += serializedAttrs.sort().join('');
if (tn === html.TAG_NAMES.TEMPLATE && treeAdapter.getNamespaceURI(node) === html.NS.HTML) {
str += `${getSerializedTreeIndent(childrenIndent)}content\n`;
childrenIndent += 2;
node = treeAdapter.getTemplateContent(node);
}
str += serializeNodeList(treeAdapter.getChildNodes(node), childrenIndent, treeAdapter);
}
}
return str;
}
export function serializeToDatFileFormat(
rootNode: T['parentNode'],
treeAdapter: TreeAdapter
): string {
return serializeNodeList(treeAdapter.getChildNodes(rootNode), 0, treeAdapter);
}