postext 1.11.3 → 1.12.1

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.
Files changed (162) hide show
  1. package/dist/__tests__/exports.test.js +24 -0
  2. package/dist/__tests__/exports.test.js.map +1 -1
  3. package/dist/__tests__/parse/anchors.test.d.ts +2 -0
  4. package/dist/__tests__/parse/anchors.test.d.ts.map +1 -0
  5. package/dist/__tests__/parse/anchors.test.js +71 -0
  6. package/dist/__tests__/parse/anchors.test.js.map +1 -0
  7. package/dist/__tests__/parse/citations.test.d.ts +2 -0
  8. package/dist/__tests__/parse/citations.test.d.ts.map +1 -0
  9. package/dist/__tests__/parse/citations.test.js +106 -0
  10. package/dist/__tests__/parse/citations.test.js.map +1 -0
  11. package/dist/__tests__/parse/containers.test.js +1 -1
  12. package/dist/__tests__/parse/containers.test.js.map +1 -1
  13. package/dist/__tests__/pipeline/citationNotes.test.d.ts +2 -0
  14. package/dist/__tests__/pipeline/citationNotes.test.d.ts.map +1 -0
  15. package/dist/__tests__/pipeline/citationNotes.test.js +46 -0
  16. package/dist/__tests__/pipeline/citationNotes.test.js.map +1 -0
  17. package/dist/__tests__/pipeline/crossRefs.test.d.ts +2 -0
  18. package/dist/__tests__/pipeline/crossRefs.test.d.ts.map +1 -0
  19. package/dist/__tests__/pipeline/crossRefs.test.js +170 -0
  20. package/dist/__tests__/pipeline/crossRefs.test.js.map +1 -0
  21. package/dist/__tests__/pipeline/footnoteNumberGap.test.d.ts +2 -0
  22. package/dist/__tests__/pipeline/footnoteNumberGap.test.d.ts.map +1 -0
  23. package/dist/__tests__/pipeline/footnoteNumberGap.test.js +75 -0
  24. package/dist/__tests__/pipeline/footnoteNumberGap.test.js.map +1 -0
  25. package/dist/bundle/book.d.ts.map +1 -1
  26. package/dist/bundle/book.js +22 -4
  27. package/dist/bundle/book.js.map +1 -1
  28. package/dist/citations/bibtex.d.ts +19 -0
  29. package/dist/citations/bibtex.d.ts.map +1 -0
  30. package/dist/citations/bibtex.js +376 -0
  31. package/dist/citations/bibtex.js.map +1 -0
  32. package/dist/citations/context.d.ts +64 -0
  33. package/dist/citations/context.d.ts.map +1 -0
  34. package/dist/citations/context.js +115 -0
  35. package/dist/citations/context.js.map +1 -0
  36. package/dist/citations/data.d.ts +35 -0
  37. package/dist/citations/data.d.ts.map +1 -0
  38. package/dist/citations/data.js +158 -0
  39. package/dist/citations/data.js.map +1 -0
  40. package/dist/citations/html.d.ts +16 -0
  41. package/dist/citations/html.d.ts.map +1 -0
  42. package/dist/citations/html.js +99 -0
  43. package/dist/citations/html.js.map +1 -0
  44. package/dist/citations/registry.d.ts +30 -0
  45. package/dist/citations/registry.d.ts.map +1 -0
  46. package/dist/citations/registry.js +51 -0
  47. package/dist/citations/registry.js.map +1 -0
  48. package/dist/citations/types.d.ts +138 -0
  49. package/dist/citations/types.d.ts.map +1 -0
  50. package/dist/citations/types.js +9 -0
  51. package/dist/citations/types.js.map +1 -0
  52. package/dist/defaults/citations.d.ts +5 -0
  53. package/dist/defaults/citations.d.ts.map +1 -0
  54. package/dist/defaults/citations.js +99 -0
  55. package/dist/defaults/citations.js.map +1 -0
  56. package/dist/defaults/crossRefs.d.ts +7 -0
  57. package/dist/defaults/crossRefs.d.ts.map +1 -0
  58. package/dist/defaults/crossRefs.js +35 -0
  59. package/dist/defaults/crossRefs.js.map +1 -0
  60. package/dist/defaults/index.d.ts +2 -0
  61. package/dist/defaults/index.d.ts.map +1 -1
  62. package/dist/defaults/index.js +18 -0
  63. package/dist/defaults/index.js.map +1 -1
  64. package/dist/html-backend.d.ts.map +1 -1
  65. package/dist/html-backend.js +79 -19
  66. package/dist/html-backend.js.map +1 -1
  67. package/dist/index.d.ts +10 -4
  68. package/dist/index.d.ts.map +1 -1
  69. package/dist/index.js +9 -2
  70. package/dist/index.js.map +1 -1
  71. package/dist/knuthPlass/richAdapter.d.ts +2 -0
  72. package/dist/knuthPlass/richAdapter.d.ts.map +1 -1
  73. package/dist/knuthPlass/richAdapter.js +1 -1
  74. package/dist/knuthPlass/richAdapter.js.map +1 -1
  75. package/dist/measure/cache.js +1 -1
  76. package/dist/measure/cache.js.map +1 -1
  77. package/dist/measure/rich.d.ts +4 -0
  78. package/dist/measure/rich.d.ts.map +1 -1
  79. package/dist/measure/rich.js +9 -2
  80. package/dist/measure/rich.js.map +1 -1
  81. package/dist/parse/attrs.d.ts.map +1 -1
  82. package/dist/parse/attrs.js +31 -4
  83. package/dist/parse/attrs.js.map +1 -1
  84. package/dist/parse/blockParser.d.ts.map +1 -1
  85. package/dist/parse/blockParser.js +68 -8
  86. package/dist/parse/blockParser.js.map +1 -1
  87. package/dist/parse/citations.d.ts +41 -0
  88. package/dist/parse/citations.d.ts.map +1 -0
  89. package/dist/parse/citations.js +214 -0
  90. package/dist/parse/citations.js.map +1 -0
  91. package/dist/parse/index.d.ts +1 -1
  92. package/dist/parse/index.d.ts.map +1 -1
  93. package/dist/parse/index.js.map +1 -1
  94. package/dist/parse/indexMarks.d.ts +2 -7
  95. package/dist/parse/indexMarks.d.ts.map +1 -1
  96. package/dist/parse/indexMarks.js +65 -20
  97. package/dist/parse/indexMarks.js.map +1 -1
  98. package/dist/parse/inlineFormatting.d.ts +2 -2
  99. package/dist/parse/inlineFormatting.d.ts.map +1 -1
  100. package/dist/parse/inlineFormatting.js +41 -14
  101. package/dist/parse/inlineFormatting.js.map +1 -1
  102. package/dist/parse/types.d.ts +54 -4
  103. package/dist/parse/types.d.ts.map +1 -1
  104. package/dist/pipeline/anchors.d.ts +28 -0
  105. package/dist/pipeline/anchors.d.ts.map +1 -0
  106. package/dist/pipeline/anchors.js +123 -0
  107. package/dist/pipeline/anchors.js.map +1 -0
  108. package/dist/pipeline/build.d.ts.map +1 -1
  109. package/dist/pipeline/build.js +51 -11
  110. package/dist/pipeline/build.js.map +1 -1
  111. package/dist/pipeline/citations.d.ts +80 -0
  112. package/dist/pipeline/citations.d.ts.map +1 -0
  113. package/dist/pipeline/citations.js +437 -0
  114. package/dist/pipeline/citations.js.map +1 -0
  115. package/dist/pipeline/config.d.ts.map +1 -1
  116. package/dist/pipeline/config.js +3 -1
  117. package/dist/pipeline/config.js.map +1 -1
  118. package/dist/pipeline/contentWarnings.d.ts +7 -1
  119. package/dist/pipeline/contentWarnings.d.ts.map +1 -1
  120. package/dist/pipeline/contentWarnings.js +57 -3
  121. package/dist/pipeline/contentWarnings.js.map +1 -1
  122. package/dist/pipeline/continuation.d.ts +2 -1
  123. package/dist/pipeline/continuation.d.ts.map +1 -1
  124. package/dist/pipeline/continuation.js +3 -0
  125. package/dist/pipeline/continuation.js.map +1 -1
  126. package/dist/pipeline/crossRefs.d.ts +79 -0
  127. package/dist/pipeline/crossRefs.d.ts.map +1 -0
  128. package/dist/pipeline/crossRefs.js +207 -0
  129. package/dist/pipeline/crossRefs.js.map +1 -0
  130. package/dist/pipeline/floatPlacement.d.ts.map +1 -1
  131. package/dist/pipeline/floatPlacement.js +2 -1
  132. package/dist/pipeline/floatPlacement.js.map +1 -1
  133. package/dist/pipeline/footnotes.d.ts.map +1 -1
  134. package/dist/pipeline/footnotes.js +5 -3
  135. package/dist/pipeline/footnotes.js.map +1 -1
  136. package/dist/pipeline/index.d.ts +2 -1
  137. package/dist/pipeline/index.d.ts.map +1 -1
  138. package/dist/pipeline/index.js +2 -1
  139. package/dist/pipeline/index.js.map +1 -1
  140. package/dist/pipeline/measureContentBlock.d.ts +4 -0
  141. package/dist/pipeline/measureContentBlock.d.ts.map +1 -1
  142. package/dist/pipeline/measureContentBlock.js +2 -1
  143. package/dist/pipeline/measureContentBlock.js.map +1 -1
  144. package/dist/pipeline/outline.d.ts +3 -0
  145. package/dist/pipeline/outline.d.ts.map +1 -1
  146. package/dist/pipeline/outline.js +38 -1
  147. package/dist/pipeline/outline.js.map +1 -1
  148. package/dist/pipeline/resourceLayout.d.ts +13 -1
  149. package/dist/pipeline/resourceLayout.d.ts.map +1 -1
  150. package/dist/pipeline/resourceLayout.js +22 -2
  151. package/dist/pipeline/resourceLayout.js.map +1 -1
  152. package/dist/pipeline/resourceNumbering.d.ts.map +1 -1
  153. package/dist/pipeline/resourceNumbering.js +2 -1
  154. package/dist/pipeline/resourceNumbering.js.map +1 -1
  155. package/dist/types.d.ts +133 -2
  156. package/dist/types.d.ts.map +1 -1
  157. package/dist/vdt.d.ts +59 -1
  158. package/dist/vdt.d.ts.map +1 -1
  159. package/dist/vdt.js.map +1 -1
  160. package/dist/worker/layout.worker.js +6 -0
  161. package/dist/worker/layout.worker.js.map +1 -1
  162. package/package.json +1 -1
