@cavelang/canonical 0.15.0 → 0.20.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/src/emit.d.ts +34 -1
- package/dist/src/emit.d.ts.map +1 -1
- package/dist/src/emit.js +40 -1
- package/dist/src/emit.js.map +1 -1
- package/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/index.js.map +1 -1
- package/package.json +3 -3
- package/src/emit.ts +55 -1
- package/src/index.ts +2 -1
package/dist/src/emit.d.ts
CHANGED
|
@@ -11,9 +11,42 @@ import { Claim } from '@cavelang/core';
|
|
|
11
11
|
import type * as Canonicalize from './canonicalize.ts';
|
|
12
12
|
/** @returns one canonical line for a claim (no indentation). */
|
|
13
13
|
export declare const emitClaim: (claim: Claim.t) => string;
|
|
14
|
+
/**
|
|
15
|
+
* A transaction annotation (spec §28.4): the full-line comment placed
|
|
16
|
+
* immediately above a claim line to carry its transaction id through
|
|
17
|
+
* canonical text. Comment lines are transparent to the grammar (§8), so
|
|
18
|
+
* annotated text reads unchanged everywhere; sync-aware readers pair each
|
|
19
|
+
* annotation with the claim line below it.
|
|
20
|
+
*/
|
|
21
|
+
export declare const txComment: (tx: string) => string;
|
|
22
|
+
/**
|
|
23
|
+
* @returns the transaction id carried by a raw line when it is a §28.4
|
|
24
|
+
* annotation (`;@ <tx>`), `undefined` otherwise. Purely lexical — the
|
|
25
|
+
* caller validates the id shape.
|
|
26
|
+
*/
|
|
27
|
+
export declare const txOfLine: (raw: string) => undefined | string;
|
|
28
|
+
export type EmitOptions = {
|
|
29
|
+
/**
|
|
30
|
+
* Per-claim annotation lines (spec §28.4): when defined for a claim
|
|
31
|
+
* index, the returned text is emitted verbatim as its own line directly
|
|
32
|
+
* above that claim, at the claim's indentation. Used by tx-carrying
|
|
33
|
+
* export ({@link txComment}); return `undefined` to annotate nothing.
|
|
34
|
+
*/
|
|
35
|
+
readonly annotate?: (index: number) => undefined | string;
|
|
36
|
+
};
|
|
14
37
|
/**
|
|
15
38
|
* Emits a whole canonicalization result as canonical CAVE text: top-level
|
|
16
39
|
* claims in claim order, children indented two spaces per level.
|
|
40
|
+
*
|
|
41
|
+
* Edges form a graph, text forms a tree, and the reconciliation is the
|
|
42
|
+
* *re-statement*: a claim's own children render exactly once — at its
|
|
43
|
+
* first appearance — and every later appearance (a row cited by several
|
|
44
|
+
* parents, §24.3 shared premises and `VIA` rules; or a §24.5 support
|
|
45
|
+
* cycle) is the claim line alone, restating the row to carry that one
|
|
46
|
+
* edge. With annotations the repeats share one id, so replay unions them
|
|
47
|
+
* back into a single row (§28.4); a component with no top-level member
|
|
48
|
+
* (a pure cycle) is emitted from its first claim, the cycle breaking at
|
|
49
|
+
* the re-statement.
|
|
17
50
|
*/
|
|
18
|
-
export declare const emit: (result: Pick<Canonicalize.Result, "claims" | "edges"
|
|
51
|
+
export declare const emit: (result: Pick<Canonicalize.Result, "claims" | "edges">, options?: EmitOptions) => string;
|
|
19
52
|
//# sourceMappingURL=emit.d.ts.map
|
package/dist/src/emit.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/emit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAA0B,MAAM,gBAAgB,CAAA;AAC9D,OAAO,KAAK,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAyCtD,gEAAgE;AAChE,eAAO,MAAM,SAAS,GAAI,OAAO,KAAK,CAAC,CAAC,KAAG,MAW1C,CAAA;AAgBD
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../src/emit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,KAAK,EAA0B,MAAM,gBAAgB,CAAA;AAC9D,OAAO,KAAK,KAAK,YAAY,MAAM,mBAAmB,CAAA;AAyCtD,gEAAgE;AAChE,eAAO,MAAM,SAAS,GAAI,OAAO,KAAK,CAAC,CAAC,KAAG,MAW1C,CAAA;AAgBD;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,GAAI,IAAI,MAAM,KAAG,MAC3B,CAAA;AAIZ;;;;GAIG;AACH,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,KAAG,SAAS,GAAG,MAC1B,CAAA;AAEzB,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,SAAS,GAAG,MAAM,CAAA;CAC1D,CAAA;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,IAAI,GAAI,QAAQ,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,EAAE,UAAS,WAAgB,KAAG,MA6CvG,CAAA"}
|
package/dist/src/emit.js
CHANGED
|
@@ -71,11 +71,36 @@ const conditionText = (claim) => {
|
|
|
71
71
|
emitClaim({ ...claim, negated: false });
|
|
72
72
|
return claim.negated ? `NOT ${body}` : body;
|
|
73
73
|
};
|
|
74
|
+
/**
|
|
75
|
+
* A transaction annotation (spec §28.4): the full-line comment placed
|
|
76
|
+
* immediately above a claim line to carry its transaction id through
|
|
77
|
+
* canonical text. Comment lines are transparent to the grammar (§8), so
|
|
78
|
+
* annotated text reads unchanged everywhere; sync-aware readers pair each
|
|
79
|
+
* annotation with the claim line below it.
|
|
80
|
+
*/
|
|
81
|
+
export const txComment = (tx) => `;@ ${tx}`;
|
|
82
|
+
const txLineRe = /^\s*;@\s+(\S+)\s*$/;
|
|
83
|
+
/**
|
|
84
|
+
* @returns the transaction id carried by a raw line when it is a §28.4
|
|
85
|
+
* annotation (`;@ <tx>`), `undefined` otherwise. Purely lexical — the
|
|
86
|
+
* caller validates the id shape.
|
|
87
|
+
*/
|
|
88
|
+
export const txOfLine = (raw) => txLineRe.exec(raw)?.[1];
|
|
74
89
|
/**
|
|
75
90
|
* Emits a whole canonicalization result as canonical CAVE text: top-level
|
|
76
91
|
* claims in claim order, children indented two spaces per level.
|
|
92
|
+
*
|
|
93
|
+
* Edges form a graph, text forms a tree, and the reconciliation is the
|
|
94
|
+
* *re-statement*: a claim's own children render exactly once — at its
|
|
95
|
+
* first appearance — and every later appearance (a row cited by several
|
|
96
|
+
* parents, §24.3 shared premises and `VIA` rules; or a §24.5 support
|
|
97
|
+
* cycle) is the claim line alone, restating the row to carry that one
|
|
98
|
+
* edge. With annotations the repeats share one id, so replay unions them
|
|
99
|
+
* back into a single row (§28.4); a component with no top-level member
|
|
100
|
+
* (a pure cycle) is emitted from its first claim, the cycle breaking at
|
|
101
|
+
* the re-statement.
|
|
77
102
|
*/
|
|
78
|
-
export const emit = (result) => {
|
|
103
|
+
export const emit = (result, options = {}) => {
|
|
79
104
|
const childEdges = new Map();
|
|
80
105
|
const isChild = new Set();
|
|
81
106
|
for (const edge of result.edges) {
|
|
@@ -89,15 +114,24 @@ export const emit = (result) => {
|
|
|
89
114
|
}
|
|
90
115
|
}
|
|
91
116
|
const lines = [];
|
|
117
|
+
const expanded = new Set();
|
|
92
118
|
const emitAt = (index, depth, role) => {
|
|
93
119
|
const { claim } = result.claims[index];
|
|
94
120
|
const indent = ' '.repeat(depth);
|
|
121
|
+
const annotation = options.annotate?.(index);
|
|
122
|
+
if (annotation !== undefined) {
|
|
123
|
+
lines.push(`${indent}${annotation}`);
|
|
124
|
+
}
|
|
95
125
|
if (role === undefined || role === 'QUALIFIES') {
|
|
96
126
|
lines.push(`${indent}${emitClaim(claim)}`);
|
|
97
127
|
}
|
|
98
128
|
else {
|
|
99
129
|
lines.push(`${indent}${role} ${conditionText(claim)}`);
|
|
100
130
|
}
|
|
131
|
+
if (expanded.has(index)) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
expanded.add(index);
|
|
101
135
|
for (const edge of childEdges.get(index) ?? []) {
|
|
102
136
|
emitAt(edge.child, depth + 1, edge.role);
|
|
103
137
|
}
|
|
@@ -107,6 +141,11 @@ export const emit = (result) => {
|
|
|
107
141
|
emitAt(index, 0, undefined);
|
|
108
142
|
}
|
|
109
143
|
});
|
|
144
|
+
result.claims.forEach((_, index) => {
|
|
145
|
+
if (!expanded.has(index)) {
|
|
146
|
+
emitAt(index, 0, undefined);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
110
149
|
return lines.length === 0 ? '' : `${lines.join('\n')}\n`;
|
|
111
150
|
};
|
|
112
151
|
//# sourceMappingURL=emit.js.map
|
package/dist/src/emit.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/emit.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/emit.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
export * as Registry from './registry.ts';
|
|
18
18
|
export { canonicalize, canonicalizeText } from './canonicalize.ts';
|
|
19
19
|
export type { Edge, EdgeRole, Entry, Problem, Result } from './canonicalize.ts';
|
|
20
|
-
export { emit, emitClaim } from './emit.ts';
|
|
20
|
+
export { emit, emitClaim, txComment, txOfLine } from './emit.ts';
|
|
21
|
+
export type { EmitOptions } from './emit.ts';
|
|
21
22
|
export { standardPrelude, standardRegistry } from './prelude.ts';
|
|
22
23
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAClE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC/E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAClE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC/E,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAChE,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA"}
|
package/dist/src/index.js
CHANGED
|
@@ -16,6 +16,6 @@
|
|
|
16
16
|
*/
|
|
17
17
|
export * as Registry from "./registry.js";
|
|
18
18
|
export { canonicalize, canonicalizeText } from "./canonicalize.js";
|
|
19
|
-
export { emit, emitClaim } from "./emit.js";
|
|
19
|
+
export { emit, emitClaim, txComment, txOfLine } from "./emit.js";
|
|
20
20
|
export { standardPrelude, standardRegistry } from "./prelude.js";
|
|
21
21
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAEhE,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cavelang/canonical",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CAVE canonicalization — verb registry, REVERSE inverse resolution, continuation expansion, canonical emitter.",
|
|
6
6
|
"license": "CC0-1.0",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"access": "public"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@cavelang/core": "0.
|
|
36
|
-
"@cavelang/parser": "0.
|
|
35
|
+
"@cavelang/core": "0.20.0",
|
|
36
|
+
"@cavelang/parser": "0.20.0"
|
|
37
37
|
},
|
|
38
38
|
"scripts": {
|
|
39
39
|
"build": "tsc -b",
|
package/src/emit.ts
CHANGED
|
@@ -78,11 +78,51 @@ const conditionText = (claim: Claim.t): string => {
|
|
|
78
78
|
return claim.negated ? `NOT ${body}` : body
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
/**
|
|
82
|
+
* A transaction annotation (spec §28.4): the full-line comment placed
|
|
83
|
+
* immediately above a claim line to carry its transaction id through
|
|
84
|
+
* canonical text. Comment lines are transparent to the grammar (§8), so
|
|
85
|
+
* annotated text reads unchanged everywhere; sync-aware readers pair each
|
|
86
|
+
* annotation with the claim line below it.
|
|
87
|
+
*/
|
|
88
|
+
export const txComment = (tx: string): string =>
|
|
89
|
+
`;@ ${tx}`
|
|
90
|
+
|
|
91
|
+
const txLineRe = /^\s*;@\s+(\S+)\s*$/
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* @returns the transaction id carried by a raw line when it is a §28.4
|
|
95
|
+
* annotation (`;@ <tx>`), `undefined` otherwise. Purely lexical — the
|
|
96
|
+
* caller validates the id shape.
|
|
97
|
+
*/
|
|
98
|
+
export const txOfLine = (raw: string): undefined | string =>
|
|
99
|
+
txLineRe.exec(raw)?.[1]
|
|
100
|
+
|
|
101
|
+
export type EmitOptions = {
|
|
102
|
+
/**
|
|
103
|
+
* Per-claim annotation lines (spec §28.4): when defined for a claim
|
|
104
|
+
* index, the returned text is emitted verbatim as its own line directly
|
|
105
|
+
* above that claim, at the claim's indentation. Used by tx-carrying
|
|
106
|
+
* export ({@link txComment}); return `undefined` to annotate nothing.
|
|
107
|
+
*/
|
|
108
|
+
readonly annotate?: (index: number) => undefined | string
|
|
109
|
+
}
|
|
110
|
+
|
|
81
111
|
/**
|
|
82
112
|
* Emits a whole canonicalization result as canonical CAVE text: top-level
|
|
83
113
|
* claims in claim order, children indented two spaces per level.
|
|
114
|
+
*
|
|
115
|
+
* Edges form a graph, text forms a tree, and the reconciliation is the
|
|
116
|
+
* *re-statement*: a claim's own children render exactly once — at its
|
|
117
|
+
* first appearance — and every later appearance (a row cited by several
|
|
118
|
+
* parents, §24.3 shared premises and `VIA` rules; or a §24.5 support
|
|
119
|
+
* cycle) is the claim line alone, restating the row to carry that one
|
|
120
|
+
* edge. With annotations the repeats share one id, so replay unions them
|
|
121
|
+
* back into a single row (§28.4); a component with no top-level member
|
|
122
|
+
* (a pure cycle) is emitted from its first claim, the cycle breaking at
|
|
123
|
+
* the re-statement.
|
|
84
124
|
*/
|
|
85
|
-
export const emit = (result: Pick<Canonicalize.Result, 'claims' | 'edges'
|
|
125
|
+
export const emit = (result: Pick<Canonicalize.Result, 'claims' | 'edges'>, options: EmitOptions = {}): string => {
|
|
86
126
|
const childEdges = new Map<number, Canonicalize.Edge[]>()
|
|
87
127
|
const isChild = new Set<number>()
|
|
88
128
|
for (const edge of result.edges) {
|
|
@@ -95,14 +135,23 @@ export const emit = (result: Pick<Canonicalize.Result, 'claims' | 'edges'>): str
|
|
|
95
135
|
}
|
|
96
136
|
}
|
|
97
137
|
const lines: string[] = []
|
|
138
|
+
const expanded = new Set<number>()
|
|
98
139
|
const emitAt = (index: number, depth: number, role: undefined | Canonicalize.EdgeRole): void => {
|
|
99
140
|
const { claim } = result.claims[index]!
|
|
100
141
|
const indent = ' '.repeat(depth)
|
|
142
|
+
const annotation = options.annotate?.(index)
|
|
143
|
+
if (annotation !== undefined) {
|
|
144
|
+
lines.push(`${indent}${annotation}`)
|
|
145
|
+
}
|
|
101
146
|
if (role === undefined || role === 'QUALIFIES') {
|
|
102
147
|
lines.push(`${indent}${emitClaim(claim)}`)
|
|
103
148
|
} else {
|
|
104
149
|
lines.push(`${indent}${role} ${conditionText(claim)}`)
|
|
105
150
|
}
|
|
151
|
+
if (expanded.has(index)) {
|
|
152
|
+
return
|
|
153
|
+
}
|
|
154
|
+
expanded.add(index)
|
|
106
155
|
for (const edge of childEdges.get(index) ?? []) {
|
|
107
156
|
emitAt(edge.child, depth + 1, edge.role)
|
|
108
157
|
}
|
|
@@ -112,5 +161,10 @@ export const emit = (result: Pick<Canonicalize.Result, 'claims' | 'edges'>): str
|
|
|
112
161
|
emitAt(index, 0, undefined)
|
|
113
162
|
}
|
|
114
163
|
})
|
|
164
|
+
result.claims.forEach((_, index) => {
|
|
165
|
+
if (!expanded.has(index)) {
|
|
166
|
+
emitAt(index, 0, undefined)
|
|
167
|
+
}
|
|
168
|
+
})
|
|
115
169
|
return lines.length === 0 ? '' : `${lines.join('\n')}\n`
|
|
116
170
|
}
|
package/src/index.ts
CHANGED
|
@@ -18,5 +18,6 @@
|
|
|
18
18
|
export * as Registry from './registry.ts'
|
|
19
19
|
export { canonicalize, canonicalizeText } from './canonicalize.ts'
|
|
20
20
|
export type { Edge, EdgeRole, Entry, Problem, Result } from './canonicalize.ts'
|
|
21
|
-
export { emit, emitClaim } from './emit.ts'
|
|
21
|
+
export { emit, emitClaim, txComment, txOfLine } from './emit.ts'
|
|
22
|
+
export type { EmitOptions } from './emit.ts'
|
|
22
23
|
export { standardPrelude, standardRegistry } from './prelude.ts'
|