reamkit 1.29.0 → 1.31.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.
Files changed (106) hide show
  1. package/README.md +60 -24
  2. package/dist/esm/core/converter/project.js +3 -1
  3. package/dist/esm/core/crypto/offcrypto.js +1 -1
  4. package/dist/esm/core/document-model/index.d.ts +1 -1
  5. package/dist/esm/core/document-model/types.d.ts +65 -0
  6. package/dist/esm/core/drawingml/shape-render.js +13 -1
  7. package/dist/esm/core/font/index.d.ts +2 -0
  8. package/dist/esm/core/font/ttf-build.d.ts +113 -0
  9. package/dist/esm/core/font/ttf-build.js +1224 -0
  10. package/dist/esm/core/font/ttf-subset.d.ts +19 -0
  11. package/dist/esm/core/font/ttf-subset.js +14 -1
  12. package/dist/esm/core/fonts/index.d.ts +1 -1
  13. package/dist/esm/core/fonts/provider.d.ts +17 -0
  14. package/dist/esm/core/fonts/provider.js +27 -2
  15. package/dist/esm/core/fonts/remote-fonts.d.ts +8 -0
  16. package/dist/esm/core/fonts/remote-fonts.js +108 -18
  17. package/dist/esm/core/ir/flow.d.ts +88 -1
  18. package/dist/esm/core/numbering/index.d.ts +1 -1
  19. package/dist/esm/core/numbering/state.d.ts +11 -1
  20. package/dist/esm/core/numbering/state.js +10 -1
  21. package/dist/esm/core/style-cascade/resolver.js +35 -4
  22. package/dist/esm/core/style-cascade/types.d.ts +19 -1
  23. package/dist/esm/core/style-cascade/types.js +3 -0
  24. package/dist/esm/index.d.ts +2 -2
  25. package/dist/esm/layout/page-doc.d.ts +10 -3
  26. package/dist/esm/layout/styled-layout.d.ts +48 -7
  27. package/dist/esm/layout/styled-layout.js +881 -119
  28. package/dist/esm/layout/turned-section.d.ts +38 -0
  29. package/dist/esm/layout/turned-section.js +193 -0
  30. package/dist/esm/pdf/styled-page-emitter.js +78 -2
  31. package/dist/esm/pdf-reader/annot-draw.js +93 -1
  32. package/dist/esm/pdf-reader/annots.d.ts +18 -0
  33. package/dist/esm/pdf-reader/annots.js +86 -9
  34. package/dist/esm/pdf-reader/cff-outline.d.ts +27 -0
  35. package/dist/esm/pdf-reader/cff-outline.js +169 -21
  36. package/dist/esm/pdf-reader/cmap.js +5 -2
  37. package/dist/esm/pdf-reader/content.d.ts +70 -4
  38. package/dist/esm/pdf-reader/content.js +172 -12
  39. package/dist/esm/pdf-reader/display.d.ts +36 -0
  40. package/dist/esm/pdf-reader/display.js +82 -1
  41. package/dist/esm/pdf-reader/document.js +5 -1
  42. package/dist/esm/pdf-reader/embedded-fonts.d.ts +25 -0
  43. package/dist/esm/pdf-reader/embedded-fonts.js +78 -9
  44. package/dist/esm/pdf-reader/encodings.d.ts +8 -0
  45. package/dist/esm/pdf-reader/encodings.js +25 -3
  46. package/dist/esm/pdf-reader/face-outlines.d.ts +78 -0
  47. package/dist/esm/pdf-reader/face-outlines.js +362 -0
  48. package/dist/esm/pdf-reader/figures.d.ts +52 -0
  49. package/dist/esm/pdf-reader/figures.js +433 -0
  50. package/dist/esm/pdf-reader/flow-build.d.ts +224 -7
  51. package/dist/esm/pdf-reader/flow-build.js +545 -39
  52. package/dist/esm/pdf-reader/font.d.ts +27 -1
  53. package/dist/esm/pdf-reader/font.js +632 -63
  54. package/dist/esm/pdf-reader/glyf-outline.d.ts +33 -0
  55. package/dist/esm/pdf-reader/glyf-outline.js +148 -3
  56. package/dist/esm/pdf-reader/glyph-names.js +154 -1
  57. package/dist/esm/pdf-reader/glyph-shapes.d.ts +18 -0
  58. package/dist/esm/pdf-reader/glyph-shapes.js +57 -0
  59. package/dist/esm/pdf-reader/image-decode.js +70 -4
  60. package/dist/esm/pdf-reader/images.d.ts +5 -0
  61. package/dist/esm/pdf-reader/images.js +4 -2
  62. package/dist/esm/pdf-reader/jbig2.d.ts +40 -1
  63. package/dist/esm/pdf-reader/jbig2.js +78 -16
  64. package/dist/esm/pdf-reader/jpeg.d.ts +6 -3
  65. package/dist/esm/pdf-reader/jpeg.js +21 -1
  66. package/dist/esm/pdf-reader/layout.d.ts +119 -2
  67. package/dist/esm/pdf-reader/layout.js +2219 -184
  68. package/dist/esm/pdf-reader/lexer.d.ts +10 -0
  69. package/dist/esm/pdf-reader/lexer.js +17 -0
  70. package/dist/esm/pdf-reader/page-numbers.d.ts +53 -0
  71. package/dist/esm/pdf-reader/page-numbers.js +167 -0
  72. package/dist/esm/pdf-reader/pattern-tint.d.ts +11 -1
  73. package/dist/esm/pdf-reader/pattern-tint.js +21 -3
  74. package/dist/esm/pdf-reader/regions.d.ts +25 -0
  75. package/dist/esm/pdf-reader/regions.js +167 -0
  76. package/dist/esm/pdf-reader/shading.d.ts +58 -2
  77. package/dist/esm/pdf-reader/shading.js +181 -11
  78. package/dist/esm/pdf-reader/struct-tree.js +112 -8
  79. package/dist/esm/pdf-reader/tagged.js +207 -28
  80. package/dist/esm/pdf-reader/text-rules.js +1 -1
  81. package/dist/esm/pdf-reader/text.d.ts +6 -3
  82. package/dist/esm/pdf-reader/text.js +106 -22
  83. package/dist/esm/pdf-reader/type1-outline.d.ts +11 -0
  84. package/dist/esm/pdf-reader/type1-outline.js +63 -8
  85. package/dist/esm/pdf-reader/vector.d.ts +8 -2
  86. package/dist/esm/pdf-reader/vector.js +105 -6
  87. package/dist/esm/word/doc/doc-reader.js +6 -2
  88. package/dist/esm/word/doc/doc-text.d.ts +6 -0
  89. package/dist/esm/word/doc/doc-text.js +19 -1
  90. package/dist/esm/word/document-parser.d.ts +2 -2
  91. package/dist/esm/word/document-parser.js +11 -1
  92. package/dist/esm/word/docx-reader.js +5 -3
  93. package/dist/esm/word/docx-writer.js +341 -54
  94. package/dist/esm/word/drawing-parser.d.ts +5 -3
  95. package/dist/esm/word/drawing-parser.js +56 -10
  96. package/dist/esm/word/font-embed.d.ts +30 -0
  97. package/dist/esm/word/font-embed.js +173 -0
  98. package/dist/esm/word/font-table.d.ts +10 -0
  99. package/dist/esm/word/font-table.js +13 -1
  100. package/dist/esm/word/index.js +1 -1
  101. package/dist/esm/word/numbering-parser.d.ts +3 -1
  102. package/dist/esm/word/numbering-parser.js +2 -1
  103. package/dist/esm/word/paragraph-properties.d.ts +7 -6
  104. package/dist/esm/word/paragraph-properties.js +16 -2
  105. package/dist/esm/word/run-properties.js +26 -0
  106. package/package.json +12 -5
