|
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('') |
|
} |