File size: 1,075 Bytes
c20f20c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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('');
};