@@ -1,4 +1,4 @@
1
- import { PDF_NULL, PdfName, PdfStream } from "../pdf/objects.js";
1
+ import { PDF_NULL, PdfHexString, PdfName, PdfStream } from "../pdf/objects.js";
2
2
  import { cieToSrgb } from "./cie-color.js";
3
3
  import { iccTransform } from "./icc.js";
4
4
  import { readFunction } from "./function.js";
@@ -26,12 +26,102 @@ function buildShadingMap(file, resources) {
26
26
  if (!(pat instanceof Map)) continue;
27
27
  const shading = dictOf(file.resolve(pat.get("Shading") ?? PDF_NULL));
28
28
  if (!shading) continue;
29
- const gradient = parseShading(file, shading);
29
+ const m = numArray(file, pat.get("Matrix"));
30
+ const gradient = parseShading(file, shading, m && m.length >= 6 ? [
31
+ m[0],
32
+ m[1],
33
+ m[2],
34
+ m[3],
35
+ m[4],
36
+ m[5]
37
+ ] : void 0);
30
38
  if (gradient) out.set(nm, gradient);
31
39
  }
32
40
  return out;
33
41
  }
34
42
  /**
43
+ * A page's gradient as a shape filled with it shows it: its stops re-mapped
44
+ * from the whole axis to the part of it the shape's box covers.
45
+ *
46
+ * A DrawingML gradient spans the shape it fills, and a PDF shading spans its
47
+ * own axis, which may reach far past the shape: issue10572.pdf's pattern
48
+ * runs twenty-four stripes down 1800 points, of which its 450-point square
49
+ * shows six — spread over the square, all twenty-four came back as hairlines.
50
+ * Beyond either end of the axis the end colour carries on, as `/Extend` asks.
51
+ *
52
+ * @param g The gradient, with its axis where the page states one.
53
+ * @param box The shape's box, in the same space as the axis.
54
+ * @returns The gradient as the shape shows it, with no axis.
55
+ */
56
+ function gradientOverBox(g, box) {
57
+ const { axis, ...plain } = g;
58
+ if (!axis || g.kind !== "linear" || g.stops.length === 0) return plain;
59
+ const dx = axis.x1 - axis.x0;
60
+ const dy = axis.y1 - axis.y0;
61
+ const len2 = dx * dx + dy * dy;
62
+ if (!(len2 > 0)) return plain;
63
+ const along = (x, y) => ((x - axis.x0) * dx + (y - axis.y0) * dy) / len2;
64
+ const ts = [
65
+ along(box.minX, box.minY),
66
+ along(box.minX, box.maxY),
67
+ along(box.maxX, box.minY),
68
+ along(box.maxX, box.maxY)
69
+ ];
70
+ const t0 = Math.min(...ts);
71
+ const t1 = Math.max(...ts);
72
+ if (!(t1 - t0 > 1e-9)) return plain;
73
+ if (Math.abs(t0) < SPAN_NOISE && Math.abs(t1 - 1) < SPAN_NOISE) return plain;
74
+ const inner = g.stops.filter((st) => st.offset > t0 && st.offset < t1);
75
+ const stops = [
76
+ {
77
+ offset: 0,
78
+ colorHex: colorAlong(g.stops, t0, "after")
79
+ },
80
+ ...inner.map((st) => ({
81
+ offset: (st.offset - t0) / (t1 - t0),
82
+ colorHex: st.colorHex
83
+ })),
84
+ {
85
+ offset: 1,
86
+ colorHex: colorAlong(g.stops, t1, "before")
87
+ }
88
+ ];
89
+ return {
90
+ ...plain,
91
+ stops
92
+ };
93
+ }
94
+ /** How near the box's span may come to the whole axis and be taken for it. */
95
+ var SPAN_NOISE = .001;
96
+ /**
97
+ * A gradient's colour at `t` along it, its end colours carried on past either
98
+ * end. Where two stops share `t` the gradient changes colour AT it, and `side`
99
+ * says which of the two is wanted: the one the span after `t` starts with, or
100
+ * the one the span before it ends with. issue10572.pdf's square starts on such
101
+ * an edge, and taken from the wrong side its first stripe faded in from blue.
102
+ */
103
+ function colorAlong(stops, t, side) {
104
+ const first = stops[0];
105
+ const last = stops[stops.length - 1];
106
+ if (t <= first.offset) return first.colorHex;
107
+ if (t >= last.offset) return last.colorHex;
108
+ const at = stops.filter((st) => Math.abs(st.offset - t) < 1e-9);
109
+ if (at.length > 0) return (side === "after" ? at[at.length - 1] : at[0]).colorHex;
110
+ for (let i = 1; i < stops.length; i++) {
111
+ const b = stops[i];
112
+ if (t > b.offset) continue;
113
+ const a = stops[i - 1];
114
+ const span = b.offset - a.offset;
115
+ const f = span > 0 ? (t - a.offset) / span : 1;
116
+ const mix = (shift) => {
117
+ const ca = parseInt(a.colorHex, 16) >> shift & 255;
118
+ return ca + ((parseInt(b.colorHex, 16) >> shift & 255) - ca) * f;
119
+ };
120
+ return hex255(mix(16), mix(8), mix(0));
121
+ }
122
+ return last.colorHex;
123
+ }
124
+ /**
35
125
  * §8.7.4.5.2 — an axial or radial shading as a gradient, for a bare `sh`.
36
126
  *
37
127
  * A `sh` paints the CLIP rather than a path, so what it needs is not a fill for
@@ -42,8 +132,8 @@ function buildShadingMap(file, resources) {
42
132
  * @param sh The shading dictionary.
43
133
  * @returns The gradient, or `undefined` for a type this does not read.
44
134
  */
