asciidoc-abundant-tree 0.2.1 → 0.2.2
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/animation-yaml-export/cli.mjs +1 -1
- package/dist/browser.d.mts +2 -1
- package/dist/browser.mjs +120 -114
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +3 -2
- package/dist/index.mjs +1 -1
- package/dist/{src-DMOLXZbF.mjs → src-DmT-MEPN.mjs} +145 -131
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -295,7 +295,7 @@ const book = await parseAbundantTree({
|
|
|
295
295
|
});
|
|
296
296
|
```
|
|
297
297
|
|
|
298
|
-
`attributes` are the include attributes as Asciidoctor parses them, the same an Asciidoctor include processor receives, so the bookshelf build and this parser can register the same selector. A resolver that throws fails construction with `include.resolver-failed`; returned text that does not match its source leaves those lines without coordinates and reports `origin-map.selection-mismatch`.
|
|
298
|
+
`attributes` are the include attributes as Asciidoctor parses them, the same an Asciidoctor include processor receives, so the bookshelf build and this parser can register the same selector. A blank positional attribute is `null`: the first one in `[,beta]`, the second one in `[beta,,gamma]`. A resolver that throws fails construction with `include.resolver-failed`; returned text that does not match its source leaves those lines without coordinates and reports `origin-map.selection-mismatch`.
|
|
299
299
|
|
|
300
300
|
`parseAbundantTree` reads only the supplied source file. Interdocument xrefs keep their raw target and official href when Asciidoctor exposes one, but this package does not open the referenced `.adoc` file.
|
|
301
301
|
|
package/dist/browser.d.mts
CHANGED
|
@@ -154,7 +154,7 @@ type XrefOccurrenceNode = NodeBase & {
|
|
|
154
154
|
};
|
|
155
155
|
type AnchorOccurrenceNode = NodeBase & {
|
|
156
156
|
kind: "anchor";
|
|
157
|
-
syntax: "double-bracket" | "macro";
|
|
157
|
+
syntax: "double-bracket" | "macro" | "bibliography";
|
|
158
158
|
raw: string;
|
|
159
159
|
ids: string[];
|
|
160
160
|
reftext?: string;
|
|
@@ -179,6 +179,7 @@ type TargetNode = NodeBase & {
|
|
|
179
179
|
title?: string;
|
|
180
180
|
idOrigin: "source" | "asciidoctor-generated" | "unknown";
|
|
181
181
|
sourceSpan?: SourceSpan;
|
|
182
|
+
containingSectionId?: string;
|
|
182
183
|
};
|
|
183
184
|
type TextNode = NodeBase & {
|
|
184
185
|
kind: "text";
|
package/dist/browser.mjs
CHANGED
|
@@ -204,6 +204,7 @@ function addAnchorTargets(targets, anchorOccurrences) {
|
|
|
204
204
|
title: anchor.reftext,
|
|
205
205
|
idOrigin: "source",
|
|
206
206
|
sourceSpan: anchor.sourceSpan,
|
|
207
|
+
containingSectionId: anchor.containingSectionId,
|
|
207
208
|
asciidoctor: definedObject({
|
|
208
209
|
resolvedId: id,
|
|
209
210
|
resolvedType: targetType,
|
|
@@ -371,7 +372,8 @@ function recoverSourceAwareSourceLayer(document, logicalSpan, options) {
|
|
|
371
372
|
const lastRecord = sourceRecords.at(-1);
|
|
372
373
|
if (!firstRecord || !lastRecord) return recoveryFailure$1("source-coordinate.generated-line", `Parser core interval ${logicalSpan.startLine}-${logicalSpan.endLine} has no source-backed lines for ${options.diagnosticContext}.`, options.logicalSourceSpan);
|
|
373
374
|
const relativePath = firstRecord.origin.relativePath;
|
|
374
|
-
if (
|
|
375
|
+
if (firstRecord.origin.absolutePath !== lastRecord.origin.absolutePath) return recoveryFailure$1("block-origin.multi-source-span", `${options.diagnosticContext} starts at ${originLabel(firstRecord.origin)} and ends at ${originLabel(lastRecord.origin)}; no single origin source file holds its raw.`, options.logicalSourceSpan);
|
|
376
|
+
if (!authorLinesInSourceOrder(sourceRecords, firstRecord.origin)) return recoveryFailure$1("block-origin.multi-source-span", `${options.diagnosticContext} from ${originLabel(firstRecord.origin)} to ${originLabel(lastRecord.origin)} reads ${relativePath} out of source order; no contiguous raw exists.`, options.logicalSourceSpan);
|
|
375
377
|
const sourceFile = sourceFileForOrigin$1(document, firstRecord.origin);
|
|
376
378
|
if (!sourceFile) return recoveryFailure$1("line-origin.source-file-missing", `Origin file line table is missing for ${relativePath}.`, options.logicalSourceSpan);
|
|
377
379
|
const lineSpan = {
|
|
@@ -423,6 +425,47 @@ function recoverSourceAwarePointSourceLayer(document, logicalSourceSpan, raw) {
|
|
|
423
425
|
}
|
|
424
426
|
};
|
|
425
427
|
}
|
|
428
|
+
/**
|
|
429
|
+
* 块的 content span 在作者文件里的行区间。
|
|
430
|
+
*
|
|
431
|
+
* 内容的首行或尾行来自被引入的文件时,作者文件里与之对应的是那条 include 指令:从块里紧挨在内容之前的
|
|
432
|
+
* 作者行往后一行起,到紧挨在内容之后的作者行往前一行止。作者文件由块的首行决定,调用方应已用
|
|
433
|
+
* {@link recoverSourceAwareSourceLayer} 确认整块落在同一个作者文件里。
|
|
434
|
+
*/
|
|
435
|
+
function recoverSourceAwareContentLineSpan(document, blockSpan, contentSpan) {
|
|
436
|
+
const blockRecords = recordsForSpan(document, blockSpan)?.filter(hasOrigin);
|
|
437
|
+
const author = blockRecords?.[0]?.origin.absolutePath;
|
|
438
|
+
if (!blockRecords || author === void 0) return;
|
|
439
|
+
const authored = blockRecords.filter((record) => record.origin.absolutePath === author);
|
|
440
|
+
const inside = (record) => record.logicalLine >= contentSpan.startLine && record.logicalLine <= contentSpan.endLine;
|
|
441
|
+
const firstInside = authored.find(inside);
|
|
442
|
+
const lastInside = authored.findLast(inside);
|
|
443
|
+
const before = authored.findLast((record) => record.logicalLine < contentSpan.startLine);
|
|
444
|
+
const after = authored.find((record) => record.logicalLine > contentSpan.endLine);
|
|
445
|
+
const startsWithAuthorLine = firstInside !== void 0 && firstInside.logicalLine === firstOriginLine(blockRecords, contentSpan);
|
|
446
|
+
const endsWithAuthorLine = lastInside !== void 0 && lastInside.logicalLine === lastOriginLine(blockRecords, contentSpan);
|
|
447
|
+
const startLine = startsWithAuthorLine ? firstInside.origin.sourceLine : before && before.origin.sourceLine + 1;
|
|
448
|
+
const endLine = endsWithAuthorLine ? lastInside.origin.sourceLine : after && after.origin.sourceLine - 1;
|
|
449
|
+
if (startLine === void 0 || endLine === void 0 || startLine > endLine) return;
|
|
450
|
+
return {
|
|
451
|
+
startLine,
|
|
452
|
+
endLine
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* 一段逻辑行在源文件里落在哪些行上:`relativePath` 与 `line` 的组合,用 {@link originPointKey} 编成键。
|
|
457
|
+
*
|
|
458
|
+
* 出现处回源后只剩来源坐标;判断它在不在一个块里,就看它的来源是不是这个块某条逻辑行的来源
|
|
459
|
+
* (10 号书「结构关系在 Logical Document 上判定」)。被引入文件里的行也在其中。
|
|
460
|
+
*/
|
|
461
|
+
function originPointsForSpan(document, logicalSpan) {
|
|
462
|
+
const points = /* @__PURE__ */ new Set();
|
|
463
|
+
for (const record of recordsForSpan(document, logicalSpan) ?? []) if (hasOrigin(record)) points.add(originPointKey(record.origin.relativePath, record.origin.sourceLine));
|
|
464
|
+
return points;
|
|
465
|
+
}
|
|
466
|
+
function originPointKey(relativePath, line) {
|
|
467
|
+
return `${relativePath}\n${line}`;
|
|
468
|
+
}
|
|
426
469
|
function recoverSourceAwareDocumentTitleSourceLayer(document, logicalTitleSpan) {
|
|
427
470
|
if (!logicalTitleSpan) return;
|
|
428
471
|
return recoverSourceAwarePointSourceLayer(document, logicalTitleSpan, document.lines[logicalTitleSpan.start.line - 1]?.text ?? "");
|
|
@@ -460,22 +503,6 @@ function recoverSourceAwareTitleSpan(document, logicalTitleSpan) {
|
|
|
460
503
|
const recovered = recoverSourceAwareSpan(document, logicalTitleSpan, false);
|
|
461
504
|
return recovered.ok ? recovered.sourceSpan : void 0;
|
|
462
505
|
}
|
|
463
|
-
function sourceScopeFromSourceAwareInterval(document, span, headingLogicalLine) {
|
|
464
|
-
const headingRecord = document.lines[headingLogicalLine - 1];
|
|
465
|
-
if (!headingRecord || !hasOrigin(headingRecord)) return;
|
|
466
|
-
let endLine = headingRecord.origin.sourceLine;
|
|
467
|
-
for (let logicalLine = span.startLine; logicalLine <= span.endLine; logicalLine += 1) {
|
|
468
|
-
const record = document.lines[logicalLine - 1];
|
|
469
|
-
if (!record || !hasOrigin(record)) continue;
|
|
470
|
-
if (record.origin.relativePath !== headingRecord.origin.relativePath) continue;
|
|
471
|
-
endLine = Math.max(endLine, record.origin.sourceLine);
|
|
472
|
-
}
|
|
473
|
-
return {
|
|
474
|
-
relativePath: headingRecord.origin.relativePath,
|
|
475
|
-
startLine: headingRecord.origin.sourceLine,
|
|
476
|
-
endLine
|
|
477
|
-
};
|
|
478
|
-
}
|
|
479
506
|
function recoverSourceAwareSpan(document, logicalSourceSpan, requireColumns) {
|
|
480
507
|
const start = recoverSourceAwarePoint(document, logicalSourceSpan.start, requireColumns);
|
|
481
508
|
if (!start.ok) return start;
|
|
@@ -487,7 +514,7 @@ function recoverSourceAwareSpan(document, logicalSourceSpan, requireColumns) {
|
|
|
487
514
|
line: start.line
|
|
488
515
|
}
|
|
489
516
|
};
|
|
490
|
-
if (start.relativePath !== end.relativePath) return recoveryFailure$1("block-origin.multi-source-span", `Source span ${
|
|
517
|
+
if (start.relativePath !== end.relativePath) return recoveryFailure$1("block-origin.multi-source-span", `Source span starts at ${start.relativePath}:${start.line} and ends at ${end.relativePath}:${end.line}; no single origin source file holds it.`, logicalSourceSpan);
|
|
491
518
|
return {
|
|
492
519
|
ok: true,
|
|
493
520
|
relativePath: start.relativePath,
|
|
@@ -557,6 +584,24 @@ function recordsForSpan(document, span) {
|
|
|
557
584
|
function hasOrigin(record) {
|
|
558
585
|
return "origin" in record;
|
|
559
586
|
}
|
|
587
|
+
function originLabel(origin) {
|
|
588
|
+
return `${origin.relativePath}:${origin.sourceLine}`;
|
|
589
|
+
}
|
|
590
|
+
function authorLinesInSourceOrder(records, author) {
|
|
591
|
+
let previous = 0;
|
|
592
|
+
for (const record of records) {
|
|
593
|
+
if (record.origin.absolutePath !== author.absolutePath) continue;
|
|
594
|
+
if (record.origin.sourceLine <= previous) return false;
|
|
595
|
+
previous = record.origin.sourceLine;
|
|
596
|
+
}
|
|
597
|
+
return true;
|
|
598
|
+
}
|
|
599
|
+
function firstOriginLine(records, span) {
|
|
600
|
+
return records.find((record) => record.logicalLine >= span.startLine && record.logicalLine <= span.endLine)?.logicalLine;
|
|
601
|
+
}
|
|
602
|
+
function lastOriginLine(records, span) {
|
|
603
|
+
return records.findLast((record) => record.logicalLine >= span.startLine && record.logicalLine <= span.endLine)?.logicalLine;
|
|
604
|
+
}
|
|
560
605
|
function sourceFileForOrigin$1(document, origin) {
|
|
561
606
|
return document.sourceFiles.find((sourceFile) => sourceFile.absolutePath === origin.absolutePath);
|
|
562
607
|
}
|
|
@@ -1101,7 +1146,7 @@ function buildDescriptionList(block, startLine, context, interval) {
|
|
|
1101
1146
|
delimiter: descriptionListDelimiterMatch(context.lineTable, startLine)?.raw,
|
|
1102
1147
|
metadata: metadata.map((surface) => surface.node),
|
|
1103
1148
|
metadataSpan: interval?.metadataSpan,
|
|
1104
|
-
contentSpan: source ? originLineSpan(context, contentSpan) : void 0,
|
|
1149
|
+
contentSpan: source ? originLineSpan(context, contentSpan, span) : void 0,
|
|
1105
1150
|
span: source?.span,
|
|
1106
1151
|
source,
|
|
1107
1152
|
asciidoctor: definedObject({
|
|
@@ -1380,7 +1425,7 @@ function buildListing(block, delimiterLine, context, interval) {
|
|
|
1380
1425
|
metadata: metadata.map((surface) => surface.node),
|
|
1381
1426
|
content: block.getSource?.() ?? (contentSpan ? sourceLines(context.lineTable, contentSpan.startLine, contentSpan.endLine).join("\n") : void 0),
|
|
1382
1427
|
metadataSpan: interval?.metadataSpan,
|
|
1383
|
-
contentSpan: source ? originLineSpan(context, contentSpan) : void 0,
|
|
1428
|
+
contentSpan: source ? originLineSpan(context, contentSpan, span) : void 0,
|
|
1384
1429
|
span: source?.span,
|
|
1385
1430
|
source,
|
|
1386
1431
|
asciidoctor: definedObject({
|
|
@@ -1484,10 +1529,15 @@ function registerOfficialBlockTarget(context, block, options) {
|
|
|
1484
1529
|
title: options.title ?? block.getTitle?.(),
|
|
1485
1530
|
idOrigin: options.idOrigin ?? (options.targetType === "section" ? "asciidoctor-generated" : "source"),
|
|
1486
1531
|
sourceSpan: options.sourceSpan,
|
|
1532
|
+
containingSectionId: options.targetType === "section" ? void 0 : blockSectionId(context, block),
|
|
1487
1533
|
source: options.source,
|
|
1488
1534
|
asciidoctor
|
|
1489
1535
|
}));
|
|
1490
1536
|
}
|
|
1537
|
+
function blockSectionId(context, block) {
|
|
1538
|
+
const line = context.intervalByBlock.get(block)?.span.startLine;
|
|
1539
|
+
return line === void 0 ? void 0 : context.sectionByLine.get(line)?.ids[0];
|
|
1540
|
+
}
|
|
1491
1541
|
function blockSourceLayer(context, interval, fallbackSpan, diagnosticContext) {
|
|
1492
1542
|
if (!context.logicalSource && !context.sourceAwareDocument) {
|
|
1493
1543
|
const sourceSpan = sourceSpanFromLineSpan(context.lineTable, fallbackSpan);
|
|
@@ -1517,15 +1567,9 @@ function blockSourceLayer(context, interval, fallbackSpan, diagnosticContext) {
|
|
|
1517
1567
|
function sameLineSpan(left, right) {
|
|
1518
1568
|
return left.startLine === right.startLine && left.endLine === right.endLine;
|
|
1519
1569
|
}
|
|
1520
|
-
function originLineSpan(context, span) {
|
|
1570
|
+
function originLineSpan(context, span, blockSpan) {
|
|
1521
1571
|
if (!span || !context.logicalSource && !context.sourceAwareDocument) return span;
|
|
1522
|
-
if (context.sourceAwareDocument)
|
|
1523
|
-
const recovered = recoverSourceAwareSourceLayer(context.sourceAwareDocument, span, {
|
|
1524
|
-
raw: false,
|
|
1525
|
-
diagnosticContext: "block content"
|
|
1526
|
-
});
|
|
1527
|
-
return recovered.ok ? recovered.lineSpan : void 0;
|
|
1528
|
-
}
|
|
1572
|
+
if (context.sourceAwareDocument) return recoverSourceAwareContentLineSpan(context.sourceAwareDocument, blockSpan, span);
|
|
1529
1573
|
if (!context.logicalSource) return;
|
|
1530
1574
|
const recovered = recoverOriginSourceLayer(context.logicalSource, span, {
|
|
1531
1575
|
raw: false,
|
|
@@ -1544,6 +1588,13 @@ function collectHeadingInlineMetadataInSpan(context, logicalSpan, source) {
|
|
|
1544
1588
|
}
|
|
1545
1589
|
function collectOccurrencesInSpan(context, groupedByLine, occurrences, logicalSpan, source) {
|
|
1546
1590
|
if (!context.logicalSource && !context.sourceAwareDocument) return collectOccurrencesInLineRange(groupedByLine, logicalSpan.startLine, logicalSpan.endLine);
|
|
1591
|
+
if (context.sourceAwareDocument) {
|
|
1592
|
+
const points = originPointsForSpan(context.sourceAwareDocument, logicalSpan);
|
|
1593
|
+
return occurrences.filter((occurrence) => {
|
|
1594
|
+
const { relativePath, line } = occurrence.source ?? {};
|
|
1595
|
+
return relativePath !== void 0 && line !== void 0 && points.has(originPointKey(relativePath, line));
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1547
1598
|
if (!source?.relativePath || !source.span) return [];
|
|
1548
1599
|
const relativePath = source.relativePath;
|
|
1549
1600
|
const sourceSpan = source.span;
|
|
@@ -1611,61 +1662,12 @@ function locate(block, location) {
|
|
|
1611
1662
|
if (location) block.sourceLocation = location;
|
|
1612
1663
|
}
|
|
1613
1664
|
//#endregion
|
|
1614
|
-
//#region src/book-entry/source-scope-index.ts
|
|
1615
|
-
const sectionSourceScopeBySection = /* @__PURE__ */ new WeakMap();
|
|
1616
|
-
function registerSectionSourceScope(section, scope) {
|
|
1617
|
-
sectionSourceScopeBySection.set(section, scope);
|
|
1618
|
-
}
|
|
1619
|
-
function buildSourceScopeIndex(sections) {
|
|
1620
|
-
return { candidates: sections.flatMap((section) => {
|
|
1621
|
-
const scope = sourceScopeForSection(section);
|
|
1622
|
-
if (!scope) return [];
|
|
1623
|
-
return [{
|
|
1624
|
-
...scope,
|
|
1625
|
-
section
|
|
1626
|
-
}];
|
|
1627
|
-
}) };
|
|
1628
|
-
}
|
|
1629
|
-
function sourceScopeForSection(section) {
|
|
1630
|
-
const registered = sectionSourceScopeBySection.get(section);
|
|
1631
|
-
if (registered) return registered;
|
|
1632
|
-
const relativePath = section.source?.relativePath;
|
|
1633
|
-
const startLine = section.source?.span?.startLine ?? section.source?.line;
|
|
1634
|
-
const endLine = section.source?.span?.endLine ?? section.source?.line ?? startLine;
|
|
1635
|
-
if (!relativePath || startLine === void 0 || endLine === void 0) return;
|
|
1636
|
-
return {
|
|
1637
|
-
relativePath,
|
|
1638
|
-
startLine,
|
|
1639
|
-
endLine
|
|
1640
|
-
};
|
|
1641
|
-
}
|
|
1642
|
-
function lookupContainingSection(index, lookup) {
|
|
1643
|
-
const relativePath = lookup.relativePath ?? lookup.source?.relativePath;
|
|
1644
|
-
const line = lookup.line ?? lookup.source?.line;
|
|
1645
|
-
if (!relativePath || line === void 0) return;
|
|
1646
|
-
let containingSection;
|
|
1647
|
-
for (const candidate of index.candidates) {
|
|
1648
|
-
if (candidate.relativePath !== relativePath) continue;
|
|
1649
|
-
if (line < candidate.startLine || line > candidate.endLine) continue;
|
|
1650
|
-
containingSection = candidate.section;
|
|
1651
|
-
}
|
|
1652
|
-
return containingSection;
|
|
1653
|
-
}
|
|
1654
|
-
function assignContainingSectionIdsFromSourceScope(xrefs, anchors, headingInlineMetadataOccurrences, index) {
|
|
1655
|
-
for (const occurrence of [
|
|
1656
|
-
...xrefs,
|
|
1657
|
-
...anchors,
|
|
1658
|
-
...headingInlineMetadataOccurrences
|
|
1659
|
-
]) {
|
|
1660
|
-
const sectionId = lookupContainingSection(index, occurrence)?.ids[0];
|
|
1661
|
-
if (sectionId !== void 0) occurrence.containingSectionId = sectionId;
|
|
1662
|
-
}
|
|
1663
|
-
}
|
|
1664
|
-
//#endregion
|
|
1665
1665
|
//#region src/inline-occurrence-scanner.ts
|
|
1666
1666
|
const shorthandXrefPattern = /<<([^>,]+)(?:,\s*([^>]+))?>>/gu;
|
|
1667
1667
|
const macroXrefPattern = /xref:([^\s[]+)\[([^\]]*)\]/gu;
|
|
1668
|
-
const
|
|
1668
|
+
const anchorId = String.raw`[\p{Alphabetic}_:][\p{Alphabetic}\p{N}\p{Pc}\-:.]*`;
|
|
1669
|
+
const anchorPattern = new RegExp(String.raw`(?<![\\\[])\[\[(${anchorId})(?:, *(.+?))? ?\]\]` + String.raw`|(?<!\\)anchor:(${anchorId})\[(?:\]|(.*?[^\\])\])`, "gu");
|
|
1670
|
+
const bibliographyAnchorPattern = new RegExp(String.raw`^(\s*[*-]+\s+)\[\[\[(${anchorId})(?:, *(.+?))?\]\]\]`, "u");
|
|
1669
1671
|
const headingInlineMetadataPattern = /hmeta:([^\s[]+)\[([^\]]*)\]/gu;
|
|
1670
1672
|
function scanInlineOccurrencesInOfficialBlocks(options) {
|
|
1671
1673
|
const xrefOccurrences = [];
|
|
@@ -1683,8 +1685,9 @@ function scanInlineOccurrencesInOfficialBlocks(options) {
|
|
|
1683
1685
|
if (officialBlockPolicy(surface.block) !== "scan") continue;
|
|
1684
1686
|
if (!scansMacroSubstitutedContent(surface)) continue;
|
|
1685
1687
|
if (surface.context === "table") scanTableInlineRange(options.lineTable, surface.block, span.startLine, span.endLine, xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, options.toolDiagnostics);
|
|
1686
|
-
else scanInlineRange(options.lineTable, span.startLine, span.endLine, xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, options.toolDiagnostics, descendantUnscannableRanges(surface, options.intervalByBlock));
|
|
1688
|
+
else scanInlineRange(options.lineTable, span.startLine, span.endLine, xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, options.toolDiagnostics, descendantUnscannableRanges(surface, options.intervalByBlock), isBibliographyList(surface));
|
|
1687
1689
|
}
|
|
1690
|
+
assignContainingSectionIds(xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, options.sectionByLine);
|
|
1688
1691
|
const sourceAwareDocument = sourceAwareDocumentForLineTable(options.lineTable);
|
|
1689
1692
|
const logicalSource = logicalSourceForLineTable(options.lineTable);
|
|
1690
1693
|
const recoveredXrefs = sourceAwareDocument ? recoverSourceAwareInlineOrigins(xrefOccurrences, sourceAwareDocument, options.toolDiagnostics) : logicalSource ? recoverInlineOrigins(xrefOccurrences, logicalSource, options.toolDiagnostics) : xrefOccurrences;
|
|
@@ -1801,12 +1804,13 @@ function parseMacroLabel(raw) {
|
|
|
1801
1804
|
function compareSourceSpans(left, right) {
|
|
1802
1805
|
return (left.sourceSpan?.start.line ?? 0) - (right.sourceSpan?.start.line ?? 0) || (left.sourceSpan?.start.column ?? 0) - (right.sourceSpan?.start.column ?? 0);
|
|
1803
1806
|
}
|
|
1804
|
-
function scanInlineRange(lineTable, startLine, endLine, xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, toolDiagnostics, skipRanges = []) {
|
|
1807
|
+
function scanInlineRange(lineTable, startLine, endLine, xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, toolDiagnostics, skipRanges = [], bibliography = false) {
|
|
1805
1808
|
for (let lineNumber = startLine; lineNumber <= endLine; lineNumber += 1) {
|
|
1806
1809
|
if (isLineInRanges(lineNumber, skipRanges)) continue;
|
|
1807
1810
|
const line = lineTable.lines[lineNumber - 1];
|
|
1808
1811
|
if (!line) continue;
|
|
1809
1812
|
scanXrefMatches(lineTable, line, xrefOccurrences);
|
|
1813
|
+
if (bibliography) scanBibliographyAnchor(lineTable, line, anchorOccurrences);
|
|
1810
1814
|
scanAnchorMatches(lineTable, line, anchorOccurrences);
|
|
1811
1815
|
scanHeadingInlineMetadataMatches(lineTable, line, headingInlineMetadataOccurrences, toolDiagnostics);
|
|
1812
1816
|
}
|
|
@@ -1965,7 +1969,7 @@ function scanAnchorMatches(lineTable, line, anchorOccurrences) {
|
|
|
1965
1969
|
syntax: doubleBracketId ? "double-bracket" : "macro",
|
|
1966
1970
|
raw,
|
|
1967
1971
|
ids: [id],
|
|
1968
|
-
reftext: match[2]
|
|
1972
|
+
reftext: doubleBracketId ? match[2] : match[4] ?? "",
|
|
1969
1973
|
anchorScope: line.text.trim() === raw && doubleBracketId ? "block" : "inline",
|
|
1970
1974
|
sourceSpan,
|
|
1971
1975
|
source: {
|
|
@@ -1976,6 +1980,31 @@ function scanAnchorMatches(lineTable, line, anchorOccurrences) {
|
|
|
1976
1980
|
}));
|
|
1977
1981
|
}
|
|
1978
1982
|
}
|
|
1983
|
+
function scanBibliographyAnchor(lineTable, line, anchorOccurrences) {
|
|
1984
|
+
const match = bibliographyAnchorPattern.exec(line.text);
|
|
1985
|
+
const [, marker, id, reftext] = match ?? [];
|
|
1986
|
+
if (marker === void 0 || id === void 0) return;
|
|
1987
|
+
const raw = match?.[0].slice(marker.length) ?? "";
|
|
1988
|
+
const sourceSpan = sourceSpanForRange(lineTable, line.number, marker.length, raw);
|
|
1989
|
+
anchorOccurrences.push(definedObject({
|
|
1990
|
+
kind: "anchor",
|
|
1991
|
+
syntax: "bibliography",
|
|
1992
|
+
raw,
|
|
1993
|
+
ids: [id],
|
|
1994
|
+
reftext,
|
|
1995
|
+
anchorScope: "inline",
|
|
1996
|
+
sourceSpan,
|
|
1997
|
+
source: {
|
|
1998
|
+
raw,
|
|
1999
|
+
line: line.number,
|
|
2000
|
+
sourceSpan
|
|
2001
|
+
}
|
|
2002
|
+
}));
|
|
2003
|
+
}
|
|
2004
|
+
function isBibliographyList(surface) {
|
|
2005
|
+
const list = surface.context === "list_item" ? surface.parent : surface;
|
|
2006
|
+
return list?.context === "ulist" && list.block.getStyle?.() === "bibliography";
|
|
2007
|
+
}
|
|
1979
2008
|
function scanHeadingInlineMetadataMatches(lineTable, line, headingInlineMetadataOccurrences, toolDiagnostics) {
|
|
1980
2009
|
for (const match of line.text.matchAll(headingInlineMetadataPattern)) {
|
|
1981
2010
|
if (match.index === void 0 || !match[1]) continue;
|
|
@@ -2516,18 +2545,14 @@ function projectSourceSurfaces(options) {
|
|
|
2516
2545
|
if (policy === "diagnostic") toolDiagnostics.push(unknownContextDiagnostic(surface, interval));
|
|
2517
2546
|
}
|
|
2518
2547
|
const { sections, sectionByBlock } = buildSectionSurfaces(blockSurfaces, intervalByBlock, options.lineTable, toolDiagnostics, logicalSource, sourceAwareDocument);
|
|
2519
|
-
const sectionByLine =
|
|
2548
|
+
const sectionByLine = mapSectionScope(blockSurfaces, sectionByBlock, intervalByBlock);
|
|
2520
2549
|
const { xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences } = scanInlineOccurrencesInOfficialBlocks({
|
|
2521
2550
|
lineTable: options.lineTable,
|
|
2522
2551
|
blockSurfaces,
|
|
2523
2552
|
intervalByBlock,
|
|
2553
|
+
sectionByLine,
|
|
2524
2554
|
toolDiagnostics
|
|
2525
2555
|
});
|
|
2526
|
-
let sectionScopeIndex;
|
|
2527
|
-
if (logicalSource || sourceAwareDocument) {
|
|
2528
|
-
sectionScopeIndex = buildSourceScopeIndex(sections);
|
|
2529
|
-
assignContainingSectionIdsFromSourceScope(xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, sectionScopeIndex);
|
|
2530
|
-
} else assignContainingSectionIds(xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, sectionByLine);
|
|
2531
2556
|
return {
|
|
2532
2557
|
blockSurfaces,
|
|
2533
2558
|
intervalByBlock,
|
|
@@ -2538,7 +2563,6 @@ function projectSourceSurfaces(options) {
|
|
|
2538
2563
|
anchorOccurrences,
|
|
2539
2564
|
headingInlineMetadataOccurrences,
|
|
2540
2565
|
sectionByLine,
|
|
2541
|
-
...sectionScopeIndex ? { sectionScopeIndex } : {},
|
|
2542
2566
|
toolDiagnostics
|
|
2543
2567
|
};
|
|
2544
2568
|
}
|
|
@@ -2611,10 +2635,6 @@ function buildSectionSurfaces(blockSurfaces, intervalByBlock, lineTable, toolDia
|
|
|
2611
2635
|
}),
|
|
2612
2636
|
children: []
|
|
2613
2637
|
});
|
|
2614
|
-
if (logicalSource || sourceAwareDocument) {
|
|
2615
|
-
const sourceScope = sourceAwareDocument ? sourceScopeFromSourceAwareInterval(sourceAwareDocument, interval.span, sourceLine) : logicalSource ? sectionSourceScopeFromLogicalInterval(logicalSource, interval.span, sourceLine) : void 0;
|
|
2616
|
-
if (sourceScope) registerSectionSourceScope(section, sourceScope);
|
|
2617
|
-
}
|
|
2618
2638
|
sections.push(section);
|
|
2619
2639
|
sectionByBlock.set(surface.block, section);
|
|
2620
2640
|
}
|
|
@@ -2658,21 +2678,6 @@ function nextOriginHeadingBoundary(index, current) {
|
|
|
2658
2678
|
if (!index || !current) return;
|
|
2659
2679
|
return index.get(current.relativePath)?.find((candidate) => candidate.sliceStartLine > current.sliceStartLine);
|
|
2660
2680
|
}
|
|
2661
|
-
function sectionSourceScopeFromLogicalInterval(logicalSource, span, headingLogicalLine) {
|
|
2662
|
-
const headingOrigin = logicalSource.lineOrigins[headingLogicalLine - 1];
|
|
2663
|
-
if (!headingOrigin) return;
|
|
2664
|
-
let endLine = headingOrigin.sourceLine;
|
|
2665
|
-
for (let logicalLine = span.startLine; logicalLine <= span.endLine; logicalLine += 1) {
|
|
2666
|
-
const origin = logicalSource.lineOrigins[logicalLine - 1];
|
|
2667
|
-
if (!origin || origin.relativePath !== headingOrigin.relativePath) continue;
|
|
2668
|
-
endLine = Math.max(endLine, origin.sourceLine);
|
|
2669
|
-
}
|
|
2670
|
-
return {
|
|
2671
|
-
relativePath: headingOrigin.relativePath,
|
|
2672
|
-
startLine: headingOrigin.sourceLine,
|
|
2673
|
-
endLine
|
|
2674
|
-
};
|
|
2675
|
-
}
|
|
2676
2681
|
function sourceAwareOriginForLine(document, logicalLine) {
|
|
2677
2682
|
const record = document.lines[logicalLine - 1];
|
|
2678
2683
|
if (!record || !("origin" in record)) return;
|
|
@@ -2686,12 +2691,13 @@ function hasDiagnosticPolicyAncestor(surface) {
|
|
|
2686
2691
|
}
|
|
2687
2692
|
return false;
|
|
2688
2693
|
}
|
|
2689
|
-
function mapSectionScope(
|
|
2694
|
+
function mapSectionScope(blockSurfaces, sectionByBlock, intervalByBlock) {
|
|
2690
2695
|
const result = /* @__PURE__ */ new Map();
|
|
2691
|
-
for (const
|
|
2692
|
-
const
|
|
2693
|
-
const
|
|
2694
|
-
|
|
2696
|
+
for (const surface of blockSurfaces) {
|
|
2697
|
+
const section = sectionByBlock.get(surface.block);
|
|
2698
|
+
const span = intervalByBlock.get(surface.block)?.span;
|
|
2699
|
+
if (!section || !span) continue;
|
|
2700
|
+
for (let line = span.startLine; line <= span.endLine; line += 1) result.set(line, section);
|
|
2695
2701
|
}
|
|
2696
2702
|
return result;
|
|
2697
2703
|
}
|
package/dist/cli.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as parseAbundantTree, i as serializeAbundantTreeToJson, n as formatAbundantTree, t as rdf12 } from "./src-
|
|
2
|
+
import { a as parseAbundantTree, i as serializeAbundantTreeToJson, n as formatAbundantTree, t as rdf12 } from "./src-DmT-MEPN.mjs";
|
|
3
3
|
import { relative, resolve, sep } from "node:path";
|
|
4
4
|
import { existsSync } from "node:fs";
|
|
5
5
|
import process from "node:process";
|
package/dist/index.d.mts
CHANGED
|
@@ -156,7 +156,7 @@ type XrefOccurrenceNode = NodeBase & {
|
|
|
156
156
|
};
|
|
157
157
|
type AnchorOccurrenceNode = NodeBase & {
|
|
158
158
|
kind: "anchor";
|
|
159
|
-
syntax: "double-bracket" | "macro";
|
|
159
|
+
syntax: "double-bracket" | "macro" | "bibliography";
|
|
160
160
|
raw: string;
|
|
161
161
|
ids: string[];
|
|
162
162
|
reftext?: string;
|
|
@@ -181,6 +181,7 @@ type TargetNode = NodeBase & {
|
|
|
181
181
|
title?: string;
|
|
182
182
|
idOrigin: "source" | "asciidoctor-generated" | "unknown";
|
|
183
183
|
sourceSpan?: SourceSpan;
|
|
184
|
+
containingSectionId?: string;
|
|
184
185
|
};
|
|
185
186
|
type TextNode = NodeBase & {
|
|
186
187
|
kind: "text";
|
|
@@ -221,7 +222,7 @@ type IncludeResolver = {
|
|
|
221
222
|
};
|
|
222
223
|
type IncludeResolverRequest = {
|
|
223
224
|
readonly target: string;
|
|
224
|
-
readonly attributes: Readonly<Record<string, string>>;
|
|
225
|
+
readonly attributes: Readonly<Record<string, string | null>>;
|
|
225
226
|
readonly sourcePath: string;
|
|
226
227
|
};
|
|
227
228
|
type IncludeResolution = {
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as parseAbundantTree, i as serializeAbundantTreeToJson, n as formatAbundantTree, o as exportAnimationYaml, r as serializeAbundantTree, t as rdf12 } from "./src-
|
|
1
|
+
import { a as parseAbundantTree, i as serializeAbundantTreeToJson, n as formatAbundantTree, o as exportAnimationYaml, r as serializeAbundantTree, t as rdf12 } from "./src-DmT-MEPN.mjs";
|
|
2
2
|
export { exportAnimationYaml, formatAbundantTree, parseAbundantTree, rdf12, serializeAbundantTree, serializeAbundantTreeToJson };
|
|
@@ -284,6 +284,18 @@ function addFieldTriple(graph, subject, fieldName, value) {
|
|
|
284
284
|
}
|
|
285
285
|
//#endregion
|
|
286
286
|
//#region src/rdf12-projection/heading-ownership.ts
|
|
287
|
+
/**
|
|
288
|
+
* 出现处或目标所属的 section 对应的标题节点。
|
|
289
|
+
*
|
|
290
|
+
* 所属 section 已在逻辑文档上判定(10 号书「结构关系在 Logical Document 上判定」),标题可以和出现处不在
|
|
291
|
+
* 同一个源文件里:被引入的文件没有自己的标题时,它属于引入它的那个标题。ID 在一份文档里唯一,
|
|
292
|
+
* 仍多于一个候选时不选。
|
|
293
|
+
*/
|
|
294
|
+
function findHeadingBySectionId(nodeIndex, sectionId) {
|
|
295
|
+
if (sectionId === void 0) return;
|
|
296
|
+
const candidates = nodeIndex.entries().filter((entry) => entry.kind === "section" && entry.node.ids.includes(sectionId));
|
|
297
|
+
return candidates.length === 1 ? candidates[0] : void 0;
|
|
298
|
+
}
|
|
287
299
|
function findInnermostHeadingBySourceLine(input) {
|
|
288
300
|
return input.nodeIndex.entries().filter((entry) => containsLine(entry, input)).map((entry, index) => ({
|
|
289
301
|
entry,
|
|
@@ -377,14 +389,8 @@ function addHeadingLabels$1(catalog, entry) {
|
|
|
377
389
|
for (const id of entry.node.ids) addCatalogEntry(catalog, entry, labelKind, id);
|
|
378
390
|
}
|
|
379
391
|
function addLocalTargetAlias(catalog, input, target) {
|
|
380
|
-
if (target.targetType === "section" || !target.id || target.sourceSpan === void 0) return;
|
|
381
|
-
const
|
|
382
|
-
if (relativePath === void 0) return;
|
|
383
|
-
const owner = findInnermostHeadingBySourceLine({
|
|
384
|
-
nodeIndex: input.nodeIndex,
|
|
385
|
-
relativePath,
|
|
386
|
-
line: target.sourceSpan.start.line
|
|
387
|
-
});
|
|
392
|
+
if (target.targetType === "section" || !target.id || target.sourceSpan === void 0 && target.containingSectionId === void 0) return;
|
|
393
|
+
const owner = findHeadingBySectionId(input.nodeIndex, target.containingSectionId) ?? ownerBySourceLine(input, target);
|
|
388
394
|
if (owner === void 0) return;
|
|
389
395
|
addCatalogEntry(catalog, owner, "addressLabel", target.id);
|
|
390
396
|
input.graph.add(rdf12Triple(owner.iri, iriTerm(`${namespaces.aat}addressLabel`), stringLiteral(target.id)));
|
|
@@ -397,6 +403,15 @@ function addCatalogEntry(catalog, entry, labelKind, value) {
|
|
|
397
403
|
value
|
|
398
404
|
});
|
|
399
405
|
}
|
|
406
|
+
function ownerBySourceLine(input, target) {
|
|
407
|
+
const relativePath = sourceRelativePathOrFallback(target.source, input.relativePath, input.document.mode);
|
|
408
|
+
if (relativePath === void 0 || target.sourceSpan === void 0) return;
|
|
409
|
+
return findInnermostHeadingBySourceLine({
|
|
410
|
+
nodeIndex: input.nodeIndex,
|
|
411
|
+
relativePath,
|
|
412
|
+
line: target.sourceSpan.start.line
|
|
413
|
+
});
|
|
414
|
+
}
|
|
400
415
|
//#endregion
|
|
401
416
|
//#region src/rdf12-projection/path-coordinate.ts
|
|
402
417
|
function computePathCoordinate(input) {
|
|
@@ -755,7 +770,8 @@ function recoverSourceAwareSourceLayer(document, logicalSpan, options) {
|
|
|
755
770
|
const lastRecord = sourceRecords.at(-1);
|
|
756
771
|
if (!firstRecord || !lastRecord) return recoveryFailure$1("source-coordinate.generated-line", `Parser core interval ${logicalSpan.startLine}-${logicalSpan.endLine} has no source-backed lines for ${options.diagnosticContext}.`, options.logicalSourceSpan);
|
|
757
772
|
const relativePath = firstRecord.origin.relativePath;
|
|
758
|
-
if (
|
|
773
|
+
if (firstRecord.origin.absolutePath !== lastRecord.origin.absolutePath) return recoveryFailure$1("block-origin.multi-source-span", `${options.diagnosticContext} starts at ${originLabel(firstRecord.origin)} and ends at ${originLabel(lastRecord.origin)}; no single origin source file holds its raw.`, options.logicalSourceSpan);
|
|
774
|
+
if (!authorLinesInSourceOrder(sourceRecords, firstRecord.origin)) return recoveryFailure$1("block-origin.multi-source-span", `${options.diagnosticContext} from ${originLabel(firstRecord.origin)} to ${originLabel(lastRecord.origin)} reads ${relativePath} out of source order; no contiguous raw exists.`, options.logicalSourceSpan);
|
|
759
775
|
const sourceFile = sourceFileForOrigin$1(document, firstRecord.origin);
|
|
760
776
|
if (!sourceFile) return recoveryFailure$1("line-origin.source-file-missing", `Origin file line table is missing for ${relativePath}.`, options.logicalSourceSpan);
|
|
761
777
|
const lineSpan = {
|
|
@@ -807,6 +823,47 @@ function recoverSourceAwarePointSourceLayer(document, logicalSourceSpan, raw) {
|
|
|
807
823
|
}
|
|
808
824
|
};
|
|
809
825
|
}
|
|
826
|
+
/**
|
|
827
|
+
* 块的 content span 在作者文件里的行区间。
|
|
828
|
+
*
|
|
829
|
+
* 内容的首行或尾行来自被引入的文件时,作者文件里与之对应的是那条 include 指令:从块里紧挨在内容之前的
|
|
830
|
+
* 作者行往后一行起,到紧挨在内容之后的作者行往前一行止。作者文件由块的首行决定,调用方应已用
|
|
831
|
+
* {@link recoverSourceAwareSourceLayer} 确认整块落在同一个作者文件里。
|
|
832
|
+
*/
|
|
833
|
+
function recoverSourceAwareContentLineSpan(document, blockSpan, contentSpan) {
|
|
834
|
+
const blockRecords = recordsForSpan(document, blockSpan)?.filter(hasOrigin);
|
|
835
|
+
const author = blockRecords?.[0]?.origin.absolutePath;
|
|
836
|
+
if (!blockRecords || author === void 0) return;
|
|
837
|
+
const authored = blockRecords.filter((record) => record.origin.absolutePath === author);
|
|
838
|
+
const inside = (record) => record.logicalLine >= contentSpan.startLine && record.logicalLine <= contentSpan.endLine;
|
|
839
|
+
const firstInside = authored.find(inside);
|
|
840
|
+
const lastInside = authored.findLast(inside);
|
|
841
|
+
const before = authored.findLast((record) => record.logicalLine < contentSpan.startLine);
|
|
842
|
+
const after = authored.find((record) => record.logicalLine > contentSpan.endLine);
|
|
843
|
+
const startsWithAuthorLine = firstInside !== void 0 && firstInside.logicalLine === firstOriginLine(blockRecords, contentSpan);
|
|
844
|
+
const endsWithAuthorLine = lastInside !== void 0 && lastInside.logicalLine === lastOriginLine(blockRecords, contentSpan);
|
|
845
|
+
const startLine = startsWithAuthorLine ? firstInside.origin.sourceLine : before && before.origin.sourceLine + 1;
|
|
846
|
+
const endLine = endsWithAuthorLine ? lastInside.origin.sourceLine : after && after.origin.sourceLine - 1;
|
|
847
|
+
if (startLine === void 0 || endLine === void 0 || startLine > endLine) return;
|
|
848
|
+
return {
|
|
849
|
+
startLine,
|
|
850
|
+
endLine
|
|
851
|
+
};
|
|
852
|
+
}
|
|
853
|
+
/**
|
|
854
|
+
* 一段逻辑行在源文件里落在哪些行上:`relativePath` 与 `line` 的组合,用 {@link originPointKey} 编成键。
|
|
855
|
+
*
|
|
856
|
+
* 出现处回源后只剩来源坐标;判断它在不在一个块里,就看它的来源是不是这个块某条逻辑行的来源
|
|
857
|
+
* (10 号书「结构关系在 Logical Document 上判定」)。被引入文件里的行也在其中。
|
|
858
|
+
*/
|
|
859
|
+
function originPointsForSpan(document, logicalSpan) {
|
|
860
|
+
const points = /* @__PURE__ */ new Set();
|
|
861
|
+
for (const record of recordsForSpan(document, logicalSpan) ?? []) if (hasOrigin(record)) points.add(originPointKey(record.origin.relativePath, record.origin.sourceLine));
|
|
862
|
+
return points;
|
|
863
|
+
}
|
|
864
|
+
function originPointKey(relativePath, line) {
|
|
865
|
+
return `${relativePath}\n${line}`;
|
|
866
|
+
}
|
|
810
867
|
function recoverSourceAwareDocumentTitleSourceLayer(document, logicalTitleSpan) {
|
|
811
868
|
if (!logicalTitleSpan) return;
|
|
812
869
|
return recoverSourceAwarePointSourceLayer(document, logicalTitleSpan, document.lines[logicalTitleSpan.start.line - 1]?.text ?? "");
|
|
@@ -844,22 +901,6 @@ function recoverSourceAwareTitleSpan(document, logicalTitleSpan) {
|
|
|
844
901
|
const recovered = recoverSourceAwareSpan(document, logicalTitleSpan, false);
|
|
845
902
|
return recovered.ok ? recovered.sourceSpan : void 0;
|
|
846
903
|
}
|
|
847
|
-
function sourceScopeFromSourceAwareInterval(document, span, headingLogicalLine) {
|
|
848
|
-
const headingRecord = document.lines[headingLogicalLine - 1];
|
|
849
|
-
if (!headingRecord || !hasOrigin(headingRecord)) return;
|
|
850
|
-
let endLine = headingRecord.origin.sourceLine;
|
|
851
|
-
for (let logicalLine = span.startLine; logicalLine <= span.endLine; logicalLine += 1) {
|
|
852
|
-
const record = document.lines[logicalLine - 1];
|
|
853
|
-
if (!record || !hasOrigin(record)) continue;
|
|
854
|
-
if (record.origin.relativePath !== headingRecord.origin.relativePath) continue;
|
|
855
|
-
endLine = Math.max(endLine, record.origin.sourceLine);
|
|
856
|
-
}
|
|
857
|
-
return {
|
|
858
|
-
relativePath: headingRecord.origin.relativePath,
|
|
859
|
-
startLine: headingRecord.origin.sourceLine,
|
|
860
|
-
endLine
|
|
861
|
-
};
|
|
862
|
-
}
|
|
863
904
|
function recoverSourceAwareSpan(document, logicalSourceSpan, requireColumns) {
|
|
864
905
|
const start = recoverSourceAwarePoint(document, logicalSourceSpan.start, requireColumns);
|
|
865
906
|
if (!start.ok) return start;
|
|
@@ -871,7 +912,7 @@ function recoverSourceAwareSpan(document, logicalSourceSpan, requireColumns) {
|
|
|
871
912
|
line: start.line
|
|
872
913
|
}
|
|
873
914
|
};
|
|
874
|
-
if (start.relativePath !== end.relativePath) return recoveryFailure$1("block-origin.multi-source-span", `Source span ${
|
|
915
|
+
if (start.relativePath !== end.relativePath) return recoveryFailure$1("block-origin.multi-source-span", `Source span starts at ${start.relativePath}:${start.line} and ends at ${end.relativePath}:${end.line}; no single origin source file holds it.`, logicalSourceSpan);
|
|
875
916
|
return {
|
|
876
917
|
ok: true,
|
|
877
918
|
relativePath: start.relativePath,
|
|
@@ -941,6 +982,24 @@ function recordsForSpan(document, span) {
|
|
|
941
982
|
function hasOrigin(record) {
|
|
942
983
|
return "origin" in record;
|
|
943
984
|
}
|
|
985
|
+
function originLabel(origin) {
|
|
986
|
+
return `${origin.relativePath}:${origin.sourceLine}`;
|
|
987
|
+
}
|
|
988
|
+
function authorLinesInSourceOrder(records, author) {
|
|
989
|
+
let previous = 0;
|
|
990
|
+
for (const record of records) {
|
|
991
|
+
if (record.origin.absolutePath !== author.absolutePath) continue;
|
|
992
|
+
if (record.origin.sourceLine <= previous) return false;
|
|
993
|
+
previous = record.origin.sourceLine;
|
|
994
|
+
}
|
|
995
|
+
return true;
|
|
996
|
+
}
|
|
997
|
+
function firstOriginLine(records, span) {
|
|
998
|
+
return records.find((record) => record.logicalLine >= span.startLine && record.logicalLine <= span.endLine)?.logicalLine;
|
|
999
|
+
}
|
|
1000
|
+
function lastOriginLine(records, span) {
|
|
1001
|
+
return records.findLast((record) => record.logicalLine >= span.startLine && record.logicalLine <= span.endLine)?.logicalLine;
|
|
1002
|
+
}
|
|
944
1003
|
function sourceFileForOrigin$1(document, origin) {
|
|
945
1004
|
return document.sourceFiles.find((sourceFile) => sourceFile.absolutePath === origin.absolutePath);
|
|
946
1005
|
}
|
|
@@ -1623,10 +1682,10 @@ function writeSourceBinding(context, xrefIri, xref) {
|
|
|
1623
1682
|
}
|
|
1624
1683
|
function sourceHeadingForXref(context, xref) {
|
|
1625
1684
|
if (xref.sourceSpan === void 0) return;
|
|
1685
|
+
const selectorHeading = findHeadingBySectionId(context.nodeIndex, xref.containingSectionId)?.iri;
|
|
1686
|
+
if (selectorHeading !== void 0) return selectorHeading;
|
|
1626
1687
|
const relativePath = sourceRelativePathOrFallback(xref.source, context.relativePath, context.document.mode);
|
|
1627
1688
|
if (relativePath === void 0) return;
|
|
1628
|
-
const selectorHeading = sourceHeadingBySelector(context.nodeIndex, relativePath, xref.containingSectionId);
|
|
1629
|
-
if (selectorHeading !== void 0) return selectorHeading;
|
|
1630
1689
|
const line = xref.sourceSpan.start.line;
|
|
1631
1690
|
return findInnermostHeadingBySourceLine({
|
|
1632
1691
|
nodeIndex: context.nodeIndex,
|
|
@@ -1634,13 +1693,6 @@ function sourceHeadingForXref(context, xref) {
|
|
|
1634
1693
|
line
|
|
1635
1694
|
})?.iri;
|
|
1636
1695
|
}
|
|
1637
|
-
function sourceHeadingBySelector(nodeIndex, relativePath, selector) {
|
|
1638
|
-
if (selector === void 0) return;
|
|
1639
|
-
const candidates = nodeIndex.entries().filter((entry) => {
|
|
1640
|
-
return entry.relativePath === relativePath && entry.kind === "section" && entry.node.ids.includes(selector);
|
|
1641
|
-
});
|
|
1642
|
-
return candidates.length === 1 ? candidates[0]?.iri : void 0;
|
|
1643
|
-
}
|
|
1644
1696
|
function writeTargetBinding(context, xrefIri, xref) {
|
|
1645
1697
|
const result = bindSelector(context.labelCatalog, xref.target);
|
|
1646
1698
|
if (result.status === "bound") {
|
|
@@ -3531,6 +3583,7 @@ function addAnchorTargets(targets, anchorOccurrences) {
|
|
|
3531
3583
|
title: anchor.reftext,
|
|
3532
3584
|
idOrigin: "source",
|
|
3533
3585
|
sourceSpan: anchor.sourceSpan,
|
|
3586
|
+
containingSectionId: anchor.containingSectionId,
|
|
3534
3587
|
asciidoctor: definedObject({
|
|
3535
3588
|
resolvedId: id,
|
|
3536
3589
|
resolvedType: targetType,
|
|
@@ -4095,7 +4148,7 @@ function buildDescriptionList(block, startLine, context, interval) {
|
|
|
4095
4148
|
delimiter: descriptionListDelimiterMatch(context.lineTable, startLine)?.raw,
|
|
4096
4149
|
metadata: metadata.map((surface) => surface.node),
|
|
4097
4150
|
metadataSpan: interval?.metadataSpan,
|
|
4098
|
-
contentSpan: source ? originLineSpan(context, contentSpan) : void 0,
|
|
4151
|
+
contentSpan: source ? originLineSpan(context, contentSpan, span) : void 0,
|
|
4099
4152
|
span: source?.span,
|
|
4100
4153
|
source,
|
|
4101
4154
|
asciidoctor: definedObject({
|
|
@@ -4374,7 +4427,7 @@ function buildListing(block, delimiterLine, context, interval) {
|
|
|
4374
4427
|
metadata: metadata.map((surface) => surface.node),
|
|
4375
4428
|
content: block.getSource?.() ?? (contentSpan ? sourceLines(context.lineTable, contentSpan.startLine, contentSpan.endLine).join("\n") : void 0),
|
|
4376
4429
|
metadataSpan: interval?.metadataSpan,
|
|
4377
|
-
contentSpan: source ? originLineSpan(context, contentSpan) : void 0,
|
|
4430
|
+
contentSpan: source ? originLineSpan(context, contentSpan, span) : void 0,
|
|
4378
4431
|
span: source?.span,
|
|
4379
4432
|
source,
|
|
4380
4433
|
asciidoctor: definedObject({
|
|
@@ -4478,10 +4531,15 @@ function registerOfficialBlockTarget(context, block, options) {
|
|
|
4478
4531
|
title: options.title ?? block.getTitle?.(),
|
|
4479
4532
|
idOrigin: options.idOrigin ?? (options.targetType === "section" ? "asciidoctor-generated" : "source"),
|
|
4480
4533
|
sourceSpan: options.sourceSpan,
|
|
4534
|
+
containingSectionId: options.targetType === "section" ? void 0 : blockSectionId(context, block),
|
|
4481
4535
|
source: options.source,
|
|
4482
4536
|
asciidoctor
|
|
4483
4537
|
}));
|
|
4484
4538
|
}
|
|
4539
|
+
function blockSectionId(context, block) {
|
|
4540
|
+
const line = context.intervalByBlock.get(block)?.span.startLine;
|
|
4541
|
+
return line === void 0 ? void 0 : context.sectionByLine.get(line)?.ids[0];
|
|
4542
|
+
}
|
|
4485
4543
|
function blockSourceLayer(context, interval, fallbackSpan, diagnosticContext) {
|
|
4486
4544
|
if (!context.logicalSource && !context.sourceAwareDocument) {
|
|
4487
4545
|
const sourceSpan = sourceSpanFromLineSpan(context.lineTable, fallbackSpan);
|
|
@@ -4511,15 +4569,9 @@ function blockSourceLayer(context, interval, fallbackSpan, diagnosticContext) {
|
|
|
4511
4569
|
function sameLineSpan(left, right) {
|
|
4512
4570
|
return left.startLine === right.startLine && left.endLine === right.endLine;
|
|
4513
4571
|
}
|
|
4514
|
-
function originLineSpan(context, span) {
|
|
4572
|
+
function originLineSpan(context, span, blockSpan) {
|
|
4515
4573
|
if (!span || !context.logicalSource && !context.sourceAwareDocument) return span;
|
|
4516
|
-
if (context.sourceAwareDocument)
|
|
4517
|
-
const recovered = recoverSourceAwareSourceLayer(context.sourceAwareDocument, span, {
|
|
4518
|
-
raw: false,
|
|
4519
|
-
diagnosticContext: "block content"
|
|
4520
|
-
});
|
|
4521
|
-
return recovered.ok ? recovered.lineSpan : void 0;
|
|
4522
|
-
}
|
|
4574
|
+
if (context.sourceAwareDocument) return recoverSourceAwareContentLineSpan(context.sourceAwareDocument, blockSpan, span);
|
|
4523
4575
|
if (!context.logicalSource) return;
|
|
4524
4576
|
const recovered = recoverOriginSourceLayer(context.logicalSource, span, {
|
|
4525
4577
|
raw: false,
|
|
@@ -4538,6 +4590,13 @@ function collectHeadingInlineMetadataInSpan(context, logicalSpan, source) {
|
|
|
4538
4590
|
}
|
|
4539
4591
|
function collectOccurrencesInSpan(context, groupedByLine, occurrences, logicalSpan, source) {
|
|
4540
4592
|
if (!context.logicalSource && !context.sourceAwareDocument) return collectOccurrencesInLineRange(groupedByLine, logicalSpan.startLine, logicalSpan.endLine);
|
|
4593
|
+
if (context.sourceAwareDocument) {
|
|
4594
|
+
const points = originPointsForSpan(context.sourceAwareDocument, logicalSpan);
|
|
4595
|
+
return occurrences.filter((occurrence) => {
|
|
4596
|
+
const { relativePath, line } = occurrence.source ?? {};
|
|
4597
|
+
return relativePath !== void 0 && line !== void 0 && points.has(originPointKey(relativePath, line));
|
|
4598
|
+
});
|
|
4599
|
+
}
|
|
4541
4600
|
if (!source?.relativePath || !source.span) return [];
|
|
4542
4601
|
const relativePath = source.relativePath;
|
|
4543
4602
|
const sourceSpan = source.span;
|
|
@@ -4605,61 +4664,12 @@ function locate(block, location) {
|
|
|
4605
4664
|
if (location) block.sourceLocation = location;
|
|
4606
4665
|
}
|
|
4607
4666
|
//#endregion
|
|
4608
|
-
//#region src/book-entry/source-scope-index.ts
|
|
4609
|
-
const sectionSourceScopeBySection = /* @__PURE__ */ new WeakMap();
|
|
4610
|
-
function registerSectionSourceScope(section, scope) {
|
|
4611
|
-
sectionSourceScopeBySection.set(section, scope);
|
|
4612
|
-
}
|
|
4613
|
-
function buildSourceScopeIndex(sections) {
|
|
4614
|
-
return { candidates: sections.flatMap((section) => {
|
|
4615
|
-
const scope = sourceScopeForSection(section);
|
|
4616
|
-
if (!scope) return [];
|
|
4617
|
-
return [{
|
|
4618
|
-
...scope,
|
|
4619
|
-
section
|
|
4620
|
-
}];
|
|
4621
|
-
}) };
|
|
4622
|
-
}
|
|
4623
|
-
function sourceScopeForSection(section) {
|
|
4624
|
-
const registered = sectionSourceScopeBySection.get(section);
|
|
4625
|
-
if (registered) return registered;
|
|
4626
|
-
const relativePath = section.source?.relativePath;
|
|
4627
|
-
const startLine = section.source?.span?.startLine ?? section.source?.line;
|
|
4628
|
-
const endLine = section.source?.span?.endLine ?? section.source?.line ?? startLine;
|
|
4629
|
-
if (!relativePath || startLine === void 0 || endLine === void 0) return;
|
|
4630
|
-
return {
|
|
4631
|
-
relativePath,
|
|
4632
|
-
startLine,
|
|
4633
|
-
endLine
|
|
4634
|
-
};
|
|
4635
|
-
}
|
|
4636
|
-
function lookupContainingSection(index, lookup) {
|
|
4637
|
-
const relativePath = lookup.relativePath ?? lookup.source?.relativePath;
|
|
4638
|
-
const line = lookup.line ?? lookup.source?.line;
|
|
4639
|
-
if (!relativePath || line === void 0) return;
|
|
4640
|
-
let containingSection;
|
|
4641
|
-
for (const candidate of index.candidates) {
|
|
4642
|
-
if (candidate.relativePath !== relativePath) continue;
|
|
4643
|
-
if (line < candidate.startLine || line > candidate.endLine) continue;
|
|
4644
|
-
containingSection = candidate.section;
|
|
4645
|
-
}
|
|
4646
|
-
return containingSection;
|
|
4647
|
-
}
|
|
4648
|
-
function assignContainingSectionIdsFromSourceScope(xrefs, anchors, headingInlineMetadataOccurrences, index) {
|
|
4649
|
-
for (const occurrence of [
|
|
4650
|
-
...xrefs,
|
|
4651
|
-
...anchors,
|
|
4652
|
-
...headingInlineMetadataOccurrences
|
|
4653
|
-
]) {
|
|
4654
|
-
const sectionId = lookupContainingSection(index, occurrence)?.ids[0];
|
|
4655
|
-
if (sectionId !== void 0) occurrence.containingSectionId = sectionId;
|
|
4656
|
-
}
|
|
4657
|
-
}
|
|
4658
|
-
//#endregion
|
|
4659
4667
|
//#region src/inline-occurrence-scanner.ts
|
|
4660
4668
|
const shorthandXrefPattern = /<<([^>,]+)(?:,\s*([^>]+))?>>/gu;
|
|
4661
4669
|
const macroXrefPattern = /xref:([^\s[]+)\[([^\]]*)\]/gu;
|
|
4662
|
-
const
|
|
4670
|
+
const anchorId = String.raw`[\p{Alphabetic}_:][\p{Alphabetic}\p{N}\p{Pc}\-:.]*`;
|
|
4671
|
+
const anchorPattern = new RegExp(String.raw`(?<![\\\[])\[\[(${anchorId})(?:, *(.+?))? ?\]\]` + String.raw`|(?<!\\)anchor:(${anchorId})\[(?:\]|(.*?[^\\])\])`, "gu");
|
|
4672
|
+
const bibliographyAnchorPattern = new RegExp(String.raw`^(\s*[*-]+\s+)\[\[\[(${anchorId})(?:, *(.+?))?\]\]\]`, "u");
|
|
4663
4673
|
const headingInlineMetadataPattern = /hmeta:([^\s[]+)\[([^\]]*)\]/gu;
|
|
4664
4674
|
function scanInlineOccurrencesInOfficialBlocks(options) {
|
|
4665
4675
|
const xrefOccurrences = [];
|
|
@@ -4677,8 +4687,9 @@ function scanInlineOccurrencesInOfficialBlocks(options) {
|
|
|
4677
4687
|
if (officialBlockPolicy(surface.block) !== "scan") continue;
|
|
4678
4688
|
if (!scansMacroSubstitutedContent(surface)) continue;
|
|
4679
4689
|
if (surface.context === "table") scanTableInlineRange(options.lineTable, surface.block, span.startLine, span.endLine, xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, options.toolDiagnostics);
|
|
4680
|
-
else scanInlineRange(options.lineTable, span.startLine, span.endLine, xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, options.toolDiagnostics, descendantUnscannableRanges(surface, options.intervalByBlock));
|
|
4690
|
+
else scanInlineRange(options.lineTable, span.startLine, span.endLine, xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, options.toolDiagnostics, descendantUnscannableRanges(surface, options.intervalByBlock), isBibliographyList(surface));
|
|
4681
4691
|
}
|
|
4692
|
+
assignContainingSectionIds(xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, options.sectionByLine);
|
|
4682
4693
|
const sourceAwareDocument = sourceAwareDocumentForLineTable(options.lineTable);
|
|
4683
4694
|
const logicalSource = logicalSourceForLineTable(options.lineTable);
|
|
4684
4695
|
const recoveredXrefs = sourceAwareDocument ? recoverSourceAwareInlineOrigins(xrefOccurrences, sourceAwareDocument, options.toolDiagnostics) : logicalSource ? recoverInlineOrigins(xrefOccurrences, logicalSource, options.toolDiagnostics) : xrefOccurrences;
|
|
@@ -4795,12 +4806,13 @@ function parseMacroLabel(raw) {
|
|
|
4795
4806
|
function compareSourceSpans(left, right) {
|
|
4796
4807
|
return (left.sourceSpan?.start.line ?? 0) - (right.sourceSpan?.start.line ?? 0) || (left.sourceSpan?.start.column ?? 0) - (right.sourceSpan?.start.column ?? 0);
|
|
4797
4808
|
}
|
|
4798
|
-
function scanInlineRange(lineTable, startLine, endLine, xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, toolDiagnostics, skipRanges = []) {
|
|
4809
|
+
function scanInlineRange(lineTable, startLine, endLine, xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, toolDiagnostics, skipRanges = [], bibliography = false) {
|
|
4799
4810
|
for (let lineNumber = startLine; lineNumber <= endLine; lineNumber += 1) {
|
|
4800
4811
|
if (isLineInRanges(lineNumber, skipRanges)) continue;
|
|
4801
4812
|
const line = lineTable.lines[lineNumber - 1];
|
|
4802
4813
|
if (!line) continue;
|
|
4803
4814
|
scanXrefMatches(lineTable, line, xrefOccurrences);
|
|
4815
|
+
if (bibliography) scanBibliographyAnchor(lineTable, line, anchorOccurrences);
|
|
4804
4816
|
scanAnchorMatches(lineTable, line, anchorOccurrences);
|
|
4805
4817
|
scanHeadingInlineMetadataMatches(lineTable, line, headingInlineMetadataOccurrences, toolDiagnostics);
|
|
4806
4818
|
}
|
|
@@ -4959,7 +4971,7 @@ function scanAnchorMatches(lineTable, line, anchorOccurrences) {
|
|
|
4959
4971
|
syntax: doubleBracketId ? "double-bracket" : "macro",
|
|
4960
4972
|
raw,
|
|
4961
4973
|
ids: [id],
|
|
4962
|
-
reftext: match[2]
|
|
4974
|
+
reftext: doubleBracketId ? match[2] : match[4] ?? "",
|
|
4963
4975
|
anchorScope: line.text.trim() === raw && doubleBracketId ? "block" : "inline",
|
|
4964
4976
|
sourceSpan,
|
|
4965
4977
|
source: {
|
|
@@ -4970,6 +4982,31 @@ function scanAnchorMatches(lineTable, line, anchorOccurrences) {
|
|
|
4970
4982
|
}));
|
|
4971
4983
|
}
|
|
4972
4984
|
}
|
|
4985
|
+
function scanBibliographyAnchor(lineTable, line, anchorOccurrences) {
|
|
4986
|
+
const match = bibliographyAnchorPattern.exec(line.text);
|
|
4987
|
+
const [, marker, id, reftext] = match ?? [];
|
|
4988
|
+
if (marker === void 0 || id === void 0) return;
|
|
4989
|
+
const raw = match?.[0].slice(marker.length) ?? "";
|
|
4990
|
+
const sourceSpan = sourceSpanForRange(lineTable, line.number, marker.length, raw);
|
|
4991
|
+
anchorOccurrences.push(definedObject({
|
|
4992
|
+
kind: "anchor",
|
|
4993
|
+
syntax: "bibliography",
|
|
4994
|
+
raw,
|
|
4995
|
+
ids: [id],
|
|
4996
|
+
reftext,
|
|
4997
|
+
anchorScope: "inline",
|
|
4998
|
+
sourceSpan,
|
|
4999
|
+
source: {
|
|
5000
|
+
raw,
|
|
5001
|
+
line: line.number,
|
|
5002
|
+
sourceSpan
|
|
5003
|
+
}
|
|
5004
|
+
}));
|
|
5005
|
+
}
|
|
5006
|
+
function isBibliographyList(surface) {
|
|
5007
|
+
const list = surface.context === "list_item" ? surface.parent : surface;
|
|
5008
|
+
return list?.context === "ulist" && list.block.getStyle?.() === "bibliography";
|
|
5009
|
+
}
|
|
4973
5010
|
function scanHeadingInlineMetadataMatches(lineTable, line, headingInlineMetadataOccurrences, toolDiagnostics) {
|
|
4974
5011
|
for (const match of line.text.matchAll(headingInlineMetadataPattern)) {
|
|
4975
5012
|
if (match.index === void 0 || !match[1]) continue;
|
|
@@ -5510,18 +5547,14 @@ function projectSourceSurfaces(options) {
|
|
|
5510
5547
|
if (policy === "diagnostic") toolDiagnostics.push(unknownContextDiagnostic(surface, interval));
|
|
5511
5548
|
}
|
|
5512
5549
|
const { sections, sectionByBlock } = buildSectionSurfaces(blockSurfaces, intervalByBlock, options.lineTable, toolDiagnostics, logicalSource, sourceAwareDocument);
|
|
5513
|
-
const sectionByLine =
|
|
5550
|
+
const sectionByLine = mapSectionScope(blockSurfaces, sectionByBlock, intervalByBlock);
|
|
5514
5551
|
const { xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences } = scanInlineOccurrencesInOfficialBlocks({
|
|
5515
5552
|
lineTable: options.lineTable,
|
|
5516
5553
|
blockSurfaces,
|
|
5517
5554
|
intervalByBlock,
|
|
5555
|
+
sectionByLine,
|
|
5518
5556
|
toolDiagnostics
|
|
5519
5557
|
});
|
|
5520
|
-
let sectionScopeIndex;
|
|
5521
|
-
if (logicalSource || sourceAwareDocument) {
|
|
5522
|
-
sectionScopeIndex = buildSourceScopeIndex(sections);
|
|
5523
|
-
assignContainingSectionIdsFromSourceScope(xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, sectionScopeIndex);
|
|
5524
|
-
} else assignContainingSectionIds(xrefOccurrences, anchorOccurrences, headingInlineMetadataOccurrences, sectionByLine);
|
|
5525
5558
|
return {
|
|
5526
5559
|
blockSurfaces,
|
|
5527
5560
|
intervalByBlock,
|
|
@@ -5532,7 +5565,6 @@ function projectSourceSurfaces(options) {
|
|
|
5532
5565
|
anchorOccurrences,
|
|
5533
5566
|
headingInlineMetadataOccurrences,
|
|
5534
5567
|
sectionByLine,
|
|
5535
|
-
...sectionScopeIndex ? { sectionScopeIndex } : {},
|
|
5536
5568
|
toolDiagnostics
|
|
5537
5569
|
};
|
|
5538
5570
|
}
|
|
@@ -5605,10 +5637,6 @@ function buildSectionSurfaces(blockSurfaces, intervalByBlock, lineTable, toolDia
|
|
|
5605
5637
|
}),
|
|
5606
5638
|
children: []
|
|
5607
5639
|
});
|
|
5608
|
-
if (logicalSource || sourceAwareDocument) {
|
|
5609
|
-
const sourceScope = sourceAwareDocument ? sourceScopeFromSourceAwareInterval(sourceAwareDocument, interval.span, sourceLine) : logicalSource ? sectionSourceScopeFromLogicalInterval(logicalSource, interval.span, sourceLine) : void 0;
|
|
5610
|
-
if (sourceScope) registerSectionSourceScope(section, sourceScope);
|
|
5611
|
-
}
|
|
5612
5640
|
sections.push(section);
|
|
5613
5641
|
sectionByBlock.set(surface.block, section);
|
|
5614
5642
|
}
|
|
@@ -5652,21 +5680,6 @@ function nextOriginHeadingBoundary(index, current) {
|
|
|
5652
5680
|
if (!index || !current) return;
|
|
5653
5681
|
return index.get(current.relativePath)?.find((candidate) => candidate.sliceStartLine > current.sliceStartLine);
|
|
5654
5682
|
}
|
|
5655
|
-
function sectionSourceScopeFromLogicalInterval(logicalSource, span, headingLogicalLine) {
|
|
5656
|
-
const headingOrigin = logicalSource.lineOrigins[headingLogicalLine - 1];
|
|
5657
|
-
if (!headingOrigin) return;
|
|
5658
|
-
let endLine = headingOrigin.sourceLine;
|
|
5659
|
-
for (let logicalLine = span.startLine; logicalLine <= span.endLine; logicalLine += 1) {
|
|
5660
|
-
const origin = logicalSource.lineOrigins[logicalLine - 1];
|
|
5661
|
-
if (!origin || origin.relativePath !== headingOrigin.relativePath) continue;
|
|
5662
|
-
endLine = Math.max(endLine, origin.sourceLine);
|
|
5663
|
-
}
|
|
5664
|
-
return {
|
|
5665
|
-
relativePath: headingOrigin.relativePath,
|
|
5666
|
-
startLine: headingOrigin.sourceLine,
|
|
5667
|
-
endLine
|
|
5668
|
-
};
|
|
5669
|
-
}
|
|
5670
5683
|
function sourceAwareOriginForLine(document, logicalLine) {
|
|
5671
5684
|
const record = document.lines[logicalLine - 1];
|
|
5672
5685
|
if (!record || !("origin" in record)) return;
|
|
@@ -5680,12 +5693,13 @@ function hasDiagnosticPolicyAncestor(surface) {
|
|
|
5680
5693
|
}
|
|
5681
5694
|
return false;
|
|
5682
5695
|
}
|
|
5683
|
-
function mapSectionScope(
|
|
5696
|
+
function mapSectionScope(blockSurfaces, sectionByBlock, intervalByBlock) {
|
|
5684
5697
|
const result = /* @__PURE__ */ new Map();
|
|
5685
|
-
for (const
|
|
5686
|
-
const
|
|
5687
|
-
const
|
|
5688
|
-
|
|
5698
|
+
for (const surface of blockSurfaces) {
|
|
5699
|
+
const section = sectionByBlock.get(surface.block);
|
|
5700
|
+
const span = intervalByBlock.get(surface.block)?.span;
|
|
5701
|
+
if (!section || !span) continue;
|
|
5702
|
+
for (let line = span.startLine; line <= span.endLine; line += 1) result.set(line, section);
|
|
5689
5703
|
}
|
|
5690
5704
|
return result;
|
|
5691
5705
|
}
|
package/package.json
CHANGED