doc-model.js 2.7.17 → 3.0.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/README.md CHANGED
@@ -48,7 +48,7 @@ graph TD
48
48
  style schema fill:#f9a825,stroke:#333,stroke-width:3px
49
49
  ```
50
50
 
51
- `ContentDocument` (the semantic pivot) is a discriminated union of five kinds: `wordprocessing` (docx/odt sections of paragraphs/runs/tables/images), `presentation` (pptx/odp slides of shapes), `spreadsheet` (xlsx/ods sheets of cells, columns, rows, print settings), `drawing` (odg pages of shapes plus vector primitives — rect/ellipse/line/path), and `formula` (an equation carrying its own MathML node tree plus StarMath source when the producing format had one). `ContentEmbeddedObjectSchema` lets any of the five embed another whole `ContentDocument`. `LayoutDocument` (the PDF-rendering pivot) is pages of positioned `LayoutItem`s (`text`/`image`/`rect`/`line`/`ellipse`/`path`/`link`) in PDF user-space coordinates. `DocumentPackageSchema` pairs the two: `content` required, `layout` optional (derived, absent until something lays content out); the schema does not keep them in sync or detect staleness.
51
+ `ContentDocument` (the semantic pivot) is a discriminated union of five kinds: `wordprocessing` (docx/odt sections of paragraphs/runs/tables/images), `presentation` (pptx/odp slides of shapes), `spreadsheet` (xlsx/ods sheets of cells, columns, rows, print settings), `drawing` (odg pages of shapes plus vector primitives — rect/ellipse/line/path), and `formula` (an equation carrying its own MathML node tree plus StarMath source when the producing format had one). `ContentEmbeddedObjectSchema` lets any of the five embed another whole `ContentDocument`. Every paragraph/run/image/table/shape/vector/spreadsheet-cell leaf also carries its own canonical `headingLevel`-or-position fields directly: a `ContentParagraph`'s optional `headingLevel` (1 = the outermost heading, independent of the round-trip-only `styleId`), and every such leaf's optional `frames: LayoutFrame[]` — that node's own rendered page position(s) (`pageIndex` plus PDF user-space `xPt`/`yPt`/`widthPt`/`heightPt`), fused directly onto the content tree once a layout pass has run. `LayoutDocument` (the PDF-rendering pivot pdf-codec's `readPdf`/`writePdf` operate on directly, independent of any `ContentDocument`) is pages of positioned `LayoutItem`s (`text`/`image`/`rect`/`line`/`ellipse`/`path`/`link`) in PDF user-space coordinates. `DocumentPackageSchema` wraps `content` (required) with `pages` (optional, derived: each rendered page's own size, indexed to match every node's own `frames[].pageIndex`) — a single fused tree rather than a second, independent `LayoutDocument` correlated back to `content` only by matching `sourcePath` strings; the schema does not keep `content`'s populated `frames` fields and `pages` in sync or detect staleness.
52
52
 
53
53
  The package contains only [Zod](https://zod.dev) schemas, their inferred types, trivial schema-attached helpers (hex-colour conversion, recursive structural type guards), and two small structural interfaces (`ContentCodec`/`LayoutCodec`, see [Codecs](#codecs)). No XML, ZIP, PDF, or binary handling; the sole dependency is `zod`.
54
54
 
@@ -60,8 +60,16 @@ Two format-agnostic helpers live here because they operate on the content model
60
60
  import { ContentDocumentSchema, DocumentPackageSchema, LayoutDocumentSchema } from 'document-schema.js';
61
61
 
62
62
  const content = ContentDocumentSchema.parse(someWordprocessingOrPresentationValue);
63
- const layout = LayoutDocumentSchema.parse(somePageLayoutValue);
64
- const pkg = DocumentPackageSchema.parse({ formatVersion: 1, content, layout });
63
+ // A content-only package -- no layout pass has run yet, so no node carries `frames` and `pages` stays absent.
64
+ const pkg = DocumentPackageSchema.parse({ formatVersion: 2, content });
65
+
66
+ // Once a layout pass has fused rendered positions onto content's own nodes (each via its own `frames` array)
67
+ // and reported each page's own size, `pages` is populated to match:
68
+ const laidOut = DocumentPackageSchema.parse({ formatVersion: 2, content: someAlreadyPositionedContent, pages: [{ widthPt: 612, heightPt: 792 }] });
69
+
70
+ // LayoutDocumentSchema is unrelated to DocumentPackageSchema -- it is the standalone PDF-rendering pivot
71
+ // pdf-codec's own readPdf/writePdf read and write directly, with no ContentDocument in the loop at all.
72
+ const layout = LayoutDocumentSchema.parse(somePdfPageLayoutValue);
65
73
  ```
