From 2745531bc541b9e526f0b25ffd396dad4749546b Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 15 Mar 2023 01:37:33 +0900 Subject: feat(nuldoc): support CDATA section --- nuldoc-src/xml.ts | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'nuldoc-src/xml.ts') diff --git a/nuldoc-src/xml.ts b/nuldoc-src/xml.ts index 0bfbd8d..bb7d499 100644 --- a/nuldoc-src/xml.ts +++ b/nuldoc-src/xml.ts @@ -3,7 +3,6 @@ import { XmlParseError } from "./errors.ts"; // TODO // Support comment? -// Support CDATA export async function parseXmlFile(filePath: string): Promise { const source = await Deno.readTextFile(filePath); @@ -64,8 +63,11 @@ function parseChildNodes(p: Parser): Node[] { if (c === "<") { if (c2 === "/") { break; + } else if (c2 === "!") { + nodes.push(parseCdata(p)); + } else { + nodes.push(parseXmlElement(p)); } - nodes.push(parseXmlElement(p)); } else { nodes.push(parseTextNode(p)); } @@ -81,6 +83,37 @@ function parseTextNode(p: Parser): Text { }; } +function parseCdata(p: Parser): Text { + expect(p, ""); + next(p, "]]>".length); + return { + kind: "text", + content: formatCdata(content), + }; +} + +function formatCdata(s: string): string { + // + // => "foo\n bar\nbaz" + s = s.replace(/^\n(.*)\n *$/s, "$1"); + const ls = s.split("\n"); + const n = Math.min( + ...ls.filter((l) => l !== "").map((l) => + l.match(/^( *)/)?.[0]?.length ?? 0 + ), + ); + let z = ""; + for (const p of s.split("\n")) { + z += p.slice(n) + "\n"; + } + return z.slice(0, -1); +} + function parseStartTag( p: Parser, ): { name: string; attributes: Map; closed: boolean } { -- cgit v1.2.3-70-g09d2