@json-to-office/core-docx 1.9.0 → 1.11.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.
@@ -33,6 +33,14 @@ export interface IrDocxGenerationOptions {
33
33
  generatedAt?: string | Date;
34
34
  /** Backend to render with. Defaults to `docxjs`. */
35
35
  renderer?: DocxRendererId;
36
+ /**
37
+ * Rasterize a PNG fallback for each inline SVG. Defaults to true.
38
+ *
39
+ * Only readers older than Word 2016 draw that raster; everything current
40
+ * draws the vector. Producing it is the dominant cost of a document whose
41
+ * artwork is many small SVGs, so it can be turned off.
42
+ */
43
+ svgRasterFallback?: boolean;
36
44
  /**
37
45
  * A prologue already run by the caller.
38
46
  *
@@ -1 +1 @@
1
- {"version":3,"file":"generateFromIr.d.ts","sourceRoot":"","sources":["../../src/core/generateFromIr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAM9D,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAE1D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAKlE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,uBAAuB;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,iEAAiE;IACjE,QAAQ,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED;;;;;GAKG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,SAAgB,IAAI,0BAA0B;IAC9C,SAAgB,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;gBAEhD,UAAU,EAAE,SAAS,oBAAoB,EAAE;CAiBxD;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,QAAQ,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,UAAU,CAAC,CAAC;IACzD,WAAW,EAAE,oBAAoB,EAAE,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,yBAAyB,EACnC,OAAO,GAAE,uBAA4B,EACrC,SAAS,CAAC,EAAE,iBAAiB,EAAE,GAC9B,OAAO,CAAC,YAAY,CAAC,CAOvB;AAkGD,0EAA0E;AAC1E,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,yBAAyB,EACnC,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAcjC"}
1
+ {"version":3,"file":"generateFromIr.d.ts","sourceRoot":"","sources":["../../src/core/generateFromIr.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAM9D,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAE1D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAKlE,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,MAAM,WAAW,uBAAuB;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAC3C,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B;;;;;;OAMG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,iEAAiE;IACjE,QAAQ,CAAC,EAAE,gBAAgB,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;CAChE;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,iBAAiB,EAAE,CAAC;CAC/B;AAED;;;;;GAKG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IACjD,SAAgB,IAAI,0BAA0B;IAC9C,SAAgB,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;gBAEhD,UAAU,EAAE,SAAS,oBAAoB,EAAE;CAiBxD;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,QAAQ,EAAE,UAAU,CAAC,OAAO,eAAe,CAAC,CAAC,UAAU,CAAC,CAAC;IACzD,WAAW,EAAE,oBAAoB,EAAE,CAAC;CACrC;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,yBAAyB,EACnC,OAAO,GAAE,uBAA4B,EACrC,SAAS,CAAC,EAAE,iBAAiB,EAAE,GAC9B,OAAO,CAAC,YAAY,CAAC,CAOvB;AAkGD,0EAA0E;AAC1E,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,yBAAyB,EACnC,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,sBAAsB,CAAC,CAcjC"}
@@ -65,6 +65,14 @@ export interface JsonGenerationOptions {
65
65
  * produced; anything else is opt-in and may not.
66
66
  */
67
67
  renderer?: DocxRendererId;
68
+ /**
69
+ * Rasterize a PNG fallback for each inline SVG. Defaults to true.
70
+ *
71
+ * Only readers older than Word 2016 draw that raster; everything current
72
+ * draws the vector. Producing it dominates the render of a document whose
73
+ * artwork is many small SVGs, so it can be turned off.
74
+ */
75
+ svgRasterFallback?: boolean;
68
76
  /** Canonical prepared model; internal hosts use it to avoid a second prologue. */
69
77
  prepared?: PreparedDocument<DocxQualityModel, DocxQualityFact>;
70
78
  }
