Archived
1
0
Fork 0
This repository has been archived on 2024-07-25. You can view files and clone it, but cannot push or open issues or pull requests.
paren/lib/str.mjs

53 lines
1.4 KiB
JavaScript
Raw Normal View History

2022-03-14 10:32:45 +03:00
import { isBool, isNil } from "./lang.mjs";
2022-03-16 22:25:36 +03:00
import { Elem, TextNode } from "./nodes.mjs";
2022-03-14 10:32:45 +03:00
export class StrRenderer {
2022-03-18 22:00:44 +03:00
render(node) {
return encodeNode(node);
2022-03-14 10:32:45 +03:00
}
}
2022-03-18 22:00:44 +03:00
function encodeAnyNode(node) {
return !node
? null
2022-03-18 22:00:44 +03:00
: node instanceof TextNode
? encodeTextNode(node)
: encodeNode(node);
2022-03-14 10:32:45 +03:00
}
function encodeTextNode(node) {
2022-03-16 22:25:36 +03:00
return String(node);
2022-03-14 10:32:45 +03:00
}
2022-03-18 22:00:44 +03:00
function encodeNode(node) {
2022-03-16 22:25:36 +03:00
const encodedChildren = isNil(node.children)
? undefined
2022-03-18 22:14:42 +03:00
: node.children.map(encodeAnyNode);
2022-03-16 22:25:36 +03:00
return node instanceof Elem
? encodeHtmlElement(node.tagName, node.attrs, encodedChildren)
: encodeHtmlFragment(encodedChildren);
2022-03-14 10:32:45 +03:00
}
2022-03-16 22:25:36 +03:00
function encodeHtmlFragment(children) {
2022-03-18 22:14:42 +03:00
return concat(children ?? []);
2022-03-16 22:25:36 +03:00
}
function encodeHtmlElement(tagName, attrs, children) {
2022-03-18 22:14:42 +03:00
const open = `<${join(" ", [tagName, encodeAttrs(attrs)])}>`;
2022-03-14 10:32:45 +03:00
if (isNil(children))
return open;
2022-03-18 22:14:42 +03:00
return `${open}${concat(children)}</${tagName}>`;
2022-03-14 10:32:45 +03:00
}
function encodeAttrs(attrs) {
if (!attrs)
2022-03-18 22:14:42 +03:00
return null;
return join(" ", Object.entries(attrs).map(([key, value]) => encodeAttr(key, value)));
2022-03-14 10:32:45 +03:00
}
function encodeAttr(key, value) {
if (isNil(value))
return null;
if (isBool(value))
return value ? key : null;
return `${key}="${value}"`;
}
2022-03-18 22:14:42 +03:00
function concat(arr) {
return join("", arr);
}
function join(sep, arr) {
return arr.filter(Boolean).join(sep);
}