@ferax564/noma-cli 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +199 -0
- package/bin/noma.mjs +8 -0
- package/dist/ast.d.ts +111 -0
- package/dist/ast.js +23 -0
- package/dist/ast.js.map +1 -0
- package/dist/book.d.ts +56 -0
- package/dist/book.js +120 -0
- package/dist/book.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +573 -0
- package/dist/cli.js.map +1 -0
- package/dist/diff.d.ts +29 -0
- package/dist/diff.js +77 -0
- package/dist/diff.js.map +1 -0
- package/dist/fmt.d.ts +1 -0
- package/dist/fmt.js +105 -0
- package/dist/fmt.js.map +1 -0
- package/dist/ids.d.ts +15 -0
- package/dist/ids.js +27 -0
- package/dist/ids.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/inline.d.ts +14 -0
- package/dist/inline.js +83 -0
- package/dist/inline.js.map +1 -0
- package/dist/loader.d.ts +12 -0
- package/dist/loader.js +59 -0
- package/dist/loader.js.map +1 -0
- package/dist/parser.d.ts +7 -0
- package/dist/parser.js +434 -0
- package/dist/parser.js.map +1 -0
- package/dist/patch.d.ts +61 -0
- package/dist/patch.js +530 -0
- package/dist/patch.js.map +1 -0
- package/dist/renderer-html.d.ts +44 -0
- package/dist/renderer-html.js +929 -0
- package/dist/renderer-html.js.map +1 -0
- package/dist/renderer-json.d.ts +5 -0
- package/dist/renderer-json.js +4 -0
- package/dist/renderer-json.js.map +1 -0
- package/dist/renderer-llm.d.ts +29 -0
- package/dist/renderer-llm.js +275 -0
- package/dist/renderer-llm.js.map +1 -0
- package/dist/renderer-noma.d.ts +10 -0
- package/dist/renderer-noma.js +179 -0
- package/dist/renderer-noma.js.map +1 -0
- package/dist/renderer-site.d.ts +11 -0
- package/dist/renderer-site.js +175 -0
- package/dist/renderer-site.js.map +1 -0
- package/dist/validator.d.ts +24 -0
- package/dist/validator.js +699 -0
- package/dist/validator.js.map +1 -0
- package/dist/verify.d.ts +10 -0
- package/dist/verify.js +141 -0
- package/dist/verify.js.map +1 -0
- package/package.json +83 -0
- package/schemas/ast.schema.json +187 -0
- package/schemas/capability.schema.json +70 -0
- package/schemas/patch-op.schema.json +92 -0
- package/schemas/patch-transaction.schema.json +28 -0
- package/schemas/transcript.schema.json +95 -0
- package/src/ast.ts +152 -0
- package/src/book.ts +162 -0
- package/src/cli.ts +595 -0
- package/src/diff.ts +108 -0
- package/src/fmt.ts +126 -0
- package/src/ids.ts +42 -0
- package/src/index.ts +20 -0
- package/src/inline.ts +92 -0
- package/src/loader.ts +55 -0
- package/src/parser.ts +501 -0
- package/src/patch.ts +646 -0
- package/src/renderer-html.ts +1047 -0
- package/src/renderer-json.ts +9 -0
- package/src/renderer-llm.ts +320 -0
- package/src/renderer-noma.ts +220 -0
- package/src/renderer-site.ts +245 -0
- package/src/validator.ts +733 -0
- package/src/verify.ts +157 -0
- package/themes/dark.css +382 -0
- package/themes/default.css +537 -0
package/dist/diff.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { isDirective, walk } from "./ast.js";
|
|
2
|
+
/**
|
|
3
|
+
* Compare two parsed documents and emit a flat list of synthesized
|
|
4
|
+
* `::state_change` directives describing every scalar attribute drift on
|
|
5
|
+
* blocks identified by `id` and present in both snapshots.
|
|
6
|
+
*
|
|
7
|
+
* v0.7 scope: only attributes defined on both sides where the value differs.
|
|
8
|
+
* Out of scope: attribute add (only-after), attribute delete (only-before),
|
|
9
|
+
* prose/heading changes, block adds/deletes, block renames, ID-less
|
|
10
|
+
* directives, nested-children diffs. Tracked for v0.7.1.
|
|
11
|
+
*
|
|
12
|
+
* Throws if either document contains duplicate IDs (the validator already
|
|
13
|
+
* flags this as an error; diff cannot reason about which copy to compare).
|
|
14
|
+
*/
|
|
15
|
+
export function diffDocs(before, after, options) {
|
|
16
|
+
if (typeof options.at !== "string" || options.at.length === 0) {
|
|
17
|
+
throw new Error("diffDocs: options.at is required (YYYY-MM-DD)");
|
|
18
|
+
}
|
|
19
|
+
const at = options.at;
|
|
20
|
+
const beforeIdx = indexById(before);
|
|
21
|
+
const afterIdx = indexById(after);
|
|
22
|
+
const deltas = [];
|
|
23
|
+
for (const [id, afterNode] of afterIdx) {
|
|
24
|
+
const beforeNode = beforeIdx.get(id);
|
|
25
|
+
if (!beforeNode)
|
|
26
|
+
continue;
|
|
27
|
+
for (const delta of diffAttrs(beforeNode.attrs, afterNode.attrs)) {
|
|
28
|
+
deltas.push(makeStateChange(id, delta, at, options.reason));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return deltas;
|
|
32
|
+
}
|
|
33
|
+
function diffAttrs(a, b) {
|
|
34
|
+
const keys = new Set([...Object.keys(a), ...Object.keys(b)]);
|
|
35
|
+
keys.delete("id");
|
|
36
|
+
const out = [];
|
|
37
|
+
for (const k of [...keys].sort()) {
|
|
38
|
+
const av = a[k];
|
|
39
|
+
const bv = b[k];
|
|
40
|
+
if (av === undefined || bv === undefined)
|
|
41
|
+
continue;
|
|
42
|
+
if (Object.is(av, bv))
|
|
43
|
+
continue;
|
|
44
|
+
out.push({ attribute: k, from: av, to: bv });
|
|
45
|
+
}
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
function indexById(doc) {
|
|
49
|
+
const map = new Map();
|
|
50
|
+
for (const node of walk(doc)) {
|
|
51
|
+
if (!isDirective(node) || !node.id)
|
|
52
|
+
continue;
|
|
53
|
+
if (map.has(node.id)) {
|
|
54
|
+
throw new Error(`diffDocs: duplicate id "${node.id}" — fix with \`noma check\` first`);
|
|
55
|
+
}
|
|
56
|
+
map.set(node.id, node);
|
|
57
|
+
}
|
|
58
|
+
return map;
|
|
59
|
+
}
|
|
60
|
+
function makeStateChange(blockId, delta, at, reason) {
|
|
61
|
+
const attrs = {
|
|
62
|
+
block: blockId,
|
|
63
|
+
attribute: delta.attribute,
|
|
64
|
+
from: delta.from,
|
|
65
|
+
to: delta.to,
|
|
66
|
+
at,
|
|
67
|
+
};
|
|
68
|
+
if (reason)
|
|
69
|
+
attrs.reason = reason;
|
|
70
|
+
return {
|
|
71
|
+
type: "directive",
|
|
72
|
+
name: "state_change",
|
|
73
|
+
attrs,
|
|
74
|
+
children: [],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=diff.js.map
|
package/dist/diff.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"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"}
|
package/dist/fmt.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function formatSource(source: string): string;
|
package/dist/fmt.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source formatter — currently scoped to GitHub-style pipe tables.
|
|
3
|
+
*
|
|
4
|
+
* The parser already accepts misaligned tables; this rewriter exists so the
|
|
5
|
+
* *source* stays readable even when cell widths drift (mixed `✓`/long-prose
|
|
6
|
+
* columns are the friction point). It only touches recognised pipe-table
|
|
7
|
+
* blocks; unrelated lines are byte-identical to the input.
|
|
8
|
+
*/
|
|
9
|
+
import { splitPipeRow } from "./inline.js";
|
|
10
|
+
const TABLE_ROW_RE = /^\s*\|.*\|\s*$/;
|
|
11
|
+
const TABLE_SEPARATOR_RE = /^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/;
|
|
12
|
+
const FENCE_RE = /^```(\w*)\s*$/;
|
|
13
|
+
function visibleWidth(s) {
|
|
14
|
+
// js String.length — good enough for ASCII; not perfect for full-width
|
|
15
|
+
// CJK or emoji clusters, but predictable and dependency-free.
|
|
16
|
+
return Array.from(s).length;
|
|
17
|
+
}
|
|
18
|
+
const splitRow = splitPipeRow;
|
|
19
|
+
function parseSeparator(line) {
|
|
20
|
+
if (!TABLE_SEPARATOR_RE.test(line))
|
|
21
|
+
return null;
|
|
22
|
+
return splitRow(line).map((c) => ({
|
|
23
|
+
left: c.startsWith(":"),
|
|
24
|
+
right: c.endsWith(":"),
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
function buildSeparator(widths, aligns) {
|
|
28
|
+
const cells = widths.map((w, i) => {
|
|
29
|
+
const a = aligns[i] ?? { left: false, right: false };
|
|
30
|
+
const target = Math.max(3, w);
|
|
31
|
+
if (a.left && a.right)
|
|
32
|
+
return `:${"-".repeat(target - 2)}:`;
|
|
33
|
+
if (a.right)
|
|
34
|
+
return `${"-".repeat(target - 1)}:`;
|
|
35
|
+
if (a.left)
|
|
36
|
+
return `:${"-".repeat(target - 1)}`;
|
|
37
|
+
return "-".repeat(target);
|
|
38
|
+
});
|
|
39
|
+
return `| ${cells.join(" | ")} |`;
|
|
40
|
+
}
|
|
41
|
+
function pad(cell, width, align) {
|
|
42
|
+
const w = visibleWidth(cell);
|
|
43
|
+
const slack = Math.max(0, width - w);
|
|
44
|
+
if (align.left && align.right) {
|
|
45
|
+
const left = Math.floor(slack / 2);
|
|
46
|
+
const right = slack - left;
|
|
47
|
+
return " ".repeat(left) + cell + " ".repeat(right);
|
|
48
|
+
}
|
|
49
|
+
if (align.right)
|
|
50
|
+
return " ".repeat(slack) + cell;
|
|
51
|
+
return cell + " ".repeat(slack);
|
|
52
|
+
}
|
|
53
|
+
function buildRow(cells, widths, aligns) {
|
|
54
|
+
const padded = cells.map((c, i) => pad(c, widths[i] ?? visibleWidth(c), aligns[i] ?? { left: false, right: false }));
|
|
55
|
+
return `| ${padded.join(" | ")} |`;
|
|
56
|
+
}
|
|
57
|
+
export function formatSource(source) {
|
|
58
|
+
const lines = source.replace(/\r\n?/g, "\n").split("\n");
|
|
59
|
+
const out = [];
|
|
60
|
+
let i = 0;
|
|
61
|
+
let inFence = false;
|
|
62
|
+
while (i < lines.length) {
|
|
63
|
+
const line = lines[i] ?? "";
|
|
64
|
+
if (FENCE_RE.test(line)) {
|
|
65
|
+
inFence = !inFence;
|
|
66
|
+
out.push(line);
|
|
67
|
+
i++;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (inFence) {
|
|
71
|
+
out.push(line);
|
|
72
|
+
i++;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (TABLE_ROW_RE.test(line) &&
|
|
76
|
+
i + 1 < lines.length &&
|
|
77
|
+
TABLE_SEPARATOR_RE.test(lines[i + 1] ?? "")) {
|
|
78
|
+
const header = splitRow(line);
|
|
79
|
+
const sepAligns = parseSeparator(lines[i + 1] ?? "") ?? [];
|
|
80
|
+
const rows = [];
|
|
81
|
+
let j = i + 2;
|
|
82
|
+
while (j < lines.length && TABLE_ROW_RE.test(lines[j] ?? "")) {
|
|
83
|
+
const cells = splitRow(lines[j] ?? "");
|
|
84
|
+
while (cells.length < header.length)
|
|
85
|
+
cells.push("");
|
|
86
|
+
if (cells.length > header.length)
|
|
87
|
+
cells.length = header.length;
|
|
88
|
+
rows.push(cells);
|
|
89
|
+
j++;
|
|
90
|
+
}
|
|
91
|
+
const widths = header.map((h, idx) => Math.max(visibleWidth(h), ...rows.map((r) => visibleWidth(r[idx] ?? "")), 3));
|
|
92
|
+
const aligns = header.map((_, idx) => sepAligns[idx] ?? { left: false, right: false });
|
|
93
|
+
out.push(buildRow(header, widths, aligns));
|
|
94
|
+
out.push(buildSeparator(widths, aligns));
|
|
95
|
+
for (const r of rows)
|
|
96
|
+
out.push(buildRow(r, widths, aligns));
|
|
97
|
+
i = j;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
out.push(line);
|
|
101
|
+
i++;
|
|
102
|
+
}
|
|
103
|
+
return out.join("\n");
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=fmt.js.map
|
package/dist/fmt.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fmt.js","sourceRoot":"","sources":["../src/fmt.ts"],"names":[],"mappings":"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"}
|
package/dist/ids.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DocumentNode, Node } from "./ast.js";
|
|
2
|
+
export interface IdRecord {
|
|
3
|
+
id: string;
|
|
4
|
+
type: Node["type"];
|
|
5
|
+
name?: string;
|
|
6
|
+
title?: string;
|
|
7
|
+
aliases?: string[];
|
|
8
|
+
line?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface IdRegistry {
|
|
11
|
+
ids: string[];
|
|
12
|
+
aliases: Record<string, string>;
|
|
13
|
+
records: IdRecord[];
|
|
14
|
+
}
|
|
15
|
+
export declare function collectIdRegistry(doc: DocumentNode): IdRegistry;
|
package/dist/ids.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { walk } from "./ast.js";
|
|
2
|
+
export function collectIdRegistry(doc) {
|
|
3
|
+
const ids = [];
|
|
4
|
+
const aliases = {};
|
|
5
|
+
const records = [];
|
|
6
|
+
for (const node of walk(doc)) {
|
|
7
|
+
if (!node.id)
|
|
8
|
+
continue;
|
|
9
|
+
ids.push(node.id);
|
|
10
|
+
const record = {
|
|
11
|
+
id: node.id,
|
|
12
|
+
type: node.type,
|
|
13
|
+
...(node.aliases && node.aliases.length > 0 ? { aliases: node.aliases } : {}),
|
|
14
|
+
...(node.pos?.line ? { line: node.pos.line } : {}),
|
|
15
|
+
};
|
|
16
|
+
if (node.type === "directive")
|
|
17
|
+
record.name = node.name;
|
|
18
|
+
if (node.type === "section")
|
|
19
|
+
record.title = node.title;
|
|
20
|
+
records.push(record);
|
|
21
|
+
for (const alias of node.aliases ?? []) {
|
|
22
|
+
aliases[alias] = node.id;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return { ids, aliases, records };
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=ids.js.map
|
package/dist/ids.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ids.js","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAiBhC,MAAM,UAAU,iBAAiB,CAAC,GAAiB;IACjD,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,OAAO,GAAe,EAAE,CAAC;IAE/B,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,EAAE;YAAE,SAAS;QACvB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClB,MAAM,MAAM,GAAa;YACvB,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7E,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnD,CAAC;QACF,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;YAAE,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACvD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YACvC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AACnC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export * from "./ast.js";
|
|
2
|
+
export { parse, slugify } from "./parser.js";
|
|
3
|
+
export type { ParseOptions } from "./parser.js";
|
|
4
|
+
export { renderHtml } from "./renderer-html.js";
|
|
5
|
+
export type { HtmlRenderOptions } from "./renderer-html.js";
|
|
6
|
+
export { renderLlm } from "./renderer-llm.js";
|
|
7
|
+
export { renderJson } from "./renderer-json.js";
|
|
8
|
+
export type { JsonRenderOptions } from "./renderer-json.js";
|
|
9
|
+
export { renderNoma } from "./renderer-noma.js";
|
|
10
|
+
export type { NomaRenderOptions } from "./renderer-noma.js";
|
|
11
|
+
export { patch, patchAll, patchSource, findById, PatchError } from "./patch.js";
|
|
12
|
+
export type { PatchOp } from "./patch.js";
|
|
13
|
+
export { loadBook, isBookManifestPath, listChapters } from "./book.js";
|
|
14
|
+
export type { BookManifest } from "./book.js";
|
|
15
|
+
export { validate, formatDiagnostics } from "./validator.js";
|
|
16
|
+
export type { ValidateOptions } from "./validator.js";
|
|
17
|
+
export { diffDocs } from "./diff.js";
|
|
18
|
+
export type { DiffOptions } from "./diff.js";
|
|
19
|
+
export { collectIdRegistry } from "./ids.js";
|
|
20
|
+
export type { IdRecord, IdRegistry } from "./ids.js";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export * from "./ast.js";
|
|
2
|
+
export { parse, slugify } from "./parser.js";
|
|
3
|
+
export { renderHtml } from "./renderer-html.js";
|
|
4
|
+
export { renderLlm } from "./renderer-llm.js";
|
|
5
|
+
export { renderJson } from "./renderer-json.js";
|
|
6
|
+
export { renderNoma } from "./renderer-noma.js";
|
|
7
|
+
export { patch, patchAll, patchSource, findById, PatchError } from "./patch.js";
|
|
8
|
+
export { loadBook, isBookManifestPath, listChapters } from "./book.js";
|
|
9
|
+
export { validate, formatDiagnostics } from "./validator.js";
|
|
10
|
+
export { diffDocs } from "./diff.js";
|
|
11
|
+
export { collectIdRegistry } from "./ids.js";
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE7C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhF,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEvE,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAE7D,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAErC,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC"}
|
package/dist/inline.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tiny inline markup parser. Operates on plain text and emits HTML.
|
|
3
|
+
* Order matters: handle code spans first so emphasis inside `code` stays raw.
|
|
4
|
+
*/
|
|
5
|
+
export declare function inlineToHtml(src: string): string;
|
|
6
|
+
export declare function inlineToPlain(src: string): string;
|
|
7
|
+
export declare function escapeHtml(s: string): string;
|
|
8
|
+
export declare function escapeAttr(s: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Split a pipe-table row respecting `code spans` and `\|` escapes — pipes
|
|
11
|
+
* inside backticks or escaped with a backslash are kept verbatim inside the
|
|
12
|
+
* cell. Used by the parser and by `noma fmt` so both agree on cell counts.
|
|
13
|
+
*/
|
|
14
|
+
export declare function splitPipeRow(line: string): string[];
|
package/dist/inline.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tiny inline markup parser. Operates on plain text and emits HTML.
|
|
3
|
+
* Order matters: handle code spans first so emphasis inside `code` stays raw.
|
|
4
|
+
*/
|
|
5
|
+
export function inlineToHtml(src) {
|
|
6
|
+
let text = escapeHtml(src);
|
|
7
|
+
// Code spans go first AND get placeholdered so subsequent inline rules
|
|
8
|
+
// (emphasis, links, wikilinks) don't reach into their content. Without the
|
|
9
|
+
// placeholder, a sequence like `x_y` ... `a_b` lets the underscore regex
|
|
10
|
+
// greedily span across the rendered <code> tags.
|
|
11
|
+
const codeSpans = [];
|
|
12
|
+
const PH_OPEN = String.fromCharCode(2);
|
|
13
|
+
const PH_CLOSE = String.fromCharCode(3);
|
|
14
|
+
text = text.replace(/`([^`]+)`/g, (_m, body) => {
|
|
15
|
+
const i = codeSpans.push("<code>" + body + "</code>") - 1;
|
|
16
|
+
return PH_OPEN + i + PH_CLOSE;
|
|
17
|
+
});
|
|
18
|
+
text = text.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
|
|
19
|
+
text = text.replace(/\*([^*]+)\*/g, "<em>$1</em>");
|
|
20
|
+
text = text.replace(/\b_([^_]+)_\b/g, "<em>$1</em>");
|
|
21
|
+
text = text.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, (_m, label, href) => `<a href="${escapeAttr(href)}">${label}</a>`);
|
|
22
|
+
text = text.replace(/\[\[([a-zA-Z_][\w\-./:]*)\]\]/g, (_m, id) => `<a class="noma-ref" href="#${escapeAttr(id)}">${id}</a>`);
|
|
23
|
+
// CommonMark: a single newline inside a paragraph is a soft line break
|
|
24
|
+
// (renders as a space); two trailing spaces or a trailing backslash before
|
|
25
|
+
// the newline make it a hard break (`<br/>`).
|
|
26
|
+
text = text.replace(/(?: +|\\)\n/g, "<br />");
|
|
27
|
+
text = text.replace(/\n/g, " ");
|
|
28
|
+
// Restore code-span placeholders.
|
|
29
|
+
const restoreRe = new RegExp(PH_OPEN + "(\\d+)" + PH_CLOSE, "g");
|
|
30
|
+
text = text.replace(restoreRe, (_m, i) => codeSpans[Number(i)] ?? "");
|
|
31
|
+
return text;
|
|
32
|
+
}
|
|
33
|
+
export function inlineToPlain(src) {
|
|
34
|
+
return src
|
|
35
|
+
.replace(/`([^`]+)`/g, "$1")
|
|
36
|
+
.replace(/\*\*([^*]+)\*\*/g, "$1")
|
|
37
|
+
.replace(/\*([^*]+)\*/g, "$1")
|
|
38
|
+
.replace(/\b_([^_]+)_\b/g, "$1")
|
|
39
|
+
.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g, "$1 ($2)")
|
|
40
|
+
.replace(/\[\[([a-zA-Z_][\w\-./:]*)\]\]/g, "$1");
|
|
41
|
+
}
|
|
42
|
+
export function escapeHtml(s) {
|
|
43
|
+
return s
|
|
44
|
+
.replace(/&/g, "&")
|
|
45
|
+
.replace(/</g, "<")
|
|
46
|
+
.replace(/>/g, ">");
|
|
47
|
+
}
|
|
48
|
+
export function escapeAttr(s) {
|
|
49
|
+
return escapeHtml(s).replace(/"/g, """);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Split a pipe-table row respecting `code spans` and `\|` escapes — pipes
|
|
53
|
+
* inside backticks or escaped with a backslash are kept verbatim inside the
|
|
54
|
+
* cell. Used by the parser and by `noma fmt` so both agree on cell counts.
|
|
55
|
+
*/
|
|
56
|
+
export function splitPipeRow(line) {
|
|
57
|
+
const trimmed = line.trim().replace(/^\|/, "").replace(/\|$/, "");
|
|
58
|
+
const cells = [];
|
|
59
|
+
let buf = "";
|
|
60
|
+
let inBacktick = false;
|
|
61
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
62
|
+
const ch = trimmed[i];
|
|
63
|
+
if (ch === "\\" && trimmed[i + 1] === "|") {
|
|
64
|
+
buf += "\\|";
|
|
65
|
+
i++;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (ch === "`") {
|
|
69
|
+
inBacktick = !inBacktick;
|
|
70
|
+
buf += ch;
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (ch === "|" && !inBacktick) {
|
|
74
|
+
cells.push(buf.trim());
|
|
75
|
+
buf = "";
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
buf += ch;
|
|
79
|
+
}
|
|
80
|
+
cells.push(buf.trim());
|
|
81
|
+
return cells;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=inline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inline.js","sourceRoot":"","sources":["../src/inline.ts"],"names":[],"mappings":"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"}
|
package/dist/loader.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { DocumentNode } from "./ast.js";
|
|
2
|
+
/**
|
|
3
|
+
* In-place: for every `::dataset{src="..."}` block without an inline body,
|
|
4
|
+
* read the referenced file and stuff its contents into `body`. Sets the
|
|
5
|
+
* `format` attribute (csv/tsv/json/yaml) when not already provided.
|
|
6
|
+
*
|
|
7
|
+
* Path resolution: absolute paths used as-is, relative paths resolved
|
|
8
|
+
* against `baseDir` (or the document's own filename's directory).
|
|
9
|
+
*
|
|
10
|
+
* Renderers stay pure — they read `body` and `format`, never the filesystem.
|
|
11
|
+
*/
|
|
12
|
+
export declare function inlineDatasetSources(doc: DocumentNode, baseDir?: string): DocumentNode;
|
package/dist/loader.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { readFileSync } from "node:fs";
|
|
2
|
+
import { dirname, isAbsolute, resolve } from "node:path";
|
|
3
|
+
import { walk } from "./ast.js";
|
|
4
|
+
/**
|
|
5
|
+
* In-place: for every `::dataset{src="..."}` block without an inline body,
|
|
6
|
+
* read the referenced file and stuff its contents into `body`. Sets the
|
|
7
|
+
* `format` attribute (csv/tsv/json/yaml) when not already provided.
|
|
8
|
+
*
|
|
9
|
+
* Path resolution: absolute paths used as-is, relative paths resolved
|
|
10
|
+
* against `baseDir` (or the document's own filename's directory).
|
|
11
|
+
*
|
|
12
|
+
* Renderers stay pure — they read `body` and `format`, never the filesystem.
|
|
13
|
+
*/
|
|
14
|
+
export function inlineDatasetSources(doc, baseDir) {
|
|
15
|
+
const dir = baseDir ??
|
|
16
|
+
(typeof doc.meta.filename === "string"
|
|
17
|
+
? dirname(doc.meta.filename)
|
|
18
|
+
: process.cwd());
|
|
19
|
+
for (const node of walk(doc)) {
|
|
20
|
+
if (node.type !== "directive" || node.name !== "dataset")
|
|
21
|
+
continue;
|
|
22
|
+
const src = node.attrs.src;
|
|
23
|
+
if (typeof src !== "string" || !src.trim())
|
|
24
|
+
continue;
|
|
25
|
+
if (node.body && node.body.trim())
|
|
26
|
+
continue;
|
|
27
|
+
const path = isAbsolute(src) ? src : resolve(dir, src);
|
|
28
|
+
try {
|
|
29
|
+
const content = readFileSync(path, "utf8");
|
|
30
|
+
node.body = content;
|
|
31
|
+
if (!node.attrs.format) {
|
|
32
|
+
node.attrs.format = inferFormat(src, content);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
node.body = `# error loading ${src}: ${e.message}`;
|
|
37
|
+
node.attrs.format = "error";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return doc;
|
|
41
|
+
}
|
|
42
|
+
function inferFormat(src, content) {
|
|
43
|
+
const ext = src.split(".").pop()?.toLowerCase();
|
|
44
|
+
if (ext === "csv")
|
|
45
|
+
return "csv";
|
|
46
|
+
if (ext === "tsv")
|
|
47
|
+
return "tsv";
|
|
48
|
+
if (ext === "json")
|
|
49
|
+
return "json";
|
|
50
|
+
if (ext === "yaml" || ext === "yml")
|
|
51
|
+
return "yaml";
|
|
52
|
+
const head = content.trimStart()[0];
|
|
53
|
+
if (head === "{" || head === "[")
|
|
54
|
+
return "json";
|
|
55
|
+
if (/^[^\n]*,[^\n]*\n/.test(content))
|
|
56
|
+
return "csv";
|
|
57
|
+
return "yaml";
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzD,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAiB,EACjB,OAAgB;IAEhB,MAAM,GAAG,GACP,OAAO;QACP,CAAC,OAAO,GAAG,CAAC,IAAI,CAAC,QAAQ,KAAK,QAAQ;YACpC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC;YAC5B,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7B,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS;QACnE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC;QAC3B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;YAAE,SAAS;QACrD,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,SAAS;QAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC3C,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC;YACpB,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBACvB,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAChD,CAAC;QACH,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,CAAC,IAAI,GAAG,mBAAmB,GAAG,KAAM,CAAW,CAAC,OAAO,EAAE,CAAC;YAC9D,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,WAAW,CAAC,GAAW,EAAE,OAAe;IAC/C,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,WAAW,EAAE,CAAC;IAChD,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IAChC,IAAI,GAAG,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK;QAAE,OAAO,MAAM,CAAC;IACnD,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;IACpC,IAAI,IAAI,KAAK,GAAG,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,MAAM,CAAC;IAChD,IAAI,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC;IACnD,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
package/dist/parser.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DocumentNode } from "./ast.js";
|
|
2
|
+
export interface ParseOptions {
|
|
3
|
+
/** Optional source filename, kept on the document meta for diagnostics. */
|
|
4
|
+
filename?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function parse(source: string, options?: ParseOptions): DocumentNode;
|
|
7
|
+
export declare function slugify(input: string): string;
|