@sobree/core 0.1.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/LICENSE +21 -0
- package/README.md +106 -0
- package/dist/__vite-browser-external-DYxpcVy9.js +5 -0
- package/dist/__vite-browser-external-DYxpcVy9.js.map +1 -0
- package/dist/blob/cache.d.ts +69 -0
- package/dist/blob/fetch.d.ts +18 -0
- package/dist/blob/hash.d.ts +13 -0
- package/dist/blob/index.d.ts +33 -0
- package/dist/blob/memory.d.ts +2 -0
- package/dist/blob/types.d.ts +80 -0
- package/dist/createSobree.d.ts +132 -0
- package/dist/doc/api.d.ts +132 -0
- package/dist/doc/builders.d.ts +42 -0
- package/dist/doc/pageSetupBridge.d.ts +26 -0
- package/dist/doc/parts.d.ts +18 -0
- package/dist/doc/runs.d.ts +47 -0
- package/dist/doc/styles.d.ts +19 -0
- package/dist/doc/types.d.ts +800 -0
- package/dist/doc/walk.d.ts +30 -0
- package/dist/docx/export/contentTypes.d.ts +35 -0
- package/dist/docx/export/context.d.ts +59 -0
- package/dist/docx/export/document.d.ts +19 -0
- package/dist/docx/export/drawings.d.ts +10 -0
- package/dist/docx/export/headers.d.ts +19 -0
- package/dist/docx/export/index.d.ts +14 -0
- package/dist/docx/export/runs.d.ts +8 -0
- package/dist/docx/export/styles.d.ts +8 -0
- package/dist/docx/export/zip.d.ts +13 -0
- package/dist/docx/import/anchoredFrames.d.ts +34 -0
- package/dist/docx/import/comments.d.ts +3 -0
- package/dist/docx/import/document.d.ts +57 -0
- package/dist/docx/import/flowFrames.d.ts +11 -0
- package/dist/docx/import/footnotes.d.ts +3 -0
- package/dist/docx/import/headers.d.ts +50 -0
- package/dist/docx/import/index.d.ts +12 -0
- package/dist/docx/import/inlineFrames.d.ts +62 -0
- package/dist/docx/import/numbering.d.ts +2 -0
- package/dist/docx/import/paragraph.d.ts +24 -0
- package/dist/docx/import/paragraphs.d.ts +27 -0
- package/dist/docx/import/rels.d.ts +5 -0
- package/dist/docx/import/runs.d.ts +64 -0
- package/dist/docx/import/settings.d.ts +48 -0
- package/dist/docx/import/styles.d.ts +3 -0
- package/dist/docx/import/tables.d.ts +12 -0
- package/dist/docx/import/unzip.d.ts +13 -0
- package/dist/docx/shared/namespaces.d.ts +31 -0
- package/dist/docx/shared/pageSize.d.ts +27 -0
- package/dist/docx/shared/shading.d.ts +2 -0
- package/dist/docx/shared/units.d.ts +35 -0
- package/dist/docx/shared/xml.d.ts +29 -0
- package/dist/docx/types.d.ts +98 -0
- package/dist/editor/index.d.ts +1078 -0
- package/dist/editor/internal/blockRegistry.d.ts +91 -0
- package/dist/editor/internal/mutations.d.ts +63 -0
- package/dist/editor/internal/positionMap.d.ts +35 -0
- package/dist/editor/table.d.ts +96 -0
- package/dist/editor/view/docRenderer/anchorLayer.d.ts +26 -0
- package/dist/editor/view/docRenderer/block.d.ts +13 -0
- package/dist/editor/view/docRenderer/fontFallback.d.ts +28 -0
- package/dist/editor/view/docRenderer/index.d.ts +18 -0
- package/dist/editor/view/docRenderer/inline.d.ts +15 -0
- package/dist/editor/view/docRenderer/inlineFrame.d.ts +4 -0
- package/dist/editor/view/docRenderer/lists.d.ts +28 -0
- package/dist/editor/view/docRenderer/paragraph.d.ts +2 -0
- package/dist/editor/view/docRenderer/properties.d.ts +2 -0
- package/dist/editor/view/docRenderer/table.d.ts +15 -0
- package/dist/editor/view/docRenderer/units.d.ts +48 -0
- package/dist/editor/view/docSerialize/block.d.ts +14 -0
- package/dist/editor/view/docSerialize/index.d.ts +8 -0
- package/dist/editor/view/docSerialize/inline.d.ts +11 -0
- package/dist/editor/view/docSerialize/table.d.ts +12 -0
- package/dist/editor/view/imageResize.d.ts +16 -0
- package/dist/embed/floatingCorner.d.ts +44 -0
- package/dist/embed/viewport.d.ts +133 -0
- package/dist/fonts/embedAPI.d.ts +33 -0
- package/dist/fonts/emit.d.ts +24 -0
- package/dist/fonts/fontFaceRegistry.d.ts +20 -0
- package/dist/fonts/fsType.d.ts +36 -0
- package/dist/fonts/index.d.ts +19 -0
- package/dist/fonts/liveness.d.ts +2 -0
- package/dist/fonts/odttf.d.ts +33 -0
- package/dist/fonts/parse.d.ts +29 -0
- package/dist/fonts/types.d.ts +52 -0
- package/dist/headless.d.ts +168 -0
- package/dist/history/history.d.ts +100 -0
- package/dist/history/index.d.ts +4 -0
- package/dist/history/types.d.ts +54 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +10561 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown/parse.d.ts +6 -0
- package/dist/pagination/cost.d.ts +32 -0
- package/dist/pagination/index.d.ts +2 -0
- package/dist/pagination/paginate.d.ts +10 -0
- package/dist/pagination/postConditions.d.ts +10 -0
- package/dist/pagination/types.d.ts +94 -0
- package/dist/paperStack/pageSetup.d.ts +42 -0
- package/dist/paperStack/paginationAdapter/buildItems.d.ts +19 -0
- package/dist/paperStack/paginationAdapter/distribute.d.ts +23 -0
- package/dist/paperStack/paginationAdapter/index.d.ts +18 -0
- package/dist/paperStack/paginationAdapter/paragraphLines.d.ts +23 -0
- package/dist/paperStack/paginationAdapter/splitList.d.ts +19 -0
- package/dist/paperStack/paginationAdapter/splitParagraph.d.ts +21 -0
- package/dist/paperStack/paginationAdapter/types.d.ts +30 -0
- package/dist/paperStack/paper.d.ts +107 -0
- package/dist/paperStack/paperStack.d.ts +245 -0
- package/dist/plugin.d.ts +24 -0
- package/dist/plugins/marks.d.ts +49 -0
- package/dist/plugins/sections.d.ts +15 -0
- package/dist/presence/attach.d.ts +48 -0
- package/dist/presence/awareness.d.ts +28 -0
- package/dist/presence/index.d.ts +19 -0
- package/dist/presence/overlay.d.ts +28 -0
- package/dist/presence/state.d.ts +36 -0
- package/dist/sobree.d.ts +211 -0
- package/dist/tokens.css +144 -0
- package/dist/util/selection.d.ts +13 -0
- package/dist/ydoc/apply.d.ts +68 -0
- package/dist/ydoc/index.d.ts +18 -0
- package/dist/ydoc/project.d.ts +41 -0
- package/dist/ydoc/runs.d.ts +51 -0
- package/dist/ydoc/schema.d.ts +123 -0
- package/dist/ydoc/seed.d.ts +45 -0
- package/dist/ydoc/textDiff.d.ts +59 -0
- package/dist/zoneEdit/index.d.ts +22 -0
- package/package.json +61 -0
|
@@ -0,0 +1,800 @@
|
|
|
1
|
+
import { FontDeclaration as _FontDeclaration } from '../fonts/types';
|
|
2
|
+
/**
|
|
3
|
+
* Sobree's internal document model.
|
|
4
|
+
*
|
|
5
|
+
* Every node here maps 1-to-1 to an OOXML construct so serialisation to
|
|
6
|
+
* `.docx` is mechanical (no decisions, no lossy translation). The names
|
|
7
|
+
* are JS-friendly — `Paragraph`, `RunProperties`, etc. — rather than
|
|
8
|
+
* `<w:p>`, `<w:rPr>` directly, but the shapes line up.
|
|
9
|
+
*
|
|
10
|
+
* Conventions:
|
|
11
|
+
* - All numeric measurements that originate in OOXML keep their native
|
|
12
|
+
* unit, suffixed in the field name: `wTwips`, `sizeHalfPt`, `widthEmu`.
|
|
13
|
+
* - All node objects are JSON-clean (no functions, classes, or
|
|
14
|
+
* references) so they cross any wire (Yjs sync messages, MCP,
|
|
15
|
+
* postMessage) untouched.
|
|
16
|
+
* - Optional fields are `?:` — absence means "not set", not "default".
|
|
17
|
+
* Defaults are applied at render time from the document's styles.
|
|
18
|
+
*/
|
|
19
|
+
export interface SobreeDocument {
|
|
20
|
+
/** Top-level body content, in document order. */
|
|
21
|
+
body: Block[];
|
|
22
|
+
/**
|
|
23
|
+
* One section per body slice. The simplest doc has exactly one section
|
|
24
|
+
* spanning the whole body. Phase N1 supports a single-section model.
|
|
25
|
+
*/
|
|
26
|
+
sections: SectionProperties[];
|
|
27
|
+
/**
|
|
28
|
+
* Header and footer bodies keyed by `HeaderFooterRef.partId`. The partId
|
|
29
|
+
* is the ZIP target name (`header1.xml`, `footer2.xml`, …). Rendering
|
|
30
|
+
* emits each body to its own OOXML part at export time.
|
|
31
|
+
*/
|
|
32
|
+
headerFooterBodies: Record<string, Block[]>;
|
|
33
|
+
/** Named styles (Heading1, Quote, Body Text, …) defined at the doc level. */
|
|
34
|
+
styles: NamedStyle[];
|
|
35
|
+
/** List/numbering definitions referenced by `Paragraph.properties.numbering`. */
|
|
36
|
+
numbering: NumberingDefinition[];
|
|
37
|
+
/**
|
|
38
|
+
* Embedded binary parts keyed by ZIP path (e.g. `word/media/image1.png`).
|
|
39
|
+
* Images, fonts, custom XML — anything not represented in body XML.
|
|
40
|
+
*/
|
|
41
|
+
rawParts: Record<string, Uint8Array>;
|
|
42
|
+
/**
|
|
43
|
+
* Font declarations from `word/fontTable.xml`. Empty for new docs.
|
|
44
|
+
* Embedded faces reference parts inside `rawParts`.
|
|
45
|
+
*/
|
|
46
|
+
fonts: FontDeclaration[];
|
|
47
|
+
/**
|
|
48
|
+
* Footnote bodies keyed by id. Body inline runs use `FootnoteRefRun`
|
|
49
|
+
* with the matching `id` to reference them. Empty for docs without
|
|
50
|
+
* footnotes (the common case).
|
|
51
|
+
*/
|
|
52
|
+
footnotes?: Record<number, Block[]>;
|
|
53
|
+
/**
|
|
54
|
+
* Comments keyed by id. Body inline runs whose properties carry a
|
|
55
|
+
* matching `commentIds` mark the range each comment annotates.
|
|
56
|
+
* Empty for docs without comments (the common case).
|
|
57
|
+
*/
|
|
58
|
+
comments?: Record<number, Comment>;
|
|
59
|
+
/**
|
|
60
|
+
* Document-wide layout settings parsed from `word/settings.xml`.
|
|
61
|
+
* Currently only `defaultTabStopTwips` — Word's default interval for
|
|
62
|
+
* tab advances in paragraphs that don't declare their own `<w:tabs>`
|
|
63
|
+
* stops. Word's factory default is 720 twips (0.5"). Without
|
|
64
|
+
* respecting this, the browser falls back to the CSS `tab-size`
|
|
65
|
+
* default of 8 characters which is much narrower than what Word
|
|
66
|
+
* shows, and tab-aligned content (e.g. label/value columns in
|
|
67
|
+
* letterheads) ends up cramped.
|
|
68
|
+
*/
|
|
69
|
+
settings?: {
|
|
70
|
+
defaultTabStopTwips?: number;
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* NOTE: inline-drawing frames are emitted as `InlineFrame` BLOCKS
|
|
74
|
+
* directly in `body` (the importer splices them in at their source
|
|
75
|
+
* paragraph's position via `ConvertOptions.replaceParagraphs`), so
|
|
76
|
+
* they paginate in document flow. This optional top-level list is
|
|
77
|
+
* a secondary handle kept for tooling/inspection; the renderer
|
|
78
|
+
* consumes the body blocks, not this list.
|
|
79
|
+
*
|
|
80
|
+
* The first-class model replaced the old `liftTextBoxContent`
|
|
81
|
+
* machinery that exploded section-heading textboxes into body
|
|
82
|
+
* paragraphs with synthetic `framePictures` / `liftedFromTextBox`
|
|
83
|
+
* metadata. See `packages/core/docs/INLINE_FRAME_DESIGN.md`.
|
|
84
|
+
*/
|
|
85
|
+
inlineFrames?: InlineFrame[];
|
|
86
|
+
/**
|
|
87
|
+
* Floating objects (`<w:drawing>/<wp:anchor>`, `<w:pict>` VML) that
|
|
88
|
+
* live in their own layer above the body. Each frame carries its
|
|
89
|
+
* own coordinates + dimensions in EMU and is independent of
|
|
90
|
+
* pagination — the paginator only sees `body` blocks. The renderer
|
|
91
|
+
* places each frame on the page its anchor resolves to and paints
|
|
92
|
+
* it into a per-page `<div class="paper-anchors">` overlay.
|
|
93
|
+
*
|
|
94
|
+
* Replaces the pre-AnchoredFrame "lifter" architecture where the
|
|
95
|
+
* importer exploded each `<w:txbxContent>` into N body paragraphs
|
|
96
|
+
* with synthetic `liftedFromTextBox` metadata. The flat list here
|
|
97
|
+
* is simpler, makes selection / resize / move trivial (each frame
|
|
98
|
+
* is one DOM element), and frees the paginator from having to
|
|
99
|
+
* route around absolute-positioned ghosts.
|
|
100
|
+
*/
|
|
101
|
+
anchoredFrames?: AnchoredFrame[];
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* A floating object pinned to a page or paragraph at an explicit
|
|
105
|
+
* coordinate. Sources: `<w:drawing>/<wp:anchor>` shapes,
|
|
106
|
+
* `<w:pict>` VML boxes.
|
|
107
|
+
*
|
|
108
|
+
* Coordinates use OOXML's EMU (914400 EMU = 1 inch). The renderer
|
|
109
|
+
* converts to CSS millimetres at paint time.
|
|
110
|
+
*/
|
|
111
|
+
export interface AnchoredFrame {
|
|
112
|
+
/** Stable id, deterministic from document import order. */
|
|
113
|
+
id: string;
|
|
114
|
+
/** What the offsets are measured from. */
|
|
115
|
+
anchor: AnchorOrigin;
|
|
116
|
+
offsetXEmu: number;
|
|
117
|
+
offsetYEmu: number;
|
|
118
|
+
widthEmu: number;
|
|
119
|
+
heightEmu: number;
|
|
120
|
+
/** Stacking order. Higher = on top. Default 0. */
|
|
121
|
+
zIndex?: number;
|
|
122
|
+
/** When true the frame paints BEHIND body text (z-index negative).
|
|
123
|
+
* Maps to OOXML `<wp:anchor behindDoc="1">`. */
|
|
124
|
+
behindText?: boolean;
|
|
125
|
+
/** Text-wrap mode from the `<wp:wrap*>` child of `<wp:anchor>`.
|
|
126
|
+
* Decides whether the frame DISPLACES body flow: `square` /
|
|
127
|
+
* `topAndBottom` / `tight` / `through` reserve vertical space (the
|
|
128
|
+
* paginator treats the anchor paragraph as that tall), while `none`
|
|
129
|
+
* floats over text and reserves nothing. Absent ⇒ unknown (treated
|
|
130
|
+
* as non-displacing). */
|
|
131
|
+
wrap?: "square" | "topAndBottom" | "tight" | "through" | "none";
|
|
132
|
+
/** What this frame contains. */
|
|
133
|
+
content: AnchoredContent;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Where an anchored frame is positioned and which page receives it.
|
|
137
|
+
*
|
|
138
|
+
* - `sectionIndex` decides which section's pages are candidates.
|
|
139
|
+
* - `paragraphIndex` (optional) ties the frame to a specific body
|
|
140
|
+
* paragraph — useful when `verticalFrom: "paragraph"` so the
|
|
141
|
+
* frame floats to whichever page the paragraph paginates onto.
|
|
142
|
+
* When absent, the frame is page-relative (lands on the first
|
|
143
|
+
* page of its section).
|
|
144
|
+
* - `horizontalFrom` / `verticalFrom` mirror OOXML's
|
|
145
|
+
* `relativeFromH` / `relativeFromV` enums.
|
|
146
|
+
*/
|
|
147
|
+
export interface AnchorOrigin {
|
|
148
|
+
sectionIndex: number;
|
|
149
|
+
paragraphIndex?: number;
|
|
150
|
+
horizontalFrom: "page" | "margin" | "column";
|
|
151
|
+
verticalFrom: "page" | "margin" | "paragraph";
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* What an AnchoredFrame contains. Closed union — adding a new variant
|
|
155
|
+
* requires both importer and renderer support.
|
|
156
|
+
*
|
|
157
|
+
* - "picture" — a single image from `rawParts`. The frame's
|
|
158
|
+
* widthEmu / heightEmu give the display size; the picture
|
|
159
|
+
* stretches to fill (matches Word's default sizing behaviour).
|
|
160
|
+
*
|
|
161
|
+
* - "textbox" — rich body content. Renders recursively via
|
|
162
|
+
* `renderBlocks` inside the frame, with `overflow: hidden` so
|
|
163
|
+
* text that exceeds the frame's height clips (Word behaviour).
|
|
164
|
+
* Optional fill / border / padding paint the textbox chrome.
|
|
165
|
+
*
|
|
166
|
+
* - "shape" — a vector primitive (filled rectangle, ellipse,
|
|
167
|
+
* rounded-rect). No text. Used for decorative backgrounds and
|
|
168
|
+
* dividers (dotted lines, banner rectangles).
|
|
169
|
+
*
|
|
170
|
+
* - "group" — wraps other frames at NESTED coordinates. The
|
|
171
|
+
* children's offsets are interpreted in the group's local
|
|
172
|
+
* coordinate system, scaled to fill `widthEmu × heightEmu`.
|
|
173
|
+
* Maps to OOXML `<wpg:wgp>`. This is how a single project
|
|
174
|
+
* heading carries its rounded-rect frame + atom icon + arrow
|
|
175
|
+
* stripe as ONE selectable unit.
|
|
176
|
+
*/
|
|
177
|
+
export type AnchoredContent = {
|
|
178
|
+
kind: "picture";
|
|
179
|
+
partPath: string;
|
|
180
|
+
altText?: string;
|
|
181
|
+
} | {
|
|
182
|
+
kind: "textbox";
|
|
183
|
+
body: Block[];
|
|
184
|
+
fill?: string;
|
|
185
|
+
border?: {
|
|
186
|
+
color: string;
|
|
187
|
+
widthEmu: number;
|
|
188
|
+
style: "solid" | "dashed" | "dotted" | "double";
|
|
189
|
+
};
|
|
190
|
+
padding?: {
|
|
191
|
+
topEmu: number;
|
|
192
|
+
rightEmu: number;
|
|
193
|
+
bottomEmu: number;
|
|
194
|
+
leftEmu: number;
|
|
195
|
+
};
|
|
196
|
+
} | {
|
|
197
|
+
kind: "shape";
|
|
198
|
+
geometry: "rect" | "ellipse" | "roundedRect" | "line";
|
|
199
|
+
fill?: string;
|
|
200
|
+
border?: {
|
|
201
|
+
color: string;
|
|
202
|
+
widthEmu: number;
|
|
203
|
+
style: "solid" | "dashed" | "dotted" | "double";
|
|
204
|
+
};
|
|
205
|
+
} | {
|
|
206
|
+
kind: "group";
|
|
207
|
+
children: AnchoredFrame[];
|
|
208
|
+
/** Local coordinate system extent — children's offsets are
|
|
209
|
+
* scaled `(width / childCoordSystemCx) × (height / childCoordSystemCy)`
|
|
210
|
+
* to fit the group's actual rendered size. */
|
|
211
|
+
childCoordSystemCx: number;
|
|
212
|
+
childCoordSystemCy: number;
|
|
213
|
+
};
|
|
214
|
+
export interface Comment {
|
|
215
|
+
id: number;
|
|
216
|
+
author?: string;
|
|
217
|
+
/** Author initials as recorded in the docx — Word uses them in the
|
|
218
|
+
* comment sidebar header. */
|
|
219
|
+
initials?: string;
|
|
220
|
+
/** ISO-8601 date string. */
|
|
221
|
+
date?: string;
|
|
222
|
+
/** Comment body — typically one or more paragraphs. */
|
|
223
|
+
body: Block[];
|
|
224
|
+
/**
|
|
225
|
+
* Resolved / "Done" flag from `word/commentsExtended.xml`
|
|
226
|
+
* (`<w15:commentEx w15:done="1">`). Absent or false → open.
|
|
227
|
+
*/
|
|
228
|
+
done?: boolean;
|
|
229
|
+
/**
|
|
230
|
+
* Id of the parent comment when this is a reply in a thread.
|
|
231
|
+
* Resolved from `<w15:commentEx w15:paraIdParent="…">` by matching
|
|
232
|
+
* the parent's body-paragraph paraId back to its comment id.
|
|
233
|
+
* Absent → top-level comment.
|
|
234
|
+
*/
|
|
235
|
+
replyToId?: number;
|
|
236
|
+
}
|
|
237
|
+
export type { FontDeclaration, FontEmbedRef } from '../fonts/types';
|
|
238
|
+
type FontDeclaration = _FontDeclaration;
|
|
239
|
+
export type Block = Paragraph | Table | SectionBreak | InlineFrame;
|
|
240
|
+
export interface Paragraph {
|
|
241
|
+
kind: "paragraph";
|
|
242
|
+
properties: ParagraphProperties;
|
|
243
|
+
/** Inline runs in document order. May be empty (a blank paragraph). */
|
|
244
|
+
runs: InlineRun[];
|
|
245
|
+
}
|
|
246
|
+
/** Explicit page-break or section-break marker emitted between paragraphs. */
|
|
247
|
+
export interface SectionBreak {
|
|
248
|
+
kind: "section_break";
|
|
249
|
+
/** Which section in `SobreeDocument.sections` continues after this point. */
|
|
250
|
+
toSectionIndex: number;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* A rectangular drawing region that flows inline with body blocks
|
|
254
|
+
* (NOT absolutely positioned — that's `AnchoredFrame`). Owns its own
|
|
255
|
+
* picture decoration(s), its own textbox body (recursive `Block[]`),
|
|
256
|
+
* and its own break / keep-with-next directives. Maps 1:1 to
|
|
257
|
+
* `<w:drawing><wp:inline>` with a `<wpg:wgp>` payload that wraps a
|
|
258
|
+
* `<wps:txbx>` textbox shape + decorative `<pic:pic>` / `<wps:wsp>`
|
|
259
|
+
* siblings.
|
|
260
|
+
*
|
|
261
|
+
* Replaces the legacy lifter's "split into N body paragraphs with
|
|
262
|
+
* `liftedFromTextBox` + `framePictures` + `textboxShape` glued on"
|
|
263
|
+
* approach. One frame = one block. The page-break directive that
|
|
264
|
+
* belonged to the containing paragraph in the source OOXML moves
|
|
265
|
+
* here (`pageBreakBefore`), where the paginator's top-level-child
|
|
266
|
+
* inspection actually finds it.
|
|
267
|
+
*
|
|
268
|
+
* See `packages/core/docs/INLINE_FRAME_DESIGN.md` for the full
|
|
269
|
+
* design and migration plan.
|
|
270
|
+
*
|
|
271
|
+
* **Status**: type declared (Phase 1.0). Importer does not yet emit
|
|
272
|
+
* this; renderer treats it as a no-op. Wiring lands in Phase 1.1-1.2.
|
|
273
|
+
*/
|
|
274
|
+
export interface InlineFrame {
|
|
275
|
+
kind: "inline_frame";
|
|
276
|
+
/** From the containing `<w:p>`'s `<w:pPr>`. The paginator emits a
|
|
277
|
+
* `Penalty(-Infinity)` before the frame when set. */
|
|
278
|
+
pageBreakBefore?: boolean;
|
|
279
|
+
/** From the containing `<w:p>`'s `<w:pPr>`. Keep with the next
|
|
280
|
+
* block to avoid widowing a section heading from its body. */
|
|
281
|
+
keepNext?: boolean;
|
|
282
|
+
/** The containing `<w:p>`'s resolved paragraph properties. An inline
|
|
283
|
+
* drawing lives inside a host paragraph; that paragraph carries
|
|
284
|
+
* spacing (before/after), alignment, etc. from its style cascade
|
|
285
|
+
* (commonly `Normal`'s `<w:spacing w:after>`). The renderer applies
|
|
286
|
+
* these to the frame wrapper so the band reserves the SAME vertical
|
|
287
|
+
* box (drawing height + paragraph spacing) Word does — without it
|
|
288
|
+
* the band is short by the spacing-after, which compounds down the
|
|
289
|
+
* page and shifts pagination. Absent → wrapper uses bare defaults. */
|
|
290
|
+
hostProps?: ParagraphProperties;
|
|
291
|
+
/** The drawing group's intrinsic coordinate-system extent. Every
|
|
292
|
+
* child's `offsetEmu` / `sizeEmu` below is expressed in this
|
|
293
|
+
* space; the renderer scales them by `sizeEmu / groupExtentEmu`
|
|
294
|
+
* when painting at the final rendered size. */
|
|
295
|
+
groupExtentEmu: {
|
|
296
|
+
wEmu: number;
|
|
297
|
+
hEmu: number;
|
|
298
|
+
};
|
|
299
|
+
/** The frame's rendered display dimensions. Usually equal to
|
|
300
|
+
* `groupExtentEmu` for inline drawings (no scaling) but kept
|
|
301
|
+
* separate so a future "render at half-size" / scaling case
|
|
302
|
+
* doesn't require touching every child. */
|
|
303
|
+
sizeEmu: {
|
|
304
|
+
wEmu: number;
|
|
305
|
+
hEmu: number;
|
|
306
|
+
};
|
|
307
|
+
/** The textbox SHAPE's intra-group position + size + body. The
|
|
308
|
+
* renderer places `body` at the EXACT coordinates the author
|
|
309
|
+
* intended. Optional because some drawings have only pictures /
|
|
310
|
+
* shapes (no textbox content). */
|
|
311
|
+
textbox?: {
|
|
312
|
+
offsetEmu: {
|
|
313
|
+
xEmu: number;
|
|
314
|
+
yEmu: number;
|
|
315
|
+
};
|
|
316
|
+
sizeEmu: {
|
|
317
|
+
wEmu: number;
|
|
318
|
+
hEmu: number;
|
|
319
|
+
};
|
|
320
|
+
body: Block[];
|
|
321
|
+
fill?: string;
|
|
322
|
+
border?: FrameBorder;
|
|
323
|
+
/** `<wps:bodyPr>` text insets (lIns/tIns/rIns/bIns). The renderer
|
|
324
|
+
* paints these as the region's CSS padding. */
|
|
325
|
+
padding?: {
|
|
326
|
+
topEmu: number;
|
|
327
|
+
rightEmu: number;
|
|
328
|
+
bottomEmu: number;
|
|
329
|
+
leftEmu: number;
|
|
330
|
+
};
|
|
331
|
+
/** Vertical text anchor from `<wps:bodyPr anchor>`. Word centers a
|
|
332
|
+
* single heading line by sizing a short textbox and centering its
|
|
333
|
+
* text; this carries that intent into the renderer's flex column.
|
|
334
|
+
* Defaults to "top" when the attribute is absent. */
|
|
335
|
+
vAlign?: "top" | "center" | "bottom";
|
|
336
|
+
};
|
|
337
|
+
/** Decorative pictures inside the group. Each carries its own
|
|
338
|
+
* intra-group position. The renderer paints them as
|
|
339
|
+
* absolute-positioned `<img>` children of the frame wrapper,
|
|
340
|
+
* scaled by the same `sizeEmu / groupExtentEmu` ratio. */
|
|
341
|
+
pictures: ReadonlyArray<{
|
|
342
|
+
partPath: string;
|
|
343
|
+
offsetEmu: {
|
|
344
|
+
xEmu: number;
|
|
345
|
+
yEmu: number;
|
|
346
|
+
};
|
|
347
|
+
sizeEmu: {
|
|
348
|
+
wEmu: number;
|
|
349
|
+
hEmu: number;
|
|
350
|
+
};
|
|
351
|
+
altText?: string;
|
|
352
|
+
}>;
|
|
353
|
+
/** Non-picture decorative shapes (rect / ellipse / line) inside
|
|
354
|
+
* the group. Same positioning model as `pictures`. */
|
|
355
|
+
shapes: ReadonlyArray<{
|
|
356
|
+
geometry: "rect" | "ellipse" | "roundedRect" | "line";
|
|
357
|
+
offsetEmu: {
|
|
358
|
+
xEmu: number;
|
|
359
|
+
yEmu: number;
|
|
360
|
+
};
|
|
361
|
+
sizeEmu: {
|
|
362
|
+
wEmu: number;
|
|
363
|
+
hEmu: number;
|
|
364
|
+
};
|
|
365
|
+
fill?: string;
|
|
366
|
+
border?: FrameBorder;
|
|
367
|
+
}>;
|
|
368
|
+
}
|
|
369
|
+
/** Shared border descriptor for inline / anchored frame chrome.
|
|
370
|
+
* Distinct from `BorderSpec` (used for paragraph / table borders
|
|
371
|
+
* whose OOXML `w:val` covers a different vocabulary). */
|
|
372
|
+
export interface FrameBorder {
|
|
373
|
+
color: string;
|
|
374
|
+
widthEmu: number;
|
|
375
|
+
style: "solid" | "dashed" | "dotted" | "double";
|
|
376
|
+
}
|
|
377
|
+
export type InlineRun = TextRun | BreakRun | TabRun | FieldRun | DrawingRun | HyperlinkRun | FootnoteRefRun | CommentRefRun;
|
|
378
|
+
export interface TextRun {
|
|
379
|
+
kind: "text";
|
|
380
|
+
text: string;
|
|
381
|
+
properties: RunProperties;
|
|
382
|
+
}
|
|
383
|
+
export interface BreakRun {
|
|
384
|
+
kind: "break";
|
|
385
|
+
/**
|
|
386
|
+
* `line` — soft line break inside a paragraph (Shift-Enter).
|
|
387
|
+
* `page` — explicit page break.
|
|
388
|
+
* `column` — column break in a multi-column section.
|
|
389
|
+
*/
|
|
390
|
+
type: "line" | "page" | "column";
|
|
391
|
+
properties?: RunProperties;
|
|
392
|
+
}
|
|
393
|
+
export interface TabRun {
|
|
394
|
+
kind: "tab";
|
|
395
|
+
properties?: RunProperties;
|
|
396
|
+
}
|
|
397
|
+
export interface FieldRun {
|
|
398
|
+
kind: "field";
|
|
399
|
+
/** Field instruction text — `PAGE`, `NUMPAGES`, `DATE`, `AUTHOR`, … */
|
|
400
|
+
instruction: string;
|
|
401
|
+
/**
|
|
402
|
+
* Cached value displayed if a viewer doesn't recalculate. Used as the
|
|
403
|
+
* preview text by Sobree's renderer.
|
|
404
|
+
*/
|
|
405
|
+
cached?: string;
|
|
406
|
+
properties?: RunProperties;
|
|
407
|
+
}
|
|
408
|
+
/**
|
|
409
|
+
* Inline reference to a comment (`<w:commentReference w:id="N"/>`).
|
|
410
|
+
* Word renders a small balloon icon at the position; we mirror with
|
|
411
|
+
* a clickable inline span linking to the comment card in the aside.
|
|
412
|
+
*/
|
|
413
|
+
export interface CommentRefRun {
|
|
414
|
+
kind: "commentRef";
|
|
415
|
+
/** ID matching a key in `SobreeDocument.comments`. */
|
|
416
|
+
id: number;
|
|
417
|
+
properties?: RunProperties;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Inline reference to a footnote (`<w:footnoteReference w:id="N"/>`).
|
|
421
|
+
* Renders as a clickable superscript number; the referenced footnote's
|
|
422
|
+
* body lives in `SobreeDocument.footnotes[id]` and is rendered at the
|
|
423
|
+
* end of the document. (True per-page pinning is a paginator feature
|
|
424
|
+
* deferred for now.)
|
|
425
|
+
*/
|
|
426
|
+
export interface FootnoteRefRun {
|
|
427
|
+
kind: "footnoteRef";
|
|
428
|
+
/** ID matching a key in `SobreeDocument.footnotes`. */
|
|
429
|
+
id: number;
|
|
430
|
+
properties?: RunProperties;
|
|
431
|
+
}
|
|
432
|
+
export interface DrawingRun {
|
|
433
|
+
kind: "drawing";
|
|
434
|
+
/** Path of the embedded media part in `rawParts` (e.g. `word/media/image1.png`). */
|
|
435
|
+
partPath: string;
|
|
436
|
+
/** Rendered size. */
|
|
437
|
+
widthEmu: number;
|
|
438
|
+
heightEmu: number;
|
|
439
|
+
/** Accessibility text. */
|
|
440
|
+
altText?: string;
|
|
441
|
+
/**
|
|
442
|
+
* Where the image lays out:
|
|
443
|
+
* - "inline" — flows in the paragraph like a tall character.
|
|
444
|
+
* - "anchor" — positioned absolutely (`<wp:anchor>`); `anchor`
|
|
445
|
+
* carries the offset + frame-of-reference.
|
|
446
|
+
*/
|
|
447
|
+
placement: "inline" | "anchor";
|
|
448
|
+
/** Set when `placement === "anchor"`. */
|
|
449
|
+
anchor?: DrawingAnchor;
|
|
450
|
+
/**
|
|
451
|
+
* Vertical alignment for an `inline` image relative to the text on
|
|
452
|
+
* its line. Defaults to the browser baseline (image bottom on the
|
|
453
|
+
* text baseline). `"middle"` centres the image on the text — used
|
|
454
|
+
* for a heading decoration (the flowed ► project arrow) that is
|
|
455
|
+
* taller than its label, so the label centres beside it as Word
|
|
456
|
+
* renders it. Omitted for ordinary inline images.
|
|
457
|
+
*/
|
|
458
|
+
verticalAlign?: "baseline" | "middle";
|
|
459
|
+
}
|
|
460
|
+
export interface DrawingAnchor {
|
|
461
|
+
/** Horizontal offset in EMU (English Metric Units; 914400 EMU = 1 inch). */
|
|
462
|
+
offsetXEmu: number;
|
|
463
|
+
/** Vertical offset in EMU. */
|
|
464
|
+
offsetYEmu: number;
|
|
465
|
+
/** What `offsetXEmu` is measured from. */
|
|
466
|
+
relativeFromH: "page" | "margin" | "column" | "character";
|
|
467
|
+
/** What `offsetYEmu` is measured from. */
|
|
468
|
+
relativeFromV: "page" | "margin" | "paragraph" | "line";
|
|
469
|
+
/** True when the image renders *behind* text (z-index negative). */
|
|
470
|
+
behindDoc?: boolean;
|
|
471
|
+
}
|
|
472
|
+
export interface HyperlinkRun {
|
|
473
|
+
kind: "hyperlink";
|
|
474
|
+
/** Either an external URL or an internal anchor id. */
|
|
475
|
+
href: string;
|
|
476
|
+
/** Display text — itself a list of runs to allow nested formatting. */
|
|
477
|
+
children: InlineRun[];
|
|
478
|
+
properties?: RunProperties;
|
|
479
|
+
}
|
|
480
|
+
export interface RunProperties {
|
|
481
|
+
/** Reference to a `NamedStyle.id` of type "character". */
|
|
482
|
+
styleId?: string;
|
|
483
|
+
bold?: boolean;
|
|
484
|
+
italic?: boolean;
|
|
485
|
+
/** Underline style — most callers want `"single"`. */
|
|
486
|
+
underline?: "single" | "double" | "dotted" | "dashed" | "wave" | "none";
|
|
487
|
+
strike?: boolean;
|
|
488
|
+
doubleStrike?: boolean;
|
|
489
|
+
/** `#rrggbb`. */
|
|
490
|
+
color?: string;
|
|
491
|
+
/** Word highlight name (`yellow`, `green`, …) or `#rrggbb`. */
|
|
492
|
+
highlight?: string;
|
|
493
|
+
/** Cell-style shading (`<w:shd w:fill="…">`). */
|
|
494
|
+
shading?: Shading;
|
|
495
|
+
/** Font family name (Calibri, Georgia, …). */
|
|
496
|
+
fontFamily?: string;
|
|
497
|
+
/** Size in points (Word stores half-points; we expose pt for ergonomics). */
|
|
498
|
+
fontSizePt?: number;
|
|
499
|
+
verticalAlign?: "subscript" | "superscript";
|
|
500
|
+
/** Whether the text is uppercase / small caps. */
|
|
501
|
+
caps?: boolean;
|
|
502
|
+
smallCaps?: boolean;
|
|
503
|
+
/** Hidden text (`<w:vanish/>`). */
|
|
504
|
+
hidden?: boolean;
|
|
505
|
+
/**
|
|
506
|
+
* Tracked-change marker — set when the run is inside a `<w:ins>`
|
|
507
|
+
* (insertion) or `<w:del>` (deletion) wrapper. The renderer
|
|
508
|
+
* applies a visual revision style; the underlying text is preserved
|
|
509
|
+
* either way so the document round-trips faithfully.
|
|
510
|
+
*/
|
|
511
|
+
revision?: RevisionMark;
|
|
512
|
+
/**
|
|
513
|
+
* Comment ids whose `<w:commentRangeStart>` … `<w:commentRangeEnd>`
|
|
514
|
+
* span includes this run. The renderer highlights ranges with any
|
|
515
|
+
* active comment. Multiple ids let nested/overlapping comments
|
|
516
|
+
* coexist on the same run.
|
|
517
|
+
*/
|
|
518
|
+
commentIds?: readonly number[];
|
|
519
|
+
/**
|
|
520
|
+
* Tracked **format change** — a snapshot of this run's properties
|
|
521
|
+
* *before* the most recent tracked formatting edit. Word stores this
|
|
522
|
+
* as `<w:rPrChange>` (ECMA-376 §17.13.5.32).
|
|
523
|
+
*
|
|
524
|
+
* Accepting the format revision drops `revisionFormat` (the current
|
|
525
|
+
* `properties` stays). Rejecting it restores `properties` *to* the
|
|
526
|
+
* `before` snapshot. Repeated tracked format edits don't overwrite
|
|
527
|
+
* the snapshot — the *original* properties stay captured, so a
|
|
528
|
+
* reject always returns the run to its pre-tracking state.
|
|
529
|
+
*
|
|
530
|
+
* `before` is itself a `RunProperties` but `revisionFormat` doesn't
|
|
531
|
+
* recurse (the snapshot is "what the run looked like before we
|
|
532
|
+
* started tracking format changes").
|
|
533
|
+
*/
|
|
534
|
+
revisionFormat?: {
|
|
535
|
+
before: RunProperties;
|
|
536
|
+
author?: string;
|
|
537
|
+
date?: string;
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
export interface RevisionMark {
|
|
541
|
+
/** `ins` = insertion, `del` = deletion. */
|
|
542
|
+
type: "ins" | "del";
|
|
543
|
+
/** Author name as recorded in the docx (`<w:ins w:author="...">`). */
|
|
544
|
+
author?: string;
|
|
545
|
+
/** ISO-8601 timestamp string from the docx. */
|
|
546
|
+
date?: string;
|
|
547
|
+
}
|
|
548
|
+
export interface ParagraphProperties {
|
|
549
|
+
/** Reference to a `NamedStyle.id` of type "paragraph". */
|
|
550
|
+
styleId?: string;
|
|
551
|
+
alignment?: ParagraphAlignment;
|
|
552
|
+
/** Numbered/bulleted list reference. */
|
|
553
|
+
numbering?: {
|
|
554
|
+
numId: number;
|
|
555
|
+
level: number;
|
|
556
|
+
};
|
|
557
|
+
spacing?: ParagraphSpacing;
|
|
558
|
+
indent?: ParagraphIndent;
|
|
559
|
+
borders?: ParagraphBorders;
|
|
560
|
+
shading?: Shading;
|
|
561
|
+
/** Keep this paragraph on the same page as the next one. */
|
|
562
|
+
keepNext?: boolean;
|
|
563
|
+
/** Don't allow this paragraph to break across pages. */
|
|
564
|
+
keepLines?: boolean;
|
|
565
|
+
/** Insert a page break before this paragraph. */
|
|
566
|
+
pageBreakBefore?: boolean;
|
|
567
|
+
/** Custom tab stops from `<w:pPr><w:tabs>`, positions in twips. The
|
|
568
|
+
* renderer uses the smallest stop's position to compute a CSS
|
|
569
|
+
* `tab-size` on the paragraph so `\t` characters in the text honour
|
|
570
|
+
* the document's tab geometry instead of the browser's 8-char
|
|
571
|
+
* default. Mixed alignments (right / decimal / leader) collapse to
|
|
572
|
+
* "left" for now — covering the common case (label-value columns
|
|
573
|
+
* in headers + form fields). */
|
|
574
|
+
tabStops?: readonly {
|
|
575
|
+
positionTwips: number;
|
|
576
|
+
alignment: string;
|
|
577
|
+
leader?: string;
|
|
578
|
+
}[];
|
|
579
|
+
/** Default run properties applied to runs that don't override. */
|
|
580
|
+
runDefaults?: RunProperties;
|
|
581
|
+
/**
|
|
582
|
+
* Tracked-change marker on the paragraph mark itself. Semantically:
|
|
583
|
+
* the *paragraph break that precedes this paragraph* is a tracked
|
|
584
|
+
* change. Word stores this as `<w:rPr><w:ins/></w:rPr>` inside
|
|
585
|
+
* `<w:pPr>` — see ECMA-376 §17.13.5.7.
|
|
586
|
+
*
|
|
587
|
+
* `ins` — pressing Enter created this paragraph (split the prior
|
|
588
|
+
* paragraph). Accepting keeps the split; rejecting merges
|
|
589
|
+
* the paragraph back into the previous one.
|
|
590
|
+
* `del` — the user has marked this paragraph break for deletion
|
|
591
|
+
* (e.g. Backspace at the start of this paragraph in
|
|
592
|
+
* tracked mode). Accepting merges into the previous;
|
|
593
|
+
* rejecting keeps the split.
|
|
594
|
+
*
|
|
595
|
+
* Accept/reject of this paragraph-level marker is tracked under
|
|
596
|
+
* follow-up task 26 (block-level revisions); v1 only adds the
|
|
597
|
+
* authoring path (via `Editor.splitBlock` in track-changes mode).
|
|
598
|
+
*/
|
|
599
|
+
revision?: RevisionMark;
|
|
600
|
+
}
|
|
601
|
+
export type ParagraphAlignment = "left" | "center" | "right" | "both" | "distribute";
|
|
602
|
+
export interface ParagraphSpacing {
|
|
603
|
+
/** Twips before the paragraph. */
|
|
604
|
+
beforeTwips?: number;
|
|
605
|
+
/** Twips after the paragraph. */
|
|
606
|
+
afterTwips?: number;
|
|
607
|
+
/** Twips between lines (when `lineRule === "exact" | "atLeast"`) or
|
|
608
|
+
* 240ths of a multiplier (when `lineRule === "auto"`). */
|
|
609
|
+
line?: number;
|
|
610
|
+
lineRule?: "auto" | "exact" | "atLeast";
|
|
611
|
+
}
|
|
612
|
+
export interface ParagraphIndent {
|
|
613
|
+
leftTwips?: number;
|
|
614
|
+
rightTwips?: number;
|
|
615
|
+
/** Indent of the first line of the paragraph (positive = indent in). */
|
|
616
|
+
firstLineTwips?: number;
|
|
617
|
+
/** Hanging indent (offsets first line OUT of the rest of the para). */
|
|
618
|
+
hangingTwips?: number;
|
|
619
|
+
}
|
|
620
|
+
export interface ParagraphBorders {
|
|
621
|
+
top?: BorderSpec;
|
|
622
|
+
right?: BorderSpec;
|
|
623
|
+
bottom?: BorderSpec;
|
|
624
|
+
left?: BorderSpec;
|
|
625
|
+
between?: BorderSpec;
|
|
626
|
+
}
|
|
627
|
+
export interface BorderSpec {
|
|
628
|
+
style: "single" | "double" | "dashed" | "dotted" | "thick" | "none";
|
|
629
|
+
/** Eighths of a point (Word's `w:sz`). */
|
|
630
|
+
sizeEighthsOfPt: number;
|
|
631
|
+
/** `#rrggbb` or `auto`. */
|
|
632
|
+
color: string;
|
|
633
|
+
/** Twips of clear space between border and text. */
|
|
634
|
+
spaceTwips?: number;
|
|
635
|
+
}
|
|
636
|
+
export interface Shading {
|
|
637
|
+
/** Pattern (`clear`, `pct10`, `solid`, …). Most highlights are `clear`. */
|
|
638
|
+
pattern: string;
|
|
639
|
+
/** Background `#rrggbb` or `auto`. */
|
|
640
|
+
fill: string;
|
|
641
|
+
/** Pattern foreground `#rrggbb` or `auto`. */
|
|
642
|
+
color?: string;
|
|
643
|
+
}
|
|
644
|
+
export interface Table {
|
|
645
|
+
kind: "table";
|
|
646
|
+
/** Column widths in twips. Length = number of columns. */
|
|
647
|
+
grid: number[];
|
|
648
|
+
rows: TableRow[];
|
|
649
|
+
properties: TableProperties;
|
|
650
|
+
}
|
|
651
|
+
export interface TableProperties {
|
|
652
|
+
/** Total table width in twips, or "auto" for content-driven. */
|
|
653
|
+
widthTwips?: number;
|
|
654
|
+
alignment?: ParagraphAlignment;
|
|
655
|
+
borders?: TableBorders;
|
|
656
|
+
/** Style reference (e.g. "TableGrid"). */
|
|
657
|
+
styleId?: string;
|
|
658
|
+
}
|
|
659
|
+
export interface TableBorders {
|
|
660
|
+
top?: BorderSpec;
|
|
661
|
+
right?: BorderSpec;
|
|
662
|
+
bottom?: BorderSpec;
|
|
663
|
+
left?: BorderSpec;
|
|
664
|
+
insideH?: BorderSpec;
|
|
665
|
+
insideV?: BorderSpec;
|
|
666
|
+
}
|
|
667
|
+
export interface TableRow {
|
|
668
|
+
cells: TableCell[];
|
|
669
|
+
/** True if this row is a header row repeated on each page. */
|
|
670
|
+
isHeader?: boolean;
|
|
671
|
+
}
|
|
672
|
+
export interface TableCell {
|
|
673
|
+
/** Number of grid columns this cell spans horizontally. */
|
|
674
|
+
gridSpan?: number;
|
|
675
|
+
/** Vertical merge state — `restart` begins a merge, `continue` continues. */
|
|
676
|
+
vMerge?: "restart" | "continue";
|
|
677
|
+
verticalAlign?: "top" | "center" | "bottom";
|
|
678
|
+
shading?: Shading;
|
|
679
|
+
borders?: TableCellBorders;
|
|
680
|
+
/** Cell content — paragraphs and (rare) nested tables. */
|
|
681
|
+
content: Block[];
|
|
682
|
+
}
|
|
683
|
+
export interface TableCellBorders {
|
|
684
|
+
top?: BorderSpec;
|
|
685
|
+
right?: BorderSpec;
|
|
686
|
+
bottom?: BorderSpec;
|
|
687
|
+
left?: BorderSpec;
|
|
688
|
+
}
|
|
689
|
+
export interface SectionProperties {
|
|
690
|
+
pageSize: PageSize;
|
|
691
|
+
pageMargins: PageMargins;
|
|
692
|
+
/** Header references. Most docs have one or two. */
|
|
693
|
+
headerRefs: HeaderFooterRef[];
|
|
694
|
+
footerRefs: HeaderFooterRef[];
|
|
695
|
+
/** Show the first-page header/footer slot if true. */
|
|
696
|
+
titlePage?: boolean;
|
|
697
|
+
/** Continuous, nextPage, etc. */
|
|
698
|
+
type?: "continuous" | "nextPage" | "evenPage" | "oddPage";
|
|
699
|
+
/**
|
|
700
|
+
* Vertical alignment of the body content on each page in this section.
|
|
701
|
+
* OOXML `<w:vAlign>` (ECMA-376 §17.6.21). Only visible on partial pages
|
|
702
|
+
* — full pages have no slack to redistribute. Default is `"top"` (the
|
|
703
|
+
* field is omitted in that case).
|
|
704
|
+
*
|
|
705
|
+
* - `top` — content anchored to top margin (default).
|
|
706
|
+
* - `center` — content centred between top and bottom margin.
|
|
707
|
+
* - `bottom` — content anchored to bottom margin.
|
|
708
|
+
* - `both` — paragraph spacing stretched to fill the page.
|
|
709
|
+
*/
|
|
710
|
+
vAlign?: "top" | "center" | "bottom" | "both";
|
|
711
|
+
/**
|
|
712
|
+
* Multi-column layout for the section's content (`<w:cols>`).
|
|
713
|
+
* Absent or `count <= 1` → single column (the default; the renderer
|
|
714
|
+
* does not wrap in a column container in that case).
|
|
715
|
+
*/
|
|
716
|
+
columns?: SectionColumns;
|
|
717
|
+
}
|
|
718
|
+
export interface SectionColumns {
|
|
719
|
+
/** Number of equal-width columns. */
|
|
720
|
+
count: number;
|
|
721
|
+
/** Inter-column gap in twips (Word's `<w:cols w:space>` attribute). */
|
|
722
|
+
spaceTwips?: number;
|
|
723
|
+
}
|
|
724
|
+
export interface PageSize {
|
|
725
|
+
wTwips: number;
|
|
726
|
+
hTwips: number;
|
|
727
|
+
orientation: "portrait" | "landscape";
|
|
728
|
+
}
|
|
729
|
+
export interface PageMargins {
|
|
730
|
+
topTwips: number;
|
|
731
|
+
rightTwips: number;
|
|
732
|
+
bottomTwips: number;
|
|
733
|
+
leftTwips: number;
|
|
734
|
+
headerTwips: number;
|
|
735
|
+
footerTwips: number;
|
|
736
|
+
gutterTwips: number;
|
|
737
|
+
}
|
|
738
|
+
export interface HeaderFooterRef {
|
|
739
|
+
type: "default" | "first" | "even";
|
|
740
|
+
/** Internal id pointing into `SobreeDocument.rawParts` /
|
|
741
|
+
* `relationships`. We store the header/footer body itself as a
|
|
742
|
+
* `Block[]` keyed in a side table at the SobreeDocument level. */
|
|
743
|
+
partId: string;
|
|
744
|
+
}
|
|
745
|
+
export interface NamedStyle {
|
|
746
|
+
id: string;
|
|
747
|
+
type: "paragraph" | "character" | "table" | "numbering";
|
|
748
|
+
/** Display name shown in Word's style picker. */
|
|
749
|
+
displayName: string;
|
|
750
|
+
/** Inherits from another style id. */
|
|
751
|
+
basedOn?: string;
|
|
752
|
+
/** The style applied to the next paragraph after this one (for headings). */
|
|
753
|
+
nextStyleId?: string;
|
|
754
|
+
/** Default run properties. */
|
|
755
|
+
runDefaults?: RunProperties;
|
|
756
|
+
/** Default paragraph properties. */
|
|
757
|
+
paragraphDefaults?: ParagraphProperties;
|
|
758
|
+
/** Default table properties (only for table styles). */
|
|
759
|
+
tableDefaults?: TableProperties;
|
|
760
|
+
}
|
|
761
|
+
export interface NumberingDefinition {
|
|
762
|
+
/** `numId` referenced from `ParagraphProperties.numbering`. */
|
|
763
|
+
numId: number;
|
|
764
|
+
/** The abstract format definition. */
|
|
765
|
+
abstractFormat: AbstractNumberingFormat;
|
|
766
|
+
}
|
|
767
|
+
export interface AbstractNumberingFormat {
|
|
768
|
+
/** One per indent level (0..8 typically). */
|
|
769
|
+
levels: NumberingLevel[];
|
|
770
|
+
}
|
|
771
|
+
export interface NumberingLevel {
|
|
772
|
+
level: number;
|
|
773
|
+
/** Format: `bullet`, `decimal`, `lowerRoman`, `upperLetter`, … */
|
|
774
|
+
format: string;
|
|
775
|
+
/** Text template, e.g. `%1.` or a literal bullet character. */
|
|
776
|
+
text: string;
|
|
777
|
+
/** Restart numbering after this level. */
|
|
778
|
+
restart?: number;
|
|
779
|
+
/** Indentation of the numbered text. */
|
|
780
|
+
paragraphIndent?: ParagraphIndent;
|
|
781
|
+
/** Run properties for the bullet/number marker itself. */
|
|
782
|
+
runDefaults?: RunProperties;
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Mirror of the `_rels/document.xml.rels` table — Sobree tracks
|
|
786
|
+
* relationships as data so headers, footers, images, hyperlinks all share
|
|
787
|
+
* one allocation strategy at export time.
|
|
788
|
+
*/
|
|
789
|
+
export interface RelationshipManifest {
|
|
790
|
+
/** Map of `rId…` → relationship descriptor. */
|
|
791
|
+
byId: Record<string, Relationship>;
|
|
792
|
+
}
|
|
793
|
+
export interface Relationship {
|
|
794
|
+
id: string;
|
|
795
|
+
type: RelationshipType;
|
|
796
|
+
target: string;
|
|
797
|
+
/** External (true) means `target` is a URL; otherwise a part path. */
|
|
798
|
+
external?: boolean;
|
|
799
|
+
}
|
|
800
|
+
export type RelationshipType = "header" | "footer" | "image" | "hyperlink" | "styles" | "numbering" | "settings" | "fontTable" | "theme" | "comments" | "footnotes" | "endnotes";
|