@agentshouse/mdmodel 0.1.0-cc9fa0498a7f7 → 0.1.0-cd90851746292
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/API.md +231 -225
- package/README.md +16 -19
- package/dist/blocks.d.ts.map +1 -1
- package/dist/blocks.js +35 -20
- package/dist/condition.d.ts +41 -11
- package/dist/condition.d.ts.map +1 -1
- package/dist/condition.js +223 -87
- package/dist/definition.d.ts +17 -1
- package/dist/definition.d.ts.map +1 -1
- package/dist/definition.js +319 -43
- package/dist/divide.d.ts.map +1 -1
- package/dist/divide.js +27 -17
- package/dist/document.d.ts +6 -3
- package/dist/document.d.ts.map +1 -1
- package/dist/document.js +326 -176
- package/dist/index.d.ts +13 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -6
- package/dist/links.d.ts +3 -0
- package/dist/links.d.ts.map +1 -1
- package/dist/links.js +108 -51
- package/dist/paths.d.ts +10 -1
- package/dist/paths.d.ts.map +1 -1
- package/dist/paths.js +118 -12
- package/dist/pattern.d.ts +10 -0
- package/dist/pattern.d.ts.map +1 -0
- package/dist/pattern.js +355 -0
- package/dist/project.d.ts +1 -0
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +38 -15
- package/dist/references.d.ts +2 -2
- package/dist/references.d.ts.map +1 -1
- package/dist/references.js +6 -1
- package/dist/schema.d.ts +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +55 -4
- package/dist/types.d.ts +50 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/validate.d.ts +30 -2
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +317 -114
- package/dist/yaml.d.ts.map +1 -1
- package/dist/yaml.js +66 -21
- package/fixtures/README.md +10 -5
- package/fixtures/cases/conditional-section/context.json +1 -0
- package/fixtures/cases/conditional-section/expected.json +6 -0
- package/fixtures/cases/conditional-section/library/questions/hosting.md +9 -0
- package/fixtures/cases/conditional-section/library/questions/payments.md +12 -0
- package/fixtures/cases/conditional-section/schema.yaml +14 -0
- package/fixtures/cases/cross-room-link/context.json +1 -0
- package/fixtures/cases/cross-room-link/expected.json +1 -0
- package/fixtures/cases/cross-room-link/library/clients/acme.md +6 -0
- package/fixtures/cases/cross-room-link/schema.yaml +3 -0
- package/fixtures/cases/cross-room-reference/context.json +1 -0
- package/fixtures/cases/cross-room-reference/expected.json +1 -0
- package/fixtures/cases/cross-room-reference/library/clients/acme.md +9 -0
- package/fixtures/cases/cross-room-reference/schema.yaml +9 -0
- package/fixtures/division.json +26 -26
- package/package.json +10 -3
package/dist/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
export { dated, datePointers, factKind, facts, fires, holds, instant, itemFires, pointed, prosePaths, WRITE_DOORS, } from './condition.js';
|
|
1
|
+
export { ACTOR_PATHS, actorOperators, changeFields, CONDITION_OPERATORS, dated, datePointers, DOCUMENT_PATHS, factKind, facts, fires, holds, instant, ITEM_PATHS, itemFires, itemKind, itemOperators, memberPointers, members, MESSAGE_PATHS, messageFires, messageOperators, notificationFires, pointed, prosePaths, testOperators, TEXT_FIELD, valuedChange, WRITE_DOORS, } from './condition.js';
|
|
2
|
+
export { headingLines } from './blocks.js';
|
|
2
3
|
export { divide } from './divide.js';
|
|
3
|
-
export { apply, bodyLinks, links, parse, relativize, relativizeBody, relinkBody, serialize, } from './document.js';
|
|
4
|
+
export { apply, bodyLinks, links, parse, parseFrontmatter, relativize, relativizeBody, relinkBody, serialize, } from './document.js';
|
|
4
5
|
export { HOUSE_FIELDS, MEMBER_FIELD, RECEIVED_FIELD, SITE_FIELD, TYPE_FIELD } from './fields.js';
|
|
5
|
-
export { relative, retarget, target } from './paths.js';
|
|
6
|
+
export { relative, retarget, roomPath, roomTarget, target } from './paths.js';
|
|
6
7
|
export { MARKDOWN_SYNTAX_PROFILE } from './profile.js';
|
|
7
8
|
export { project } from './project.js';
|
|
8
9
|
export { references } from './references.js';
|
|
9
|
-
export { ARRAY_INDEX, ATTACHMENT, crossedFacts, escapePointer, itemFacts, memberFacts, pointerFacts, pointerSegments, } from './definition.js';
|
|
10
|
-
export { validate, verify } from './validate.js';
|
|
10
|
+
export { ARRAY_INDEX, ATTACHMENT, crossedFacts, escapePointer, itemFacts, JSON_POINTER, memberFacts, pointerFacts, pointerSegments, } from './definition.js';
|
|
11
|
+
export { assess, bodyRoomLinks, checkDocument, resolves, roomReferences, sectionReferences, validate, validating, verdicts, verify, } from './validate.js';
|
|
11
12
|
export { VERSION } from './version.js';
|
|
12
|
-
export { equalValue, frontmatterValue } from './yaml.js';
|
|
13
|
+
export { bodyAfterFrontmatter, equalValue, frontmatterValue } from './yaml.js';
|
package/dist/links.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
export declare function escapes(text: string, index: number): boolean;
|
|
2
|
+
export declare function spanCursor(spans: readonly (readonly [number, number])[]): (index: number) => number | undefined;
|
|
1
3
|
export type HrefOccurrence = {
|
|
2
4
|
readonly href: string;
|
|
3
5
|
readonly start: number;
|
|
@@ -22,5 +24,6 @@ export type LinkInventory = {
|
|
|
22
24
|
};
|
|
23
25
|
export declare function fenceSpans(text: string): readonly (readonly [number, number])[];
|
|
24
26
|
export declare function linkInventory(body: string): LinkInventory;
|
|
27
|
+
export declare function destinations(inventory: LinkInventory): readonly HrefOccurrence[];
|
|
25
28
|
export declare function hrefOccurrences(body: string): readonly HrefOccurrence[];
|
|
26
29
|
//# sourceMappingURL=links.d.ts.map
|
package/dist/links.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../src/links.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"links.d.ts","sourceRoot":"","sources":["../src/links.ts"],"names":[],"mappings":"AAgiBA,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D;AAyLD,wBAAgB,UAAU,CACxB,KAAK,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,GAC5C,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAOvC;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;CACtC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,SAAS,eAAe,EAAE,CAAC;CAC7C,CAAC;AAEF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,CAe/E;AA+CD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,CAmEzD;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,aAAa,GAAG,SAAS,cAAc,EAAE,CAIhF;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,cAAc,EAAE,CAEvE"}
|
package/dist/links.js
CHANGED
|
@@ -17,17 +17,28 @@ const HTML_TAG_LINE = /^(?:<[A-Za-z][A-Za-z0-9-]*(?:[ \t\v\f]+[A-Za-z_:][A-Za-z0
|
|
|
17
17
|
const ORDERED = /^(\d{1,9})[.)]/;
|
|
18
18
|
const LABEL_LENGTH = 999;
|
|
19
19
|
const PUNCTUATION = /^[!-/:-@[-`{-~]$/;
|
|
20
|
-
const
|
|
20
|
+
const INLINE_TAG = new RegExp([
|
|
21
21
|
'<[A-Za-z][A-Za-z0-9-]*(?:[ \\t\\n\\v\\f\\r]+[A-Za-z_:][A-Za-z0-9_.:-]*(?:[ \\t\\n\\v\\f\\r]*=[ \\t\\n\\v\\f\\r]*(?:[^ \\t\\n\\v\\f\\r"\'=<>`]+|\'[^\']*\'|"[^"]*"))?)*[ \\t\\n\\v\\f\\r]*\\/?>',
|
|
22
22
|
'<\\/[A-Za-z][A-Za-z0-9-]*[ \\t\\n\\v\\f\\r]*>',
|
|
23
23
|
'<!--(?!-?>)(?:-?[^-])*-->',
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
'<!\\[CDATA\\[[\\s\\S]*?\\]\\]>',
|
|
24
|
+
].join('|'), 'y');
|
|
25
|
+
const AUTOLINK = new RegExp([
|
|
27
26
|
'<[A-Za-z][A-Za-z0-9+.-]{1,31}:[^\\x00-\\x20<>]*>',
|
|
28
27
|
"<[A-Za-z0-9.!#$%&'*+/=?^_`{|}~-]+@[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*>",
|
|
29
28
|
].join('|'), 'y');
|
|
30
|
-
const
|
|
29
|
+
const DECLARATION = /<![A-Z]+[ \t\n\v\f\r]/y;
|
|
30
|
+
const INSTRUCTION = '<?';
|
|
31
|
+
const CDATA = '<![CDATA[';
|
|
32
|
+
const BACKSLASH = 0x5c;
|
|
33
|
+
const BACKTICK = 0x60;
|
|
34
|
+
const LINE_FEED = 0x0a;
|
|
35
|
+
const CARRIAGE_RETURN = 0x0d;
|
|
36
|
+
const LESS_THAN = 0x3c;
|
|
37
|
+
const OPEN_BRACKET = 0x5b;
|
|
38
|
+
const CLOSE_BRACKET = 0x5d;
|
|
39
|
+
const EXCLAMATION = 0x21;
|
|
40
|
+
const OPEN_PAREN = 0x28;
|
|
41
|
+
const DELIMITER_ROW = /^\|?[ \t]*:?-+:?(?:[ \t]*\|[ \t]*:?-+:?)*(?:[ \t]*\|)?[ \t]*$/;
|
|
31
42
|
const GAP = /^[ \t\v\f]+/;
|
|
32
43
|
function endOfLine(text, from) {
|
|
33
44
|
const nl = text.indexOf('\n', from);
|
|
@@ -155,28 +166,34 @@ function fenceSpan(text, line, open) {
|
|
|
155
166
|
}
|
|
156
167
|
return text.length;
|
|
157
168
|
}
|
|
158
|
-
function skipInlineCode(text, index, joins) {
|
|
169
|
+
function skipInlineCode(text, index, joins, unclosed) {
|
|
159
170
|
let ticks = 0;
|
|
160
171
|
while (text[index + ticks] === '`')
|
|
161
172
|
ticks += 1;
|
|
173
|
+
if (index < unclosed.stop && (unclosed.runs.get(ticks) ?? -1) <= index)
|
|
174
|
+
return index + ticks;
|
|
175
|
+
const runs = new Map();
|
|
162
176
|
let i = index + ticks;
|
|
163
177
|
while (i < text.length) {
|
|
164
|
-
const
|
|
165
|
-
if (
|
|
178
|
+
const code = text.charCodeAt(i);
|
|
179
|
+
if (code === BACKTICK) {
|
|
166
180
|
let run = 0;
|
|
167
|
-
while (text
|
|
181
|
+
while (text.charCodeAt(i + run) === BACKTICK)
|
|
168
182
|
run += 1;
|
|
169
183
|
if (run === ticks)
|
|
170
184
|
return i + run;
|
|
185
|
+
runs.set(run, i);
|
|
171
186
|
i += run;
|
|
172
187
|
continue;
|
|
173
188
|
}
|
|
174
|
-
if (
|
|
189
|
+
if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
|
|
175
190
|
break;
|
|
176
|
-
if (
|
|
191
|
+
if (code === LINE_FEED && !joins.has(i))
|
|
177
192
|
break;
|
|
178
193
|
i += 1;
|
|
179
194
|
}
|
|
195
|
+
unclosed.stop = i;
|
|
196
|
+
unclosed.runs = runs;
|
|
180
197
|
return index + ticks;
|
|
181
198
|
}
|
|
182
199
|
function skipLinkSpace(text, start) {
|
|
@@ -194,21 +211,21 @@ function skipInlineSpace(text, start, joins) {
|
|
|
194
211
|
return afterIndent(text, readLine(text, i + 1, endOfLine(text, i + 1)));
|
|
195
212
|
}
|
|
196
213
|
function closeEnd(text, start, open, joins) {
|
|
197
|
-
const close = open === '(' ? ')' : open;
|
|
214
|
+
const close = (open === '(' ? ')' : open).charCodeAt(0);
|
|
198
215
|
let i = start;
|
|
199
216
|
while (i < text.length) {
|
|
200
|
-
const
|
|
217
|
+
const code = text.charCodeAt(i);
|
|
201
218
|
if (escapes(text, i)) {
|
|
202
219
|
i += 2;
|
|
203
220
|
continue;
|
|
204
221
|
}
|
|
205
|
-
if (
|
|
222
|
+
if (code === close)
|
|
206
223
|
return i + 1;
|
|
207
|
-
if (open === '(' &&
|
|
224
|
+
if (open === '(' && code === OPEN_PAREN)
|
|
208
225
|
return null;
|
|
209
|
-
if (
|
|
226
|
+
if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
|
|
210
227
|
return null;
|
|
211
|
-
if (
|
|
228
|
+
if (code === LINE_FEED && !joins.has(i))
|
|
212
229
|
return null;
|
|
213
230
|
i += 1;
|
|
214
231
|
}
|
|
@@ -504,24 +521,24 @@ function structure(text) {
|
|
|
504
521
|
}
|
|
505
522
|
return { joins, raw };
|
|
506
523
|
}
|
|
507
|
-
function escapes(text, index) {
|
|
508
|
-
return text
|
|
524
|
+
export function escapes(text, index) {
|
|
525
|
+
return text.charCodeAt(index) === BACKSLASH && PUNCTUATION.test(text[index + 1] ?? '');
|
|
509
526
|
}
|
|
510
527
|
function referenceEnd(text, start, joins) {
|
|
511
528
|
let i = start;
|
|
512
529
|
while (i < text.length) {
|
|
513
|
-
const
|
|
530
|
+
const code = text.charCodeAt(i);
|
|
514
531
|
if (escapes(text, i)) {
|
|
515
532
|
i += 2;
|
|
516
533
|
continue;
|
|
517
534
|
}
|
|
518
|
-
if (
|
|
535
|
+
if (code === CLOSE_BRACKET)
|
|
519
536
|
return i + 1;
|
|
520
|
-
if (
|
|
537
|
+
if (code === OPEN_BRACKET)
|
|
521
538
|
return -1;
|
|
522
|
-
if (
|
|
539
|
+
if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
|
|
523
540
|
return -1;
|
|
524
|
-
if (
|
|
541
|
+
if (code === LINE_FEED && !joins.has(i))
|
|
525
542
|
return -1;
|
|
526
543
|
i += 1;
|
|
527
544
|
}
|
|
@@ -641,12 +658,13 @@ function endsBlock(content) {
|
|
|
641
658
|
}
|
|
642
659
|
function scanBlocks(text) {
|
|
643
660
|
const { joins, raw } = structure(text);
|
|
661
|
+
const rawEnd = spanCursor(raw);
|
|
644
662
|
const definitions = new Map();
|
|
645
663
|
const blocks = [];
|
|
646
664
|
let fresh = 0;
|
|
647
665
|
let i = 0;
|
|
648
666
|
while (i < text.length) {
|
|
649
|
-
const skip =
|
|
667
|
+
const skip = rawEnd(i);
|
|
650
668
|
if (skip !== undefined) {
|
|
651
669
|
i = skip;
|
|
652
670
|
continue;
|
|
@@ -667,12 +685,14 @@ function scanBlocks(text) {
|
|
|
667
685
|
}
|
|
668
686
|
return { raw, definitions, blocks, joins };
|
|
669
687
|
}
|
|
670
|
-
function
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
688
|
+
export function spanCursor(spans) {
|
|
689
|
+
let next = 0;
|
|
690
|
+
return (index) => {
|
|
691
|
+
while (next < spans.length && spans[next][1] <= index)
|
|
692
|
+
next += 1;
|
|
693
|
+
const span = spans[next];
|
|
694
|
+
return span !== undefined && span[0] <= index ? span[1] : undefined;
|
|
695
|
+
};
|
|
676
696
|
}
|
|
677
697
|
export function fenceSpans(text) {
|
|
678
698
|
const fences = [];
|
|
@@ -693,61 +713,95 @@ export function fenceSpans(text) {
|
|
|
693
713
|
function paragraphEnd(text, from, joins) {
|
|
694
714
|
let i = from;
|
|
695
715
|
while (i < text.length) {
|
|
696
|
-
|
|
716
|
+
const code = text.charCodeAt(i);
|
|
717
|
+
if (code === LINE_FEED && !joins.has(i))
|
|
697
718
|
return i;
|
|
698
|
-
if (
|
|
719
|
+
if (code === CARRIAGE_RETURN && text.charCodeAt(i + 1) !== LINE_FEED)
|
|
699
720
|
return i;
|
|
700
721
|
i += 1;
|
|
701
722
|
}
|
|
702
723
|
return i;
|
|
703
724
|
}
|
|
725
|
+
function closerAt(text, closer, from, closers) {
|
|
726
|
+
const held = closers.get(closer);
|
|
727
|
+
if (held !== undefined && from >= held[0] && (held[1] === -1 || from <= held[1]))
|
|
728
|
+
return held[1];
|
|
729
|
+
const at = text.indexOf(closer, from);
|
|
730
|
+
closers.set(closer, [from, at]);
|
|
731
|
+
return at;
|
|
732
|
+
}
|
|
733
|
+
function closedAfter(text, closer, from, closers) {
|
|
734
|
+
const at = closerAt(text, closer, from, closers);
|
|
735
|
+
return at === -1 ? -1 : at + closer.length;
|
|
736
|
+
}
|
|
737
|
+
function stuck(pattern, text, at) {
|
|
738
|
+
pattern.lastIndex = at;
|
|
739
|
+
return pattern.test(text) ? pattern.lastIndex : -1;
|
|
740
|
+
}
|
|
741
|
+
function markupEnd(text, at, closers) {
|
|
742
|
+
if (text.startsWith(INSTRUCTION, at))
|
|
743
|
+
return closedAfter(text, '?>', at + INSTRUCTION.length, closers);
|
|
744
|
+
if (text.startsWith(CDATA, at))
|
|
745
|
+
return closedAfter(text, ']]>', at + CDATA.length, closers);
|
|
746
|
+
const declared = stuck(DECLARATION, text, at);
|
|
747
|
+
if (declared !== -1)
|
|
748
|
+
return closedAfter(text, '>', declared, closers);
|
|
749
|
+
return stuck(INLINE_TAG, text, at);
|
|
750
|
+
}
|
|
751
|
+
function inlineRawEnd(text, at, closers) {
|
|
752
|
+
const end = markupEnd(text, at, closers);
|
|
753
|
+
return end === -1 ? stuck(AUTOLINK, text, at) : end;
|
|
754
|
+
}
|
|
704
755
|
export function linkInventory(body) {
|
|
705
756
|
const { raw, definitions, blocks, joins } = scanBlocks(body);
|
|
706
|
-
const
|
|
757
|
+
const rawEnd = spanCursor(raw);
|
|
758
|
+
const blockEnd = spanCursor(blocks.map((block) => [block.start, block.end]));
|
|
707
759
|
const uses = [];
|
|
708
760
|
const openers = [];
|
|
709
|
-
|
|
761
|
+
const unclosed = { stop: 0, runs: new Map() };
|
|
762
|
+
let paragraph = { start: 0, end: -1, text: '', closers: new Map() };
|
|
710
763
|
let i = 0;
|
|
711
764
|
while (i < body.length) {
|
|
712
|
-
const skipEnd =
|
|
765
|
+
const skipEnd = rawEnd(i) ?? blockEnd(i);
|
|
713
766
|
if (skipEnd !== undefined) {
|
|
714
767
|
openers.length = 0;
|
|
715
768
|
i = skipEnd;
|
|
716
769
|
continue;
|
|
717
770
|
}
|
|
718
|
-
const
|
|
771
|
+
const code = body.charCodeAt(i);
|
|
719
772
|
if (escapes(body, i)) {
|
|
720
773
|
i += 2;
|
|
721
774
|
continue;
|
|
722
775
|
}
|
|
723
|
-
if (
|
|
724
|
-
i = skipInlineCode(body, i, joins);
|
|
776
|
+
if (code === BACKTICK) {
|
|
777
|
+
i = skipInlineCode(body, i, joins, unclosed);
|
|
725
778
|
continue;
|
|
726
779
|
}
|
|
727
|
-
if (
|
|
780
|
+
if (code === LESS_THAN) {
|
|
728
781
|
if (i >= paragraph.end) {
|
|
729
782
|
const end = paragraphEnd(body, i, joins);
|
|
730
|
-
paragraph = { start: i, end, text: body.slice(i, end) };
|
|
783
|
+
paragraph = { start: i, end, text: body.slice(i, end), closers: new Map() };
|
|
731
784
|
}
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
i += raw[0].length;
|
|
785
|
+
const raw = inlineRawEnd(paragraph.text, i - paragraph.start, paragraph.closers);
|
|
786
|
+
if (raw !== -1) {
|
|
787
|
+
i = paragraph.start + raw;
|
|
736
788
|
continue;
|
|
737
789
|
}
|
|
738
790
|
}
|
|
739
|
-
if ((
|
|
791
|
+
if ((code === LINE_FEED && !joins.has(i)) ||
|
|
792
|
+
(code === CARRIAGE_RETURN && body.charCodeAt(i + 1) !== LINE_FEED))
|
|
740
793
|
openers.length = 0;
|
|
741
|
-
if (
|
|
794
|
+
if (code === OPEN_BRACKET ||
|
|
795
|
+
(code === EXCLAMATION && body.charCodeAt(i + 1) === OPEN_BRACKET)) {
|
|
742
796
|
const previous = openers.at(-1);
|
|
743
797
|
if (previous !== undefined)
|
|
744
798
|
previous.bracketAfter = true;
|
|
745
|
-
const image =
|
|
799
|
+
const image = code === EXCLAMATION;
|
|
746
800
|
openers.push({ at: image ? i + 1 : i, start: i, image, active: true, bracketAfter: false });
|
|
747
801
|
i += image ? 2 : 1;
|
|
748
802
|
continue;
|
|
749
803
|
}
|
|
750
|
-
if (
|
|
804
|
+
if (code === CLOSE_BRACKET) {
|
|
751
805
|
const opener = openers.pop();
|
|
752
806
|
const use = opener?.active ? closeLink(body, opener, i, definitions, joins) : null;
|
|
753
807
|
if (opener === undefined || use === null) {
|
|
@@ -766,9 +820,12 @@ export function linkInventory(body) {
|
|
|
766
820
|
}
|
|
767
821
|
return { uses, blocks };
|
|
768
822
|
}
|
|
769
|
-
export function
|
|
823
|
+
export function destinations(inventory) {
|
|
770
824
|
const byStart = new Map();
|
|
771
|
-
for (const use of
|
|
825
|
+
for (const use of inventory.uses)
|
|
772
826
|
byStart.set(use.destination.start, use.destination);
|
|
773
827
|
return [...byStart.values()].sort((left, right) => left.start - right.start);
|
|
774
828
|
}
|
|
829
|
+
export function hrefOccurrences(body) {
|
|
830
|
+
return destinations(linkInventory(body));
|
|
831
|
+
}
|
package/dist/paths.d.ts
CHANGED
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
export declare function dirname(path: string): string;
|
|
2
2
|
export declare function join(base: string, relative: string): string;
|
|
3
3
|
export declare function normalize(path: string): string | null;
|
|
4
|
+
export declare function destinationPath(href: string): string | null;
|
|
5
|
+
export type RoomTarget = {
|
|
6
|
+
readonly handle: string;
|
|
7
|
+
readonly path: string;
|
|
8
|
+
};
|
|
4
9
|
export declare function classifyHref(from: string, href: string): {
|
|
5
10
|
kind: 'skip';
|
|
6
11
|
} | {
|
|
7
12
|
kind: 'path';
|
|
8
13
|
path: string;
|
|
9
|
-
} | {
|
|
14
|
+
} | ({
|
|
15
|
+
kind: 'room';
|
|
16
|
+
} & RoomTarget) | {
|
|
10
17
|
kind: 'invalid';
|
|
11
18
|
};
|
|
19
|
+
export declare function roomTarget(href: string): RoomTarget | null;
|
|
20
|
+
export declare function roomPath(href: string): string | null;
|
|
12
21
|
export declare function target(from: string, href: string): string | null;
|
|
13
22
|
export declare function retarget(href: string, to: string): string;
|
|
14
23
|
export declare function relative(from: string, target: string): string;
|
package/dist/paths.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"AAIA,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG5C;AAED,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG3D;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYrD;AAwDD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW3D;AAgBD,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAY5E,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,GAEV;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC9B,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,UAAU,CAAC,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAatB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAG1D;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGpD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGhE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAGzD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAW7D;AAED,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMvE"}
|
package/dist/paths.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { decodeNamedCharacterReference } from 'decode-named-character-reference';
|
|
2
|
+
import { decodeNumericCharacterReference } from 'micromark-util-decode-numeric-character-reference';
|
|
3
|
+
import { escapes } from './links.js';
|
|
1
4
|
export function dirname(path) {
|
|
2
5
|
const index = path.lastIndexOf('/');
|
|
3
6
|
return index === -1 ? '' : path.slice(0, index);
|
|
@@ -22,30 +25,132 @@ export function normalize(path) {
|
|
|
22
25
|
}
|
|
23
26
|
return parts.join('/');
|
|
24
27
|
}
|
|
28
|
+
const REFERENCE = /&(?:#[xX]([0-9a-fA-F]{1,6})|#([0-9]{1,7})|([A-Za-z][A-Za-z0-9]{0,31}));/y;
|
|
29
|
+
const PERCENT = /^%[0-9a-fA-F]{2}/;
|
|
30
|
+
function referenceAt(text, at) {
|
|
31
|
+
REFERENCE.lastIndex = at;
|
|
32
|
+
const match = REFERENCE.exec(text);
|
|
33
|
+
if (match === null)
|
|
34
|
+
return null;
|
|
35
|
+
const [whole, hex, decimal, name] = match;
|
|
36
|
+
const end = at + whole.length;
|
|
37
|
+
if (name !== undefined) {
|
|
38
|
+
const decoded = decodeNamedCharacterReference(name);
|
|
39
|
+
return decoded === false ? null : { text: decoded, end };
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
text: decodeNumericCharacterReference(hex ?? decimal, hex === undefined ? 10 : 16),
|
|
43
|
+
end,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function unescaped(written) {
|
|
47
|
+
let base = '';
|
|
48
|
+
let i = 0;
|
|
49
|
+
while (i < written.length) {
|
|
50
|
+
const escaped = escapes(written, i);
|
|
51
|
+
const reference = escaped || written[i] !== '&' ? null : referenceAt(written, i);
|
|
52
|
+
const text = escaped ? written[i + 1] : (reference?.text ?? written[i]);
|
|
53
|
+
if (text.startsWith('?') || text.startsWith('#'))
|
|
54
|
+
return { base, suffix: i };
|
|
55
|
+
base += text;
|
|
56
|
+
i = escaped ? i + 2 : (reference?.end ?? i + 1);
|
|
57
|
+
}
|
|
58
|
+
return { base, suffix: written.length };
|
|
59
|
+
}
|
|
60
|
+
function located(href) {
|
|
61
|
+
const written = href.trim();
|
|
62
|
+
const { base, suffix } = unescaped(written);
|
|
63
|
+
const url = base.replace(/[\t\n\r]/g, '').replace(/^[\u0000-\u0020]+/, '');
|
|
64
|
+
return {
|
|
65
|
+
base: suffix === written.length ? url.replace(/(?<![\u0000-\u0020])[\u0000-\u0020]+$/, '') : url,
|
|
66
|
+
suffix,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const ENCODED = /(?:%[0-9a-fA-F]{2})+/g;
|
|
70
|
+
function decodedRun(run) {
|
|
71
|
+
try {
|
|
72
|
+
return decodeURIComponent(run);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
export function destinationPath(href) {
|
|
79
|
+
const base = located(href).base;
|
|
80
|
+
let path = '';
|
|
81
|
+
let cursor = 0;
|
|
82
|
+
for (const match of base.matchAll(ENCODED)) {
|
|
83
|
+
const decoded = decodedRun(match[0]);
|
|
84
|
+
if (decoded === null)
|
|
85
|
+
return null;
|
|
86
|
+
path += base.slice(cursor, match.index) + decoded;
|
|
87
|
+
cursor = match.index + match[0].length;
|
|
88
|
+
}
|
|
89
|
+
return path + base.slice(cursor);
|
|
90
|
+
}
|
|
91
|
+
function written(path) {
|
|
92
|
+
let text = '';
|
|
93
|
+
for (let i = 0; i < path.length; i += 1) {
|
|
94
|
+
const char = path[i];
|
|
95
|
+
if (char === '?' || char === '#' || char < ' ')
|
|
96
|
+
text += encodeURIComponent(char);
|
|
97
|
+
else if (char === ' ' && (i === 0 || i === path.length - 1))
|
|
98
|
+
text += '%20';
|
|
99
|
+
else if (char === '%' && PERCENT.test(path.slice(i)))
|
|
100
|
+
text += '%25';
|
|
101
|
+
else if (escapes(path, i))
|
|
102
|
+
text += '%5C';
|
|
103
|
+
else if (char === '&' && referenceAt(path, i) !== null)
|
|
104
|
+
text += '%26';
|
|
105
|
+
else
|
|
106
|
+
text += char;
|
|
107
|
+
}
|
|
108
|
+
return text;
|
|
109
|
+
}
|
|
110
|
+
function roomTargetOf(path) {
|
|
111
|
+
if (!path.startsWith(SHELL_ROOMS))
|
|
112
|
+
return null;
|
|
113
|
+
const rest = path.slice(SHELL_ROOMS.length);
|
|
114
|
+
const slash = rest.indexOf('/');
|
|
115
|
+
const handle = rest.slice(0, slash);
|
|
116
|
+
if (slash <= 0 || handle === '.' || handle === '..')
|
|
117
|
+
return null;
|
|
118
|
+
const within = normalize(rest.slice(slash + 1));
|
|
119
|
+
return within === null || within === '' ? null : { handle, path: within };
|
|
120
|
+
}
|
|
25
121
|
export function classifyHref(from, href) {
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
122
|
+
const base = located(href).base;
|
|
123
|
+
if (base === '')
|
|
28
124
|
return { kind: 'skip' };
|
|
29
|
-
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(
|
|
125
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(base))
|
|
30
126
|
return { kind: 'skip' };
|
|
31
|
-
|
|
127
|
+
const path = destinationPath(href);
|
|
128
|
+
if (path === null)
|
|
32
129
|
return { kind: 'invalid' };
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return { kind: '
|
|
36
|
-
|
|
130
|
+
if (path.startsWith('/')) {
|
|
131
|
+
const room = roomTargetOf(path);
|
|
132
|
+
return room === null ? { kind: 'invalid' } : { kind: 'room', ...room };
|
|
133
|
+
}
|
|
134
|
+
const resolved = normalize(join(dirname(from), path));
|
|
37
135
|
if (resolved === null || resolved === '')
|
|
38
136
|
return { kind: 'invalid' };
|
|
39
137
|
return { kind: 'path', path: resolved };
|
|
40
138
|
}
|
|
139
|
+
export function roomTarget(href) {
|
|
140
|
+
const path = destinationPath(href);
|
|
141
|
+
return path === null ? null : roomTargetOf(path);
|
|
142
|
+
}
|
|
143
|
+
export function roomPath(href) {
|
|
144
|
+
const room = roomTarget(href);
|
|
145
|
+
return room === null ? null : `${SHELL_ROOMS}${room.handle}/${room.path}`;
|
|
146
|
+
}
|
|
41
147
|
export function target(from, href) {
|
|
42
148
|
const resolved = classifyHref(from, href);
|
|
43
149
|
return resolved.kind === 'path' ? resolved.path : null;
|
|
44
150
|
}
|
|
45
151
|
export function retarget(href, to) {
|
|
46
152
|
const trimmed = href.trim();
|
|
47
|
-
|
|
48
|
-
return match === null ? to : to + trimmed.slice(match.index);
|
|
153
|
+
return written(to) + trimmed.slice(unescaped(trimmed).suffix);
|
|
49
154
|
}
|
|
50
155
|
export function relative(from, target) {
|
|
51
156
|
const base = dirname(from)
|
|
@@ -62,8 +167,9 @@ export function relative(from, target) {
|
|
|
62
167
|
export const SHELL_ROOMS = '/rooms/';
|
|
63
168
|
export function shellTarget(href, handle) {
|
|
64
169
|
const prefix = `${SHELL_ROOMS}${handle}/`;
|
|
65
|
-
|
|
170
|
+
const decoded = destinationPath(href);
|
|
171
|
+
if (decoded === null || !decoded.startsWith(prefix))
|
|
66
172
|
return null;
|
|
67
|
-
const path = normalize(
|
|
173
|
+
const path = normalize(decoded.slice(prefix.length));
|
|
68
174
|
return path === null || path === '' ? null : path;
|
|
69
175
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const PATTERN_STATES = 1000;
|
|
2
|
+
export declare class PatternTooCostly extends Error {
|
|
3
|
+
}
|
|
4
|
+
export type Pattern = {
|
|
5
|
+
readonly test: (text: string) => boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function linearPattern(source: string): Pattern | null;
|
|
8
|
+
export declare function withLinearRegExp<T>(run: () => T): T;
|
|
9
|
+
export declare function openPatternBudget(): () => void;
|
|
10
|
+
//# sourceMappingURL=pattern.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pattern.d.ts","sourceRoot":"","sources":["../src/pattern.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,cAAc,OAAQ,CAAC;AAMpC,qBAAa,gBAAiB,SAAQ,KAAK;CAAG;AAQ9C,MAAM,MAAM,OAAO,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,CAAC;AAiUnE,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,CAM5D;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAkBnD;AAED,wBAAgB,iBAAiB,IAAI,MAAM,IAAI,CAM9C"}
|