| import type { AST, ElementAST, ElementAttribute } from './types' | |
| import { voidTags } from './tags' | |
| export const formatAttributes = (attributes: ElementAttribute[]) => { | |
| return attributes.reduce((attrs, attribute) => { | |
| const { key, value } = attribute | |
| if (value === null) return `${attrs} ${key}` | |
| if (key === 'style' && !value) return '' | |
| const quoteEscape = value.indexOf('\'') !== -1 | |
| const quote = quoteEscape ? '"' : '\'' | |
| return `${attrs} ${key}=${quote}${value}${quote}` | |
| }, '') | |
| } | |
| export const toHTML = (tree: AST[]) => { | |
| const htmlStrings: string[] = tree.map(node => { | |
| if (node.type === 'text') return node.content | |
| if (node.type === 'comment') return `<!--${node.content}-->` | |
| const { tagName, attributes, children } = node as ElementAST | |
| const isSelfClosing = voidTags.includes(tagName.toLowerCase()) | |
| if (isSelfClosing) return `<${tagName}${formatAttributes(attributes)}>` | |
| return `<${tagName}${formatAttributes(attributes)}>${toHTML(children)}</${tagName}>` | |
| }) | |
| return htmlStrings.join('') | |
| } |