66
74
 
67
75
  Every module is also importable directly — `tsdown` builds one file per source module, and `package.json`'s `"./*"` export makes each individually resolvable:
@@ -138,7 +146,7 @@ export const MathMlNodeSchema: z.ZodType<MathMlNode> = z.discriminatedUnion('typ
138
146
  import { documentPackageWithSchema } from 'document-schema.js';
139
147
 
140
148
  const tagged = documentPackageWithSchema(pkg);
141
- // { $schema: 'https://cdn.jsdelivr.net/npm/document-schema.js@1.6.1/schemas/document-package.schema.json', formatVersion: 1, content: {...}, layout: {...} }
149
+ // { $schema: 'https://cdn.jsdelivr.net/npm/document-schema.js@2.0.0/schemas/document-package.schema.json', formatVersion: 2, content: {...}, pages: [...] }
142
150
  writeFileSync('package.json.doc', JSON.stringify(tagged, null, 2));
143
151
  ```
144
152
 
@@ -59,6 +59,34 @@ const CONTENT_DEFS = {
59
59
  ],
60
60
  additionalProperties: false
61
61
  },
62
+ LayoutFrame: {
63
+ type: "object",
64
+ properties: {
65
+ pageIndex: {
66
+ type: "integer",
67
+ minimum: 0,
68
+ maximum: MAX_SAFE_INTEGER
69
+ },
70
+ xPt: { type: "number" },
71
+ yPt: { type: "number" },
72
+ widthPt: {
73
+ type: "number",
74
+ minimum: 0
75
+ },
76
+ heightPt: {
77
+ type: "number",
78
+ minimum: 0
79
+ }
80
+ },
81
+ required: [
82
+ "pageIndex",
83
+ "xPt",
84
+ "yPt",
85
+ "widthPt",
86
+ "heightPt"
87
+ ],
88
+ additionalProperties: false
89
+ },
62
90
  Alignment: {
63
91
  type: "string",
64
92
  enum: [
@@ -128,7 +156,11 @@ const CONTENT_DEFS = {
128
156
  },
129
157
  color: { $ref: "#/$defs/Color" },
130
158
  hyperlink: { type: "string" },
131
- sourcePath: { type: "string" }
159
+ sourcePath: { type: "string" },
160
+ frames: {
161
+ type: "array",
162
+ items: { $ref: "#/$defs/LayoutFrame" }
163
+ }
132
164
  },
133
165
  required: ["text"],
134
166
  additionalProperties: false
@@ -145,6 +177,11 @@ const CONTENT_DEFS = {
145
177
  items: { $ref: "#/$defs/ContentRun" }
146
178
  },
147
179
  styleId: { type: "string" },
180
+ headingLevel: {
181
+ type: "integer",
182
+ exclusiveMinimum: 0,
183
+ maximum: MAX_SAFE_INTEGER
184
+ },
148
185
  alignment: { $ref: "#/$defs/Alignment" },
149
186
  list: { $ref: "#/$defs/ContentListMembership" },
150
187
  spacingBeforePt: { type: "number" },
@@ -155,7 +192,11 @@ const CONTENT_DEFS = {
155
192
  },
156
193
  indentLeftPt: { type: "number" },
157
194
  indentFirstLinePt: { type: "number" },
158
- sourcePath: { type: "string" }
195
+ sourcePath: { type: "string" },
196
+ frames: {
197
+ type: "array",
198
+ items: { $ref: "#/$defs/LayoutFrame" }
199
+ }
159
200
  },
160
201
  required: ["kind", "runs"],
161
202
  additionalProperties: false
@@ -181,7 +222,11 @@ const CONTENT_DEFS = {
181
222
  exclusiveMinimum: 0
182
223
  },
183
224
  altText: { type: "string" },
184
- sourcePath: { type: "string" }
225
+ sourcePath: { type: "string" },
226
+ frames: {
227
+ type: "array",
228
+ items: { $ref: "#/$defs/LayoutFrame" }
229
+ }
185
230
  },
186
231
  required: [
187
232
  "kind",
@@ -199,7 +244,11 @@ const CONTENT_DEFS = {
199
244
  type: "string",
200
245
  const: "pageBreak"
201
246
  },
202
- sourcePath: { type: "string" }
247
+ sourcePath: { type: "string" },
248
+ frames: {
249
+ type: "array",
250
+ items: { $ref: "#/$defs/LayoutFrame" }
251
+ }
203
252
  },
204
253
  required: ["kind"],
205
254
  additionalProperties: false
@@ -223,7 +272,11 @@ const CONTENT_DEFS = {
223
272
  },
224
273
  background: { $ref: "#/$defs/Color" },
225
274
  borders: { $ref: "#/$defs/ContentCellBorders" },
226
- sourcePath: { type: "string" }
275
+ sourcePath: { type: "string" },
276
+ frames: {
277
+ type: "array",
278
+ items: { $ref: "#/$defs/LayoutFrame" }
279
+ }
227
280
  },
228
281
  required: ["blocks"],
229
282
  additionalProperties: false
@@ -261,7 +314,11 @@ const CONTENT_DEFS = {
261
314
  exclusiveMinimum: 0
262
315
  }
263
316
  },
264
- sourcePath: { type: "string" }
317
+ sourcePath: { type: "string" },
318
+ frames: {
319
+ type: "array",
320
+ items: { $ref: "#/$defs/LayoutFrame" }
321
+ }
265
322
  },
266
323
  required: [
267
324
  "kind",
@@ -284,6 +341,10 @@ const CONTENT_DEFS = {
284
341
  document: { $ref: CONTENT_DOCUMENT_URI },
285
342
  frame: { $ref: "#/$defs/Box" },
286
343
  sourcePath: { type: "string" },
344
+ frames: {
345
+ type: "array",
346
+ items: { $ref: "#/$defs/LayoutFrame" }
347
+ },
287
348
  anchorRow: {
288
349
  type: "integer",
289
350
  minimum: 0,
@@ -58,6 +58,34 @@ const CONTENT_DEFS = {
58
58
  ],
59
59
  additionalProperties: false
60
60
  },
61
+ LayoutFrame: {
62
+ type: "object",
63
+ properties: {
64
+ pageIndex: {
65
+ type: "integer",
66
+ minimum: 0,
67
+ maximum: MAX_SAFE_INTEGER
68
+ },
69
+ xPt: { type: "number" },
70
+ yPt: { type: "number" },
71
+ widthPt: {
72
+ type: "number",
73
+ minimum: 0
74
+ },
75
+ heightPt: {
76
+ type: "number",
77
+ minimum: 0
78
+ }
79
+ },
80
+ required: [
81
+ "pageIndex",
82
+ "xPt",
83
+ "yPt",
84
+ "widthPt",
85
+ "heightPt"
86
+ ],
87
+ additionalProperties: false
88
+ },
61
89
  Alignment: {
62
90
  type: "string",
63
91
  enum: [
@@ -127,7 +155,11 @@ const CONTENT_DEFS = {
127
155
  },
128
156
  color: { $ref: "#/$defs/Color" },
129
157
  hyperlink: { type: "string" },
130
- sourcePath: { type: "string" }
158
+ sourcePath: { type: "string" },
159
+ frames: {
160
+ type: "array",
161
+ items: { $ref: "#/$defs/LayoutFrame" }
162
+ }
131
163
  },
132
164
  required: ["text"],
133
165
  additionalProperties: false
@@ -144,6 +176,11 @@ const CONTENT_DEFS = {
144
176
  items: { $ref: "#/$defs/ContentRun" }
145
177
  },
146
178
  styleId: { type: "string" },
179
+ headingLevel: {
180
+ type: "integer",
181
+ exclusiveMinimum: 0,
182
+ maximum: MAX_SAFE_INTEGER
183
+ },
147
184
  alignment: { $ref: "#/$defs/Alignment" },
148
185
  list: { $ref: "#/$defs/ContentListMembership" },
149
186
  spacingBeforePt: { type: "number" },
@@ -154,7 +191,11 @@ const CONTENT_DEFS = {
154
191
  },
155
192
  indentLeftPt: { type: "number" },
156
193
  indentFirstLinePt: { type: "number" },
157
- sourcePath: { type: "string" }
194
+ sourcePath: { type: "string" },
195
+ frames: {
196
+ type: "array",
197
+ items: { $ref: "#/$defs/LayoutFrame" }
198
+ }
158
199
  },
159
200
  required: ["kind", "runs"],
160
201
  additionalProperties: false
@@ -180,7 +221,11 @@ const CONTENT_DEFS = {
180
221
  exclusiveMinimum: 0
181
222
  },
182
223
  altText: { type: "string" },
183
- sourcePath: { type: "string" }
224
+ sourcePath: { type: "string" },
225
+ frames: {
226
+ type: "array",
227
+ items: { $ref: "#/$defs/LayoutFrame" }
228
+ }
184
229
  },
185
230
  required: [
186
231
  "kind",
@@ -198,7 +243,11 @@ const CONTENT_DEFS = {
198
243
  type: "string",
199
244
  const: "pageBreak"
200
245
  },
201
- sourcePath: { type: "string" }
246
+ sourcePath: { type: "string" },
247
+ frames: {
248
+ type: "array",
249
+ items: { $ref: "#/$defs/LayoutFrame" }
250
+ }
202
251
  },
203
252
  required: ["kind"],
204
253
  additionalProperties: false
@@ -222,7 +271,11 @@ const CONTENT_DEFS = {
222
271
  },
223
272
  background: { $ref: "#/$defs/Color" },
224
273
  borders: { $ref: "#/$defs/ContentCellBorders" },
225
- sourcePath: { type: "string" }
274
+ sourcePath: { type: "string" },
275
+ frames: {
276
+ type: "array",
277
+ items: { $ref: "#/$defs/LayoutFrame" }
278
+ }
226
279
  },
227
280
  required: ["blocks"],
228
281
  additionalProperties: false
@@ -260,7 +313,11 @@ const CONTENT_DEFS = {
260
313
  exclusiveMinimum: 0
261
314
  }
262
315
  },
263
- sourcePath: { type: "string" }
316
+ sourcePath: { type: "string" },
317
+ frames: {
318
+ type: "array",
319
+ items: { $ref: "#/$defs/LayoutFrame" }
320
+ }
264
321
  },
265
322
  required: [
266
323
  "kind",
@@ -283,6 +340,10 @@ const CONTENT_DEFS = {
283
340
  document: { $ref: CONTENT_DOCUMENT_URI },
284
341
  frame: { $ref: "#/$defs/Box" },
285
342
  sourcePath: { type: "string" },
343
+ frames: {
344
+ type: "array",
345
+ items: { $ref: "#/$defs/LayoutFrame" }
346
+ },
286
347
  anchorRow: {
287
348
  type: "integer",
288
349
  minimum: 0,
package/dist/content.cjs CHANGED
@@ -16,7 +16,8 @@ const ContentRunSchema = zod.z.object({
16
16
  sizePt: zod.z.number().positive().optional(),
17
17
  color: require_color.ColorSchema.optional(),
18
18
  hyperlink: zod.z.string().optional(),
19
- sourcePath: zod.z.string().optional()
19
+ sourcePath: zod.z.string().optional(),
20
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional()
20
21
  });
21
22
  const ContentListMembershipSchema = zod.z.object({
22
23
  numId: zod.z.string(),
@@ -26,6 +27,7 @@ const ContentParagraphSchema = zod.z.object({
26
27
  kind: zod.z.literal("paragraph"),
27
28
  runs: zod.z.array(ContentRunSchema),
28
29
  styleId: zod.z.string().optional(),
30
+ headingLevel: zod.z.number().int().positive().optional(),
29
31
  alignment: require_style.AlignmentSchema.optional(),
30
32
  list: ContentListMembershipSchema.optional(),
31
33
  spacingBeforePt: zod.z.number().optional(),
@@ -33,8 +35,12 @@ const ContentParagraphSchema = zod.z.object({
33
35
  lineSpacing: zod.z.number().positive().optional(),
34
36
  indentLeftPt: zod.z.number().optional(),
35
37
  indentFirstLinePt: zod.z.number().optional(),
36
- sourcePath: zod.z.string().optional()
38
+ sourcePath: zod.z.string().optional(),
39
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional()
37
40
  });
41
+ function clampHeadingLevel(level) {
42
+ return Math.min(6, Math.max(1, Math.round(level)));
43
+ }
38
44
  const ContentImageBlockSchema = zod.z.object({
39
45
  kind: zod.z.literal("image"),
40
46
  format: zod.z.enum(["png", "jpeg"]),
@@ -42,11 +48,13 @@ const ContentImageBlockSchema = zod.z.object({
42
48
  widthPt: zod.z.number().positive(),
43
49
  heightPt: zod.z.number().positive(),
44
50
  altText: zod.z.string().optional(),
45
- sourcePath: zod.z.string().optional()
51
+ sourcePath: zod.z.string().optional(),
52
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional()
46
53
  });
47
54
  const ContentPageBreakSchema = zod.z.object({
48
55
  kind: zod.z.literal("pageBreak"),
49
- sourcePath: zod.z.string().optional()
56
+ sourcePath: zod.z.string().optional(),
57
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional()
50
58
  });
51
59
  function isRecord(value) {
52
60
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -105,7 +113,8 @@ const ContentTableCellSchema = zod.z.object({
105
113
  rowSpan: zod.z.number().int().positive().optional(),
106
114
  background: require_color.ColorSchema.optional(),
107
115
  borders: ContentCellBordersSchema.optional(),
108
- sourcePath: zod.z.string().optional()
116
+ sourcePath: zod.z.string().optional(),
117
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional()
109
118
  });
110
119
  const ContentTableRowSchema = zod.z.object({
111
120
  cells: zod.z.array(ContentTableCellSchema),
@@ -115,7 +124,8 @@ const ContentTableSchema = zod.z.object({
115
124
  kind: zod.z.literal("table"),
116
125
  rows: zod.z.array(ContentTableRowSchema),
117
126
  columnWidthsPt: zod.z.array(zod.z.number().positive()),
118
- sourcePath: zod.z.string().optional()
127
+ sourcePath: zod.z.string().optional(),
128
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional()
119
129
  });
120
130
  const ContentSectionSchema = zod.z.object({
121
131
  pageSize: require_geometry.PageSizeSchema,
@@ -134,6 +144,7 @@ const ContentShapeSchema = zod.z.object({
134
144
  lineSpacingReduction: zod.z.number().nonnegative().optional(),
135
145
  paintOrder: zod.z.number().optional(),
136
146
  sourcePath: zod.z.string().optional(),
147
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional(),
137
148
  blocks: zod.z.array(ContentBlockSchema)
138
149
  });
139
150
  const ContentSlideSchema = zod.z.object({
@@ -202,7 +213,8 @@ const ContentSheetCellSchema = zod.z.object({
202
213
  "middle",
203
214
  "bottom"
204
215
  ]).optional(),
205
- sourcePath: zod.z.string().optional()
216
+ sourcePath: zod.z.string().optional(),
217
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional()
206
218
  });
207
219
  const ContentSheetColumnSchema = zod.z.object({
208
220
  index: zod.z.number().int().nonnegative(),
@@ -289,7 +301,8 @@ const ContentVectorSchema = zod.z.discriminatedUnion("kind", [
289
301
  fill: require_color.ColorSchema.optional(),
290
302
  stroke: ContentStrokeSchema.optional(),
291
303
  paintOrder: zod.z.number().optional(),
292
- sourcePath: zod.z.string().optional()
304
+ sourcePath: zod.z.string().optional(),
305
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional()
293
306
  }),
294
307
  zod.z.object({
295
308
  kind: zod.z.literal("ellipse"),
@@ -298,7 +311,8 @@ const ContentVectorSchema = zod.z.discriminatedUnion("kind", [
298
311
  fill: require_color.ColorSchema.optional(),
299
312
  stroke: ContentStrokeSchema.optional(),
300
313
  paintOrder: zod.z.number().optional(),
301
- sourcePath: zod.z.string().optional()
314
+ sourcePath: zod.z.string().optional(),
315
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional()
302
316
  }),
303
317
  zod.z.object({
304
318
  kind: zod.z.literal("line"),
@@ -306,7 +320,8 @@ const ContentVectorSchema = zod.z.discriminatedUnion("kind", [
306
320
  to: ContentPathPointSchema,
307
321
  stroke: ContentStrokeSchema,
308
322
  paintOrder: zod.z.number().optional(),
309
- sourcePath: zod.z.string().optional()
323
+ sourcePath: zod.z.string().optional(),
324
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional()
310
325
  }),
311
326
  zod.z.object({
312
327
  kind: zod.z.literal("path"),
@@ -317,7 +332,8 @@ const ContentVectorSchema = zod.z.discriminatedUnion("kind", [
317
332
  fillRule: zod.z.enum(["nonzero", "evenodd"]).optional(),
318
333
  stroke: ContentStrokeSchema.optional(),
319
334
  paintOrder: zod.z.number().optional(),
320
- sourcePath: zod.z.string().optional()
335
+ sourcePath: zod.z.string().optional(),
336
+ frames: zod.z.array(require_geometry.LayoutFrameSchema).optional()
321
337
  })
322
338
  ]);
323
339
  const ContentDrawPageSchema = zod.z.object({
@@ -329,35 +345,35 @@ const ContentFormulaSchema = zod.z.object({
329
345
  mathml: zod.z.array(require_mathml.MathMlNodeSchema),
330
346
  starMath: zod.z.string().optional()
331
347
  });
332
- const CONTENT_FORMAT_VERSION = 2;
348
+ const CONTENT_FORMAT_VERSION = 3;
333
349
  const ContentDocumentSchema = zod.z.discriminatedUnion("kind", [
334
350
  zod.z.object({
335
351
  kind: zod.z.literal("wordprocessing"),
336
- formatVersion: zod.z.literal(2),
352
+ formatVersion: zod.z.literal(3),
337
353
  metadata: require_metadata.LayoutMetadataSchema,
338
354
  sections: zod.z.array(ContentSectionSchema)
339
355
  }),
340
356
  zod.z.object({
341
357
  kind: zod.z.literal("presentation"),
342
- formatVersion: zod.z.literal(2),
358
+ formatVersion: zod.z.literal(3),
343
359
  metadata: require_metadata.LayoutMetadataSchema,
344
360
  slides: zod.z.array(ContentSlideSchema)
345
361
  }),
346
362
  zod.z.object({
347
363
  kind: zod.z.literal("spreadsheet"),
348
- formatVersion: zod.z.literal(2),
364
+ formatVersion: zod.z.literal(3),
349
365
  metadata: require_metadata.LayoutMetadataSchema,
350
366
  sheets: zod.z.array(ContentSheetSchema)
351
367
  }),
352
368
  zod.z.object({
353
369
  kind: zod.z.literal("drawing"),
354
- formatVersion: zod.z.literal(2),
370
+ formatVersion: zod.z.literal(3),
355
371
  metadata: require_metadata.LayoutMetadataSchema,
356
372
  pages: zod.z.array(ContentDrawPageSchema)
357
373
  }),
358
374
  zod.z.object({
359
375
  kind: zod.z.literal("formula"),
360
- formatVersion: zod.z.literal(2),
376
+ formatVersion: zod.z.literal(3),
361
377
  metadata: require_metadata.LayoutMetadataSchema,
362
378
  formula: ContentFormulaSchema
363
379
  })
@@ -399,4 +415,5 @@ exports.ContentTableRowSchema = ContentTableRowSchema;
399
415
  exports.ContentTableSchema = ContentTableSchema;
400
416
  exports.ContentVectorSchema = ContentVectorSchema;
401
417
  exports.DecimalStringSchema = DecimalStringSchema;
418
+ exports.clampHeadingLevel = clampHeadingLevel;
402
419
  exports.isContentBlock = isContentBlock;