reamkit 1.21.0 → 1.23.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 (90) hide show
  1. package/dist/esm/core/bytes.d.ts +22 -4
  2. package/dist/esm/core/bytes.js +73 -5
  3. package/dist/esm/core/converter/ream.d.ts +16 -0
  4. package/dist/esm/core/converter/ream.js +59 -9
  5. package/dist/esm/core/document-model/types.d.ts +78 -0
  6. package/dist/esm/core/drawingml/chart-geometry.js +11 -5
  7. package/dist/esm/core/drawingml/chart-parser.d.ts +2 -1
  8. package/dist/esm/core/drawingml/chart-parser.js +23 -1
  9. package/dist/esm/core/drawingml/colors.d.ts +30 -4
  10. package/dist/esm/core/drawingml/colors.js +45 -6
  11. package/dist/esm/core/drawingml/preset-geometry.js +236 -0
  12. package/dist/esm/core/drawingml/theme-parser.d.ts +38 -0
  13. package/dist/esm/core/drawingml/theme-parser.js +64 -1
  14. package/dist/esm/core/fonts/families.d.ts +10 -0
  15. package/dist/esm/core/fonts/families.js +44 -0
  16. package/dist/esm/core/fonts/index.d.ts +3 -2
  17. package/dist/esm/core/fonts/remote-fonts.d.ts +50 -0
  18. package/dist/esm/core/fonts/remote-fonts.js +114 -8
  19. package/dist/esm/core/fonts/scripts.d.ts +26 -0
  20. package/dist/esm/core/fonts/scripts.js +177 -0
  21. package/dist/esm/core/metafile/blit.d.ts +33 -0
  22. package/dist/esm/core/metafile/blit.js +67 -0
  23. package/dist/esm/core/metafile/dib.d.ts +61 -0
  24. package/dist/esm/core/metafile/dib.js +205 -0
  25. package/dist/esm/core/metafile/emf.js +139 -24
  26. package/dist/esm/core/metafile/picture.d.ts +12 -1
  27. package/dist/esm/core/metafile/symbol-fonts.d.ts +42 -0
  28. package/dist/esm/core/metafile/symbol-fonts.js +154 -0
  29. package/dist/esm/core/metafile/wmf.js +183 -10
  30. package/dist/esm/core/ole/escher-blip.d.ts +12 -0
  31. package/dist/esm/core/ole/escher-blip.js +88 -0
  32. package/dist/esm/{pdf-reader → core}/png-encode.js +1 -1
  33. package/dist/esm/core/vector.d.ts +5 -0
  34. package/dist/esm/excel/print-model.js +3 -1
  35. package/dist/esm/excel/sheet-shape-parser.js +1 -12
  36. package/dist/esm/excel/styles-parser.js +1 -1
  37. package/dist/esm/excel/xls/biff-reader.js +53 -18
  38. package/dist/esm/excel/xls/biff-styles.d.ts +5 -2
  39. package/dist/esm/excel/xls/biff-styles.js +9 -7
  40. package/dist/esm/excel/xls/escher.js +90 -24
  41. package/dist/esm/excel/xlsx-reader.d.ts +1 -1
  42. package/dist/esm/excel/xlsx-reader.js +3 -3
  43. package/dist/esm/layout/page-doc.d.ts +77 -0
  44. package/dist/esm/layout/page-doc.js +34 -18
  45. package/dist/esm/layout/styled-layout.d.ts +2 -2
  46. package/dist/esm/layout/styled-layout.js +467 -76
  47. package/dist/esm/pdf/shading.d.ts +19 -0
  48. package/dist/esm/pdf/shading.js +84 -11
  49. package/dist/esm/pdf/styled-page-emitter.js +647 -444
  50. package/dist/esm/pdf-reader/image-decode.js +1 -1
  51. package/dist/esm/pptx/embedded-fonts.d.ts +31 -0
  52. package/dist/esm/pptx/embedded-fonts.js +104 -0
  53. package/dist/esm/pptx/ole-preview.d.ts +10 -0
  54. package/dist/esm/pptx/ole-preview.js +52 -0
  55. package/dist/esm/pptx/placeholder-cascade.d.ts +136 -5
  56. package/dist/esm/pptx/placeholder-cascade.js +260 -27
  57. package/dist/esm/pptx/ppt/ppt-reader.js +120 -10
  58. package/dist/esm/pptx/ppt/ppt-text.d.ts +66 -1
  59. package/dist/esm/pptx/ppt/ppt-text.js +576 -137
  60. package/dist/esm/pptx/pptx-reader.d.ts +8 -0
  61. package/dist/esm/pptx/pptx-reader.js +271 -41
  62. package/dist/esm/pptx/preset-table-styles.d.ts +9 -0
  63. package/dist/esm/pptx/preset-table-styles.js +27 -0
  64. package/dist/esm/pptx/slide-parser.d.ts +78 -10
  65. package/dist/esm/pptx/slide-parser.js +396 -95
  66. package/dist/esm/pptx/sp-helpers.d.ts +2 -1
  67. package/dist/esm/pptx/sp-helpers.js +22 -6
  68. package/dist/esm/pptx/table-style.d.ts +64 -0
  69. package/dist/esm/pptx/table-style.js +203 -0
  70. package/dist/esm/svg/svg-writer.js +53 -5
  71. package/dist/esm/word/document-parser.d.ts +7 -1
  72. package/dist/esm/word/document-parser.js +6 -6
  73. package/dist/esm/word/docx-reader.js +8 -5
  74. package/dist/esm/word/docx-to-pdf.d.ts +8 -7
  75. package/dist/esm/word/docx-to-pdf.js +25 -7
  76. package/dist/esm/word/drawing-parser.d.ts +34 -0
  77. package/dist/esm/word/drawing-parser.js +173 -15
  78. package/dist/esm/word/numbering-parser.d.ts +2 -1
  79. package/dist/esm/word/numbering-parser.js +6 -6
  80. package/dist/esm/word/paragraph-properties.d.ts +2 -1
  81. package/dist/esm/word/paragraph-properties.js +2 -2
  82. package/dist/esm/word/run-properties.d.ts +5 -2
  83. package/dist/esm/word/run-properties.js +13 -8
  84. package/dist/esm/word/styles-parser.d.ts +2 -1
  85. package/dist/esm/word/styles-parser.js +12 -12
  86. package/dist/esm/word/table-parser.js +3 -3
  87. package/dist/esm/word/theme-fonts.d.ts +10 -0
  88. package/dist/esm/word/theme-fonts.js +28 -0
  89. package/package.json +1 -1
  90. /package/dist/esm/{pdf-reader → core}/png-encode.d.ts +0 -0
