30 lines
2.4 KiB
JavaScript
30 lines
2.4 KiB
JavaScript
// Per-block round trip: parse each top-level block's own source and serialise it again.
|
|
import { readFileSync } from "node:fs";
|
|
import { pathToFileURL } from "node:url";
|
|
const [, , pmdist, mdindex, root, list] = process.argv;
|
|
const PM = await import(pathToFileURL(pmdist).href);
|
|
const MarkdownIt = (await import(pathToFileURL(mdindex).href)).default;
|
|
const { MarkdownParser, MarkdownSerializer, defaultMarkdownParser: D, defaultMarkdownSerializer: S, schema } = PM;
|
|
const tokenizer = MarkdownIt("commonmark", { html: false });
|
|
const keepWraps = { parse(text, env) { const ts = tokenizer.parse(text, env); for (const t of ts) if (t.children) for (const c of t.children) if (c.type === "softbreak") { c.type = "text"; c.content = "\n"; } return ts; } };
|
|
const P2 = new MarkdownParser(schema, keepWraps, D.tokens);
|
|
const S2 = new MarkdownSerializer({ ...S.nodes, bullet_list(state, node) { state.renderList(node, " ", () => "- "); } }, S.marks);
|
|
const mi = MarkdownIt("commonmark", { html: true }).enable("table");
|
|
const stat = {}; const bump = (k, v) => { const s = (stat[k] ??= { n: 0, stock: 0, fixed: 0 }); s.n++; if (v.stock) s.stock++; if (v.fixed) s.fixed++; };
|
|
for (const f of readFileSync(list, "utf8").split("\n").filter(Boolean)) {
|
|
const src = readFileSync(`${root}/${f}`, "utf8"), lines = src.split("\n");
|
|
for (const t of mi.parse(src, {})) {
|
|
if (t.level !== 0 || !t.map || t.nesting === -1) continue;
|
|
const kind = t.type.replace(/_open$/, "");
|
|
if (!["paragraph", "heading", "bullet_list", "ordered_list", "fence", "blockquote", "code_block"].includes(kind)) continue;
|
|
const text = lines.slice(t.map[0], t.map[1]).join("\n").replace(/\n+$/, "");
|
|
let a = false, b = false;
|
|
try { a = S.serialize(D.parse(text)) === text; } catch {}
|
|
try { b = S2.serialize(P2.parse(text)) === text; } catch {}
|
|
bump(kind, { stock: a, fixed: b });
|
|
}
|
|
}
|
|
let N = 0, A = 0, B = 0;
|
|
for (const [k, s] of Object.entries(stat)) { N += s.n; A += s.stock; B += s.fixed; console.log(k.padEnd(13), String(s.n).padStart(5), "stock exact", String(s.stock).padStart(5), (100 * s.stock / s.n).toFixed(0) + "%", " wraps+dash exact", String(s.fixed).padStart(5), (100 * s.fixed / s.n).toFixed(0) + "%"); }
|
|
console.log("ALL".padEnd(13), String(N).padStart(5), "stock exact", String(A).padStart(5), (100 * A / N).toFixed(0) + "%", " wraps+dash exact", String(B).padStart(5), (100 * B / N).toFixed(0) + "%");
|