import type { HTMLNode, CommentOrTextAST, ElementAST, AST } from './types'; export const splitHead = (str: string, sep: string) => { const idx = str.indexOf(sep); if (idx === -1) return [str]; return [str.slice(0, idx), str.slice(idx + sep.length)]; }; const unquote = (str: string) => { const car = str.charAt(0); const end = str.length - 1; const isQuoteStart = car === '"' || car === "'"; if (isQuoteStart && car === str.charAt(end)) { return str.slice(1, end); } return str; }; const formatAttributes = (attributes: string[]) => { return attributes.map((attribute) => { const parts = splitHead(attribute.trim(), '='); const key = parts[0]; const value = typeof parts[1] === 'string' ? unquote(parts[1]) : null; return { key, value }; }); }; export const format = (nodes: HTMLNode[]): AST[] => { return nodes.map((node) => { if (node.type === 'element') { const children = format(node.children); const item: ElementAST = { type: 'element', tagName: node.tagName.toLowerCase(), attributes: formatAttributes(node.attributes), children, }; return item; } const item: CommentOrTextAST = { type: node.type, content: node.content, }; return item; }); };