@@ -1,8 +1,8 @@
1
1
  import { PDF_NULL, PdfHexString, PdfName, PdfStream } from "../pdf/objects.js";
2
2
  import { lzwDecodeMsb } from "../core/lzw.js";
3
+ import { encodePng } from "../core/png-encode.js";
3
4
  import { reversePredictor } from "./predictor.js";
4
5
  import { decodeCcitt } from "./ccitt.js";
5
- import { encodePng } from "./png-encode.js";
6
6
  import { unzlibSync } from "fflate";
7
7
  //#region src/pdf-reader/image-decode.ts
8
8
  var MAX_PIXELS = 4e7;
@@ -0,0 +1,31 @@
1
+ import { Loss } from '../core/ir/index.js';
2
+ import { OpcPackage } from '../core/opc/index.js';
3
+ import { PoNode } from '../core/po-helpers.js';
4
+ import { FontRegistry } from '../core/font/index.js';
5
+ /** What an `fntdata` part turned out to hold. */
6
+ type FaceBytes = {
7
+ readonly kind: 'font';
8
+ readonly bytes: Uint8Array;
9
+ } | {
10
+ readonly kind: 'compressed';
11
+ } | {
12
+ readonly kind: 'unreadable';
13
+ };
14
+ /**
15
+ * Read one `fntdata` part: the font itself when the container stores it
16
+ * plainly, and what stopped it otherwise.
17
+ *
18
+ * @param data The part's bytes.
19
+ */
20
+ export declare function readFntData(data: Uint8Array): FaceBytes;
21
+ /**
22
+ * §19.2.1.13 — the fonts a deck embeds, by normalized family name.
23
+ *
24
+ * @param pkg The opened `.pptx` package.
25
+ * @param presPath The presentation part's path (relationships resolve from it).
26
+ * @param pres Its parsed `p:presentation` element.
27
+ * @param onLoss Where a face that cannot be unpacked records itself.
28
+ * @returns The families whose faces were readable (empty when none were).
29
+ */
30
+ export declare function loadPptxEmbeddedFonts(pkg: OpcPackage, presPath: string, pres: PoNode | undefined, onLoss: (loss: Loss) => void): Map<string, FontRegistry>;
31
+ export {};
@@ -0,0 +1,104 @@
1
+ import { FontRegistry } from "../core/font/font-registry.js";
2
+ import { poAttr, poChildren, poIs } from "../core/po-helpers.js";
3
+ //#region src/pptx/embedded-fonts.ts
4
+ var REL_FONT = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/font";
5
+ /** §19.2.1.13 — the four faces a `p:embeddedFont` may name, by element. */
6
+ var VARIANTS = [
7
+ ["p:regular", "regular"],
8
+ ["p:bold", "bold"],
9
+ ["p:italic", "italic"],
10
+ ["p:boldItalic", "boldItalic"]
11
+ ];
12
+ var EOT_VERSIONS = new Set([
13
+ 65536,
14
+ 131073,
15
+ 131074
16
+ ]);
17
+ var TTEMBED_TTCOMPRESSED = 4;
18
+ var TTEMBED_XORENCRYPTDATA = 268435456;
19
+ /**
20
+ * Read one `fntdata` part: the font itself when the container stores it
21
+ * plainly, and what stopped it otherwise.
22
+ *
23
+ * @param data The part's bytes.
24
+ */
25
+ function readFntData(data) {
26
+ if (isSfnt(data)) return {
27
+ kind: "font",
28
+ bytes: data
29
+ };
30
+ if (data.length < 82) return { kind: "unreadable" };
31
+ const v = new DataView(data.buffer, data.byteOffset, data.byteLength);
32
+ const eotSize = v.getUint32(0, true);
33
+ const version = v.getUint32(8, true);
34
+ const flags = v.getUint32(12, true);
35
+ if (eotSize !== data.length || !EOT_VERSIONS.has(version)) return { kind: "unreadable" };
36
+ if ((flags & (TTEMBED_TTCOMPRESSED | TTEMBED_XORENCRYPTDATA)) !== 0) return { kind: "compressed" };
37
+ let at = 82;
38
+ for (let i = 0; i < 4; i++) {
39
+ if (at + 2 > data.length) return { kind: "unreadable" };
40
+ at += 2 + v.getUint16(at, true) + 2;
41
+ }
42
+ if (version !== 65536) {
43
+ if (at + 2 > data.length) return { kind: "unreadable" };
44
+ at += 2 + v.getUint16(at, true);
45
+ at = data.length - v.getUint32(4, true);
46
+ }
47
+ const bytes = data.subarray(at);
48
+ return isSfnt(bytes) ? {
49
+ kind: "font",
50
+ bytes
51
+ } : { kind: "unreadable" };
52
+ }
53
+ /**
54
+ * §19.2.1.13 — the fonts a deck embeds, by normalized family name.
55
+ *
56
+ * @param pkg The opened `.pptx` package.
57
+ * @param presPath The presentation part's path (relationships resolve from it).
58
+ * @param pres Its parsed `p:presentation` element.
59
+ * @param onLoss Where a face that cannot be unpacked records itself.
60
+ * @returns The families whose faces were readable (empty when none were).
61
+ */
62
+ function loadPptxEmbeddedFonts(pkg, presPath, pres, onLoss) {
63
+ const out = /* @__PURE__ */ new Map();
64
+ const list = pres ? poChildren(pres).find((c) => poIs(c, "p:embeddedFontLst")) : void 0;
65
+ if (!list) return out;
66
+ const relById = new Map(pkg.getPartRelationships(presPath).map((r) => [r.id, r]));
67
+ for (const font of poChildren(list).filter((c) => poIs(c, "p:embeddedFont"))) {
68
+ const bytes = {};
69
+ let compressed = false;
70
+ for (const [tag, variant] of VARIANTS) {
71
+ const node = poChildren(font).find((c) => poIs(c, tag));
72
+ const rId = node ? poAttr(node, "r:id") : void 0;
73
+ const rel = rId !== void 0 ? relById.get(rId) : void 0;
74
+ if (!rel || rel.type !== REL_FONT) continue;
75
+ const part = pkg.resolveRelatedPart(presPath, rel);
76
+ if (!part) continue;
77
+ const face = readFntData(part.data);
78
+ if (face.kind === "compressed") compressed = true;
79
+ if (face.kind === "font") bytes[variant] = face.bytes;
80
+ }
81
+ const typeface = poChildren(font).find((c) => poIs(c, "p:font"));
82
+ const name = (typeface ? poAttr(typeface, "typeface") : void 0)?.trim() ?? "";
83
+ if (bytes.regular) try {
84
+ out.set(name.toLowerCase(), FontRegistry.fromBytes({
85
+ ...bytes,
86
+ regular: bytes.regular
87
+ }));
88
+ continue;
89
+ } catch {}
90
+ if (compressed) onLoss({
91
+ feature: "font",
92
+ detail: `the deck embeds ${name || "a font"}, packed with MicroType Express (EOT TTEMBED_TTCOMPRESSED); it renders in a substitute`,
93
+ severity: "substituted"
94
+ });
95
+ }
96
+ return out;
97
+ }
98
+ function isSfnt(data) {
99
+ if (data.length < 4) return false;
100
+ const sig = (data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3]) >>> 0;
101
+ return sig === 65536 || sig === 1330926671 || sig === 1953658213 || sig === 1953784678;
102
+ }
103
+ //#endregion
104
+ export { loadPptxEmbeddedFonts };
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Shape id → the relationship id of its `v:imagedata`, for every shape in a
3
+ * legacy VML drawing part that has one.
4
+ *
5
+ * @param data The raw `vmlDrawing#.vml` bytes.
6
+ * @returns The map, keyed by shape id with the `_x0000_s` prefix stripped.
7
+ */
8
+ export declare function parseVmlImageRels(data: Uint8Array): Map<string, string>;
9
+ /** Strip the `_x0000_s` prefix a VML shape id carries, so both spellings meet. */
10
+ export declare function normalizeSpid(id: string): string;
@@ -0,0 +1,52 @@
1
+ import { XMLParser } from "fast-xml-parser";
2
+ //#region src/pptx/ole-preview.ts
3
+ var decoder = new TextDecoder("utf-8");
4
+ var parser = new XMLParser({
5
+ ignoreAttributes: false,
6
+ attributeNamePrefix: "@_",
7
+ parseAttributeValue: false,
8
+ parseTagValue: false,
9
+ removeNSPrefix: true
10
+ });
11
+ var SPID_PREFIX = /^_x0000_s/u;
12
+ /**
13
+ * Shape id → the relationship id of its `v:imagedata`, for every shape in a
14
+ * legacy VML drawing part that has one.
15
+ *
16
+ * @param data The raw `vmlDrawing#.vml` bytes.
17
+ * @returns The map, keyed by shape id with the `_x0000_s` prefix stripped.
18
+ */
19
+ function parseVmlImageRels(data) {
20
+ const out = /* @__PURE__ */ new Map();
21
+ walk(parser.parse(decoder.decode(data)), out);
22
+ return out;
23
+ }
24
+ /** Strip the `_x0000_s` prefix a VML shape id carries, so both spellings meet. */
25
+ function normalizeSpid(id) {
26
+ return id.replace(SPID_PREFIX, "");
27
+ }
28
+ function walk(node, out) {
29
+ if (node === null || typeof node !== "object") return;
30
+ if (Array.isArray(node)) {
31
+ for (const item of node) walk(item, out);
32
+ return;
33
+ }
34
+ const rec = node;
35
+ const shape = rec["shape"];
36
+ if (shape !== void 0) for (const s of Array.isArray(shape) ? shape : [shape]) collect(s, out);
37
+ for (const value of Object.values(rec)) walk(value, out);
38
+ }
39
+ function collect(shape, out) {
40
+ if (shape === null || typeof shape !== "object") return;
41
+ const rec = shape;
42
+ const id = rec["@_id"];
43
+ const imagedata = rec["imagedata"];
44
+ if (typeof id !== "string" || imagedata === void 0) return;
45
+ const first = Array.isArray(imagedata) ? imagedata[0] : imagedata;
46
+ if (first === null || typeof first !== "object") return;
47
+ const img = first;
48
+ const rel = img["@_relid"] ?? img["@_id"];
49
+ if (typeof rel === "string") out.set(normalizeSpid(id), rel);
50
+ }
51
+ //#endregion
52
+ export { normalizeSpid, parseVmlImageRels };
@@ -1,7 +1,9 @@
1
- import { RunProperties } from '../core/document-model/index.js';
1
+ import { ParagraphProperties, RunProperties } from '../core/document-model/index.js';
2
2
  import { ColorResolver } from '../core/drawingml/colors.js';
