From 0766039bd9e6b9f5e6334e84666f5be698d41fc3 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Fri, 17 Mar 2023 01:35:04 +0900 Subject: feat(nuldoc): implement syntax highlight --- nuldoc-src/docbook/to_html.ts | 31 +++++++++++++++++++++++++++++++ nuldoc-src/html.ts | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'nuldoc-src') diff --git a/nuldoc-src/docbook/to_html.ts b/nuldoc-src/docbook/to_html.ts index 64d3492..24be139 100644 --- a/nuldoc-src/docbook/to_html.ts +++ b/nuldoc-src/docbook/to_html.ts @@ -1,3 +1,5 @@ +import hljs from "hljs/highlight.min.js"; +import hljsPhp from "hljs/languages/php.min.js"; import { Document } from "./document.ts"; import { DocBookError } from "../errors.ts"; import { @@ -31,6 +33,7 @@ export default function toHtml(doc: Document): Document { transformNoteElement(doc); setDefaultLangAttribute(doc); traverseFootnotes(doc); + highlightPrograms(doc); return doc; } @@ -277,3 +280,31 @@ function traverseFootnotes(doc: Document) { 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 sourceCode = codeElement.children[0].content; + + const validLanguage = hljs.getLanguage(language) ? language : "plaintext"; + const highlighted = + hljs.highlight(sourceCode, { language: validLanguage }).value; + + codeElement.children[0].content = highlighted; + codeElement.attributes.set("class", "highlight"); + }); +} diff --git a/nuldoc-src/html.ts b/nuldoc-src/html.ts index 5e573ad..70b5748 100644 --- a/nuldoc-src/html.ts +++ b/nuldoc-src/html.ts @@ -122,8 +122,8 @@ function nodeToHtmlText(n: Node, ctx: Context): string { } function textNodeToHtmlText(t: Text, ctx: Context): string { + if (ctx.isInPre) return t.content; const s = encodeSpecialCharacters(t.content); - if (ctx.isInPre) return s; // TODO: 日本語で改行するときはスペースを入れない return s -- cgit v1.2.3-70-g09d2