n3writer-wrapper 1.0.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/dist/index.cjs +122 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +72 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.js +95 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
expandLiterals: () => expandLiterals,
|
|
24
|
+
reindent: () => reindent,
|
|
25
|
+
topoWrite: () => topoWrite
|
|
26
|
+
});
|
|
27
|
+
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
function topoWrite(writer, quads) {
|
|
29
|
+
const termKey = (t) => t.termType === "Literal" ? `L\0${t.value}\0${t.datatype?.value ?? ""}\0${t.language ?? ""}` : `${t.termType[0]}\0${t.value}`;
|
|
30
|
+
const seen = /* @__PURE__ */ new Set();
|
|
31
|
+
const deduped = [...quads].filter((q) => {
|
|
32
|
+
const k = `${termKey(q.graph)}\0${termKey(q.subject)}\0${q.predicate.value}\0${termKey(q.object)}`;
|
|
33
|
+
return seen.size !== seen.add(k).size;
|
|
34
|
+
});
|
|
35
|
+
const bySub = /* @__PURE__ */ new Map();
|
|
36
|
+
const oCount = /* @__PURE__ */ new Map();
|
|
37
|
+
for (const q of deduped) {
|
|
38
|
+
const k = `${q.graph.value}\0${q.subject.termType}\0${q.subject.value}`;
|
|
39
|
+
if (!bySub.has(k)) bySub.set(k, { term: q.subject, graph: q.graph, pos: [] });
|
|
40
|
+
bySub.get(k).pos.push(q);
|
|
41
|
+
if (q.object.termType === "BlankNode") {
|
|
42
|
+
const ok = `${q.graph.value}\0${q.object.value}`;
|
|
43
|
+
oCount.set(ok, (oCount.get(ok) ?? 0) + 1);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
const inlineable = (bn, graph) => oCount.get(`${graph.value}\0${bn.value}`) === 1 && bySub.has(`${graph.value}\0BlankNode\0${bn.value}`);
|
|
47
|
+
function buildBlank(bn, graph) {
|
|
48
|
+
const entry = bySub.get(`${graph.value}\0BlankNode\0${bn.value}`);
|
|
49
|
+
if (!entry) return writer.blank();
|
|
50
|
+
return writer.blank(
|
|
51
|
+
entry.pos.map((q) => ({
|
|
52
|
+
predicate: q.predicate,
|
|
53
|
+
object: q.object.termType === "BlankNode" && inlineable(q.object, graph) ? buildBlank(q.object, graph) : q.object
|
|
54
|
+
}))
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
for (const { term, graph, pos } of bySub.values()) {
|
|
58
|
+
if (term.termType === "BlankNode" && inlineable(term, graph)) continue;
|
|
59
|
+
for (const q of pos) {
|
|
60
|
+
writer.addQuad(
|
|
61
|
+
q.subject,
|
|
62
|
+
q.predicate,
|
|
63
|
+
q.object.termType === "BlankNode" && inlineable(q.object, graph) ? buildBlank(q.object, graph) : q.object,
|
|
64
|
+
q.graph
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function reindent(turtle, step = " ") {
|
|
70
|
+
let depth = 0;
|
|
71
|
+
return turtle.split("\n").map((line) => {
|
|
72
|
+
const t = line.trimStart();
|
|
73
|
+
if (!t) return "";
|
|
74
|
+
let leading = 0;
|
|
75
|
+
while (leading < t.length && t[leading] === "]") {
|
|
76
|
+
depth = Math.max(0, depth - 1);
|
|
77
|
+
leading++;
|
|
78
|
+
}
|
|
79
|
+
let out;
|
|
80
|
+
if (depth > 0) {
|
|
81
|
+
out = step.repeat(depth + 1) + t;
|
|
82
|
+
} else if (leading > 0 || line !== t) {
|
|
83
|
+
out = step + t;
|
|
84
|
+
} else {
|
|
85
|
+
out = line.trimEnd();
|
|
86
|
+
}
|
|
87
|
+
if (t.trimEnd().endsWith("[")) {
|
|
88
|
+
let opens = 0, closes = 0, inStr = false, i = 0;
|
|
89
|
+
while (i < t.length) {
|
|
90
|
+
const c = t[i];
|
|
91
|
+
if (c === "\\" && inStr) {
|
|
92
|
+
i += 2;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (c === '"') inStr = !inStr;
|
|
96
|
+
else if (!inStr) {
|
|
97
|
+
if (c === "[") opens++;
|
|
98
|
+
else if (c === "]") closes++;
|
|
99
|
+
}
|
|
100
|
+
i++;
|
|
101
|
+
}
|
|
102
|
+
const netOpen = opens - closes + leading;
|
|
103
|
+
if (netOpen > 0) depth += netOpen;
|
|
104
|
+
}
|
|
105
|
+
return out;
|
|
106
|
+
}).join("\n");
|
|
107
|
+
}
|
|
108
|
+
function expandLiterals(turtle) {
|
|
109
|
+
return turtle.replace(/"((?:[^"\\]|\\.)*)"/g, (match, content) => {
|
|
110
|
+
if (!content.includes("\\n")) return match;
|
|
111
|
+
const expanded = content.replace(/\\n/g, "\n");
|
|
112
|
+
if (expanded.includes('"""')) return match;
|
|
113
|
+
return `"""${expanded}"""`;
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
117
|
+
0 && (module.exports = {
|
|
118
|
+
expandLiterals,
|
|
119
|
+
reindent,
|
|
120
|
+
topoWrite
|
|
121
|
+
});
|
|
122
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * n3writer-wrapper\n *\n * Helpers that improve the readability of Turtle/TriG output from n3.Writer:\n *\n * topoWrite(writer, quads) — feed quads to an N3 Writer using nested [ ]\n * notation for blank nodes that appear as an\n * object exactly once (tree-edge inlining).\n *\n * reindent(turtle, step?) — post-process a Turtle/TriG string so that\n * predicate-continuation lines use `step`\n * (default 2 spaces) instead of n3.Writer's\n * hard-coded 4, and blank-node content at depth\n * d uses step × (d+1).\n *\n * expandLiterals(turtle) — convert STRING_LITERAL2 values containing \\n\n * into STRING_LITERAL_LONG2 (\"\"\"…\"\"\") with a\n * real embedded newline.\n */\n\n/** Minimal structural interface for terms (compatible with n3, rdfjs, graphy). */\nexport interface RdfTerm {\n termType: string;\n value: string;\n datatype?: { value: string };\n language?: string;\n}\n\n/** Minimal structural interface for quads. */\nexport interface RdfQuad {\n subject: RdfTerm;\n predicate: RdfTerm;\n object: RdfTerm;\n graph: RdfTerm;\n}\n\n/**\n * Minimal structural interface for the n3.Writer methods that topoWrite uses.\n * Any object that provides blank() and addQuad() with these signatures works.\n */\nexport interface TurtleWriter {\n blank(predicates?: Array<{ predicate: RdfTerm; object: unknown }>): unknown;\n addQuad(subject: RdfTerm, predicate: RdfTerm, object: unknown, graph?: RdfTerm): void;\n}\n\n/**\n * Write quads to an N3 Writer using nested [ ] notation for blank nodes that\n * appear as an object exactly once (sole child in a tree edge). Blank nodes\n * used more than once as objects, or that have no subject triples, fall back\n * to the normal _:label reference. CONSTRUCT-style duplicate quads are\n * deduplicated before processing.\n */\nexport function topoWrite(writer: TurtleWriter, quads: Iterable<RdfQuad>): void {\n const termKey = (t: RdfTerm): string =>\n t.termType === 'Literal'\n ? `L\\0${t.value}\\0${t.datatype?.value ?? ''}\\0${t.language ?? ''}`\n : `${t.termType[0]}\\0${t.value}`;\n\n const seen = new Set<string>();\n const deduped = [...quads].filter(q => {\n const k = `${termKey(q.graph)}\\0${termKey(q.subject)}\\0${q.predicate.value}\\0${termKey(q.object)}`;\n return seen.size !== seen.add(k).size;\n });\n\n // Index quads by (graph, subject); count blank-node object occurrences per graph.\n const bySub = new Map<string, { term: RdfTerm; graph: RdfTerm; pos: RdfQuad[] }>();\n const oCount = new Map<string, number>();\n\n for (const q of deduped) {\n const k = `${q.graph.value}\\0${q.subject.termType}\\0${q.subject.value}`;\n if (!bySub.has(k)) bySub.set(k, { term: q.subject, graph: q.graph, pos: [] });\n bySub.get(k)!.pos.push(q);\n if (q.object.termType === 'BlankNode') {\n const ok = `${q.graph.value}\\0${q.object.value}`;\n oCount.set(ok, (oCount.get(ok) ?? 0) + 1);\n }\n }\n\n const inlineable = (bn: RdfTerm, graph: RdfTerm): boolean =>\n oCount.get(`${graph.value}\\0${bn.value}`) === 1 &&\n bySub.has(`${graph.value}\\0BlankNode\\0${bn.value}`);\n\n function buildBlank(bn: RdfTerm, graph: RdfTerm): unknown {\n const entry = bySub.get(`${graph.value}\\0BlankNode\\0${bn.value}`);\n if (!entry) return writer.blank();\n return writer.blank(\n entry.pos.map(q => ({\n predicate: q.predicate,\n object:\n q.object.termType === 'BlankNode' && inlineable(q.object, graph)\n ? buildBlank(q.object, graph)\n : q.object,\n })),\n );\n }\n\n for (const { term, graph, pos } of bySub.values()) {\n if (term.termType === 'BlankNode' && inlineable(term, graph)) continue;\n for (const q of pos) {\n writer.addQuad(\n q.subject,\n q.predicate,\n q.object.termType === 'BlankNode' && inlineable(q.object, graph)\n ? buildBlank(q.object, graph)\n : q.object,\n q.graph,\n );\n }\n }\n}\n\n/**\n * Post-process an N3.js Writer Turtle/TriG string with uniform indentation.\n *\n * n3.Writer uses 4 spaces for predicate-continuation lines and 2 spaces inside\n * blank-node [ ] blocks. reindent normalises this so that each additional level\n * of [ ] nesting adds exactly one `step` (default: 2 spaces).\n */\nexport function reindent(turtle: string, step = ' '): string {\n let depth = 0;\n return turtle\n .split('\\n')\n .map(line => {\n const t = line.trimStart();\n if (!t) return '';\n\n // Leading ] chars close blocks: reduce depth before outputting this line.\n let leading = 0;\n while (leading < t.length && t[leading] === ']') {\n depth = Math.max(0, depth - 1);\n leading++;\n }\n\n let out: string;\n if (depth > 0) {\n out = step.repeat(depth + 1) + t;\n } else if (leading > 0 || line !== t) {\n out = step + t;\n } else {\n out = line.trimEnd();\n }\n\n // Count net unbalanced [ brackets outside string literals to track depth.\n if (t.trimEnd().endsWith('[')) {\n let opens = 0,\n closes = 0,\n inStr = false,\n i = 0;\n while (i < t.length) {\n const c = t[i];\n if (c === '\\\\' && inStr) {\n i += 2;\n continue;\n }\n if (c === '\"') inStr = !inStr;\n else if (!inStr) {\n if (c === '[') opens++;\n else if (c === ']') closes++;\n }\n i++;\n }\n const netOpen = opens - closes + leading;\n if (netOpen > 0) depth += netOpen;\n }\n\n return out;\n })\n .join('\\n');\n}\n\n/**\n * Replace STRING_LITERAL2 values that contain the \\n escape sequence with\n * STRING_LITERAL_LONG2 (triple-quoted) with a real embedded newline.\n *\n * Falls back to the original form if the expanded content contains \"\"\" (which\n * cannot appear unescaped inside a long literal).\n */\nexport function expandLiterals(turtle: string): string {\n return turtle.replace(/\"((?:[^\"\\\\]|\\\\.)*)\"/g, (match, content: string) => {\n if (!content.includes('\\\\n')) return match;\n const expanded = content.replace(/\\\\n/g, '\\n');\n if (expanded.includes('\"\"\"')) return match;\n return `\"\"\"${expanded}\"\"\"`;\n });\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* n3writer-wrapper
|
|
3
|
+
*
|
|
4
|
+
* Helpers that improve the readability of Turtle/TriG output from n3.Writer:
|
|
5
|
+
*
|
|
6
|
+
* topoWrite(writer, quads) — feed quads to an N3 Writer using nested [ ]
|
|
7
|
+
* notation for blank nodes that appear as an
|
|
8
|
+
* object exactly once (tree-edge inlining).
|
|
9
|
+
*
|
|
10
|
+
* reindent(turtle, step?) — post-process a Turtle/TriG string so that
|
|
11
|
+
* predicate-continuation lines use `step`
|
|
12
|
+
* (default 2 spaces) instead of n3.Writer's
|
|
13
|
+
* hard-coded 4, and blank-node content at depth
|
|
14
|
+
* d uses step × (d+1).
|
|
15
|
+
*
|
|
16
|
+
* expandLiterals(turtle) — convert STRING_LITERAL2 values containing \n
|
|
17
|
+
* into STRING_LITERAL_LONG2 ("""…""") with a
|
|
18
|
+
* real embedded newline.
|
|
19
|
+
*/
|
|
20
|
+
/** Minimal structural interface for terms (compatible with n3, rdfjs, graphy). */
|
|
21
|
+
interface RdfTerm {
|
|
22
|
+
termType: string;
|
|
23
|
+
value: string;
|
|
24
|
+
datatype?: {
|
|
25
|
+
value: string;
|
|
26
|
+
};
|
|
27
|
+
language?: string;
|
|
28
|
+
}
|
|
29
|
+
/** Minimal structural interface for quads. */
|
|
30
|
+
interface RdfQuad {
|
|
31
|
+
subject: RdfTerm;
|
|
32
|
+
predicate: RdfTerm;
|
|
33
|
+
object: RdfTerm;
|
|
34
|
+
graph: RdfTerm;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Minimal structural interface for the n3.Writer methods that topoWrite uses.
|
|
38
|
+
* Any object that provides blank() and addQuad() with these signatures works.
|
|
39
|
+
*/
|
|
40
|
+
interface TurtleWriter {
|
|
41
|
+
blank(predicates?: Array<{
|
|
42
|
+
predicate: RdfTerm;
|
|
43
|
+
object: unknown;
|
|
44
|
+
}>): unknown;
|
|
45
|
+
addQuad(subject: RdfTerm, predicate: RdfTerm, object: unknown, graph?: RdfTerm): void;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Write quads to an N3 Writer using nested [ ] notation for blank nodes that
|
|
49
|
+
* appear as an object exactly once (sole child in a tree edge). Blank nodes
|
|
50
|
+
* used more than once as objects, or that have no subject triples, fall back
|
|
51
|
+
* to the normal _:label reference. CONSTRUCT-style duplicate quads are
|
|
52
|
+
* deduplicated before processing.
|
|
53
|
+
*/
|
|
54
|
+
declare function topoWrite(writer: TurtleWriter, quads: Iterable<RdfQuad>): void;
|
|
55
|
+
/**
|
|
56
|
+
* Post-process an N3.js Writer Turtle/TriG string with uniform indentation.
|
|
57
|
+
*
|
|
58
|
+
* n3.Writer uses 4 spaces for predicate-continuation lines and 2 spaces inside
|
|
59
|
+
* blank-node [ ] blocks. reindent normalises this so that each additional level
|
|
60
|
+
* of [ ] nesting adds exactly one `step` (default: 2 spaces).
|
|
61
|
+
*/
|
|
62
|
+
declare function reindent(turtle: string, step?: string): string;
|
|
63
|
+
/**
|
|
64
|
+
* Replace STRING_LITERAL2 values that contain the \n escape sequence with
|
|
65
|
+
* STRING_LITERAL_LONG2 (triple-quoted) with a real embedded newline.
|
|
66
|
+
*
|
|
67
|
+
* Falls back to the original form if the expanded content contains """ (which
|
|
68
|
+
* cannot appear unescaped inside a long literal).
|
|
69
|
+
*/
|
|
70
|
+
declare function expandLiterals(turtle: string): string;
|
|
71
|
+
|
|
72
|
+
export { type RdfQuad, type RdfTerm, type TurtleWriter, expandLiterals, reindent, topoWrite };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* n3writer-wrapper
|
|
3
|
+
*
|
|
4
|
+
* Helpers that improve the readability of Turtle/TriG output from n3.Writer:
|
|
5
|
+
*
|
|
6
|
+
* topoWrite(writer, quads) — feed quads to an N3 Writer using nested [ ]
|
|
7
|
+
* notation for blank nodes that appear as an
|
|
8
|
+
* object exactly once (tree-edge inlining).
|
|
9
|
+
*
|
|
10
|
+
* reindent(turtle, step?) — post-process a Turtle/TriG string so that
|
|
11
|
+
* predicate-continuation lines use `step`
|
|
12
|
+
* (default 2 spaces) instead of n3.Writer's
|
|
13
|
+
* hard-coded 4, and blank-node content at depth
|
|
14
|
+
* d uses step × (d+1).
|
|
15
|
+
*
|
|
16
|
+
* expandLiterals(turtle) — convert STRING_LITERAL2 values containing \n
|
|
17
|
+
* into STRING_LITERAL_LONG2 ("""…""") with a
|
|
18
|
+
* real embedded newline.
|
|
19
|
+
*/
|
|
20
|
+
/** Minimal structural interface for terms (compatible with n3, rdfjs, graphy). */
|
|
21
|
+
interface RdfTerm {
|
|
22
|
+
termType: string;
|
|
23
|
+
value: string;
|
|
24
|
+
datatype?: {
|
|
25
|
+
value: string;
|
|
26
|
+
};
|
|
27
|
+
language?: string;
|
|
28
|
+
}
|
|
29
|
+
/** Minimal structural interface for quads. */
|
|
30
|
+
interface RdfQuad {
|
|
31
|
+
subject: RdfTerm;
|
|
32
|
+
predicate: RdfTerm;
|
|
33
|
+
object: RdfTerm;
|
|
34
|
+
graph: RdfTerm;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Minimal structural interface for the n3.Writer methods that topoWrite uses.
|
|
38
|
+
* Any object that provides blank() and addQuad() with these signatures works.
|
|
39
|
+
*/
|
|
40
|
+
interface TurtleWriter {
|
|
41
|
+
blank(predicates?: Array<{
|
|
42
|
+
predicate: RdfTerm;
|
|
43
|
+
object: unknown;
|
|
44
|
+
}>): unknown;
|
|
45
|
+
addQuad(subject: RdfTerm, predicate: RdfTerm, object: unknown, graph?: RdfTerm): void;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Write quads to an N3 Writer using nested [ ] notation for blank nodes that
|
|
49
|
+
* appear as an object exactly once (sole child in a tree edge). Blank nodes
|
|
50
|
+
* used more than once as objects, or that have no subject triples, fall back
|
|
51
|
+
* to the normal _:label reference. CONSTRUCT-style duplicate quads are
|
|
52
|
+
* deduplicated before processing.
|
|
53
|
+
*/
|
|
54
|
+
declare function topoWrite(writer: TurtleWriter, quads: Iterable<RdfQuad>): void;
|
|
55
|
+
/**
|
|
56
|
+
* Post-process an N3.js Writer Turtle/TriG string with uniform indentation.
|
|
57
|
+
*
|
|
58
|
+
* n3.Writer uses 4 spaces for predicate-continuation lines and 2 spaces inside
|
|
59
|
+
* blank-node [ ] blocks. reindent normalises this so that each additional level
|
|
60
|
+
* of [ ] nesting adds exactly one `step` (default: 2 spaces).
|
|
61
|
+
*/
|
|
62
|
+
declare function reindent(turtle: string, step?: string): string;
|
|
63
|
+
/**
|
|
64
|
+
* Replace STRING_LITERAL2 values that contain the \n escape sequence with
|
|
65
|
+
* STRING_LITERAL_LONG2 (triple-quoted) with a real embedded newline.
|
|
66
|
+
*
|
|
67
|
+
* Falls back to the original form if the expanded content contains """ (which
|
|
68
|
+
* cannot appear unescaped inside a long literal).
|
|
69
|
+
*/
|
|
70
|
+
declare function expandLiterals(turtle: string): string;
|
|
71
|
+
|
|
72
|
+
export { type RdfQuad, type RdfTerm, type TurtleWriter, expandLiterals, reindent, topoWrite };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
function topoWrite(writer, quads) {
|
|
3
|
+
const termKey = (t) => t.termType === "Literal" ? `L\0${t.value}\0${t.datatype?.value ?? ""}\0${t.language ?? ""}` : `${t.termType[0]}\0${t.value}`;
|
|
4
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5
|
+
const deduped = [...quads].filter((q) => {
|
|
6
|
+
const k = `${termKey(q.graph)}\0${termKey(q.subject)}\0${q.predicate.value}\0${termKey(q.object)}`;
|
|
7
|
+
return seen.size !== seen.add(k).size;
|
|
8
|
+
});
|
|
9
|
+
const bySub = /* @__PURE__ */ new Map();
|
|
10
|
+
const oCount = /* @__PURE__ */ new Map();
|
|
11
|
+
for (const q of deduped) {
|
|
12
|
+
const k = `${q.graph.value}\0${q.subject.termType}\0${q.subject.value}`;
|
|
13
|
+
if (!bySub.has(k)) bySub.set(k, { term: q.subject, graph: q.graph, pos: [] });
|
|
14
|
+
bySub.get(k).pos.push(q);
|
|
15
|
+
if (q.object.termType === "BlankNode") {
|
|
16
|
+
const ok = `${q.graph.value}\0${q.object.value}`;
|
|
17
|
+
oCount.set(ok, (oCount.get(ok) ?? 0) + 1);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const inlineable = (bn, graph) => oCount.get(`${graph.value}\0${bn.value}`) === 1 && bySub.has(`${graph.value}\0BlankNode\0${bn.value}`);
|
|
21
|
+
function buildBlank(bn, graph) {
|
|
22
|
+
const entry = bySub.get(`${graph.value}\0BlankNode\0${bn.value}`);
|
|
23
|
+
if (!entry) return writer.blank();
|
|
24
|
+
return writer.blank(
|
|
25
|
+
entry.pos.map((q) => ({
|
|
26
|
+
predicate: q.predicate,
|
|
27
|
+
object: q.object.termType === "BlankNode" && inlineable(q.object, graph) ? buildBlank(q.object, graph) : q.object
|
|
28
|
+
}))
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
for (const { term, graph, pos } of bySub.values()) {
|
|
32
|
+
if (term.termType === "BlankNode" && inlineable(term, graph)) continue;
|
|
33
|
+
for (const q of pos) {
|
|
34
|
+
writer.addQuad(
|
|
35
|
+
q.subject,
|
|
36
|
+
q.predicate,
|
|
37
|
+
q.object.termType === "BlankNode" && inlineable(q.object, graph) ? buildBlank(q.object, graph) : q.object,
|
|
38
|
+
q.graph
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function reindent(turtle, step = " ") {
|
|
44
|
+
let depth = 0;
|
|
45
|
+
return turtle.split("\n").map((line) => {
|
|
46
|
+
const t = line.trimStart();
|
|
47
|
+
if (!t) return "";
|
|
48
|
+
let leading = 0;
|
|
49
|
+
while (leading < t.length && t[leading] === "]") {
|
|
50
|
+
depth = Math.max(0, depth - 1);
|
|
51
|
+
leading++;
|
|
52
|
+
}
|
|
53
|
+
let out;
|
|
54
|
+
if (depth > 0) {
|
|
55
|
+
out = step.repeat(depth + 1) + t;
|
|
56
|
+
} else if (leading > 0 || line !== t) {
|
|
57
|
+
out = step + t;
|
|
58
|
+
} else {
|
|
59
|
+
out = line.trimEnd();
|
|
60
|
+
}
|
|
61
|
+
if (t.trimEnd().endsWith("[")) {
|
|
62
|
+
let opens = 0, closes = 0, inStr = false, i = 0;
|
|
63
|
+
while (i < t.length) {
|
|
64
|
+
const c = t[i];
|
|
65
|
+
if (c === "\\" && inStr) {
|
|
66
|
+
i += 2;
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
if (c === '"') inStr = !inStr;
|
|
70
|
+
else if (!inStr) {
|
|
71
|
+
if (c === "[") opens++;
|
|
72
|
+
else if (c === "]") closes++;
|
|
73
|
+
}
|
|
74
|
+
i++;
|
|
75
|
+
}
|
|
76
|
+
const netOpen = opens - closes + leading;
|
|
77
|
+
if (netOpen > 0) depth += netOpen;
|
|
78
|
+
}
|
|
79
|
+
return out;
|
|
80
|
+
}).join("\n");
|
|
81
|
+
}
|
|
82
|
+
function expandLiterals(turtle) {
|
|
83
|
+
return turtle.replace(/"((?:[^"\\]|\\.)*)"/g, (match, content) => {
|
|
84
|
+
if (!content.includes("\\n")) return match;
|
|
85
|
+
const expanded = content.replace(/\\n/g, "\n");
|
|
86
|
+
if (expanded.includes('"""')) return match;
|
|
87
|
+
return `"""${expanded}"""`;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
export {
|
|
91
|
+
expandLiterals,
|
|
92
|
+
reindent,
|
|
93
|
+
topoWrite
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * n3writer-wrapper\n *\n * Helpers that improve the readability of Turtle/TriG output from n3.Writer:\n *\n * topoWrite(writer, quads) — feed quads to an N3 Writer using nested [ ]\n * notation for blank nodes that appear as an\n * object exactly once (tree-edge inlining).\n *\n * reindent(turtle, step?) — post-process a Turtle/TriG string so that\n * predicate-continuation lines use `step`\n * (default 2 spaces) instead of n3.Writer's\n * hard-coded 4, and blank-node content at depth\n * d uses step × (d+1).\n *\n * expandLiterals(turtle) — convert STRING_LITERAL2 values containing \\n\n * into STRING_LITERAL_LONG2 (\"\"\"…\"\"\") with a\n * real embedded newline.\n */\n\n/** Minimal structural interface for terms (compatible with n3, rdfjs, graphy). */\nexport interface RdfTerm {\n termType: string;\n value: string;\n datatype?: { value: string };\n language?: string;\n}\n\n/** Minimal structural interface for quads. */\nexport interface RdfQuad {\n subject: RdfTerm;\n predicate: RdfTerm;\n object: RdfTerm;\n graph: RdfTerm;\n}\n\n/**\n * Minimal structural interface for the n3.Writer methods that topoWrite uses.\n * Any object that provides blank() and addQuad() with these signatures works.\n */\nexport interface TurtleWriter {\n blank(predicates?: Array<{ predicate: RdfTerm; object: unknown }>): unknown;\n addQuad(subject: RdfTerm, predicate: RdfTerm, object: unknown, graph?: RdfTerm): void;\n}\n\n/**\n * Write quads to an N3 Writer using nested [ ] notation for blank nodes that\n * appear as an object exactly once (sole child in a tree edge). Blank nodes\n * used more than once as objects, or that have no subject triples, fall back\n * to the normal _:label reference. CONSTRUCT-style duplicate quads are\n * deduplicated before processing.\n */\nexport function topoWrite(writer: TurtleWriter, quads: Iterable<RdfQuad>): void {\n const termKey = (t: RdfTerm): string =>\n t.termType === 'Literal'\n ? `L\\0${t.value}\\0${t.datatype?.value ?? ''}\\0${t.language ?? ''}`\n : `${t.termType[0]}\\0${t.value}`;\n\n const seen = new Set<string>();\n const deduped = [...quads].filter(q => {\n const k = `${termKey(q.graph)}\\0${termKey(q.subject)}\\0${q.predicate.value}\\0${termKey(q.object)}`;\n return seen.size !== seen.add(k).size;\n });\n\n // Index quads by (graph, subject); count blank-node object occurrences per graph.\n const bySub = new Map<string, { term: RdfTerm; graph: RdfTerm; pos: RdfQuad[] }>();\n const oCount = new Map<string, number>();\n\n for (const q of deduped) {\n const k = `${q.graph.value}\\0${q.subject.termType}\\0${q.subject.value}`;\n if (!bySub.has(k)) bySub.set(k, { term: q.subject, graph: q.graph, pos: [] });\n bySub.get(k)!.pos.push(q);\n if (q.object.termType === 'BlankNode') {\n const ok = `${q.graph.value}\\0${q.object.value}`;\n oCount.set(ok, (oCount.get(ok) ?? 0) + 1);\n }\n }\n\n const inlineable = (bn: RdfTerm, graph: RdfTerm): boolean =>\n oCount.get(`${graph.value}\\0${bn.value}`) === 1 &&\n bySub.has(`${graph.value}\\0BlankNode\\0${bn.value}`);\n\n function buildBlank(bn: RdfTerm, graph: RdfTerm): unknown {\n const entry = bySub.get(`${graph.value}\\0BlankNode\\0${bn.value}`);\n if (!entry) return writer.blank();\n return writer.blank(\n entry.pos.map(q => ({\n predicate: q.predicate,\n object:\n q.object.termType === 'BlankNode' && inlineable(q.object, graph)\n ? buildBlank(q.object, graph)\n : q.object,\n })),\n );\n }\n\n for (const { term, graph, pos } of bySub.values()) {\n if (term.termType === 'BlankNode' && inlineable(term, graph)) continue;\n for (const q of pos) {\n writer.addQuad(\n q.subject,\n q.predicate,\n q.object.termType === 'BlankNode' && inlineable(q.object, graph)\n ? buildBlank(q.object, graph)\n : q.object,\n q.graph,\n );\n }\n }\n}\n\n/**\n * Post-process an N3.js Writer Turtle/TriG string with uniform indentation.\n *\n * n3.Writer uses 4 spaces for predicate-continuation lines and 2 spaces inside\n * blank-node [ ] blocks. reindent normalises this so that each additional level\n * of [ ] nesting adds exactly one `step` (default: 2 spaces).\n */\nexport function reindent(turtle: string, step = ' '): string {\n let depth = 0;\n return turtle\n .split('\\n')\n .map(line => {\n const t = line.trimStart();\n if (!t) return '';\n\n // Leading ] chars close blocks: reduce depth before outputting this line.\n let leading = 0;\n while (leading < t.length && t[leading] === ']') {\n depth = Math.max(0, depth - 1);\n leading++;\n }\n\n let out: string;\n if (depth > 0) {\n out = step.repeat(depth + 1) + t;\n } else if (leading > 0 || line !== t) {\n out = step + t;\n } else {\n out = line.trimEnd();\n }\n\n // Count net unbalanced [ brackets outside string literals to track depth.\n if (t.trimEnd().endsWith('[')) {\n let opens = 0,\n closes = 0,\n inStr = false,\n i = 0;\n while (i < t.length) {\n const c = t[i];\n if (c === '\\\\' && inStr) {\n i += 2;\n continue;\n }\n if (c === '\"') inStr = !inStr;\n else if (!inStr) {\n if (c === '[') opens++;\n else if (c === ']') closes++;\n }\n i++;\n }\n const netOpen = opens - closes + leading;\n if (netOpen > 0) depth += netOpen;\n }\n\n return out;\n })\n .join('\\n');\n}\n\n/**\n * Replace STRING_LITERAL2 values that contain the \\n escape sequence with\n * STRING_LITERAL_LONG2 (triple-quoted) with a real embedded newline.\n *\n * Falls back to the original form if the expanded content contains \"\"\" (which\n * cannot appear unescaped inside a long literal).\n */\nexport function expandLiterals(turtle: string): string {\n return turtle.replace(/\"((?:[^\"\\\\]|\\\\.)*)\"/g, (match, content: string) => {\n if (!content.includes('\\\\n')) return match;\n const expanded = content.replace(/\\\\n/g, '\\n');\n if (expanded.includes('\"\"\"')) return match;\n return `\"\"\"${expanded}\"\"\"`;\n });\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "n3writer-wrapper",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Helpers for n3.Writer: topological blank-node inlining, uniform reindent, and multiline literal expansion",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"require": "./dist/index.cjs"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"main": "./dist/index.cjs",
|
|
14
|
+
"module": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsup",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"test:watch": "vitest",
|
|
24
|
+
"prepublishOnly": "npm run build && npm test"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"rdf",
|
|
28
|
+
"turtle",
|
|
29
|
+
"n3",
|
|
30
|
+
"blank-node",
|
|
31
|
+
"pretty-print"
|
|
32
|
+
],
|
|
33
|
+
"author": "Eric Prud'hommeaux",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"n3": ">=1.0.0"
|
|
37
|
+
},
|
|
38
|
+
"peerDependenciesMeta": {
|
|
39
|
+
"n3": {
|
|
40
|
+
"optional": true
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"n3": "^1.26.0",
|
|
45
|
+
"tsup": "^8.0.0",
|
|
46
|
+
"typescript": "^5.0.0",
|
|
47
|
+
"vitest": "^2.0.0"
|
|
48
|
+
}
|
|
49
|
+
}
|