3
+ import { ThemeFonts } from '../core/drawingml/theme-parser.js';
3
4
  import { PoNode } from '../core/po-helpers.js';
4
5
  import { PlaceholderRef, ShapeBoxEmu } from './sp-helpers.js';
6
+ import { Pt } from '../core/ir/index.js';
5
7
  /**
6
8
  * The placeholder cascade (PX2): the resolver a slide parser consults whenever a
7
9
  * slide placeholder shape (`p:sp` with a `p:ph`) lacks its own geometry or run
@@ -12,11 +14,78 @@ export interface PlaceholderCascade {
12
14
  /** The inherited EMU box for a slide placeholder without its own `a:xfrm`. */
13
15
  readonly geometryFor: (ph: PlaceholderRef) => ShapeBoxEmu | undefined;
14
16
  /**
15
- * The master's default run formatting for a placeholder's paragraph at the
16
- * given 0-based outline level (empty when no master text styles apply).
17
+ * The inherited run formatting for a paragraph at the given 0-based outline
18
+ * level. Without a placeholder this is the presentation's default text style
19
+ * — what an ordinary text box on a slide is written in.
17
20
  */
18
- readonly defaultsFor: (ph: PlaceholderRef, level: number) => RunProperties;
21
+ readonly defaultsFor: (ph: PlaceholderRef | undefined, level: number) => RunProperties;
22
+ /** The inherited paragraph shape at that level: alignment, indent, spacing. */
23
+ readonly paragraphDefaultsFor: (ph: PlaceholderRef | undefined, level: number) => ParagraphProperties;
24
+ /** The bullet that level inherits, which a paragraph states only to change. */
25
+ readonly bulletFor: (ph: PlaceholderRef | undefined, level: number) => LevelBullet | undefined;
26
+ /**
27
+ * The vertical anchor the placeholder's prototype states (`a:bodyPr@anchor`),
28
+ * the layout's before the master's, for a shape that states none itself.
29
+ */
30
+ readonly anchorFor: (ph: PlaceholderRef) => 't' | 'ctr' | 'b' | undefined;
31
+ /**
32
+ * The prototypes' own `p:spPr`, nearest first — the layout's, then the
33
+ * master's — for the properties a slide placeholder inherits rather than
34
+ * states: its fill, its outline, its geometry.
35
+ *
36
+ * A CHAIN and not one node, because the inheritance is per property. The
37
+ * layout's prototype may state a box and nothing else, and the fill then
38
+ * comes from the master: tdf104015's title is red in every reader and was a
39
+ * bare outline here, because the layout's `p:spPr` existed and stopped the
40
+ * search.
41
+ */
42
+ readonly shapePropsFor: (ph: PlaceholderRef) => ReadonlyArray<PoNode>;
43
+ }
44
+ /** One level of a text style: how its paragraphs sit and how their runs read. */
45
+ interface LevelStyle {
46
+ readonly run: RunProperties;
47
+ readonly paragraph: ParagraphProperties;
48
+ readonly bullet?: LevelBullet;
49
+ /**
50
+ * §21.1.2.2.9/.10 — the space around the paragraph stated as a FRACTION of a
51
+ * line rather than a distance. A fraction of WHAT is only known once the
52
+ * levels have merged and the size is settled, so it travels this far raw.
53
+ */
54
+ readonly spacingPct?: {
55
+ readonly before?: number;
56
+ readonly after?: number;
57
+ };
19
58
  }