@@ -1 +1 @@
1
- {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/core/generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/core/generator.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1862,6 +1862,7 @@ var init_widthUtils = __esm({
1862
1862
 
1863
1863
  // src/utils/imageUtils.ts
1864
1864
  import { readFileSync } from "fs";
1865
+ import { availableParallelism } from "os";
1865
1866
  import probe from "probe-image-size";
1866
1867
  function loadResvg() {
1867
1868
  resvgModule ??= import("@resvg/resvg-js");
@@ -1880,10 +1881,36 @@ function capToPixelBudget(edge, aspect) {
1880
1881
  const scaled = Math.floor(edge * Math.sqrt(SVG_MAX_TOTAL_PX / total));
1881
1882
  return scaled >= SVG_MIN_EDGE_PX ? scaled : void 0;
1882
1883
  }
1884
+ function fallbackConcurrency() {
1885
+ const cpus = availableParallelism?.() ?? 4;
1886
+ return Math.max(1, Math.min(8, cpus));
1887
+ }
1888
+ async function rasterizeSvgFallbacks(jobs, enabled = true) {
1889
+ const out = /* @__PURE__ */ new Map();
1890
+ if (!enabled || jobs.length === 0) return out;
1891
+ let next = 0;
1892
+ const worker = async () => {
1893
+ for (let i = next++; i < jobs.length; i = next++) {
1894
+ const job = jobs[i];
1895
+ out.set(
1896
+ job.key,
1897
+ await rasterizeSvgFallback(job.svg, {
1898
+ width: job.width,
1899
+ height: job.height
1900
+ })
1901
+ );
1902
+ }
1903
+ };
1904
+ await Promise.all(
1905
+ Array.from({ length: Math.min(fallbackConcurrency(), jobs.length) }, worker)
1906
+ );
1907
+ return out;
1908
+ }
1883
1909
  async function rasterizeSvgFallback(svg, transformation) {
1884
1910
  let Resvg;
1911
+ let renderAsync;
1885
1912
  try {
1886
- ({ Resvg } = await loadResvg());
1913
+ ({ Resvg, renderAsync } = await loadResvg());
1887
1914
  } catch (error) {
1888
1915
  reportWarning(
1889
1916
  "image",
@@ -1918,7 +1945,7 @@ async function rasterizeSvgFallback(svg, transformation) {
1918
1945
  return void 0;
1919
1946
  }
1920
1947
  return Buffer.from(
1921
- new Resvg(markup, { fitTo: { mode, value } }).render().asPng()
1948
+ (await renderAsync(markup, { fitTo: { mode, value } })).asPng()
1922
1949
  );
1923
1950
  } catch (error) {
1924
1951
  reportWarning(
@@ -2207,10 +2234,10 @@ import {
2207
2234
  EndnoteReferenceRun,
2208
2235
  ExternalHyperlink,
2209
2236
  FootnoteReferenceRun,
2237
+ ImportedXmlComponent,
2210
2238
  InsertedTextRun,
2211
2239
  InternalHyperlink,
2212
2240
  OverlapType,
2213
- PageNumber,
2214
2241
  Paragraph,
2215
2242
  RelativeHorizontalPosition,
2216
2243
  RelativeVerticalPosition,
@@ -2230,6 +2257,28 @@ import {
2230
2257
  WpsShapeRun
2231
2258
  } from "docx";
2232
2259
  import { assertNever } from "@json-to-office/shared/rendering";
2260
+ function complexField(instruction, formatting, leading) {
2261
+ const options = runOptions(formatting);
2262
+ const fieldChar = (type, extra = {}) => new TextRun({
2263
+ children: [
2264
+ new ImportedXmlComponent("w:fldChar", { "w:fldCharType": type })
2265
+ ],
2266
+ ...options,
2267
+ ...extra
2268
+ });
2269
+ const instrText = new ImportedXmlComponent("w:instrText", {
2270
+ "xml:space": "preserve"
2271
+ });
2272
+ instrText.push(instruction);
2273
+ return [
2274
+ // A pending line break rides on the first run of the field, the same way
2275
+ // it rides on the single run every other inline node emits.
2276
+ fieldChar("begin", leading),
2277
+ new TextRun({ children: [instrText], ...options }),
2278
+ fieldChar("separate"),
2279
+ fieldChar("end")
2280
+ ];
2281
+ }
2233
2282
  function runOptions(formatting) {
2234
2283
  if (!formatting) return {};
2235
2284
  const options = {};
@@ -2334,18 +2383,13 @@ function inlineChildren(children, resources = /* @__PURE__ */ new Map()) {
2334
2383
  out.push(new SimpleField(child.instruction, child.cachedText));
2335
2384
  break;
2336
2385
  }
2337
- const page = PAGE_FIELD[child.instruction];
2338
- if (!page) {
2386
+ if (!PAGE_FIELDS.has(child.instruction)) {
2339
2387
  throw new Error(
2340
2388
  `the docxjs renderer has no emitter for the field "${child.instruction}"`
2341
2389
  );
2342
2390
  }
2343
2391
  out.push(
2344
- new TextRun({
2345
- children: [page],
2346
- ...runOptions(child.formatting),
2347
- ...breakOption()
2348
- })
2392
+ ...complexField(child.instruction, child.formatting, breakOption())
2349
2393
  );
2350
2394
  break;
2351
2395
  }
@@ -2719,7 +2763,7 @@ function emitBorder(border3) {
2719
2763
  ...border3.spacePoints !== void 0 ? { space: border3.spacePoints } : {}
2720
2764
  };
2721
2765
  }
2722
- var ALIGNMENT2, PAGE_FIELD, WRAP_TYPE, VERTICAL_ALIGN, TABLE_ANCHOR, HORIZONTAL_POSITION, VERTICAL_POSITION, BORDER_STYLE;
2766
+ var ALIGNMENT2, PAGE_FIELDS, WRAP_TYPE, VERTICAL_ALIGN, TABLE_ANCHOR, HORIZONTAL_POSITION, VERTICAL_POSITION, BORDER_STYLE;
2723
2767
  var init_emit = __esm({
2724
2768
  "src/renderers/docxjs/emit.ts"() {
2725
2769
  "use strict";
@@ -2731,10 +2775,7 @@ var init_emit = __esm({
2731
2775
  start: AlignmentType.START,
2732
2776
  end: AlignmentType.END
2733
2777
  };
2734
- PAGE_FIELD = {
2735
- PAGE: PageNumber.CURRENT,
2736
- NUMPAGES: PageNumber.TOTAL_PAGES
2737
- };
2778
+ PAGE_FIELDS = /* @__PURE__ */ new Set(["PAGE", "NUMPAGES"]);
2738
2779
  WRAP_TYPE = {
2739
2780
  none: TextWrappingType.NONE,
2740
2781
  square: TextWrappingType.SQUARE,
@@ -3081,7 +3122,10 @@ function createDocxJsRenderer() {
3081
3122
  format: "docx",
3082
3123
  capabilities: DOCXJS_CAPABILITIES,
3083
3124
  async render(ir, renderOptions) {
3084
- const resources = await prepareImages(ir);
3125
+ const resources = await prepareImages(
3126
+ ir,
3127
+ renderOptions?.svgRasterFallback
3128
+ );
3085
3129
  const document = buildDocument(ir, resources);
3086
3130
  const packed = await Packer.toBuffer(document);
3087
3131
  const fixed = fixFloatingImageIdsInBuffer(packed);
@@ -3166,22 +3210,22 @@ function numberingConfig(numbering) {
3166
3210
  }))
3167
3211
  };
3168
3212
  }
3169
- async function prepareImages(ir) {
3213
+ async function prepareImages(ir, svgRasterFallback) {
3170
3214
  const placements = collectImagePlacements(ir);
3171
- const rasters = /* @__PURE__ */ new Map();
3215
+ const jobs = [];
3172
3216
  for (const resource of ir.resources) {
3173
3217
  if (resource.kind !== "image" || resource.mediaType !== "svg") continue;
3174
3218
  for (const size of placements.get(resource.id) ?? []) {
3175
3219
  const [width, height] = size.split("x").map(Number);
3176
- rasters.set(
3177
- `${resource.id}:${size}`,
3178
- await rasterizeSvgFallback(Buffer.from(resource.bytes), {
3179
- width,
3180
- height
3181
- })
3182
- );
3220
+ jobs.push({
3221
+ key: `${resource.id}:${size}`,
3222
+ svg: Buffer.from(resource.bytes),
3223
+ width,
3224
+ height
3225
+ });
3183
3226
  }
3184
3227
  }
3228
+ const rasters = await rasterizeSvgFallbacks(jobs, svgRasterFallback);
3185
3229
  const resources = /* @__PURE__ */ new Map();
3186
3230
  for (const resource of ir.resources) {
3187
3231
  if (resource.kind !== "image") continue;
@@ -4348,7 +4392,11 @@ async function createOfficeOpenDocxRenderer() {
4348
4392
  capabilities: OFFICE_OPEN_CAPABILITIES,
4349
4393
  async render(ir, options) {
4350
4394
  const charts = [];
4351
- const document = await buildDocumentOptions(ir, charts);
4395
+ const document = await buildDocumentOptions(
4396
+ ir,
4397
+ charts,
4398
+ options?.svgRasterFallback
4399
+ );
4352
4400
  const bytes = await backend.generateDocument(document, {
4353
4401
  type: "uint8array"
4354
4402
  });
@@ -4373,10 +4421,10 @@ async function createOfficeOpenDocxRenderer() {
4373
4421
  }
4374
4422
  };
4375
4423
  }
4376
- async function buildDocumentOptions(ir, charts = []) {
4424
+ async function buildDocumentOptions(ir, charts = [], svgRasterFallback) {
4377
4425
  let nextDrawingId = 1;
4378
4426
  const ctx = {
4379
- pictures: await prepareImages2(ir),
4427
+ pictures: await prepareImages2(ir, svgRasterFallback),
4380
4428
  nextDrawingId: () => nextDrawingId++,
4381
4429
  charts
4382
4430
  };
@@ -4425,22 +4473,22 @@ function noteBodies2(notes, ctx) {
4425
4473
  }
4426
4474
  return bodies;
4427
4475
  }
4428
- async function prepareImages2(ir) {
4476
+ async function prepareImages2(ir, svgRasterFallback) {
4429
4477
  const placements = collectImagePlacements2(ir);
4430
- const rasters = /* @__PURE__ */ new Map();
4478
+ const jobs = [];
4431
4479
  for (const resource of ir.resources) {
4432
4480
  if (resource.kind !== "image" || resource.mediaType !== "svg") continue;
4433
4481
  for (const size of placements.get(resource.id) ?? []) {
4434
4482
  const [width, height] = size.split("x").map(Number);
4435
- rasters.set(
4436
- `${resource.id}:${size}`,
4437
- await rasterizeSvgFallback(Buffer.from(resource.bytes), {
4438
- width,
4439
- height
4440
- })
4441
- );
4483
+ jobs.push({
4484
+ key: `${resource.id}:${size}`,
4485
+ svg: Buffer.from(resource.bytes),
4486
+ width,
4487
+ height
4488
+ });
4442
4489
  }
4443
4490
  }
4491
+ const rasters = await rasterizeSvgFallbacks(jobs, svgRasterFallback);
4444
4492
  const resources = /* @__PURE__ */ new Map();
4445
4493
  for (const resource of ir.resources) {
4446
4494
  if (resource.kind !== "image") continue;
@@ -7819,6 +7867,44 @@ function buildNoProofWordsRegex(noProofWords2) {
7819
7867
  );
7820
7868
  }
7821
7869
  var DECORATOR = /(\*\*\*|___)([\s\S]*?)\1|(\*\*|__)([\s\S]*?)\3|(\*|_)([\s\S]*?)\5/g;
7870
+ var ESCAPABLE = "*_[]{}\\";
7871
+ var ESCAPE = /\\([*_[\]{}\\])/g;
7872
+ var SENTINEL = "\uE000";
7873
+ var SENTINEL_SELF = "x";
7874
+ var SENTINEL_DIGIT_BASE = 48;
7875
+ function encodeEscapes(text) {
7876
+ const authored = text.includes(SENTINEL);
7877
+ if (!authored && !text.includes("\\")) return text;
7878
+ const guarded = authored ? text.split(SENTINEL).join(SENTINEL + SENTINEL_SELF) : text;
7879
+ return guarded.replace(
7880
+ ESCAPE,
7881
+ (_whole, char) => SENTINEL + String.fromCharCode(SENTINEL_DIGIT_BASE + ESCAPABLE.indexOf(char))
7882
+ );
7883
+ }
7884
+ function decodeEscapes(text) {
7885
+ if (!text.includes(SENTINEL)) return text;
7886
+ let out = "";
7887
+ for (let i = 0; i < text.length; i += 1) {
7888
+ if (text[i] !== SENTINEL) {
7889
+ out += text[i];
7890
+ continue;
7891
+ }
7892
+ const marker = text[i + 1];
7893
+ if (marker === SENTINEL_SELF) {
7894
+ out += SENTINEL;
7895
+ i += 1;
7896
+ continue;
7897
+ }
7898
+ const index = marker === void 0 ? -1 : marker.charCodeAt(0) - SENTINEL_DIGIT_BASE;
7899
+ if (index >= 0 && index < ESCAPABLE.length) {
7900
+ out += ESCAPABLE[index];
7901
+ i += 1;
7902
+ continue;
7903
+ }
7904
+ out += text[i];
7905
+ }
7906
+ return out;
7907
+ }
7822
7908
  var LINK = /\[([^\]]+)\]\(([^)]+)\)/g;
7823
7909
  var DECORATOR_OR_PLACEHOLDER = /(\*\*\*|___)([\s\S]*?)\1|(\*\*|__)([\s\S]*?)\3|(\*|_)([\s\S]*?)\5|\{([^}]+)\}/g;
7824
7910
  var PLACEHOLDER = /\{([^}]+)\}/;
@@ -7845,7 +7931,7 @@ function containsUnsupportedSyntax(text) {
7845
7931
  return void 0;
7846
7932
  }
7847
7933
  function parseInline(text, options) {
7848
- const normalized = normalizeUnicodeText(text);
7934
+ const normalized = encodeEscapes(normalizeUnicodeText(text));
7849
7935
  if (!normalized) {
7850
7936
  return [
7851
7937
  { kind: "text", text: "", formatting: emptyToUndefined(options.base) }
@@ -7943,7 +8029,7 @@ function parseLinks(normalized, options) {
7943
8029
  lastIndex = match.index + match[0].length;
7944
8030
  if (match[1] === void 0) {
7945
8031
  const resolved = options.resolveCrossReference?.(
7946
- match[3],
8032
+ decodeEscapes(match[3]),
7947
8033
  match[4] ?? "relative",
7948
8034
  match[0]
7949
8035
  );
@@ -7951,7 +8037,8 @@ function parseLinks(normalized, options) {
7951
8037
  else out.push(...parseDecorated(match[0], options));
7952
8038
  continue;
7953
8039
  }
7954
- const [, linkText, target] = match;
8040
+ const [, linkText] = match;
8041
+ const target = decodeEscapes(match[2]);
7955
8042
  out.push({
7956
8043
  kind: "hyperlink",
7957
8044
  // A `#anchor` target names a bookmark in this document and needs no
@@ -8007,7 +8094,7 @@ function pushSegment(out, text, options, override = {}) {
8007
8094
  const bold = override.bold ?? options.base.bold;
8008
8095
  const italic = override.italic ?? options.base.italic;
8009
8096
  const formatting = runFormatting2(options, { bold, italic });
8010
- const lines = text.split("\n");
8097
+ const lines = decodeEscapes(text).split("\n");
8011
8098
  for (const [lineIndex, line] of lines.entries()) {
8012
8099
  if (!line && lineIndex === 0) continue;
8013
8100
  if (lineIndex > 0) out.push({ kind: "lineBreak" });
@@ -8478,8 +8565,8 @@ function compileComponent(component, scope) {
8478
8565
  return compileStatistic(component, scope);
8479
8566
  case "toc":
8480
8567
  return compileToc(component, scope);
8481
- case "rule":
8482
- return compileRule(component, scope);
8568
+ case "divider":
8569
+ return compileDivider(component, scope);
8483
8570
  case "text-box":
8484
8571
  return compileTextBox(component, scope);
8485
8572
  case "columns":
@@ -9056,16 +9143,16 @@ function compileToc(component, scope) {
9056
9143
  });
9057
9144
  return blocks;
9058
9145
  }
9059
- var DEFAULT_RULE_SPACING_PT = 6;
9060
- var DEFAULT_RULE_THICKNESS_PT = 1;
9061
- var RULE_LINE_TWIPS = 20;
9062
- var RULE_BORDER_STYLE = {
9146
+ var DEFAULT_DIVIDER_SPACING_PT = 6;
9147
+ var DEFAULT_DIVIDER_THICKNESS_PT = 1;
9148
+ var DIVIDER_LINE_TWIPS = 20;
9149
+ var DIVIDER_BORDER_STYLE = {
9063
9150
  solid: "single",
9064
9151
  dashed: "dashed",
9065
9152
  dotted: "dotted",
9066
9153
  double: "double"
9067
9154
  };
9068
- function compileRule(component, scope) {
9155
+ function compileDivider(component, scope) {
9069
9156
  const { ctx, path: path4 } = scope;
9070
9157
  const props = component.props ?? {};
9071
9158
  ctx.features.require("borders", path4);
@@ -9073,12 +9160,12 @@ function compileRule(component, scope) {
9073
9160
  12,
9074
9161
  Math.max(
9075
9162
  0.25,
9076
- typeof props.thickness === "number" && Number.isFinite(props.thickness) ? props.thickness : DEFAULT_RULE_THICKNESS_PT
9163
+ typeof props.thickness === "number" && Number.isFinite(props.thickness) ? props.thickness : DEFAULT_DIVIDER_THICKNESS_PT
9077
9164
  )
9078
9165
  );
9079
9166
  const spacing = props.spacing ?? {};
9080
- const beforePt = typeof spacing.before === "number" && Number.isFinite(spacing.before) ? spacing.before : DEFAULT_RULE_SPACING_PT;
9081
- const afterPt = typeof spacing.after === "number" && Number.isFinite(spacing.after) ? spacing.after : DEFAULT_RULE_SPACING_PT;
9167
+ const beforePt = typeof spacing.before === "number" && Number.isFinite(spacing.before) ? spacing.before : DEFAULT_DIVIDER_SPACING_PT;
9168
+ const afterPt = typeof spacing.after === "number" && Number.isFinite(spacing.after) ? spacing.after : DEFAULT_DIVIDER_SPACING_PT;
9082
9169
  return [
9083
9170
  {
9084
9171
  kind: "paragraph",
@@ -9090,13 +9177,13 @@ function compileRule(component, scope) {
9090
9177
  spacing: {
9091
9178
  beforeTwips: pointsToTwips2(beforePt),
9092
9179
  afterTwips: pointsToTwips2(afterPt),
9093
- lineTwips: RULE_LINE_TWIPS,
9180
+ lineTwips: DIVIDER_LINE_TWIPS,
9094
9181
  lineRule: "exact"
9095
9182
  },
9096
- ...ruleIndent(props, ctx, path4),
9183
+ ...dividerIndent(props, ctx, path4),
9097
9184
  borders: {
9098
9185
  bottom: {
9099
- style: RULE_BORDER_STYLE[String(props.style)] ?? "single",
9186
+ style: DIVIDER_BORDER_STYLE[String(props.style)] ?? "single",
9100
9187
  sizeEighthPoints: pointsToEighthPoints(thicknessPt),
9101
9188
  color: irColor(
9102
9189
  resolveColor(String(props.color ?? "border"), ctx.theme)
@@ -9110,7 +9197,7 @@ function compileRule(component, scope) {
9110
9197
  }
9111
9198
  ];
9112
9199
  }
9113
- function ruleIndent(props, ctx, path4) {
9200
+ function dividerIndent(props, ctx, path4) {
9114
9201
  const width = props.width;
9115
9202
  if (width === void 0) return {};
9116
9203
  const page = getPageSetup(ctx.theme);
@@ -9133,8 +9220,8 @@ function ruleIndent(props, ctx, path4) {
9133
9220
  if (remainder < 0) {
9134
9221
  warnOnce(
9135
9222
  ctx,
9136
- "rule",
9137
- `Rule width ${JSON.stringify(width)} at ${path4} is wider than the ${Math.round(measureTwips / 20)}pt text measure; it runs the full measure instead.`
9223
+ "divider",
9224
+ `Divider width ${JSON.stringify(width)} at ${path4} is wider than the ${Math.round(measureTwips / 20)}pt text measure; it runs the full measure instead.`
9138
9225
  );
9139
9226
  }
9140
9227
  return {};
@@ -12029,6 +12116,7 @@ async function renderScoped(document, options, warnings) {
12029
12116
  const bytes = await renderer.render(compiled.ir, {
12030
12117
  ...options.deterministic !== void 0 ? { deterministic: options.deterministic } : {},
12031
12118
  ...options.generatedAt !== void 0 ? { generatedAt: toDate(options.generatedAt) } : {},
12119
+ ...options.svgRasterFallback !== void 0 ? { svgRasterFallback: options.svgRasterFallback } : {},
12032
12120
  warnings: compiled.warnings
12033
12121
  });
12034
12122
  return { buffer: Buffer.from(bytes), warnings: compiled.warnings };
@@ -12146,6 +12234,7 @@ async function generateBufferWithWarnings(jsonConfig, options) {
12146
12234
  ...options?.deterministic !== void 0 ? { deterministic: options.deterministic } : {},
12147
12235
  ...options?.generatedAt !== void 0 ? { generatedAt: options.generatedAt } : {},
12148
12236
  ...renderer ? { renderer } : {},
12237
+ ...options?.svgRasterFallback !== void 0 ? { svgRasterFallback: options.svgRasterFallback } : {},
12149
12238
  ...options?.prepared ? { prepared: options.prepared } : {}
12150
12239
  });
12151
12240
  }
@@ -12734,9 +12823,9 @@ var docxLineBoxRule = {
12734
12823
  message: `An exact ${tenths(fact.lineBoxPt)}pt line box holds ${tenths(fact.fontSizePt)}pt text${inherited} \u2014 shorter than the capitals it contains, so the lines overlap or lose their tops.`,
12735
12824
  path: fact.path,
12736
12825
  // The second sentence is the exit from the incentive that
12737
- // produced this geometry: the reported route to a 3pt rule was a
12826
+ // produced this geometry: the reported route to a 3pt line was a
12738
12827
  // collapsed line box on 8pt type, because nothing else drew one.
12739
- suggestion: `Set the box to at least ${repairPt}pt \u2014 as tall as the type it holds \u2014 or use "atLeast" so the line grows to fit the text. To draw a line rather than set leading, use the "rule" component.${fact.patchable ? "" : " This box is not stated on the component: it arrives through `componentDefaults` and has to be repaired there."}`,
12828
+ suggestion: `Set the box to at least ${repairPt}pt \u2014 as tall as the type it holds \u2014 or use "atLeast" so the line grows to fit the text. To draw a line rather than set leading, use the "divider" component.${fact.patchable ? "" : " This box is not stated on the component: it arrives through `componentDefaults` and has to be repaired there."}`,
12740
12829
  context: {
12741
12830
  lineBoxPt: tenths(fact.lineBoxPt),
12742
12831
  fontSizePt: tenths(fact.fontSizePt),
@@ -13504,7 +13593,8 @@ function createBuilderImpl(state) {
13504
13593
  deterministic: state.deterministic,
13505
13594
  generatedAt: state.generatedAt,
13506
13595
  baseDir: state.baseDir,
13507
- renderer: state.renderer
13596
+ renderer: state.renderer,
13597
+ svgRasterFallback: state.svgRasterFallback
13508
13598
  };
13509
13599
  return createBuilderImpl(
13510
13600
  newState
@@ -13761,7 +13851,8 @@ function createDocumentGenerator(options) {
13761
13851
  deterministic: options.deterministic ?? true,
13762
13852
  generatedAt: options.generatedAt,
13763
13853
  baseDir: options.baseDir,
13764
- renderer: options.renderer
13854
+ renderer: options.renderer,
13855
+ svgRasterFallback: options.svgRasterFallback
13765
13856
  };
13766
13857
  return createBuilderImpl(initialState);
13767
13858
  }