aboutsummaryrefslogtreecommitdiffhomepage
path: root/nuldoc-src/xml.ts
diff options
context:
space:
mode:
Diffstat (limited to 'nuldoc-src/xml.ts')
-rw-r--r--nuldoc-src/xml.ts37
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 } {