59
+ /**
60
+ * §21.1.2.4.4/.5/.6 — the bullet a level declares: none at all, a literal
61
+ * character, or a number that counts. A slide paragraph states one only where
62
+ * it differs from this: themes.pptx's second slide writes one bare line, and
63
+ * the dot in front of it is the master's body style, nine levels up.
64
+ */
65
+ export interface LevelBullet {
66
+ /** What it draws: nothing at all, a character, or a number that counts. */
67
+ readonly kind?: 'none' | 'char' | 'autoNum';
68
+ /** `a:buChar` — the character, already read out of the face that states it. */
69
+ readonly char?: string;
70
+ /** `a:buAutoNum @type`/`@startAt` — the numbering and where it starts. */
71
+ readonly type?: string;
72
+ readonly startAt?: number;
73
+ /** §21.1.2.4.2/.3 — its size, as a fraction of the text or in points. */
74
+ readonly sizePct?: number;
75
+ readonly sizePts?: number;
76
+ /** §21.1.2.4.1 `a:buClr` — the colour it is drawn in, when it has its own. */
77
+ readonly colorHex?: string;
78
+ }
79
+ /**
80
+ * What an `a:pPr` (or an `a:lvlNpPr`, the same vocabulary) says about its
81
+ * bullet — each part on its own, because a paragraph may restate the SIZE and
82
+ * leave the character to its level.
83
+ *
84
+ * @param pPr The paragraph-properties node.
85
+ * @param colors The colour resolver, for `a:buClr`.
86
+ * @returns What it states, or `undefined` when it says nothing about bullets.
87
+ */
88
+ export declare function parseBullet(pPr: PoNode | undefined, colors?: ColorResolver): LevelBullet | undefined;
20
89
  /**
21
90
  * Build a {@link PlaceholderCascade} from a slide's already-parsed layout and
22
91
  * master trees: it resolves a placeholder's inherited geometry (the layout's
@@ -26,5 +95,67 @@ export interface PlaceholderCascade {
26
95
  * @param layoutTree The parsed `p:sldLayout` part.
27
96
  * @param masterTree The parsed `p:sldMaster` part, when present.
28
97
  * @param colors The deck's colour resolver, for scheme colours in the text styles.
98
+ * @param deckDefaults The presentation's own default text style, as the floor.
99
+ * @param themeFonts The theme's font scheme, for the `+mn-lt` tokens.
100
+ */
101
+ export declare function buildPlaceholderCascade(layoutTree: ReadonlyArray<PoNode>, masterTree: ReadonlyArray<PoNode> | undefined, colors: ColorResolver, deckDefaults?: ReadonlyArray<LevelStyle>, themeFonts?: ThemeFonts): PlaceholderCascade;
102
+ /**
103
+ * §21.1.2.2.9/.10 — the space a paragraph states as a FRACTION of a line, in
104
+ * points.
105
+ *
106
+ * A "line" here is the paragraph's own text at its natural height, which is the
107
+ * size times the same 1.2 the layout gives an unstated line. A level that
108
+ * states the fraction and leaves the size to another level is resolved once
109
+ * they have merged, which is why this is not read where the fraction is.
110
+ *
111
+ * @param pct The fraction, `0..n` (20% arrives as 0.2).
112
+ * @param sizePt The paragraph's resolved font size.
113
+ * @returns The distance, or `undefined` when the size is not known.
114
+ */
115
+ export declare function spacingFromLineFraction(pct: number | undefined, sizePt: number | undefined): Pt | undefined;
116
+ /**
117
+ * `a:lstStyle` (or a `p:txStyles` family) → its nine levels. Shared by the
118
+ * deck's default text style, the master's families and a prototype's own list,
119
+ * which are the same vocabulary written in different places.
120
+ *
121
+ * @param list The `a:lstStyle` / `p:titleStyle` / … node.
122
+ * @param colors The deck's colour resolver.
123
+ * @param prefix The level element prefix: `a:lvl` here, always.
124
+ * @returns The nine levels, or an empty list when there is no such node.
125
+ */
126
+ export declare function parseLevelStyles(list: PoNode | undefined, colors: ColorResolver, themeFonts?: ThemeFonts): Array<LevelStyle>;
127
+ /**
128
+ * A level's paragraph shape — §21.1.2.2.7 `@algn`, `@marL`/`@indent`, and the
129
+ * space around and between its lines.
130
+ *
131
+ * Both spacings come in two spellings: `a:spcPts` is a distance (hundredths of
132
+ * a point) and `a:spcPct` a FRACTION of a line (thousandths of a percent). Only
133
+ * the distance was read, so a deck that spaces its bullets the usual way — by
134
+ * fraction — set them solid.
135
+ */
136
+ export declare function pPrToParagraphProps(lvlPr: PoNode | undefined): ParagraphProperties;
137
+ /**
138
+ * §21.1.2.2.5 `a:lnSpc` — the height of each line: a fraction of the natural
139
+ * one (`a:spcPct`) or a distance (`a:spcPts`).
140
+ *
141
+ * The model states a multiple the way §17.3.1.33 does — 12pt under the `auto`
142
+ * rule IS single — so a fraction needs no font size to express, which is why
143
+ * this resolves here and the paragraph SPACING has to wait for the size.
144
+ *
145
+ * @param pPr The paragraph properties (a level's or a paragraph's own).
146
+ * @returns The line spacing, or nothing when the node states none.
147
+ */
148
+ export declare function lineSpacing(pPr: PoNode | undefined): ParagraphProperties;
149
+ /**
150
+ * §21.1.2.2.9/.10 — the fraction of a line a paragraph puts before and after
151
+ * itself, when it states one. The distance form is read beside it; this is what
152
+ * the caller must still resolve against the size.
153
+ *
154
+ * @param pPr The paragraph properties.
155
+ * @returns The two fractions (`0..n`), each present only when stated.
29
156
  */
30
- export declare function buildPlaceholderCascade(layoutTree: ReadonlyArray<PoNode>, masterTree: ReadonlyArray<PoNode> | undefined, colors: ColorResolver): PlaceholderCascade;
157
+ export declare function spacingFractions(pPr: PoNode | undefined): {
158
+ readonly before?: number;
159
+ readonly after?: number;
160
+ } | undefined;
161
+ export {};