@openuji/speculator 0.7.4 → 0.8.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/README.md +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/parse/assembler.d.ts +1 -1
- package/dist/parse/assembler.d.ts.map +1 -1
- package/dist/parse/assembler.js +67 -13
- package/dist/parse/assembler.js.map +1 -1
- package/dist/parse/html/AsideHtmlParser.d.ts.map +1 -1
- package/dist/parse/html/AsideHtmlParser.js +85 -3
- package/dist/parse/html/AsideHtmlParser.js.map +1 -1
- package/dist/parse/html/CodeHtmlParser.d.ts.map +1 -1
- package/dist/parse/html/CodeHtmlParser.js +6 -2
- package/dist/parse/html/CodeHtmlParser.js.map +1 -1
- package/dist/parse/html/HeadingsHtmlParser.d.ts.map +1 -1
- package/dist/parse/html/HeadingsHtmlParser.js +3 -4
- package/dist/parse/html/HeadingsHtmlParser.js.map +1 -1
- package/dist/parse/html/IdlHtmlParser.d.ts +0 -4
- package/dist/parse/html/IdlHtmlParser.d.ts.map +1 -1
- package/dist/parse/html/IdlHtmlParser.js +2 -138
- package/dist/parse/html/IdlHtmlParser.js.map +1 -1
- package/dist/parse/html/MiscHtmlParser.d.ts.map +1 -1
- package/dist/parse/html/MiscHtmlParser.js +2 -42
- package/dist/parse/html/MiscHtmlParser.js.map +1 -1
- package/dist/parse/html/SectionsHtmlParser.d.ts.map +1 -1
- package/dist/parse/html/SectionsHtmlParser.js +17 -26
- package/dist/parse/html/SectionsHtmlParser.js.map +1 -1
- package/dist/parse/html/SpecStatementHtmlParser.js +3 -0
- package/dist/parse/html/SpecStatementHtmlParser.js.map +1 -1
- package/dist/parse/html/VocabHtmlParser.d.ts +12 -0
- package/dist/parse/html/VocabHtmlParser.d.ts.map +1 -0
- package/dist/parse/html/VocabHtmlParser.js +1156 -0
- package/dist/parse/html/VocabHtmlParser.js.map +1 -0
- package/dist/parse/html/parser.d.ts +13 -4
- package/dist/parse/html/parser.d.ts.map +1 -1
- package/dist/parse/html/parser.js +105 -119
- package/dist/parse/html/parser.js.map +1 -1
- package/dist/parse/index.d.ts +1 -2
- package/dist/parse/index.d.ts.map +1 -1
- package/dist/parse/index.js +0 -1
- package/dist/parse/index.js.map +1 -1
- package/dist/parse/markdown/CodeMarkdownParser.d.ts.map +1 -1
- package/dist/parse/markdown/CodeMarkdownParser.js +20 -2
- package/dist/parse/markdown/CodeMarkdownParser.js.map +1 -1
- package/dist/parse/markdown/HeadingsMarkdownParser.d.ts.map +1 -1
- package/dist/parse/markdown/HeadingsMarkdownParser.js +10 -33
- package/dist/parse/markdown/HeadingsMarkdownParser.js.map +1 -1
- package/dist/parse/markdown/MdxJsxMarkdownParser.d.ts +8 -0
- package/dist/parse/markdown/MdxJsxMarkdownParser.d.ts.map +1 -0
- package/dist/parse/markdown/MdxJsxMarkdownParser.js +61 -0
- package/dist/parse/markdown/MdxJsxMarkdownParser.js.map +1 -0
- package/dist/parse/markdown/MdxMarkdownParser.d.ts +13 -0
- package/dist/parse/markdown/MdxMarkdownParser.d.ts.map +1 -0
- package/dist/parse/markdown/MdxMarkdownParser.js +351 -0
- package/dist/parse/markdown/MdxMarkdownParser.js.map +1 -0
- package/dist/parse/markdown/ShorthandsMarkdownParser.d.ts.map +1 -1
- package/dist/parse/markdown/ShorthandsMarkdownParser.js +57 -2
- package/dist/parse/markdown/ShorthandsMarkdownParser.js.map +1 -1
- package/dist/parse/markdown/parser.d.ts +12 -3
- package/dist/parse/markdown/parser.d.ts.map +1 -1
- package/dist/parse/markdown/parser.js +90 -57
- package/dist/parse/markdown/parser.js.map +1 -1
- package/dist/parse/markdown/plugins.d.ts +26 -0
- package/dist/parse/markdown/plugins.d.ts.map +1 -0
- package/dist/parse/markdown/plugins.js +90 -0
- package/dist/parse/markdown/plugins.js.map +1 -0
- package/dist/parse/markdown/remark-mdx-jsx-only.d.ts +10 -0
- package/dist/parse/markdown/remark-mdx-jsx-only.d.ts.map +1 -0
- package/dist/parse/markdown/remark-mdx-jsx-only.js +26 -0
- package/dist/parse/markdown/remark-mdx-jsx-only.js.map +1 -0
- package/dist/parse/parsers.d.ts +2 -2
- package/dist/parse/parsers.d.ts.map +1 -1
- package/dist/parse/parsers.js +6 -6
- package/dist/parse/parsers.js.map +1 -1
- package/dist/parse/pipeline.d.ts.map +1 -1
- package/dist/parse/pipeline.js +41 -14
- package/dist/parse/pipeline.js.map +1 -1
- package/dist/parse/registry.d.ts +5 -5
- package/dist/parse/registry.d.ts.map +1 -1
- package/dist/parse/registry.js +12 -12
- package/dist/parse/registry.js.map +1 -1
- package/dist/parse/source-mapper.d.ts +42 -0
- package/dist/parse/source-mapper.d.ts.map +1 -0
- package/dist/parse/source-mapper.js +117 -0
- package/dist/parse/source-mapper.js.map +1 -0
- package/dist/parse/types.d.ts +20 -9
- package/dist/parse/types.d.ts.map +1 -1
- package/dist/parse/types.js +2 -13
- package/dist/parse/types.js.map +1 -1
- package/dist/parse/utils/hast-utils.d.ts.map +1 -1
- package/dist/parse/utils/hast-utils.js +69 -29
- package/dist/parse/utils/hast-utils.js.map +1 -1
- package/dist/parse/utils/html-element-utils.d.ts +9 -0
- package/dist/parse/utils/html-element-utils.d.ts.map +1 -0
- package/dist/parse/utils/html-element-utils.js +88 -0
- package/dist/parse/utils/html-element-utils.js.map +1 -0
- package/dist/parse/utils/idl-tokenizer.d.ts +7 -0
- package/dist/parse/utils/idl-tokenizer.d.ts.map +1 -0
- package/dist/parse/utils/idl-tokenizer.js +137 -0
- package/dist/parse/utils/idl-tokenizer.js.map +1 -0
- package/dist/parse/utils/markdown-utils.d.ts +16 -10
- package/dist/parse/utils/markdown-utils.d.ts.map +1 -1
- package/dist/parse/utils/markdown-utils.js +39 -75
- package/dist/parse/utils/markdown-utils.js.map +1 -1
- package/dist/pipeline/index.d.ts.map +1 -1
- package/dist/pipeline/index.js +1 -0
- package/dist/pipeline/index.js.map +1 -1
- package/dist/pipeline/runner.d.ts.map +1 -1
- package/dist/pipeline/runner.js +10 -4
- package/dist/pipeline/runner.js.map +1 -1
- package/dist/pipeline/types.d.ts +2 -0
- package/dist/pipeline/types.d.ts.map +1 -1
- package/dist/postprocess/index.d.ts +3 -1
- package/dist/postprocess/index.d.ts.map +1 -1
- package/dist/postprocess/index.js +9 -3
- package/dist/postprocess/index.js.map +1 -1
- package/dist/postprocess/plugins/bibliography-generator.d.ts.map +1 -1
- package/dist/postprocess/plugins/bibliography-generator.js +20 -3
- package/dist/postprocess/plugins/bibliography-generator.js.map +1 -1
- package/dist/postprocess/plugins/citation-resolve.d.ts.map +1 -1
- package/dist/postprocess/plugins/citation-resolve.js +255 -11
- package/dist/postprocess/plugins/citation-resolve.js.map +1 -1
- package/dist/postprocess/plugins/example-index.d.ts +16 -0
- package/dist/postprocess/plugins/example-index.d.ts.map +1 -0
- package/dist/postprocess/plugins/example-index.js +131 -0
- package/dist/postprocess/plugins/example-index.js.map +1 -0
- package/dist/postprocess/plugins/note-index.d.ts +14 -0
- package/dist/postprocess/plugins/note-index.d.ts.map +1 -0
- package/dist/postprocess/plugins/note-index.js +103 -0
- package/dist/postprocess/plugins/note-index.js.map +1 -0
- package/dist/postprocess/plugins/note-shorthands.d.ts +11 -0
- package/dist/postprocess/plugins/note-shorthands.d.ts.map +1 -0
- package/dist/postprocess/plugins/note-shorthands.js +298 -0
- package/dist/postprocess/plugins/note-shorthands.js.map +1 -0
- package/dist/postprocess/plugins/reference-resolve.d.ts.map +1 -1
- package/dist/postprocess/plugins/reference-resolve.js +46 -1
- package/dist/postprocess/plugins/reference-resolve.js.map +1 -1
- package/dist/postprocess/plugins/statement-distribute.d.ts.map +1 -1
- package/dist/postprocess/plugins/statement-distribute.js +46 -8
- package/dist/postprocess/plugins/statement-distribute.js.map +1 -1
- package/dist/postprocess/plugins/toc.d.ts.map +1 -1
- package/dist/postprocess/plugins/toc.js +20 -16
- package/dist/postprocess/plugins/toc.js.map +1 -1
- package/dist/postprocess/walk-ast.d.ts +5 -1
- package/dist/postprocess/walk-ast.d.ts.map +1 -1
- package/dist/postprocess/walk-ast.js +9 -0
- package/dist/postprocess/walk-ast.js.map +1 -1
- package/dist/preprocess/config/doc-config.d.ts +4 -1
- package/dist/preprocess/config/doc-config.d.ts.map +1 -1
- package/dist/preprocess/config/doc-config.js +6 -3
- package/dist/preprocess/config/doc-config.js.map +1 -1
- package/dist/preprocess/config/normalize.d.ts.map +1 -1
- package/dist/preprocess/config/normalize.js +34 -11
- package/dist/preprocess/config/normalize.js.map +1 -1
- package/dist/preprocess/config/types.d.ts +7 -3
- package/dist/preprocess/config/types.d.ts.map +1 -1
- package/dist/preprocess/include/resolver.d.ts.map +1 -1
- package/dist/preprocess/include/resolver.js +137 -33
- package/dist/preprocess/include/resolver.js.map +1 -1
- package/dist/preprocess/include/scan-html.js +1 -1
- package/dist/preprocess/include/scan-html.js.map +1 -1
- package/dist/preprocess/index.d.ts +1 -1
- package/dist/preprocess/index.d.ts.map +1 -1
- package/dist/preprocess/index.js.map +1 -1
- package/dist/preprocess/pipeline.d.ts.map +1 -1
- package/dist/preprocess/pipeline.js +1 -1
- package/dist/preprocess/pipeline.js.map +1 -1
- package/dist/preprocess/types.d.ts +32 -12
- package/dist/preprocess/types.d.ts.map +1 -1
- package/dist/types/ast.generated.d.ts +69 -13
- package/dist/types/ast.generated.d.ts.map +1 -1
- package/dist/types/ast.generated.js +4 -4
- package/dist/types/ast.generated.js.map +1 -1
- package/dist/workspace/sort.js +1 -1
- package/dist/workspace/sort.js.map +1 -1
- package/package.json +11 -2
- package/schema/spec-ast.schema.json +143 -9
package/dist/parse/pipeline.js
CHANGED
|
@@ -8,6 +8,7 @@ import { MarkdownUnitParser } from '#src/parse/markdown/index';
|
|
|
8
8
|
import { HtmlUnitParser } from '#src/parse/html/index';
|
|
9
9
|
import { assembleDocument } from '#src/parse/assembler';
|
|
10
10
|
import { defaultRegistry } from '#src/parse/registry';
|
|
11
|
+
import { SourceMapper } from '#src/parse/source-mapper';
|
|
11
12
|
/**
|
|
12
13
|
* Parser registry - maps format to parser factory
|
|
13
14
|
*/
|
|
@@ -30,16 +31,36 @@ function getParser(parsers, format) {
|
|
|
30
31
|
return parser;
|
|
31
32
|
}
|
|
32
33
|
/**
|
|
33
|
-
*
|
|
34
|
+
* Helper to parse content with error handling
|
|
34
35
|
*/
|
|
35
|
-
function
|
|
36
|
+
function parseContent(content, format, sourceMapper, entryFile, parsers, errors) {
|
|
36
37
|
try {
|
|
37
|
-
const parser = getParser(parsers,
|
|
38
|
-
return parser.parse(
|
|
38
|
+
const parser = getParser(parsers, format);
|
|
39
|
+
return parser.parse(content, sourceMapper);
|
|
39
40
|
}
|
|
40
41
|
catch (error) {
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
43
|
+
// Extract position from message if adjusted by parser (e.g. "(99:1)")
|
|
44
|
+
const posMatch = message.match(/\((\d+):(\d+)(?:-[\d:]+)?\)/);
|
|
45
|
+
let posSuffix = "";
|
|
46
|
+
let reportedFile = entryFile;
|
|
47
|
+
if (posMatch) {
|
|
48
|
+
const startLineOffset = parseInt(posMatch[1], 10);
|
|
49
|
+
// Convert remark's global line to actual source line via mapper
|
|
50
|
+
const srcPos = sourceMapper.createSourcePos({ start: { line: startLineOffset, column: parseInt(posMatch[2], 10), offset: 0 } });
|
|
51
|
+
if (srcPos) {
|
|
52
|
+
reportedFile = srcPos.file;
|
|
53
|
+
posSuffix = `:${srcPos.line}:${srcPos.column}`;
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
posSuffix = `:${posMatch[1]}:${posMatch[2]}`;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const formattedError = `${reportedFile}${posSuffix}: ${message}`;
|
|
60
|
+
errors.push(formattedError);
|
|
61
|
+
console.error(formattedError);
|
|
62
|
+
if (error instanceof Error)
|
|
63
|
+
console.error(error);
|
|
43
64
|
return [];
|
|
44
65
|
}
|
|
45
66
|
}
|
|
@@ -47,22 +68,28 @@ function parseUnit(unit, parsers) {
|
|
|
47
68
|
* Internal parse implementation
|
|
48
69
|
*/
|
|
49
70
|
function parseInternal(preprocessed, parsers) {
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
71
|
+
const errors = [];
|
|
72
|
+
const source = preprocessed.source;
|
|
73
|
+
const sourceMapper = new SourceMapper(source.content, source.sourceMap);
|
|
74
|
+
// If entry is HTML but we have markdown fragments, we MUST use the Markdown/MDX
|
|
75
|
+
// parser for the whole thing to allow markdown-inside-tags. MDX is a superset
|
|
76
|
+
// of HTML for our purposes.
|
|
77
|
+
let effectiveFormat = source.entryFormat;
|
|
78
|
+
if (effectiveFormat === 'html' && source.sourceMap.fragments.some(f => f.format === 'markdown')) {
|
|
79
|
+
effectiveFormat = 'markdown';
|
|
55
80
|
}
|
|
56
|
-
|
|
57
|
-
|
|
81
|
+
const blocks = parseContent(source.content, effectiveFormat, sourceMapper, source.entryFile, parsers, errors);
|
|
82
|
+
if (blocks.length === 0) {
|
|
83
|
+
return { errors: errors.length > 0 ? errors : undefined };
|
|
58
84
|
}
|
|
59
85
|
// Assemble document
|
|
60
|
-
const document = assembleDocument(
|
|
86
|
+
const document = assembleDocument(blocks, preprocessed.config, preprocessed.source.entryFile);
|
|
61
87
|
return {
|
|
62
88
|
result: {
|
|
63
89
|
config: preprocessed.config,
|
|
64
90
|
document,
|
|
65
91
|
},
|
|
92
|
+
errors: errors.length > 0 ? errors : undefined
|
|
66
93
|
};
|
|
67
94
|
}
|
|
68
95
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/parse/pipeline.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAwB,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../src/parse/pipeline.ts"],"names":[],"mappings":"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"}
|
package/dist/parse/registry.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import type { Element, RootContent as HastRootContent } from 'hast';
|
|
7
7
|
import type { RootContent as MdastRootContent } from 'mdast';
|
|
8
8
|
import type { Block, Inline, Section, SourcePos } from '#src/types/ast.generated';
|
|
9
|
-
import type {
|
|
9
|
+
import type { SourceMapper } from '#src/parse/source-mapper';
|
|
10
10
|
/** Node with position info from standard parsers */
|
|
11
11
|
export interface NodeWithPosition {
|
|
12
12
|
position?: {
|
|
@@ -36,8 +36,8 @@ export type ParseContextChildren = HastRootContent[] | MdastRootContent[];
|
|
|
36
36
|
* Context provided to parser modules during transformation.
|
|
37
37
|
*/
|
|
38
38
|
export interface ParseContext {
|
|
39
|
-
/** The source
|
|
40
|
-
readonly
|
|
39
|
+
/** The source mapper for absolute coordinates */
|
|
40
|
+
readonly sourceMapper: SourceMapper;
|
|
41
41
|
/** Create a source position for the AST node */
|
|
42
42
|
createSourcePos(node: NodeWithPosition): SourcePos;
|
|
43
43
|
/** Transform an array of mdast/hast inline children */
|
|
@@ -106,11 +106,11 @@ export declare class ParseHandlerRegistry {
|
|
|
106
106
|
/**
|
|
107
107
|
* Get block handler for an HTML tag
|
|
108
108
|
*/
|
|
109
|
-
|
|
109
|
+
getHtmlBlockHandlers(tagName: string): HtmlParserModule[];
|
|
110
110
|
/**
|
|
111
111
|
* Get inline handler for an HTML tag
|
|
112
112
|
*/
|
|
113
|
-
|
|
113
|
+
getHtmlInlineHandlers(tagName: string): HtmlParserModule[];
|
|
114
114
|
}
|
|
115
115
|
/**
|
|
116
116
|
* Default global registry used by the application.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/parse/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,IAAI,eAAe,EAAE,MAAM,MAAM,CAAC;AACpE,OAAO,KAAK,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAC7D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAClF,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/parse/registry.ts"],"names":[],"mappings":"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"}
|
package/dist/parse/registry.js
CHANGED
|
@@ -52,30 +52,30 @@ export class ParseHandlerRegistry {
|
|
|
52
52
|
for (const tag of parser.handles) {
|
|
53
53
|
const normalizedTag = tag.toLowerCase();
|
|
54
54
|
if (parser.handleBlock) {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
const handlers = this.htmlBlockHandlers.get(normalizedTag) || [];
|
|
56
|
+
handlers.push(parser);
|
|
57
|
+
handlers.sort((a, b) => (a.order ?? 10) - (b.order ?? 10));
|
|
58
|
+
this.htmlBlockHandlers.set(normalizedTag, handlers);
|
|
59
59
|
}
|
|
60
60
|
if (parser.handleInline) {
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
61
|
+
const handlers = this.htmlInlineHandlers.get(normalizedTag) || [];
|
|
62
|
+
handlers.push(parser);
|
|
63
|
+
handlers.sort((a, b) => (a.order ?? 10) - (b.order ?? 10));
|
|
64
|
+
this.htmlInlineHandlers.set(normalizedTag, handlers);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
69
|
* Get block handler for an HTML tag
|
|
70
70
|
*/
|
|
71
|
-
|
|
72
|
-
return this.htmlBlockHandlers.get(tagName.toLowerCase());
|
|
71
|
+
getHtmlBlockHandlers(tagName) {
|
|
72
|
+
return this.htmlBlockHandlers.get(tagName.toLowerCase()) || [];
|
|
73
73
|
}
|
|
74
74
|
/**
|
|
75
75
|
* Get inline handler for an HTML tag
|
|
76
76
|
*/
|
|
77
|
-
|
|
78
|
-
return this.htmlInlineHandlers.get(tagName.toLowerCase());
|
|
77
|
+
getHtmlInlineHandlers(tagName) {
|
|
78
|
+
return this.htmlInlineHandlers.get(tagName.toLowerCase()) || [];
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/parse/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsGH,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E;;GAEG;AACH,MAAM,OAAO,oBAAoB;IACrB,eAAe,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC5D,gBAAgB,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC7D,iBAAiB,GAAG,IAAI,GAAG,
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/parse/registry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsGH,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E;;GAEG;AACH,MAAM,OAAO,oBAAoB;IACrB,eAAe,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC5D,gBAAgB,GAAG,IAAI,GAAG,EAAkC,CAAC;IAC7D,iBAAiB,GAAG,IAAI,GAAG,EAA8B,CAAC;IAC1D,kBAAkB,GAAG,IAAI,GAAG,EAA8B,CAAC;IAEnE;;OAEG;IACH,sBAAsB,CAAC,MAA4B;QAC/C,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC1D,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC3D,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YACjD,CAAC;YACD,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBAC3D,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC3D,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAClD,CAAC;QACL,CAAC;IACL,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,QAAgB;QAC/B,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,mBAAmB,CAAC,QAAgB;QAChC,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;IACrD,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,MAAwB;QACvC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAC/B,MAAM,aAAa,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;YAExC,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBACrB,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;gBACjE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC3D,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YACxD,CAAC;YAED,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;gBAClE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBACtB,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC3D,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YACzD,CAAC;QACL,CAAC;IACL,CAAC;IAED;;OAEG;IACH,oBAAoB,CAAC,OAAe;QAChC,OAAO,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IACnE,CAAC;IAED;;OAEG;IACH,qBAAqB,CAAC,OAAe;QACjC,OAAO,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;IACpE,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import type { SourceMap } from '#src/preprocess/types';
|
|
2
|
+
import type { SourcePos } from '#src/types/ast.generated';
|
|
3
|
+
/**
|
|
4
|
+
* Maps a global character offset in the concatenated content string
|
|
5
|
+
* back to the original file and line number.
|
|
6
|
+
*/
|
|
7
|
+
export declare class SourceMapper {
|
|
8
|
+
private sourceMap;
|
|
9
|
+
private globalLineStarts;
|
|
10
|
+
constructor(content: string, sourceMap: SourceMap);
|
|
11
|
+
private buildLineMapping;
|
|
12
|
+
/**
|
|
13
|
+
* Converts an absolute offset in the composed string to an absolute line/column.
|
|
14
|
+
*/
|
|
15
|
+
private offsetToGlobalLineColumn;
|
|
16
|
+
/**
|
|
17
|
+
* Find the source map fragment that covers the given offset.
|
|
18
|
+
*/
|
|
19
|
+
private findFragment;
|
|
20
|
+
/**
|
|
21
|
+
* Creates a full SourcePos mapping for a given set of absolute offsets/lines/columns.
|
|
22
|
+
* Since remark gives us global lines and columns for the concatenated string,
|
|
23
|
+
* we will map those to original lines based on the fragment.
|
|
24
|
+
*/
|
|
25
|
+
createSourcePos(pos: {
|
|
26
|
+
start: {
|
|
27
|
+
line: number;
|
|
28
|
+
column: number;
|
|
29
|
+
offset?: number;
|
|
30
|
+
};
|
|
31
|
+
end?: {
|
|
32
|
+
line: number;
|
|
33
|
+
column: number;
|
|
34
|
+
offset?: number;
|
|
35
|
+
};
|
|
36
|
+
}): SourcePos | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Get sideFiles for a given offset. Useful for resolving relative assets/vocabularies.
|
|
39
|
+
*/
|
|
40
|
+
getSideFiles(offset: number): Record<string, string> | undefined;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=source-mapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-mapper.d.ts","sourceRoot":"","sources":["../../src/parse/source-mapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAqB,MAAM,uBAAuB,CAAC;AAC1E,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAE1D;;;GAGG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,SAAS,CAAY;IAE7B,OAAO,CAAC,gBAAgB,CAAgB;gBAE5B,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS;IAOjD,OAAO,CAAC,gBAAgB;IASxB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAuBhC;;OAEG;IACH,OAAO,CAAC,YAAY;IA6BpB;;;;OAIG;IACI,eAAe,CAClB,GAAG,EAAE;QAAE,KAAK,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,GAAG,CAAC,EAAE;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,GAC3H,SAAS,GAAG,SAAS;IAkCxB;;OAEG;IACI,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS;CAI1E"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Maps a global character offset in the concatenated content string
|
|
3
|
+
* back to the original file and line number.
|
|
4
|
+
*/
|
|
5
|
+
export class SourceMapper {
|
|
6
|
+
sourceMap;
|
|
7
|
+
// Cache the lines array for the composed content so we can convert offset -> line/column
|
|
8
|
+
globalLineStarts = [];
|
|
9
|
+
constructor(content, sourceMap) {
|
|
10
|
+
this.sourceMap = sourceMap;
|
|
11
|
+
if (content) {
|
|
12
|
+
this.buildLineMapping(content);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
buildLineMapping(content) {
|
|
16
|
+
this.globalLineStarts.push(0);
|
|
17
|
+
for (let i = 0; i < content.length; i++) {
|
|
18
|
+
if (content[i] === '\n') {
|
|
19
|
+
this.globalLineStarts.push(i + 1);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Converts an absolute offset in the composed string to an absolute line/column.
|
|
25
|
+
*/
|
|
26
|
+
offsetToGlobalLineColumn(offset) {
|
|
27
|
+
// Binary search to find the line
|
|
28
|
+
let low = 0;
|
|
29
|
+
let high = this.globalLineStarts.length - 1;
|
|
30
|
+
while (low <= high) {
|
|
31
|
+
const mid = Math.floor((low + high) / 2);
|
|
32
|
+
if (this.globalLineStarts[mid] <= offset) {
|
|
33
|
+
if (mid === this.globalLineStarts.length - 1 || this.globalLineStarts[mid + 1] > offset) {
|
|
34
|
+
return {
|
|
35
|
+
line: mid + 1, // 1-indexed
|
|
36
|
+
column: offset - this.globalLineStarts[mid] + 1 // 1-indexed
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
low = mid + 1;
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
high = mid - 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { line: 1, column: 1 };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Find the source map fragment that covers the given offset.
|
|
49
|
+
*/
|
|
50
|
+
findFragment(offset) {
|
|
51
|
+
// Binary search the fragments (they are ordered by startOffset and non-overlapping)
|
|
52
|
+
let low = 0;
|
|
53
|
+
let high = this.sourceMap.fragments.length - 1;
|
|
54
|
+
while (low <= high) {
|
|
55
|
+
const mid = Math.floor((low + high) / 2);
|
|
56
|
+
const fragment = this.sourceMap.fragments[mid];
|
|
57
|
+
if (offset >= fragment.startOffset && offset < fragment.endOffset) {
|
|
58
|
+
return fragment;
|
|
59
|
+
}
|
|
60
|
+
else if (offset < fragment.startOffset) {
|
|
61
|
+
high = mid - 1;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
low = mid + 1;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Fallback: if offset equals the document length, return the last fragment
|
|
68
|
+
if (offset > 0 && this.sourceMap.fragments.length > 0) {
|
|
69
|
+
const last = this.sourceMap.fragments[this.sourceMap.fragments.length - 1];
|
|
70
|
+
if (offset === last.endOffset) {
|
|
71
|
+
return last;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Creates a full SourcePos mapping for a given set of absolute offsets/lines/columns.
|
|
78
|
+
* Since remark gives us global lines and columns for the concatenated string,
|
|
79
|
+
* we will map those to original lines based on the fragment.
|
|
80
|
+
*/
|
|
81
|
+
createSourcePos(pos) {
|
|
82
|
+
if (pos.start.offset === undefined)
|
|
83
|
+
return undefined;
|
|
84
|
+
const fragment = this.findFragment(pos.start.offset);
|
|
85
|
+
if (!fragment)
|
|
86
|
+
return undefined;
|
|
87
|
+
// remark gives us global line. We need to find how many lines into the fragment we are.
|
|
88
|
+
const fragmentStartGlobalLC = this.offsetToGlobalLineColumn(fragment.startOffset);
|
|
89
|
+
// The local line offset within the fragment
|
|
90
|
+
const linesIntoFragment = pos.start.line - fragmentStartGlobalLC.line;
|
|
91
|
+
const originalLine = fragment.originalStartLine + linesIntoFragment;
|
|
92
|
+
const result = {
|
|
93
|
+
file: fragment.file,
|
|
94
|
+
line: originalLine,
|
|
95
|
+
column: pos.start.column,
|
|
96
|
+
offset: pos.start.offset, // keeping global offset. If we want local offset: (pos.start.offset - fragment.startOffset)
|
|
97
|
+
};
|
|
98
|
+
if (pos.end && pos.end.offset !== undefined) {
|
|
99
|
+
result.endColumn = pos.end.column;
|
|
100
|
+
result.endOffset = pos.end.offset; // global end
|
|
101
|
+
// if it stays in the same fragment, simple math
|
|
102
|
+
// technically block ends might fall into a different fragment if include spans,
|
|
103
|
+
// but we'll use the start fragment's file and calculate endLine relative to the start fragment
|
|
104
|
+
const endLinesIntoFragment = pos.end.line - fragmentStartGlobalLC.line;
|
|
105
|
+
result.endLine = fragment.originalStartLine + endLinesIntoFragment;
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Get sideFiles for a given offset. Useful for resolving relative assets/vocabularies.
|
|
111
|
+
*/
|
|
112
|
+
getSideFiles(offset) {
|
|
113
|
+
const fragment = this.findFragment(offset);
|
|
114
|
+
return fragment?.sideFiles;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=source-mapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-mapper.js","sourceRoot":"","sources":["../../src/parse/source-mapper.ts"],"names":[],"mappings":"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"}
|
package/dist/parse/types.d.ts
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Types for parsing source units into AST nodes.
|
|
5
5
|
*/
|
|
6
|
-
import type {
|
|
7
|
-
import type { Section, Block,
|
|
6
|
+
import type { SourceFormat, SpecConfig } from '#src/preprocess/types';
|
|
7
|
+
import type { Section, Block, Document } from '#src/types/ast.generated';
|
|
8
|
+
import type { SourceMapper } from '#src/parse/source-mapper';
|
|
8
9
|
/**
|
|
9
10
|
* Interface for format-specific unit parsers
|
|
10
11
|
*
|
|
@@ -15,12 +16,24 @@ export interface UnitParser {
|
|
|
15
16
|
/** Format this parser handles */
|
|
16
17
|
readonly format: SourceFormat;
|
|
17
18
|
/**
|
|
18
|
-
* Parse a
|
|
19
|
+
* Parse a final composed string into AST blocks using a source mapper
|
|
20
|
+
* for location tracking.
|
|
19
21
|
*
|
|
20
|
-
*
|
|
22
|
+
* Overload 1: New API with content string and SourceMapper
|
|
23
|
+
* Overload 2: Legacy API with SourceUnit-like object (backwards compat for tests)
|
|
24
|
+
*
|
|
25
|
+
* @param content - Full composed source string
|
|
26
|
+
* @param sourceMapper - Mapper to resolve absolute offsets to original files
|
|
21
27
|
* @returns Array of top-level blocks/sections
|
|
22
28
|
*/
|
|
23
|
-
parse(
|
|
29
|
+
parse(content: string, sourceMapper: SourceMapper): (Section | Block)[];
|
|
30
|
+
parse(unit: {
|
|
31
|
+
content: string;
|
|
32
|
+
file: string;
|
|
33
|
+
format: string;
|
|
34
|
+
startLine: number;
|
|
35
|
+
sideFiles?: Record<string, string>;
|
|
36
|
+
}): (Section | Block)[];
|
|
24
37
|
}
|
|
25
38
|
/**
|
|
26
39
|
* Result of parsing a preprocessed spec
|
|
@@ -37,9 +50,7 @@ export interface ParsedSpec {
|
|
|
37
50
|
export interface ParseResult {
|
|
38
51
|
/** Parsed spec (may be partial if errors) */
|
|
39
52
|
result?: ParsedSpec;
|
|
53
|
+
/** Encountered errors */
|
|
54
|
+
errors?: string[];
|
|
40
55
|
}
|
|
41
|
-
/**
|
|
42
|
-
* Create a source position from unit context
|
|
43
|
-
*/
|
|
44
|
-
export declare function createSourcePos(unit: SourceUnit, line: number, column: number): SourcePos;
|
|
45
56
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/parse/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/parse/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAO7D;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACvB,iCAAiC;IACjC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAE9B;;;;;;;;;;OAUG;IACH,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC;IACxE,KAAK,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC;CAC9I;AAMD;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,oCAAoC;IACpC,MAAM,EAAE,UAAU,CAAC;IAEnB,0BAA0B;IAC1B,QAAQ,EAAE,QAAQ,CAAC;CACtB;AAMD;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,6CAA6C;IAC7C,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,yBAAyB;IACzB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB"}
|
package/dist/parse/types.js
CHANGED
|
@@ -3,17 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Types for parsing source units into AST nodes.
|
|
5
5
|
*/
|
|
6
|
-
|
|
7
|
-
//
|
|
8
|
-
// ============================================================================
|
|
9
|
-
/**
|
|
10
|
-
* Create a source position from unit context
|
|
11
|
-
*/
|
|
12
|
-
export function createSourcePos(unit, line, column) {
|
|
13
|
-
return {
|
|
14
|
-
file: unit.file,
|
|
15
|
-
line: unit.startLine + line - 1,
|
|
16
|
-
column,
|
|
17
|
-
};
|
|
18
|
-
}
|
|
6
|
+
export {};
|
|
7
|
+
// Keep file valid but removed helpers not needed for offset-based mapping
|
|
19
8
|
//# sourceMappingURL=types.js.map
|
package/dist/parse/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/parse/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/parse/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAiEH,0EAA0E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hast-utils.d.ts","sourceRoot":"","sources":["../../../src/parse/utils/hast-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAoB,WAAW,IAAI,eAAe,EAAkB,MAAM,MAAM,CAAC;AAEtG,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,qBAAqB,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAkB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"hast-utils.d.ts","sourceRoot":"","sources":["../../../src/parse/utils/hast-utils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAoB,WAAW,IAAI,eAAe,EAAkB,MAAM,MAAM,CAAC;AAEtG,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,qBAAqB,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAkB,MAAM,0BAA0B,CAAC;AA0BlG;;;GAGG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAqB1E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAUvD;AAID;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,GAAG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAgCtG;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,GAAG,CAAC,OAAO,GAAG,KAAK,CAAC,EAAE,CA6ChG;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,YAAY,EAAE,eAAe,CAAC,EAAE,SAAS,GAAG,YAAY,CAmL9F"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* shared between HTML parsers and markdown HTML inline handling.
|
|
6
6
|
*/
|
|
7
7
|
import { visit } from 'unist-util-visit';
|
|
8
|
+
import { createBlockHtmlElement, createInlineHtmlElement } from './html-element-utils.js';
|
|
8
9
|
/**
|
|
9
10
|
* Offset the position of mdast nodes by a given number of lines.
|
|
10
11
|
* This is used when parsing markdown content inside HTML blocks,
|
|
@@ -30,6 +31,13 @@ function offsetMdastNodes(nodes, offsetLine) {
|
|
|
30
31
|
*/
|
|
31
32
|
export function getAttr(element, name) {
|
|
32
33
|
let val = element.properties?.[name];
|
|
34
|
+
// Handle class/className alias
|
|
35
|
+
if (val === undefined) {
|
|
36
|
+
if (name === 'class')
|
|
37
|
+
val = element.properties?.className;
|
|
38
|
+
else if (name === 'className')
|
|
39
|
+
val = element.properties?.class;
|
|
40
|
+
}
|
|
33
41
|
// Fallback: handle data- attributes (check both camelCase and kebab-case)
|
|
34
42
|
if (val === undefined && name.startsWith('data')) {
|
|
35
43
|
const camel = name.replace(/-([a-z0-9])/g, (g) => g[1].toUpperCase());
|
|
@@ -62,7 +70,7 @@ export function getTextContent(element) {
|
|
|
62
70
|
}
|
|
63
71
|
return text;
|
|
64
72
|
}
|
|
65
|
-
import { parseMarkdownInlines, parseMarkdownBlocks } from './markdown-utils.js';
|
|
73
|
+
import { isHtmlBlockTag, parseMarkdownInlines, parseMarkdownBlocks } from './markdown-utils.js';
|
|
66
74
|
/**
|
|
67
75
|
* Transform a hast node to Speculator inline(s) using HTML handlers.
|
|
68
76
|
* This is the core transformation logic shared by both paragraph and block HTML parsers.
|
|
@@ -79,13 +87,20 @@ export function transformHastInline(node, ctx) {
|
|
|
79
87
|
return null;
|
|
80
88
|
const element = node;
|
|
81
89
|
const tagName = element.tagName.toLowerCase();
|
|
82
|
-
// Look up
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
85
|
-
|
|
90
|
+
// Look up handlers in the registry provided in the context
|
|
91
|
+
const handlers = ctx.registry.getHtmlInlineHandlers(tagName);
|
|
92
|
+
if (handlers.length > 0) {
|
|
93
|
+
for (const handler of handlers) {
|
|
94
|
+
if (handler.handleInline) {
|
|
95
|
+
const result = handler.handleInline(element, ctx);
|
|
96
|
+
if (result !== null)
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// All tried handlers returned null
|
|
101
|
+
return null;
|
|
86
102
|
}
|
|
87
|
-
|
|
88
|
-
return ctx.transformInlineChildren(element.children);
|
|
103
|
+
return createInlineHtmlElement(element, ctx, ctx.transformInlineChildren(element.children));
|
|
89
104
|
}
|
|
90
105
|
/**
|
|
91
106
|
* Transform a hast node to Speculator block(s) using HTML handlers.
|
|
@@ -95,28 +110,44 @@ export function transformHastBlock(node, ctx) {
|
|
|
95
110
|
return [];
|
|
96
111
|
const element = node;
|
|
97
112
|
const tagName = element.tagName.toLowerCase();
|
|
98
|
-
const
|
|
99
|
-
if (
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
113
|
+
const handlers = ctx.registry.getHtmlBlockHandlers(tagName);
|
|
114
|
+
if (handlers.length > 0) {
|
|
115
|
+
for (const handler of handlers) {
|
|
116
|
+
if (handler.handleBlock) {
|
|
117
|
+
const result = handler.handleBlock(element, ctx);
|
|
118
|
+
if (result !== null) {
|
|
119
|
+
if (Array.isArray(result))
|
|
120
|
+
return result;
|
|
121
|
+
return [result];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
106
125
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
126
|
+
const inlineHandlers = ctx.registry.getHtmlInlineHandlers(tagName);
|
|
127
|
+
if (inlineHandlers.length > 0) {
|
|
128
|
+
for (const inlineHandler of inlineHandlers) {
|
|
129
|
+
if (inlineHandler.handleInline) {
|
|
130
|
+
const inlineResult = inlineHandler.handleInline(element, ctx);
|
|
131
|
+
if (inlineResult !== null) {
|
|
132
|
+
const sourcePos = ctx.createSourcePos(element);
|
|
133
|
+
const inlines = Array.isArray(inlineResult) ? inlineResult : [inlineResult];
|
|
134
|
+
const paragraph = {
|
|
135
|
+
type: 'paragraph',
|
|
136
|
+
children: inlines,
|
|
137
|
+
};
|
|
138
|
+
if (sourcePos)
|
|
139
|
+
paragraph.sourcePos = sourcePos;
|
|
140
|
+
return [paragraph];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
118
144
|
}
|
|
119
|
-
|
|
145
|
+
// Only fall back to generic element if NO handlers were registered for this tag at all.
|
|
146
|
+
// If handlers existed but all returned null, we return an empty block list.
|
|
147
|
+
if (handlers.length > 0 || inlineHandlers.length > 0) {
|
|
148
|
+
return [];
|
|
149
|
+
}
|
|
150
|
+
return [createBlockHtmlElement(element, ctx, ctx.transformBlockChildren(element.children))];
|
|
120
151
|
}
|
|
121
152
|
/**
|
|
122
153
|
* Create a hast-aware ParseContext from a base (markdown) context.
|
|
@@ -164,6 +195,13 @@ export function createHastContext(ctx, parentSourcePos) {
|
|
|
164
195
|
const camelName = name.replace(/-([a-z])/g, (g) => g[1].toUpperCase());
|
|
165
196
|
val = element.properties?.[camelName];
|
|
166
197
|
}
|
|
198
|
+
// Handle class/className alias
|
|
199
|
+
if (val === undefined) {
|
|
200
|
+
if (name === 'class')
|
|
201
|
+
val = element.properties?.className;
|
|
202
|
+
else if (name === 'className')
|
|
203
|
+
val = element.properties?.class;
|
|
204
|
+
}
|
|
167
205
|
if (Array.isArray(val)) {
|
|
168
206
|
return val.join(' ');
|
|
169
207
|
}
|
|
@@ -241,8 +279,10 @@ export function createHastContext(ctx, parentSourcePos) {
|
|
|
241
279
|
if (child.type === 'element') {
|
|
242
280
|
// We know it's an element, but TS needs help differentiating from the generic object
|
|
243
281
|
const element = child;
|
|
244
|
-
const
|
|
245
|
-
|
|
282
|
+
const tagName = element.tagName.toLowerCase();
|
|
283
|
+
const handlers = hastCtx.registry.getHtmlBlockHandlers(tagName);
|
|
284
|
+
const shouldTreatAsBlock = handlers.some(h => h.handleBlock) || isHtmlBlockTag(tagName);
|
|
285
|
+
if (shouldTreatAsBlock) {
|
|
246
286
|
flushInlines();
|
|
247
287
|
results.push(...transformHastBlock(child, hastCtx));
|
|
248
288
|
continue;
|