@@ -13,7 +13,11 @@ import { getMeasureRegion, getMeasureUprightDigits, getMeasureWritingMode, setMe
13
13
  import { stampCentralBaselines } from './verticalMetrics';
14
14
  import { resolveAllConfig, computeBaselineGrid, resolvedLocale } from './config';
15
15
  import { createHeadingLevelResolver, deriveSectionGeometryConfig, sectionWritingMode, deriveSectionMeasureContext, headingIsHidden, headingIsNumbered, headingMarksFor, headingStyleOf, planHeadingSections, } from './headingStyles';
16
- import { computeOutline, hasIndexDirective, hasTocDirective, headingNumberingOptions, headingTemplatesOf, outlineFromDoc, sameOutline } from './outline';
16
+ import { locateAnchors } from './anchors';
17
+ import { applyCitations, citationLocale, processCitations, withBibliographyStyle } from './citations';
18
+ import { bookCitationContexts, needsCitationContext } from '../citations/context';
19
+ import { anchorTargetsOf, hasAnchorRefs, printsAnchorPages } from './crossRefs';
20
+ import { anchorOutline, computeOutline, hasIndexDirective, hasTocDirective, headingNumberingOptions, headingTemplatesOf, outlineFromDoc, sameOutline } from './outline';
17
21
  import { expandTocDirectives } from './toc';
18
22
  import { expandIndexDirectives, locateIndexMarks } from './indexDirective';
19
23
  import { resolveBodyStyle, resolveBlockquoteStyle, resolveParagraphStyle } from './styles';
@@ -271,7 +275,16 @@ function placeDocumentPass(content, config, cache, options, hints) {
271
275
  // Footnote definitions (`[^id]: …`) leave the flow; the markers are
272
276
  // numbered in citation order. With `placement: 'chapterEnd'` the notes
273
277
  // come back as paragraphs after each chapter's last block.
274
- const footnoteSplit = splitFootnoteDefinitions(headingMarksFor(parseMarkdownMemo(markdownBody), resolved));
278
+ // Citations (#268): formatted against the book's references (or set as
279
+ // notes under a note style) before the notes leave the flow; the
280
+ // bibliography takes `:::bibliography`'s place or follows the text.
281
+ const parsedBody = headingMarksFor(parseMarkdownMemo(markdownBody), resolved);
282
+ const citationContext = content.citations
283
+ ?? (needsCitationContext(parsedBody, frontmatterMeta) ? bookCitationContexts([{ metadata: frontmatterMeta, blocks: parsedBody }])[0] : undefined);
284
+ const citationsApplied = citationContext
285
+ ? applyCitations(parsedBody, citationContext, processCitations(citationContext, resolved, citationLocale(resolved, resolvedLocale(resolved))), resolved, resolvedLocale(resolved))
286
+ : undefined;
287
+ const footnoteSplit = splitFootnoteDefinitions(citationsApplied?.blocks ?? parsedBody);
275
288
  const footnoteDefs = footnoteSplit.defs;
276
289
  // Numbered by page or column (`numbering: 'page'`), a note takes the
277
290
  // number the previous build gave it where it landed; the first build
@@ -293,8 +306,15 @@ function placeDocumentPass(content, config, cache, options, hints) {
293
306
  // first pass; `buildDocument` lays the document out again with them).
294
307
  // `:::index` expands into the entries of the book's index marks, from
295
308
  // the same outline.
309
+ // A reference naming an anchor (#262) reads its number, title and page
310
+ // from the same outline.
311
+ const resourceIds = new Set((content.resources ?? []).map((r) => r.id));
312
+ const anchorRefs = hasAnchorRefs(parsedBlocks, resourceIds);
296
313
  const outline = content.outline
297
- ?? (hasTocDirective(parsedBlocks) || hasIndexDirective(parsedBlocks) ? computeOutline(parsedBlocks, resolved, headingStart) : undefined);
314
+ ?? (hasTocDirective(parsedBlocks) || hasIndexDirective(parsedBlocks) || anchorRefs ? computeOutline(parsedBlocks, resolved, headingStart) : undefined);
315
+ const anchorRefContext = anchorRefs
316
+ ? { targets: anchorTargetsOf(outline), strings: resolved.crossRefs }
317
+ : undefined;
298
318
  const indexExpanded = expandIndexDirectives(expandTocDirectives(parsedBlocks, outline, resolved), outline, resolved);
299
319
  const contentBlocks = indexExpanded.blocks;
300
320
  if (indexExpanded.warnings.length > 0)
@@ -332,7 +352,10 @@ function placeDocumentPass(content, config, cache, options, hints) {
332
352
  const orderedMetrics = computeOrderedListRunMetrics(contentBlocks, resolved, bodyStyle.fontSizePx);
333
353
  const orderedLevelIndentsPx = computeOrderedLevelIndentsPx(resolved, bodyStyle.fontSizePx, orderedMetrics.maxWidthByDepth);
334
354
  // `:::paragraphs{style="…"}` containers, resolved per content-block index.
335
- const paragraphContainers = planParagraphContainers(contentBlocks, chapterEndNotes ? withFootnoteStyle(resolved) : resolved);
355
+ let containerStyles = chapterEndNotes ? withFootnoteStyle(resolved) : resolved;
356
+ if (citationsApplied?.bibliography)
357
+ containerStyles = withBibliographyStyle(containerStyles, citationsApplied.labelChars);
358
+ const paragraphContainers = planParagraphContainers(contentBlocks, containerStyles);
336
359
  // `:::callout` ranges keyed by their start marker index (same rationale).
337
360
  const calloutPlan = planCallouts(contentBlocks);
338
361
  // `:::part` ranges: start/end marker indices and the enclosed blocks.
@@ -1573,6 +1596,7 @@ function placeDocumentPass(content, config, cache, options, hints) {
1573
1596
  floatedIds,
1574
1597
  leftFlow: calloutsOutOfFlow,
1575
1598
  ...(footnoteNumbering.numbers.size > 0 ? { footnoteNumbers: footnoteNumbering.numbers } : {}),
1599
+ ...(anchorRefContext ? { anchorRefs: anchorRefContext } : {}),
1576
1600
  };
1577
1601
  // --- Footnotes at the column foot (`footnotes.placement: 'column'`) ------
1578
1602
  // A text block placed in a column reserves, at the column's foot, the
@@ -1916,6 +1940,8 @@ function placeDocumentPass(content, config, cache, options, hints) {
1916
1940
  }
1917
1941
  if (raw.footnoteNote !== undefined)
1918
1942
  blk.footnoteNote = raw.footnoteNote;
1943
+ if (raw.bibEntry !== undefined)
1944
+ blk.bibEntry = raw.bibEntry;
1919
1945
  if (raw.toc?.kind === 'entry') {
1920
1946
  blk.tocEntry = raw.toc.pageIndex !== undefined ? { pageIndex: raw.toc.pageIndex } : {};
1921
1947
  }
@@ -5295,7 +5321,9 @@ export function* buildDocumentGen(content, config, cache, options) {
5295
5321
  // References and markup the source names wrongly: read from the source
5296
5322
  // once, located on the pages of the finished layout. Kept apart from
5297
5323
  // `doc.warnings`, whose entries keep their postext 1.4 shape.
5298
- const found = [...collectContentWarnings(content.markdown, config, content.resources ?? []), ...(indexWarnings.get(doc) ?? [])];
5324
+ const bookAnchors = content.outline ? new Set(anchorOutline(content.outline).map((e) => e.anchorId)) : undefined;
5325
+ const bookCitationKeys = content.citations ? new Set(content.citations.items.map((i) => i.id)) : undefined;
5326
+ const found = [...collectContentWarnings(content.markdown, config, content.resources ?? [], bookAnchors, bookCitationKeys), ...(indexWarnings.get(doc) ?? [])];
5299
5327
  const located = found.length > 0 ? locateContentWarnings(doc, found) : [];
5300
5328
  // Justified CJK lines the composer could not fill within its tracking cap.
5301
5329
  const loose = cjkLooseLineWarnings(doc);
@@ -5317,12 +5345,17 @@ export function* buildDocumentGen(content, config, cache, options) {
5317
5345
  const indexWarnings = new WeakMap();
5318
5346
  /** `doc` with the page of each of its index marks (`doc.indexMarks`). */
5319
5347
  function withIndexMarks(doc, content) {
5320
- if (!content.markdown.includes(':index'))
5321
- return doc;
5322
5348
  const { content: body, contentOffset } = extractFrontmatter(content.markdown);
5323
- const marks = locateIndexMarks(doc, parseMarkdownMemo(body), contentOffset);
5324
- if (marks)
5325
- doc.indexMarks = marks;
5349
+ const blocks = parseMarkdownMemo(body);
5350
+ if (content.markdown.includes(':index')) {
5351
+ const marks = locateIndexMarks(doc, blocks, contentOffset);
5352
+ if (marks)
5353
+ doc.indexMarks = marks;
5354
+ }
5355
+ // Where every anchor landed (#261), for links and page references.
5356
+ const anchors = locateAnchors(doc, blocks, contentOffset);
5357
+ if (anchors)
5358
+ doc.anchors = anchors;
5326
5359
  return doc;
5327
5360
  }
5328
5361
  /** {@link buildDocumentGen} before the document-wide warnings: the
@@ -5335,7 +5368,14 @@ function* buildDocumentRounds(content, config, cache, options) {
5335
5368
  // it in one extra round.
5336
5369
  if (content.outline === undefined) {
5337
5370
  const parsed = parseMarkdownMemo(extractFrontmatter(content.markdown).content);
5338
- if (hasTocDirective(parsed) || hasIndexDirective(parsed)) {
5371
+ // A reference printing an anchor's page (#263) settles the same way.
5372
+ const pageRefs = () => {
5373
+ if (!hasAnchorRefs(parsed, new Set((content.resources ?? []).map((r) => r.id))))
5374
+ return false;
5375
+ const resolved = resolveAllConfig(config);
5376
+ return printsAnchorPages(parsed, anchorTargetsOf(computeOutline(parsed, resolved, content.continuation?.headings)), resolved.crossRefs.defaultStyle);
5377
+ };
5378
+ if (hasTocDirective(parsed) || hasIndexDirective(parsed) || pageRefs()) {
5339
5379
  let outline = computeOutline(parsed, resolveAllConfig(config), content.continuation?.headings);
5340
5380
  let doc = withIndexMarks(yield* buildDocumentNumbered({ ...content, outline }, config, cache, options, 0), content);
5341
5381
  for (let round = 0; round < MAX_TOC_ROUNDS; round++) {