diff options
| -rw-r--r-- | nuldoc-src/xml.ts | 37 |
1 files changed, 35 insertions, 2 deletions
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<Element> { 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, "<![CDATA["); + const content = skipTo(p, "]]>"); + next(p, "]]>".length); + return { + kind: "text", + content: formatCdata(content), + }; +} + +function formatCdata(s: string): string { + // <![CDATA[ + // foo + // bar + // baz + // ]]> + // => "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<string, string>; closed: boolean } { |
