@baiyibai-antora/extensions 1.14.0 → 1.15.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/CHANGELOG.adoc +14 -0
- package/README.adoc +1 -1
- package/dist/extensions/cite-it/asciidoc.d.ts +2 -2
- package/dist/extensions/cite-it/asciidoc.js +2 -2
- package/dist/extensions/cite-it/assembly-numbering.d.ts +7 -7
- package/dist/extensions/cite-it/assembly-numbering.d.ts.map +1 -1
- package/dist/extensions/cite-it/assembly-numbering.js +17 -17
- package/dist/extensions/cite-it/assembly-numbering.js.map +1 -1
- package/dist/extensions/cite-it/csl.d.ts +4 -13
- package/dist/extensions/cite-it/csl.d.ts.map +1 -1
- package/dist/extensions/cite-it/csl.js +38 -5
- package/dist/extensions/cite-it/csl.js.map +1 -1
- package/dist/extensions/cite-it/index.d.ts +18 -17
- package/dist/extensions/cite-it/index.d.ts.map +1 -1
- package/dist/extensions/cite-it/index.js +162 -69
- package/dist/extensions/cite-it/index.js.map +1 -1
- package/dist/extensions/cite-it/macro.d.ts +13 -8
- package/dist/extensions/cite-it/macro.d.ts.map +1 -1
- package/dist/extensions/cite-it/macro.js +32 -15
- package/dist/extensions/cite-it/macro.js.map +1 -1
- package/dist/extensions/cite-it/registry.d.ts +1 -1
- package/dist/extensions/cite-it/registry.js +1 -1
- package/dist/extensions/trademark-it/index.d.ts +1 -1
- package/dist/extensions/trademark-it/index.js +1 -1
- package/dist/lib/asciidoc-indexterms.d.ts +3 -37
- package/dist/lib/asciidoc-indexterms.d.ts.map +1 -1
- package/dist/lib/asciidoc-indexterms.js +23 -4
- package/dist/lib/asciidoc-indexterms.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @baiyibai-antora/extensions - cite-it
|
|
4
4
|
*
|
|
5
|
-
* Resolves `
|
|
5
|
+
* Resolves `cite:[key]` citations against BibTeX/BibLaTeX `.bib` files and
|
|
6
6
|
* generates a categorized bibliography partial. Numbering is a PDF/Antora
|
|
7
7
|
* Assembler-flattened-output concept only; ordinary, non-assembled HTML
|
|
8
8
|
* citations render a templated author/year fragment instead, carrying no
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* autoterm's `mergeTerminology` already establishes.
|
|
18
18
|
*
|
|
19
19
|
* Each category generates its OWN partial (`categoryPartialName`,
|
|
20
|
-
* `<output_partial>-<
|
|
20
|
+
* `<output_partial>-<ref_category>.adoc`). A component author routes a
|
|
21
21
|
* category to whichever page they choose, simply by including that
|
|
22
22
|
* category's own partial there; different categories may genuinely live
|
|
23
23
|
* on different pages, and citations correctly cross-link to whichever
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
* generated-partial injection are real per-build cost, so a component
|
|
42
42
|
* shouldn't pay it just because a sibling component happens to use
|
|
43
43
|
* cite-it). In practice this produced a bad failure mode: a page citing
|
|
44
|
-
* a key with `
|
|
44
|
+
* a key with `cite:[key]` in a component-version that forgot the
|
|
45
45
|
* `ext.cite_it` block either silently rendered an unrelated component's
|
|
46
46
|
* entry (if the key happened to collide) or a generic "unknown key"
|
|
47
47
|
* message that read like a typo rather than "this component-version
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
* for trademark-it/autoterm: declared once, inherited by every
|
|
59
59
|
* component-version automatically. A component-version's own
|
|
60
60
|
* `ext.cite_it.categories`, if present at all, is entirely optional and
|
|
61
|
-
* purely additive to the scaffold, matched by `
|
|
62
|
-
* mergeCategoriesConfig): naming a
|
|
61
|
+
* purely additive to the scaffold, matched by `ref_category` (see
|
|
62
|
+
* mergeCategoriesConfig): naming a category already in the scaffold
|
|
63
63
|
* extends it (its `ref_files`/`ref_force` append to the scaffold's),
|
|
64
|
-
* and naming a new
|
|
64
|
+
* and naming a new category adds one local to that component
|
|
65
65
|
* alone. A component-version with
|
|
66
66
|
* genuinely no categories anywhere, no playbook scaffold and no local
|
|
67
67
|
* `ext.cite_it.categories`, is still skipped: there is nothing to scan
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
* # Only 'ieee-bracket' is bundled and supported in this version.
|
|
78
78
|
* style: 'ieee-bracket'
|
|
79
79
|
* # Base filename for each category's own generated partial
|
|
80
|
-
* # (e.g.
|
|
80
|
+
* # (e.g. category "standards" -> generated-bibliography-
|
|
81
81
|
* # standards.adoc), one per category, injected into each
|
|
82
82
|
* # participating component-version.
|
|
83
83
|
* output_partial: 'generated-bibliography.adoc'
|
|
@@ -88,12 +88,12 @@
|
|
|
88
88
|
* write_to_disk: false
|
|
89
89
|
* # The global scaffold: every participating component-version
|
|
90
90
|
* # inherits these categories as-is unless it names the same
|
|
91
|
-
* #
|
|
91
|
+
* # ref_category itself, in which case its own entry extends this
|
|
92
92
|
* # one rather than replacing it.
|
|
93
93
|
* categories:
|
|
94
|
-
* -
|
|
94
|
+
* - ref_category: standards
|
|
95
95
|
* ref_files: ['cite-it-data:ROOT:partial$standards.bib']
|
|
96
|
-
* -
|
|
96
|
+
* - ref_category: literature
|
|
97
97
|
* ref_files: ['cite-it-data:ROOT:partial$literature-shared.bib']
|
|
98
98
|
* ref_force: ['rfc2119']
|
|
99
99
|
*
|
|
@@ -112,19 +112,19 @@
|
|
|
112
112
|
* ext:
|
|
113
113
|
* cite_it: {}
|
|
114
114
|
*
|
|
115
|
-
* A component needing a local-only addition to an existing
|
|
115
|
+
* A component needing a local-only addition to an existing category, or a
|
|
116
116
|
* wholly local category the scaffold does not define, adds only that:
|
|
117
117
|
*
|
|
118
118
|
* ext:
|
|
119
119
|
* cite_it:
|
|
120
120
|
* categories:
|
|
121
|
-
* # Extends the scaffold's own "literature"
|
|
121
|
+
* # Extends the scaffold's own "literature" category (above) with one
|
|
122
122
|
* # more file, appended after the scaffold's own ref_files.
|
|
123
|
-
* -
|
|
123
|
+
* - ref_category: literature
|
|
124
124
|
* ref_files: ['literature-local.bib']
|
|
125
|
-
* # A
|
|
125
|
+
* # A category the scaffold does not define at all: local to this
|
|
126
126
|
* # component only.
|
|
127
|
-
* -
|
|
127
|
+
* - ref_category: internal-notes
|
|
128
128
|
* ref_files: ['internal-notes.bib']
|
|
129
129
|
*
|
|
130
130
|
* `.bib` files are resolved from the content catalog's `partial` family,
|
|
@@ -172,7 +172,7 @@
|
|
|
172
172
|
* reading the `.bib` file directly. Bibtex itself carries no native
|
|
173
173
|
* concept of an outdated reference; this is a cite-it-specific convention,
|
|
174
174
|
* not a standard `.bib` field any external tool is expected to recognize.
|
|
175
|
-
* Deliberately not raised again at each `
|
|
175
|
+
* Deliberately not raised again at each `cite:[key]` use site in prose,
|
|
176
176
|
* one signal per generated partial is enough; managing `.bib` data itself,
|
|
177
177
|
* including deciding when an entry is superseded, stays outside cite-it's
|
|
178
178
|
* own scope (see the docs page's own "Scope" section).
|
|
@@ -281,12 +281,12 @@ function parseCategoriesConfig(v) {
|
|
|
281
281
|
if (!raw || typeof raw !== 'object')
|
|
282
282
|
continue;
|
|
283
283
|
const r = raw;
|
|
284
|
-
const
|
|
285
|
-
: typeof r['
|
|
286
|
-
if (!
|
|
284
|
+
const category = typeof r['ref_category'] === 'string' ? r['ref_category']
|
|
285
|
+
: typeof r['refCategory'] === 'string' ? r['refCategory'] : '';
|
|
286
|
+
if (!category)
|
|
287
287
|
continue;
|
|
288
288
|
result.push({
|
|
289
|
-
|
|
289
|
+
ref_category: category,
|
|
290
290
|
ref_files: toStringArray(r['ref_files'] ?? r['refFiles']),
|
|
291
291
|
ref_force: toStringArray(r['ref_force'] ?? r['refForce']),
|
|
292
292
|
});
|
|
@@ -294,25 +294,25 @@ function parseCategoriesConfig(v) {
|
|
|
294
294
|
return result;
|
|
295
295
|
}
|
|
296
296
|
// The playbook-level scaffold and a component's own categories[] merge by
|
|
297
|
-
//
|
|
297
|
+
// ref_category, the same shared-then-local-override precedence autoterm's
|
|
298
298
|
// mergeTerminology and a single category's own ref_files list both already
|
|
299
|
-
// establish: a
|
|
300
|
-
// concatenate, playbook first) rather than replaces, and a
|
|
301
|
-
// only at the component level is added as a wholly local
|
|
299
|
+
// establish: a category named at both levels extends (ref_files/ref_force
|
|
300
|
+
// concatenate, playbook first) rather than replaces, and a category named
|
|
301
|
+
// only at the component level is added as a wholly local one.
|
|
302
302
|
function mergeCategoriesConfig(scaffold, local) {
|
|
303
|
-
const
|
|
303
|
+
const byCategory = new Map();
|
|
304
304
|
for (const cat of scaffold)
|
|
305
|
-
|
|
305
|
+
byCategory.set(cat.ref_category, { ...cat });
|
|
306
306
|
for (const cat of local) {
|
|
307
|
-
const existing =
|
|
308
|
-
|
|
309
|
-
|
|
307
|
+
const existing = byCategory.get(cat.ref_category);
|
|
308
|
+
byCategory.set(cat.ref_category, existing ? {
|
|
309
|
+
ref_category: cat.ref_category,
|
|
310
310
|
ref_files: [...existing.ref_files, ...cat.ref_files],
|
|
311
311
|
ref_force: [...existing.ref_force, ...cat.ref_force],
|
|
312
312
|
} : cat);
|
|
313
313
|
}
|
|
314
|
-
return [...
|
|
315
|
-
|
|
314
|
+
return [...byCategory.values()].map((cat) => ({
|
|
315
|
+
ref_category: cat.ref_category,
|
|
316
316
|
ref_files: cat.ref_files,
|
|
317
317
|
ref_force: cat.ref_force,
|
|
318
318
|
}));
|
|
@@ -371,11 +371,11 @@ function resolveBibFiles(refs, contentCatalog, component, version, module, logge
|
|
|
371
371
|
return result;
|
|
372
372
|
}
|
|
373
373
|
// ---------------------------------------------------------------------------
|
|
374
|
-
// Orphaned
|
|
374
|
+
// Orphaned cite:[key] usage: a component-version that is not scanned
|
|
375
375
|
// ---------------------------------------------------------------------------
|
|
376
376
|
/**
|
|
377
377
|
* Checks a SKIPPED (non-participating) component-version's own pages for
|
|
378
|
-
* `
|
|
378
|
+
* `cite:[key]` usage that will never resolve, and records any found into
|
|
379
379
|
* `orphanedCiteKeys` (macro.ts) for the macro to detect at render time and
|
|
380
380
|
* report clearly, instead of either silently borrowing an unrelated
|
|
381
381
|
* component's data through the cross-component fallback (if the key
|
|
@@ -399,7 +399,7 @@ function resolveBibFiles(refs, contentCatalog, component, version, module, logge
|
|
|
399
399
|
* cite-it.adoc's own siblings) from being misreported.
|
|
400
400
|
*
|
|
401
401
|
* A cheap substring pre-check gates the real, Asciidoctor-based scan
|
|
402
|
-
* (`scanCiteKeys`): a component-version that never mentions `
|
|
402
|
+
* (`scanCiteKeys`): a component-version that never mentions `cite:[` at
|
|
403
403
|
* all pays nothing beyond a plain string search per page.
|
|
404
404
|
*/
|
|
405
405
|
function checkOrphanedCiteUsage(compKey, reason, contentCatalog, component, version, logger) {
|
|
@@ -412,7 +412,7 @@ function checkOrphanedCiteUsage(compKey, reason, contentCatalog, component, vers
|
|
|
412
412
|
const found = new Set();
|
|
413
413
|
for (const f of pages) {
|
|
414
414
|
const raw = f.contents.toString('utf8');
|
|
415
|
-
if (!raw.includes('
|
|
415
|
+
if (!raw.includes('cite:['))
|
|
416
416
|
continue;
|
|
417
417
|
const headerAttrs = (0, asciidoc_conditionals_1.pageHeaderAttributes)(raw);
|
|
418
418
|
const isDefined = (attr) => {
|
|
@@ -428,7 +428,7 @@ function checkOrphanedCiteUsage(compKey, reason, contentCatalog, component, vers
|
|
|
428
428
|
if (found.size === 0)
|
|
429
429
|
return;
|
|
430
430
|
macro_1.orphanedCiteKeys.set(compKey, found);
|
|
431
|
-
logger.warn(`cite-it: ${compKey} - ${reason}, but
|
|
431
|
+
logger.warn(`cite-it: ${compKey} - ${reason}, but cite:[${[...found].join('], cite:[')}] is used directly on its own page(s); ` +
|
|
432
432
|
'these citations will not resolve for this component-version, regardless of the playbook-level configuration');
|
|
433
433
|
}
|
|
434
434
|
// ---------------------------------------------------------------------------
|
|
@@ -444,6 +444,7 @@ function register(context) {
|
|
|
444
444
|
output_partial: 'generated-bibliography.adoc',
|
|
445
445
|
suppress_events: false,
|
|
446
446
|
write_to_disk: false,
|
|
447
|
+
blanket_pubstate: false,
|
|
447
448
|
categories: [],
|
|
448
449
|
};
|
|
449
450
|
const extByCompVer = new Map();
|
|
@@ -480,7 +481,7 @@ function register(context) {
|
|
|
480
481
|
// inside ITS OWN navigationBuilt listener instead, as an earlier version
|
|
481
482
|
// of this code did, whichever extension's navigationBuilt listener runs
|
|
482
483
|
// first would win: a playbook that lists cite-it after
|
|
483
|
-
// `@antora/pdf-extension` would silently get unrewritten
|
|
484
|
+
// `@antora/pdf-extension` would silently get unrewritten cite:[key]
|
|
484
485
|
// literal text in PDF output, no error, no warning, since
|
|
485
486
|
// assembleContent's own loadAsciiDoc reference would already be frozen to
|
|
486
487
|
// the original, unwrapped function before cite-it's replaceFunctions call
|
|
@@ -509,6 +510,7 @@ function register(context) {
|
|
|
509
510
|
const [origFile, catalog, asciidocConfig] = args;
|
|
510
511
|
let file = origFile;
|
|
511
512
|
const isAssembled = !!(asciidocConfig?.attributes && 'loader-assembler' in asciidocConfig.attributes);
|
|
513
|
+
let restoreForeignPages;
|
|
512
514
|
if (isAssembled && file?.contents && file.src?.component && file.src?.version) {
|
|
513
515
|
const compKey = `${file.src.component}@${file.src.version}`;
|
|
514
516
|
// @antora/assembler resolves the active profile as
|
|
@@ -532,11 +534,17 @@ function register(context) {
|
|
|
532
534
|
file = Object.assign(Object.create(Object.getPrototypeOf(file)), file, { contents: Buffer.from(after, 'utf8') });
|
|
533
535
|
}
|
|
534
536
|
}
|
|
537
|
+
restoreForeignPages = rewriteForeignCitedPages(file.src, profileName);
|
|
535
538
|
}
|
|
536
539
|
// realLoadAsciiDoc is always assigned by this point: this closure is
|
|
537
540
|
// only ever reachable after the synchronous assignment a few lines
|
|
538
541
|
// above it in this same if-block has already run.
|
|
539
|
-
|
|
542
|
+
try {
|
|
543
|
+
return realLoadAsciiDoc(file, catalog, asciidocConfig ?? {});
|
|
544
|
+
}
|
|
545
|
+
finally {
|
|
546
|
+
restoreForeignPages?.();
|
|
547
|
+
}
|
|
540
548
|
};
|
|
541
549
|
ctx.replaceFunctions({ loadAsciiDoc: loadAsciiDocWrapper });
|
|
542
550
|
}
|
|
@@ -561,6 +569,7 @@ function register(context) {
|
|
|
561
569
|
output_partial: String(pick(raw, ['output_partial', 'outputPartial'], cfg.output_partial)),
|
|
562
570
|
suppress_events: toBool(pick(raw, ['suppress_events', 'suppressEvents'], cfg.suppress_events), cfg.suppress_events),
|
|
563
571
|
write_to_disk: toBool(pick(raw, ['write_to_disk', 'writeToDisk'], cfg.write_to_disk), cfg.write_to_disk),
|
|
572
|
+
blanket_pubstate: toBool(pick(raw, ['blanket_pubstate', 'blanketPubstate'], cfg.blanket_pubstate), cfg.blanket_pubstate),
|
|
564
573
|
categories: Array.isArray(raw['categories']) ? parseCategoriesConfig(raw['categories']) : cfg.categories,
|
|
565
574
|
};
|
|
566
575
|
quietMode = cfg.quiet;
|
|
@@ -595,7 +604,7 @@ function register(context) {
|
|
|
595
604
|
}
|
|
596
605
|
// The playbook-level categories scaffold needs no counterpart here
|
|
597
606
|
// at all: a component's own categories[] is entirely optional,
|
|
598
|
-
// additive to the scaffold by
|
|
607
|
+
// additive to the scaffold by ref_category. See
|
|
599
608
|
// mergeCategoriesConfig for the actual merge.
|
|
600
609
|
const categories = mergeCategoriesConfig(cfg.categories, parseCategoriesConfig(compExt['categories']));
|
|
601
610
|
if (categories.length === 0) {
|
|
@@ -622,6 +631,7 @@ function register(context) {
|
|
|
622
631
|
const compStyle = typeof compExt['style'] === 'string' ? compExt['style'] : cfg.style;
|
|
623
632
|
const compOutPartial = typeof compExt['output_partial'] === 'string' ? compExt['output_partial'] : cfg.output_partial;
|
|
624
633
|
const compWriteToDisk = toBool(compExt['write_to_disk'] ?? compExt['writeToDisk'], cfg.write_to_disk);
|
|
634
|
+
const compBlanketPubstate = toBool(compExt['blanket_pubstate'] ?? compExt['blanketPubstate'], cfg.blanket_pubstate);
|
|
625
635
|
const module = files.find((f) => f.src.family === 'page')?.src.module ?? 'ROOT';
|
|
626
636
|
// A page's own include::partial$<category-partial>[] is resolved
|
|
627
637
|
// as part of the scan below (collectIncludeText walks every
|
|
@@ -640,8 +650,8 @@ function register(context) {
|
|
|
640
650
|
// component-version turns out to have any real citation usage at
|
|
641
651
|
// all, which the scan below has not yet determined at this point.
|
|
642
652
|
const categoryPartials = categories.map((cat) => ({
|
|
643
|
-
|
|
644
|
-
relative: categoryPartialName(compOutPartial, cat.
|
|
653
|
+
category: cat.ref_category,
|
|
654
|
+
relative: categoryPartialName(compOutPartial, cat.ref_category),
|
|
645
655
|
}));
|
|
646
656
|
for (const cp of categoryPartials) {
|
|
647
657
|
(0, index_2.injectPartial)(contentCatalog, files, component, version, module, cp.relative, '', false, logger);
|
|
@@ -654,7 +664,7 @@ function register(context) {
|
|
|
654
664
|
// stale snapshot from before they existed.
|
|
655
665
|
files = contentCatalog.getFiles().filter((f) => f.src.component === component && f.src.version === version);
|
|
656
666
|
// ---------------------------------------------------------------
|
|
657
|
-
// 1. Scan pages (+ resolved includes) for
|
|
667
|
+
// 1. Scan pages (+ resolved includes) for cite:[key] usage,
|
|
658
668
|
// through a real Asciidoctor conversion (macro.ts's
|
|
659
669
|
// scanCiteKeys), not a hand-rolled regex. Runs BEFORE ever
|
|
660
670
|
// resolving or reading a single .bib file: the playbook-level
|
|
@@ -666,7 +676,7 @@ function register(context) {
|
|
|
666
676
|
// unconditionally, warning "not found" for files it never had
|
|
667
677
|
// any reason to carry. Scanning first and skipping entirely
|
|
668
678
|
// when nothing was found (see below) means a component-version
|
|
669
|
-
// with zero real
|
|
679
|
+
// with zero real cite:[] usage anywhere never even looks for
|
|
670
680
|
// its category files in the first place, rather than looking
|
|
671
681
|
// and then discovering there was nothing to find. Placeholder
|
|
672
682
|
// injection above still runs unconditionally either way: it
|
|
@@ -721,7 +731,7 @@ function register(context) {
|
|
|
721
731
|
const anyForced = categories.some((cat) => cat.ref_force.length > 0);
|
|
722
732
|
if (citedKeys.size === 0 && !anyForced) {
|
|
723
733
|
const hasOwnExt = extByCompVer.has(compKey);
|
|
724
|
-
const message = `cite-it: ${compKey} - skipped (no
|
|
734
|
+
const message = `cite-it: ${compKey} - skipped (no cite:[key] usage anywhere and no ref_force entries in any category)`;
|
|
725
735
|
if (hasOwnExt)
|
|
726
736
|
logger.warn(message);
|
|
727
737
|
else
|
|
@@ -749,14 +759,14 @@ function register(context) {
|
|
|
749
759
|
}
|
|
750
760
|
const keys = new Set();
|
|
751
761
|
for (const [key, entry] of catEntries) {
|
|
752
|
-
if (keyCategory.has(key) && keyCategory.get(key) !== cat.
|
|
753
|
-
logger.warn(`cite-it: ${compKey} - citation key "${key}" appears in both category "${keyCategory.get(key)}" and "${cat.
|
|
762
|
+
if (keyCategory.has(key) && keyCategory.get(key) !== cat.ref_category) {
|
|
763
|
+
logger.warn(`cite-it: ${compKey} - citation key "${key}" appears in both category "${keyCategory.get(key)}" and "${cat.ref_category}"; the later category's membership wins`);
|
|
754
764
|
}
|
|
755
|
-
keyCategory.set(key, cat.
|
|
765
|
+
keyCategory.set(key, cat.ref_category);
|
|
756
766
|
combinedEntries.set(key, entry);
|
|
757
767
|
keys.add(key);
|
|
758
768
|
}
|
|
759
|
-
categoryKeys.set(cat.
|
|
769
|
+
categoryKeys.set(cat.ref_category, keys);
|
|
760
770
|
}
|
|
761
771
|
// A key claimed by more than one category was added to every
|
|
762
772
|
// claiming category's own Set above, since each category's loop
|
|
@@ -786,15 +796,15 @@ function register(context) {
|
|
|
786
796
|
for (const cat of categories) {
|
|
787
797
|
for (const key of cat.ref_force) {
|
|
788
798
|
if (!combinedEntries.has(key)) {
|
|
789
|
-
logger.warn(`cite-it: ${compKey} - ref_force names unknown key "${key}" in category "${cat.
|
|
799
|
+
logger.warn(`cite-it: ${compKey} - ref_force names unknown key "${key}" in category "${cat.ref_category}"; not found in any configured category's data`);
|
|
790
800
|
continue;
|
|
791
801
|
}
|
|
792
|
-
const
|
|
793
|
-
if (
|
|
794
|
-
categoryKeys.get(
|
|
802
|
+
const previousCategory = keyCategory.get(key);
|
|
803
|
+
if (previousCategory && previousCategory !== cat.ref_category) {
|
|
804
|
+
categoryKeys.get(previousCategory)?.delete(key);
|
|
795
805
|
}
|
|
796
|
-
keyCategory.set(key, cat.
|
|
797
|
-
categoryKeys.get(cat.
|
|
806
|
+
keyCategory.set(key, cat.ref_category);
|
|
807
|
+
categoryKeys.get(cat.ref_category)?.add(key);
|
|
798
808
|
}
|
|
799
809
|
}
|
|
800
810
|
if (!cfg.suppress_events) {
|
|
@@ -802,11 +812,11 @@ function register(context) {
|
|
|
802
812
|
}
|
|
803
813
|
for (const key of citedKeys) {
|
|
804
814
|
if (!combinedEntries.has(key)) {
|
|
805
|
-
logger.warn(`cite-it: ${compKey} -
|
|
815
|
+
logger.warn(`cite-it: ${compKey} - cite:[${key}] cites an unknown key; not found in any configured category`);
|
|
806
816
|
}
|
|
807
817
|
}
|
|
808
818
|
// ---------------------------------------------------------------
|
|
809
|
-
// 3. Populate the shared cache the
|
|
819
|
+
// 3. Populate the shared cache the cite:[key] macro reads at
|
|
810
820
|
// real conversion time (macro.ts). Formatted only for keys
|
|
811
821
|
// actually used (cited, or ref_force), same set the
|
|
812
822
|
// generated partial lists.
|
|
@@ -815,10 +825,10 @@ function register(context) {
|
|
|
815
825
|
const usedKeysByCategory = new Map();
|
|
816
826
|
const allUsedKeys = [];
|
|
817
827
|
for (const cat of categories) {
|
|
818
|
-
const keys = [...(categoryKeys.get(cat.
|
|
828
|
+
const keys = [...(categoryKeys.get(cat.ref_category) ?? new Set())]
|
|
819
829
|
.filter((k) => citedKeys.has(k) || refForceKeys.has(k))
|
|
820
830
|
.sort((a, b) => a.localeCompare(b));
|
|
821
|
-
usedKeysByCategory.set(cat.
|
|
831
|
+
usedKeysByCategory.set(cat.ref_category, keys);
|
|
822
832
|
allUsedKeys.push(...keys);
|
|
823
833
|
}
|
|
824
834
|
// A key's entry carrying a supersededby field (registry.ts) warns
|
|
@@ -826,18 +836,18 @@ function register(context) {
|
|
|
826
836
|
// partial actually lists (cited or ref_force'd), not every entry
|
|
827
837
|
// the registry happens to hold: an unused entry going stale is not
|
|
828
838
|
// this component-version's problem to flag. Deliberately not
|
|
829
|
-
// raised again at each
|
|
839
|
+
// raised again at each cite:[key] use site (macro.ts): one clear
|
|
830
840
|
// signal per generated partial, not one per occurrence in prose.
|
|
831
|
-
for (const [
|
|
841
|
+
for (const [category, keys] of usedKeysByCategory) {
|
|
832
842
|
for (const key of keys) {
|
|
833
843
|
const supersededBy = combinedEntries.get(key)?.['supersededby'];
|
|
834
844
|
if (typeof supersededBy === 'string' && supersededBy) {
|
|
835
|
-
logger.warn(`cite-it: ${compKey} - citation "${key}" in category "${
|
|
845
|
+
logger.warn(`cite-it: ${compKey} - citation "${key}" in category "${category}" carries supersededby "${supersededBy}"; a newer revision is available`);
|
|
836
846
|
}
|
|
837
847
|
}
|
|
838
848
|
}
|
|
839
|
-
const formattedByKey = (0, csl_1.formatBibliographyEntries)(compStyle, combinedEntries, allUsedKeys);
|
|
840
|
-
const cacheData = { entriesByKey: combinedEntries, formattedByKey };
|
|
849
|
+
const formattedByKey = (0, csl_1.formatBibliographyEntries)(compStyle, combinedEntries, allUsedKeys, compBlanketPubstate);
|
|
850
|
+
const cacheData = { entriesByKey: combinedEntries, formattedByKey, blanketPubstate: compBlanketPubstate };
|
|
841
851
|
macro_1.citeCache.set(compKey, cacheData);
|
|
842
852
|
assemblyScanContexts.set(compKey, {
|
|
843
853
|
contentCatalog: contentCatalog,
|
|
@@ -855,8 +865,8 @@ function register(context) {
|
|
|
855
865
|
// which category's partial.
|
|
856
866
|
// ---------------------------------------------------------------
|
|
857
867
|
for (const cp of categoryPartials) {
|
|
858
|
-
const cat = categories.find((c) => c.
|
|
859
|
-
const keys = usedKeysByCategory.get(cat.
|
|
868
|
+
const cat = categories.find((c) => c.ref_category === cp.category);
|
|
869
|
+
const keys = usedKeysByCategory.get(cat.ref_category) ?? [];
|
|
860
870
|
const content = generateCategoryPartial(keys, formattedByKey);
|
|
861
871
|
(0, index_2.injectPartial)(contentCatalog, files, component, version, module, cp.relative, content, compWriteToDisk, logger);
|
|
862
872
|
}
|
|
@@ -874,7 +884,7 @@ function register(context) {
|
|
|
874
884
|
// of this code did (the earlier version genuinely raced against
|
|
875
885
|
// `@antora/assembler`'s own navigationBuilt listener and lost against a
|
|
876
886
|
// real playbook where `@antora/pdf-extension` preceded cite-it in
|
|
877
|
-
// `antora.extensions`, leaving every
|
|
887
|
+
// `antora.extensions`, leaving every cite:[key] unrewritten with no
|
|
878
888
|
// error). Computing lazily on first actual use, inside this same wrapper
|
|
879
889
|
// invocation, sidesteps that race entirely regardless of extension order.
|
|
880
890
|
//
|
|
@@ -1053,7 +1063,7 @@ function register(context) {
|
|
|
1053
1063
|
for (const cat of missingScopeCategories) {
|
|
1054
1064
|
logger.warn(`cite-it: ${compKey} - could not find the page that includes category "${cat}"'s generated partial; its citation links will render as plain numbers, not clickable links`);
|
|
1055
1065
|
}
|
|
1056
|
-
// The generated bibliography partial's own
|
|
1066
|
+
// The generated bibliography partial's own cite:[key] row labels
|
|
1057
1067
|
// need rewriting too, and specifically now, before any assembly-time
|
|
1058
1068
|
// loadAsciiDoc call resolves an include:: of it: Antora's include
|
|
1059
1069
|
// processor reads an included partial's content directly from the
|
|
@@ -1064,6 +1074,89 @@ function register(context) {
|
|
|
1064
1074
|
// the wrapper, before that same invocation's real loadAsciiDoc call.
|
|
1065
1075
|
(0, assembly_numbering_1.rewritePartialForAssembly)(scanCtx, numbers);
|
|
1066
1076
|
}
|
|
1077
|
+
// Per participating component-version, the pages whose raw source
|
|
1078
|
+
// carries a cite:[ marker at all. Memoized on first use: the set is
|
|
1079
|
+
// fixed by contentClassified time, and rewriteForeignCitedPages below
|
|
1080
|
+
// runs once per assembled page load, site-wide.
|
|
1081
|
+
const citedPagesByComp = new Map();
|
|
1082
|
+
function rawSourceHolder(f) {
|
|
1083
|
+
const src = f.src;
|
|
1084
|
+
return src.contents !== undefined ? src : f;
|
|
1085
|
+
}
|
|
1086
|
+
// ---------------------------------------------------------------------
|
|
1087
|
+
// Cross-component includes in assembled output. The wrapper above
|
|
1088
|
+
// rewrites only the buffer @antora/assembler hands to loadAsciiDoc, the
|
|
1089
|
+
// page's own source. A page whose body is `include::other:ROOT:page$x.adoc[]`
|
|
1090
|
+
// carries no citation of its own, and Antora's include processor then
|
|
1091
|
+
// reads the included page (and, through it, the included bibliography
|
|
1092
|
+
// partial) straight from the catalog, never back through loadAsciiDoc.
|
|
1093
|
+
// Confirmed live: a component's own PDF rendered `[1]` correctly while a
|
|
1094
|
+
// sibling component wrapping the same page in an include:: shipped the
|
|
1095
|
+
// literal `cite:[key]` text, both inline and as the bibliography's own
|
|
1096
|
+
// row label, since Ruby asciidoctor-pdf has no citeit macro.
|
|
1097
|
+
//
|
|
1098
|
+
// For the duration of one real loadAsciiDoc call, every cited page of
|
|
1099
|
+
// every OTHER participating component-version is rewritten in the
|
|
1100
|
+
// catalog with its OWN component's numbers (the same numbering the
|
|
1101
|
+
// included partial, already rewritten by rewritePartialForAssembly, now
|
|
1102
|
+
// carries), then restored in the wrapper's finally block. Computing
|
|
1103
|
+
// every other component's numbers here, rather than only the loaded
|
|
1104
|
+
// page's own, also removes an ordering dependency: a wrapper component
|
|
1105
|
+
// assembled BEFORE the component it includes used to see that partial
|
|
1106
|
+
// still unrewritten, because rewritePartialForAssembly had not yet run
|
|
1107
|
+
// for it.
|
|
1108
|
+
//
|
|
1109
|
+
// A link target exists only when the included page itself hosts the
|
|
1110
|
+
// key's bibliography anchor: the anchor then lands inside the loaded
|
|
1111
|
+
// page's own fragment of the assembly, so the xref names the loaded
|
|
1112
|
+
// page, not the source page (an unqualified `xref:<page>.adoc` resolves
|
|
1113
|
+
// against the including document's component, where the source page's
|
|
1114
|
+
// name need not exist). Any other key is rewritten to a plain, unlinked
|
|
1115
|
+
// number, the same known-correct-but-unlinked fallback rewriteCiteMarkers
|
|
1116
|
+
// already applies to a key with no scope.
|
|
1117
|
+
// ---------------------------------------------------------------------
|
|
1118
|
+
function rewriteForeignCitedPages(loadedSrc, profileName) {
|
|
1119
|
+
const loadedKey = `${loadedSrc.component}@${loadedSrc.version}`;
|
|
1120
|
+
const loadedDocname = (loadedSrc.relative ?? '').replace(/\.[^./]+$/, '');
|
|
1121
|
+
const restores = [];
|
|
1122
|
+
for (const [compKey, scanCtx] of assemblyScanContexts) {
|
|
1123
|
+
if (compKey === loadedKey)
|
|
1124
|
+
continue;
|
|
1125
|
+
ensureAssemblyDataComputed(compKey, profileName);
|
|
1126
|
+
const numbers = citationNumbers.get(compKey);
|
|
1127
|
+
if (!numbers || numbers.size === 0)
|
|
1128
|
+
continue;
|
|
1129
|
+
const hostScopes = keyScopesByComp.get(compKey) ?? new Map();
|
|
1130
|
+
let pages = citedPagesByComp.get(compKey);
|
|
1131
|
+
if (!pages) {
|
|
1132
|
+
pages = scanCtx.contentCatalog.getFiles().filter((f) => f.src.component === scanCtx.component &&
|
|
1133
|
+
f.src.version === scanCtx.version &&
|
|
1134
|
+
f.src.family === 'page' &&
|
|
1135
|
+
Buffer.from(rawSourceHolder(f).contents).toString('utf8').includes('cite:['));
|
|
1136
|
+
citedPagesByComp.set(compKey, pages);
|
|
1137
|
+
}
|
|
1138
|
+
for (const page of pages) {
|
|
1139
|
+
const pageDocname = (page.src.relative ?? '').replace(/\.[^./]+$/, '');
|
|
1140
|
+
const scopes = new Map();
|
|
1141
|
+
for (const [key, host] of hostScopes) {
|
|
1142
|
+
if (host === pageDocname)
|
|
1143
|
+
scopes.set(key, loadedDocname);
|
|
1144
|
+
}
|
|
1145
|
+
const holder = rawSourceHolder(page);
|
|
1146
|
+
const original = holder.contents;
|
|
1147
|
+
const before = Buffer.from(original).toString('utf8');
|
|
1148
|
+
const after = (0, assembly_numbering_1.rewriteCiteMarkers)(before, numbers, true, scopes);
|
|
1149
|
+
if (after === before)
|
|
1150
|
+
continue;
|
|
1151
|
+
holder.contents = Buffer.from(after, 'utf8');
|
|
1152
|
+
restores.push(() => { holder.contents = original; });
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
if (restores.length === 0)
|
|
1156
|
+
return undefined;
|
|
1157
|
+
return () => { for (const restore of restores)
|
|
1158
|
+
restore(); };
|
|
1159
|
+
}
|
|
1067
1160
|
}
|
|
1068
1161
|
/**
|
|
1069
1162
|
* One category's own generated partial content: the bibliography list
|
|
@@ -1086,11 +1179,11 @@ function generateCategoryPartial(keys, formattedByKey) {
|
|
|
1086
1179
|
const lines = ['[horizontal.cite-it-bibliography]'];
|
|
1087
1180
|
for (const key of keys) {
|
|
1088
1181
|
const text = formattedByKey.get(key) ?? `(no formatted text for "${key}")`;
|
|
1089
|
-
// The [[cite-<key>]] anchor is what an inline
|
|
1182
|
+
// The [[cite-<key>]] anchor is what an inline cite:[key] citation
|
|
1090
1183
|
// links to for assembled/PDF output (rewriteCiteMarkers, asLink:
|
|
1091
1184
|
// true), see assembly-numbering.ts. Harmless, invisible in ordinary
|
|
1092
1185
|
// HTML rendering.
|
|
1093
|
-
lines.push(`[[cite-${key}]]
|
|
1186
|
+
lines.push(`[[cite-${key}]]cite:[${key}]:: ${text}`);
|
|
1094
1187
|
}
|
|
1095
1188
|
lines.push('');
|
|
1096
1189
|
return lines.join('\n');
|