diff options
Diffstat (limited to 'vhosts/blog/nuldoc-src/docbook/to_html.ts')
| -rw-r--r-- | vhosts/blog/nuldoc-src/docbook/to_html.ts | 319 |
1 files changed, 0 insertions, 319 deletions
diff --git a/vhosts/blog/nuldoc-src/docbook/to_html.ts b/vhosts/blog/nuldoc-src/docbook/to_html.ts deleted file mode 100644 index 4add912c..00000000 --- a/vhosts/blog/nuldoc-src/docbook/to_html.ts +++ /dev/null @@ -1,319 +0,0 @@ -// @deno-types="../types/highlight-js.d.ts" -import hljs from "npm:highlight.js"; -import { Document } from "./document.ts"; -import { DocBookError } from "../errors.ts"; -import { - addClass, - Element, - findFirstChildElement, - forEachChild, - forEachChildRecursively, - Node, - RawHTML, - removeChildElements, - Text, -} from "../dom.ts"; - -export default function toHtml(doc: Document): Document { - removeArticleInfo(doc); - removeArticleAttributes(doc); - removeUnnecessaryTextNode(doc); - transformElementNames(doc, "emphasis", "em"); - transformElementNames(doc, "informaltable", "table"); - transformElementNames(doc, "itemizedlist", "ul"); - transformElementNames(doc, "link", "a"); - transformElementNames(doc, "listitem", "li"); - transformElementNames(doc, "literal", "code"); - transformElementNames(doc, "orderedlist", "ol"); - transformElementNames(doc, "para", "p"); - transformElementNames(doc, "superscript", "sup"); - transformAttributeNames(doc, "xml:id", "id"); - transformAttributeNames(doc, "xl:href", "href"); - transformSectionIdAttribute(doc); - setSectionTitleAnchor(doc); - transformSectionTitleElement(doc); - transformProgramListingElement(doc); - transformLiteralLayoutElement(doc); - transformNoteElement(doc); - setDefaultLangAttribute(doc); - traverseFootnotes(doc); - highlightPrograms(doc); - return doc; -} - -function removeArticleInfo(doc: Document) { - const article = findFirstChildElement(doc.root, "article"); - if (!article) { - throw new DocBookError( - `[docbook.tohtml] <article> element not found`, - ); - } - removeChildElements(article, "info"); -} - -function removeArticleAttributes(doc: Document) { - const article = findFirstChildElement(doc.root, "article"); - if (!article) { - throw new DocBookError( - `[docbook.tohtml] <article> element not found`, - ); - } - article.attributes.delete("xmlns"); - article.attributes.delete("xmlns:xl"); - article.attributes.delete("version"); -} - -function removeUnnecessaryTextNode(doc: Document) { - const g = (n: Node) => { - if (n.kind !== "element") { - return; - } - - let changed = true; - while (changed) { - changed = false; - if (n.children.length === 0) { - break; - } - const firstChild = n.children[0]; - if (firstChild.kind === "text" && firstChild.content.trim() === "") { - n.children.shift(); - changed = true; - } - if (n.children.length === 0) { - break; - } - const lastChild = n.children[n.children.length - 1]; - if (lastChild.kind === "text" && lastChild.content.trim() === "") { - n.children.pop(); - changed = true; - } - } - - forEachChild(n, g); - }; - forEachChild(doc.root, g); -} - -function transformElementNames( - doc: Document, - from: string, - to: string, -) { - forEachChildRecursively(doc.root, (n) => { - if (n.kind === "element" && n.name === from) { - n.name = to; - } - }); -} - -function transformAttributeNames( - doc: Document, - from: string, - to: string, -) { - forEachChildRecursively(doc.root, (n) => { - if (n.kind !== "element") { - return; - } - const value = n.attributes.get(from) as string; - if (value !== undefined) { - n.attributes.delete(from); - n.attributes.set(to, value); - } - }); -} - -function transformSectionIdAttribute(doc: Document) { - forEachChildRecursively(doc.root, (n) => { - if (n.kind !== "element" || n.name !== "section") { - return; - } - - const idAttr = n.attributes.get("id"); - n.attributes.set("id", `section--${idAttr}`); - }); -} - -function setSectionTitleAnchor(doc: Document) { - const sectionStack: Element[] = []; - const g = (c: Node) => { - if (c.kind !== "element") { - return; - } - - if (c.name === "section") { - sectionStack.push(c); - } - forEachChild(c, g); - if (c.name === "section") { - sectionStack.pop(); - } - if (c.name === "title") { - const currentSection = sectionStack[sectionStack.length - 1]; - if (!currentSection) { - throw new DocBookError( - "[docbook.tohtml] <title> element must be inside <section>", - ); - } - const sectionId = currentSection.attributes.get("id"); - const aElement: Element = { - kind: "element", - name: "a", - attributes: new Map(), - children: c.children, - }; - aElement.attributes.set("href", `#${sectionId}`); - c.children = [aElement]; - } - }; - forEachChild(doc.root, g); -} - -function transformSectionTitleElement(doc: Document) { - let sectionLevel = 1; - const g = (c: Node) => { - if (c.kind !== "element") { - return; - } - - if (c.name === "section") { - sectionLevel += 1; - c.attributes.set("--section-level", sectionLevel.toString()); - } - forEachChild(c, g); - if (c.name === "section") { - sectionLevel -= 1; - } - if (c.name === "title") { - c.name = `h${sectionLevel}`; - } - }; - forEachChild(doc.root, g); -} - -function transformProgramListingElement(doc: Document) { - forEachChildRecursively(doc.root, (n) => { - if (n.kind !== "element" || n.name !== "programlisting") { - return; - } - - n.name = "pre"; - addClass(n, "highlight"); - const codeElement: Element = { - kind: "element", - name: "code", - attributes: new Map(), - children: n.children, - }; - n.children = [codeElement]; - }); -} - -function transformLiteralLayoutElement(doc: Document) { - forEachChildRecursively(doc.root, (n) => { - if (n.kind !== "element" || n.name !== "literallayout") { - return; - } - - n.name = "pre"; - addClass(n, "highlight"); - const codeElement: Element = { - kind: "element", - name: "code", - attributes: new Map(), - children: n.children, - }; - n.children = [codeElement]; - }); -} - -function transformNoteElement(doc: Document) { - forEachChildRecursively(doc.root, (n) => { - if (n.kind !== "element" || n.name !== "note") { - return; - } - - const labelElement: Element = { - kind: "element", - name: "div", - attributes: new Map([["class", "admonition-label"]]), - children: [{ - kind: "text", - content: "NOTE", - raw: false, - }], - }; - const contentElement: Element = { - kind: "element", - name: "div", - attributes: new Map([["class", "admonition-content"]]), - children: n.children, - }; - n.name = "div"; - addClass(n, "admonition"); - n.children = [ - labelElement, - contentElement, - ]; - }); -} - -function setDefaultLangAttribute(_doc: Document) { - // TODO - // if (!e.attributes.has("lang")) { - // e.attributes.set("lang", "ja-JP"); - // } -} - -function traverseFootnotes(doc: Document) { - forEachChildRecursively(doc.root, (n) => { - if (n.kind !== "element" || n.name !== "footnote") { - return; - } - - // TODO - // <footnote>x</footnote> - // - // <sup class="footnote">[<a id="_footnoteref_1" class="footnote" href="#_footnotedef_1">1</a>]</sup> - // - // <div class="footnote" id="_footnotedef_1"> - // <a href="#_footnoteref_1">1</a>. RAS syndrome - // </div> - n.name = "span"; - n.children = []; - }); -} - -function highlightPrograms(doc: Document) { - forEachChildRecursively(doc.root, (n) => { - if (n.kind !== "element" || n.name !== "pre") { - return; - } - const preClass = n.attributes.get("class") || ""; - if (!preClass.includes("highlight")) { - return; - } - const codeElement = findFirstChildElement(n, "code"); - if (!codeElement) { - return; - } - const language = n.attributes.get("language"); - if (!language) { - return; - } - const sourceCodeNode = codeElement.children[0] as Text | RawHTML; - const sourceCode = sourceCodeNode.content; - - if (!hljs.getLanguage(language)) { - return; - } - - const highlighted = - hljs.highlight(sourceCode, { language: language }).value; - - sourceCodeNode.content = highlighted; - sourceCodeNode.raw = true; - codeElement.attributes.set("class", "highlight"); - }); -} |