45
- function gradientShading(file, sh) {
46
- return parseShading(file, sh);
135
+ function gradientShading(file, sh, ctm) {
136
+ return parseShading(file, sh, ctm);
47
137
  }
48
138
  /**
49
139
  * §8.7.4.5 — which kind of shading this is, as the file states it.
@@ -55,7 +145,7 @@ function gradientShading(file, sh) {
55
145
  function shadingTypeOf(file, sh) {
56
146
  return numOf(file.get(sh, "ShadingType"));
57
147
  }
58
- function parseShading(file, sh) {
148
+ function parseShading(file, sh, matrix) {
59
149
  const type = numOf(file.get(sh, "ShadingType"));
60
150
  if (type !== 2 && type !== 3) return void 0;
61
151
  const stops = parseFunction(file, sh.get("Function"), shadingSpace(file, sh));
@@ -65,11 +155,33 @@ function parseShading(file, sh) {
65
155
  stops
66
156
  };
67
157
  const c = numArray(file, sh.get("Coords"));
68
- return {
158
+ if (!c || c.length < 4) return {
69
159
  kind: "linear",
70
- angle: c && c.length >= 4 ? (Math.atan2(-(c[3] - c[1]), c[2] - c[0]) * 180 / Math.PI % 360 + 360) % 360 : 0,
160
+ angle: 0,
71
161
  stops
72
162
  };
163
+ const [a, b, cc, d, e, f] = matrix ?? [
164
+ 1,
165
+ 0,
166
+ 0,
167
+ 1,
168
+ 0,
169
+ 0
170
+ ];
171
+ const at = (x, y) => [a * x + cc * y + e, b * x + d * y + f];
172
+ const [x0, y0] = at(c[0], c[1]);
173
+ const [x1, y1] = at(c[2], c[3]);
174
+ return {
175
+ kind: "linear",
176
+ angle: (Math.atan2(-(y1 - y0), x1 - x0) * 180 / Math.PI % 360 + 360) % 360,
177
+ stops,
178
+ axis: {
179
+ x0,
180
+ y0,
181
+ x1,
182
+ y1
183
+ }
184
+ };
73
185
  }
74
186
  function parseFunction(file, value, space) {
75
187
  const resolved = value !== void 0 ? file.resolve(value) : void 0;
@@ -246,6 +358,17 @@ function numArray(file, v) {
246
358
  function colorOf(c, space) {
247
359
  return spaceColor(c, space) ?? spaceColor(c, void 0) ?? grayHex(c[0] ?? 0);
248
360
  }
361
+ /** §8.6.6.3 — an Indexed space's table: a string, a hex string or a stream. */
362
+ function lookupBytes(file, v) {
363
+ const r = file.resolve(v ?? PDF_NULL);
364
+ if (r instanceof PdfHexString) return r.bytes;
365
+ if (typeof r === "string") {
366
+ const out = new Uint8Array(r.length);
367
+ for (let i = 0; i < r.length; i++) out[i] = r.charCodeAt(i) & 255;
368
+ return out;
369
+ }
370
+ if (r instanceof PdfStream) return file.streamData(r);
371
+ }
249
372
  /**
250
373
  * §8.6.8 — the colour a run of `sc` / `scn` components comes to.
251
374
  *
@@ -301,6 +424,10 @@ function grayHex(v) {
301
424
  function cmykHex(c, m, y, k) {
302
425
  return rgbHex((1 - c) * (1 - k), (1 - m) * (1 - k), (1 - y) * (1 - k));
303
426
  }
427
+ function hex255(r, g, b) {
428
+ const h = (x) => Math.max(0, Math.min(255, Math.round(x))).toString(16).padStart(2, "0");
429
+ return (h(r) + h(g) + h(b)).toUpperCase();
430
+ }
304
431
  function pushStop(stops, offset, colorHex) {
305
432
  const o = Math.max(0, Math.min(1, offset));
306
433
  const last = stops[stops.length - 1];
@@ -350,7 +477,15 @@ function buildAlphaMap(file, resources) {
350
477
  const blend = mode !== void 0 && mode !== "Normal" && mode !== "Compatible" && !darkens ? mode : void 0;
351
478
  const statesMask = state.has("SMask");
352
479
  const masked = statesMask ? file.resolve(state.get("SMask") ?? PDF_NULL) instanceof Map : void 0;
353
- if (alpha === void 0 && mode === void 0 && !statesMask) continue;
480
+ const lw = file.resolve(state.get("LW") ?? PDF_NULL);
481
+ const lineWidth = typeof lw === "number" && lw >= 0 ? lw : void 0;
482
+ const d = file.resolve(state.get("D") ?? PDF_NULL);
483
+ const dash = Array.isArray(d) ? dashLengths(file.resolve(d[0] ?? PDF_NULL)) : void 0;
484
+ const lc = file.resolve(state.get("LC") ?? PDF_NULL);
485
+ const lineCap = lc === 0 || lc === 1 || lc === 2 ? lc : void 0;
486
+ const caStroke = file.resolve(state.get("CA") ?? PDF_NULL);
487
+ const strokeAlpha = typeof caStroke === "number" && caStroke >= 0 && caStroke <= 1 ? caStroke : void 0;
488
+ if (alpha === void 0 && mode === void 0 && !statesMask && !(lineWidth !== void 0 || dash !== void 0 || lineCap !== void 0 || strokeAlpha !== void 0)) continue;
354
489
  out.set(name, {
355
490
  ...alpha !== void 0 ? { alpha } : {},
356
491
  ...mode !== void 0 ? {
@@ -358,12 +493,30 @@ function buildAlphaMap(file, resources) {
358
493
  darkens
359
494
  } : {},
360
495
  ...blend !== void 0 ? { blend } : {},
361
- ...masked !== void 0 ? { masked } : {}
496
+ ...masked !== void 0 ? { masked } : {},
497
+ ...lineWidth !== void 0 ? { lineWidth } : {},
498
+ ...dash !== void 0 ? { dash } : {},
499
+ ...lineCap !== void 0 ? { lineCap } : {},
500
+ ...strokeAlpha !== void 0 ? { strokeAlpha } : {}
362
501
  });
363
502
  }
364
503
  return out;
365
504
  }
366
505
  /**
506
+ * §8.4.3.6 — a dash array as a stroke can use it: lengths that are numbers and
507
+ * not negative, and none at all where every one is zero, which draws nothing
508
+ * and is solid by the spec's own reading.
509
+ *
510
+ * @param value The array, as the file states it.
511
+ * @returns The lengths, or an empty array for a solid line.
512
+ */
513
+ function dashLengths(value) {
514
+ if (!Array.isArray(value)) return [];
515
+ const lengths = value.filter((n) => typeof n === "number" && n >= 0);
516
+ if (lengths.length !== value.length || lengths.every((n) => n === 0)) return [];
517
+ return lengths;
518
+ }
519
+ /**
367
520
  * The spaces a `/ColorSpace` resource dictionary names, by name.
368
521
  *
369
522
  * @param file The owning file.
@@ -405,7 +558,24 @@ function colorSpaceAt(file, cs, depth) {
405
558
  icc
406
559
  } : base;
407
560
  }
408
- if (head.value === "Indexed") return;
561
+ if (head.value === "Indexed" || head.value === "I") {
562
+ const base = depth < MAX_ALTERNATE ? colorSpaceAt(file, file.resolve(cs[1] ?? PDF_NULL), depth + 1) : void 0;
563
+ const hival = file.resolve(cs[2] ?? PDF_NULL);
564
+ const table = lookupBytes(file, cs[3]);
565
+ if (!base || base.kind === "tint" || typeof hival !== "number" || !table) return void 0;
566
+ const transform = ([index = 0]) => {
567
+ const at = Math.min(Math.max(0, Math.round(index)), Math.round(hival));
568
+ return Array.from({ length: base.components }, (_, k) => (table[at * base.components + k] ?? 0) / 255);
569
+ };
570
+ return {
571
+ kind: "tint",
572
+ components: 1,
573
+ tint: {
574
+ transform,
575
+ alternate: base
576
+ }
577
+ };
578
+ }
409
579
  if (head.value === "CalRGB") {
410
580
  const params = file.resolve(cs[1] ?? PDF_NULL);
411
581
  const cie = params instanceof Map ? cieParams(file, params, true) : void 0;
@@ -516,4 +686,4 @@ function byFamily(family, n) {
516
686
  }
517
687
  }
518
688
  //#endregion
519
- export { buildAlphaMap, buildColorSpaceMap, buildShadingMap, cmykHex, gradientShading, grayHex, rgbHex, sampledShading, shadingTypeOf, spaceColor };
689
+ export { buildAlphaMap, buildColorSpaceMap, buildShadingMap, cmykHex, dashLengths, gradientOverBox, gradientShading, grayHex, rgbHex, sampledShading, shadingTypeOf, spaceColor };
@@ -23,17 +23,17 @@ function readStructTree(file) {
23
23
  return pg instanceof Map ? pageMap.get(pg) : void 0;
24
24
  };
25
25
  const seen = /* @__PURE__ */ new Set();
26
+ const typeOf = roleResolver(file, stRoot);
26
27
  const read = (value, parentPage) => {
27
28
  const elem = file.resolve(value);
28
29
  if (!(elem instanceof Map) || seen.has(elem) || seen.size > MAX_NODES) return void 0;
29
30
  seen.add(elem);
30
31
  const ownPage = pageIndexOf(elem.get("Pg") ?? PDF_NULL) ?? parentPage;
31
- const mcids = [];
32
- const children = [];
32
+ const content = [];
33
33
  for (const kid of kidList(file, elem.get("K"))) {
34
34
  const rk = file.resolve(kid);
35
35
  if (typeof rk === "number") {
36
- if (ownPage >= 0) mcids.push({
36
+ if (ownPage >= 0) content.push({
37
37
  page: ownPage,
38
38
  mcid: rk
39
39
  });
@@ -42,22 +42,24 @@ function readStructTree(file) {
42
42
  if (kind === "MCR") {
43
43
  const m = rk.get("MCID");
44
44
  const page = pageIndexOf(rk.get("Pg") ?? PDF_NULL) ?? ownPage;
45
- if (typeof m === "number" && page >= 0) mcids.push({
45
+ if (typeof m === "number" && page >= 0) content.push({
46
46
  page,
47
47
  mcid: m
48
48
  });
49
49
  } else if (kind === "OBJR") {} else {
50
50
  const child = read(rk, ownPage);
51
- if (child) children.push(child);
51
+ if (!child) continue;
52
+ if (inline(file, rk, child.type)) content.push(...allMcids(child));
53
+ else content.push(child);
52
54
  }
53
55
  }
54
56
  }
57
+ const type = typeOf(nameOf(elem.get("S")));
55
58
  const alt = elem.get("Alt");
56
59
  const { colSpan, rowSpan } = readSpans(file, elem.get("A") ?? PDF_NULL);
57
60
  return {
58
- type: nameOf(elem.get("S")),
59
- mcids,
60
- children,
61
+ type,
62
+ ...settle(type, content),
61
63
  ...typeof alt === "string" ? { alt } : {},
62
64
  ...colSpan > 1 ? { colSpan } : {},
63
65
  ...rowSpan > 1 ? { rowSpan } : {}
@@ -71,6 +73,108 @@ function readStructTree(file) {
71
73
  children: roots
72
74
  };
73
75
  }
76
+ /**
77
+ * An element's own marked content and its child elements, as the node keeps
78
+ * them.
79
+ *
80
+ * An element holds text of its own AND block elements only where the tree
81
+ * mixes them — a heading carrying its number as a child, a paragraph with a
82
+ * formula set between two of its sentences. Kept as two lists, the order
83
+ * between them was gone and the element's own text was never read at all:
84
+ * bug1937438_mml_from_latex.pdf's heading came back as "1" without "A small
85
+ * example", and its sentence around a formula without its words. Each
86
+ * stretch of the element's own content becomes a paragraph of its own
87
+ * standing where it stood — except in a figure, whose marked content is its
88
+ * picture.
89
+ */
90
+ function settle(type, content) {
91
+ const nodes = content.filter((c) => "type" in c);
92
+ const own = content.filter((c) => !("type" in c));
93
+ if (nodes.length === 0 || own.length === 0 || type === "Figure") return {
94
+ mcids: own,
95
+ children: nodes
96
+ };
97
+ const children = [];
98
+ let stretch = [];
99
+ const close = () => {
100
+ if (stretch.length > 0) children.push({
101
+ type: "P",
102
+ mcids: stretch,
103
+ children: []
104
+ });
105
+ stretch = [];
106
+ };
107
+ for (const c of content) if ("type" in c) {
108
+ close();
109
+ children.push(c);
110
+ } else stretch.push(c);
111
+ close();
112
+ return {
113
+ mcids: [],
114
+ children
115
+ };
116
+ }
117
+ /** Every marked content reference under a node, in reading order. */
118
+ function allMcids(node) {
119
+ return [...node.mcids, ...node.children.flatMap(allMcids)];
120
+ }
121
+ /**
122
+ * §14.8.4.4 — the inline-level structure types (PDF 2.0 adds `Em`, `Strong`,
123
+ * `Sub`), a formula (§14.8.4.5.5, which is set in a line as often as out of
124
+ * one), and a list label, which is the start of its item's line.
125
+ */
126
+ var INLINE = new Set([
127
+ "Span",
128
+ "Quote",
129
+ "Reference",
130
+ "BibEntry",
131
+ "Code",
132
+ "Link",
133
+ "Annot",
134
+ "Ruby",
135
+ "RB",
136
+ "RT",
137
+ "RP",
138
+ "Warichu",
139
+ "WT",
140
+ "WP",
141
+ "Em",
142
+ "Strong",
143
+ "Sub",
144
+ "Formula",
145
+ "Lbl"
146
+ ]);
147
+ /** The MathML namespace (ISO 32000-2 §14.8.6): an element in it is mathematics. */
148
+ var MATHML = "http://www.w3.org/1998/Math/MathML";
149
+ /** Whether an element is inline — by its standard type, or as MathML. */
150
+ function inline(file, elem, type) {
151
+ if (INLINE.has(type)) return true;
152
+ const ns = file.resolve(elem.get("NS") ?? PDF_NULL);
153
+ const uri = ns instanceof Map ? file.resolve(ns.get("NS") ?? PDF_NULL) : void 0;
154
+ return typeof uri === "string" && uri === MATHML;
155
+ }
156
+ /**
157
+ * §14.8.4.2 `/RoleMap` — a document's own structure types, mapped to the
158
+ * standard ones they stand for, followed until a type maps no further. A
159
+ * LaTeX document names its elements `section`, `text-unit` and
160
+ * `section-number`, and maps them to `H1`, `Part` and `Span`: read by their
161
+ * own names, none of them meant anything.
162
+ */
163
+ function roleResolver(file, stRoot) {
164
+ const map = file.resolve(stRoot.get("RoleMap") ?? PDF_NULL);
165
+ if (!(map instanceof Map)) return (type) => type;
166
+ return (type) => {
167
+ let at = type;
168
+ for (let hop = 0; hop < MAX_ROLE_HOPS; hop++) {
169
+ const next = file.resolve(map.get(at) ?? PDF_NULL);
170
+ if (!(next instanceof PdfName) || next.value === at) break;
171
+ at = next.value;
172
+ }
173
+ return at;
174
+ };
175
+ }
176
+ /** How far a chain of role mappings is followed before it is taken for a cycle. */
177
+ var MAX_ROLE_HOPS = 8;
74
178
  function kidList(file, kVal) {
75
179
  if (kVal === void 0) return [];
76
180
  const k = file.resolve(kVal);