@json-to-office/core-docx 3.0.0 → 3.2.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.
@@ -1 +1 @@
1
- {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/ir/compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,gBAAgB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAiD3D,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,wBAAwB,CAAC;AAuC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAEL,KAAK,MAAM,EAqCZ,MAAM,SAAS,CAAC;AAiBjB,2DAA2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,2EAA2E;IAC3E,QAAQ,EAAE,SAAS,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;IACrD,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B;;;;OAIG;IACH,WAAW,EAAE,oBAAoB,EAAE,CAAC;CACrC;AA8FD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,UAAU,EAClB,QAAQ,GAAE,iBAAiB,EAAO,EAClC,MAAM,GAAE,cAA0B,EAClC,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,iBAAiB,CAgHnB"}
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../src/ir/compiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EACV,iBAAiB,EAGlB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,UAAU,EAAiB,MAAM,gBAAgB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAiD3D,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,wBAAwB,CAAC;AAuC1E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAEL,KAAK,MAAM,EAqCZ,MAAM,SAAS,CAAC;AAiBjB,2DAA2D;AAC3D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,2EAA2E;IAC3E,QAAQ,EAAE,SAAS,kBAAkB,CAAC,WAAW,CAAC,EAAE,CAAC;IACrD,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B;;;;OAIG;IACH,WAAW,EAAE,oBAAoB,EAAE,CAAC;CACrC;AAoGD,wBAAgB,eAAe,CAC7B,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,UAAU,EAClB,QAAQ,GAAE,iBAAiB,EAAO,EAClC,MAAM,GAAE,cAA0B,EAClC,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,iBAAiB,CAiHnB"}
@@ -110,6 +110,7 @@ export declare function parseInline(text: string, options: ParseInlineOptions):
110
110
  export type PlaceholderResolution = {
111
111
  kind: 'field';
112
112
  instruction: string;
113
+ cachedText?: string;
113
114
  } | {
114
115
  kind: 'text';
115
116
  text: string;
@@ -1 +1 @@
1
- {"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../../src/ir/inline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAMjE;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAY7E;AA8HD,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,4DAA4D;AAC5D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAK1E;AAED,MAAM,WAAW,kBAAkB;IACjC,wCAAwC;IACxC,IAAI,EAAE,mBAAmB,CAAC;IAC1B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,SAAS,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,qBAAqB,GAAG,SAAS,CAAC;IACzE;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,CACZ,EAAE,EAAE,MAAM,KACP;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;IAClE;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,CACtB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,MAAM,KACV,YAAY,GAAG,SAAS,CAAC;CAC/B;AAED,kEAAkE;AAClE,MAAM,MAAM,oBAAoB,GAC5B,UAAU,GACV,YAAY,GACZ,cAAc,GACd,MAAM,CAAC;AAEX;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,kBAAkB,GAC1B,YAAY,EAAE,CAehB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AA8FnC;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,kBAAkB,GAC1B,YAAY,EAAE,CAShB"}
1
+ {"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../../src/ir/inline.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAMjE;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAY7E;AA8HD,0DAA0D;AAC1D,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,4DAA4D;AAC5D,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,0DAA0D;AAC1D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAK1E;AAED,MAAM,WAAW,kBAAkB;IACjC,wCAAwC;IACxC,IAAI,EAAE,mBAAmB,CAAC;IAC1B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;OAKG;IACH,SAAS,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,qBAAqB,GAAG,SAAS,CAAC;IACzE;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,CACZ,EAAE,EAAE,MAAM,KACP;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,UAAU,GAAG,SAAS,CAAA;KAAE,GAAG,SAAS,CAAC;IAClE;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,CACtB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,oBAAoB,EAC5B,KAAK,EAAE,MAAM,KACV,YAAY,GAAG,SAAS,CAAC;CAC/B;AAED,kEAAkE;AAClE,MAAM,MAAM,oBAAoB,GAC5B,UAAU,GACV,YAAY,GACZ,cAAc,GACd,MAAM,CAAC;AAEX;;;;;;GAMG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,kBAAkB,GAC1B,YAAY,EAAE,CAehB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAC7B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAiGnC;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,kBAAkB,GAC1B,YAAY,EAAE,CAShB"}
@@ -2348,7 +2348,7 @@ import {
2348
2348
  WpsShapeRun
2349
2349
  } from "docx";
2350
2350
  import { assertNever } from "@json-to-office/shared/rendering";
2351
- function complexField(instruction, formatting, leading) {
2351
+ function complexField(instruction, formatting, leading, cachedText) {
2352
2352
  const options = runOptions(formatting);
2353
2353
  const fieldChar = (type, extra = {}) => new TextRun({
2354
2354
  children: [
@@ -2367,6 +2367,9 @@ function complexField(instruction, formatting, leading) {
2367
2367
  fieldChar("begin", leading),
2368
2368
  new TextRun({ children: [instrText], ...options }),
2369
2369
  fieldChar("separate"),
2370
+ // A sequence number is the one field this pipeline can compute, so its
2371
+ // result is written: a reader that never updates fields shows the count.
2372
+ ...cachedText !== void 0 ? [new TextRun({ text: cachedText, ...options })] : [],
2370
2373
  fieldChar("end")
2371
2374
  ];
2372
2375
  }
@@ -2477,13 +2480,18 @@ function inlineChildren(children, resources = /* @__PURE__ */ new Map()) {
2477
2480
  out.push(new SimpleField(child.instruction, child.cachedText));
2478
2481
  break;
2479
2482
  }
2480
- if (!PAGE_FIELDS.has(child.instruction)) {
2483
+ if (!PAGE_FIELDS.has(child.instruction) && !isSequenceField(child.instruction)) {
2481
2484
  throw new Error(
2482
2485
  `the docxjs renderer has no emitter for the field "${child.instruction}"`
2483
2486
  );
2484
2487
  }
2485
2488
  out.push(
2486
- ...complexField(child.instruction, child.formatting, breakOption())
2489
+ ...complexField(
2490
+ child.instruction,
2491
+ child.formatting,
2492
+ breakOption(),
2493
+ child.cachedText
2494
+ )
2487
2495
  );
2488
2496
  break;
2489
2497
  }
@@ -2857,7 +2865,7 @@ function emitBorder(border3) {
2857
2865
  ...border3.spacePoints !== void 0 ? { space: border3.spacePoints } : {}
2858
2866
  };
2859
2867
  }
2860
- var ALIGNMENT2, PAGE_FIELDS, WRAP_TYPE, VERTICAL_ALIGN, TABLE_ANCHOR, HORIZONTAL_POSITION, VERTICAL_POSITION, BORDER_STYLE;
2868
+ var ALIGNMENT2, PAGE_FIELDS, isSequenceField, WRAP_TYPE, VERTICAL_ALIGN, TABLE_ANCHOR, HORIZONTAL_POSITION, VERTICAL_POSITION, BORDER_STYLE;
2861
2869
  var init_emit = __esm({
2862
2870
  "src/renderers/docxjs/emit.ts"() {
2863
2871
  "use strict";
@@ -2870,6 +2878,7 @@ var init_emit = __esm({
2870
2878
  end: AlignmentType.END
2871
2879
  };
2872
2880
  PAGE_FIELDS = /* @__PURE__ */ new Set(["PAGE", "NUMPAGES"]);
2881
+ isSequenceField = (instruction) => /^SEQ [A-Za-z][\w-]* \\\* ARABIC$/.test(instruction);
2873
2882
  WRAP_TYPE = {
2874
2883
  none: TextWrappingType.NONE,
2875
2884
  square: TextWrappingType.SQUARE,
@@ -5769,13 +5778,25 @@ init_colorUtils();
5769
5778
  init_layoutUtils();
5770
5779
  import {
5771
5780
  chartFamilyResolver,
5781
+ remoteExportNotice,
5782
+ REMOTE_EXPORT_WARNING,
5772
5783
  chartPointsPerPixel,
5773
5784
  POINTS_PER_PIXEL_96DPI,
5774
5785
  withChartFontFaceCss,
5775
5786
  withChartTypography
5776
5787
  } from "@json-to-office/shared";
5777
5788
  var DEFAULT_EXPORT_SERVER_URL = "http://localhost:7801";
5778
- async function generateChart(config, servicesConfig) {
5789
+ function assertExportServerAllowed(serverUrl, servicesConfig, warnings) {
5790
+ const notice = remoteExportNotice(serverUrl, servicesConfig?.allowRemote);
5791
+ if (notice)
5792
+ warnings?.push({
5793
+ component: "highcharts",
5794
+ severity: "warning",
5795
+ message: notice,
5796
+ context: { code: REMOTE_EXPORT_WARNING, serverUrl }
5797
+ });
5798
+ }
5799
+ async function generateChart(config, servicesConfig, warnings) {
5779
5800
  if (!isNodeEnvironment()) {
5780
5801
  throw new Error(
5781
5802
  "Highcharts export server requires a Node.js environment. Chart generation is not available in browser environments."
@@ -5786,6 +5807,7 @@ async function generateChart(config, servicesConfig) {
5786
5807
  servicesConfig?.serverUrl,
5787
5808
  DEFAULT_EXPORT_SERVER_URL
5788
5809
  );
5810
+ assertExportServerAllowed(serverUrl, servicesConfig, warnings);
5789
5811
  const requestBody = {
5790
5812
  infile: config.options,
5791
5813
  type: "png",
@@ -5898,13 +5920,13 @@ function withChartFontFaces(config, theme, faces) {
5898
5920
  theme.fonts.heading.family
5899
5921
  ]);
5900
5922
  }
5901
- async function renderChartToImageProps(props, theme, servicesConfig, chartFonts) {
5923
+ async function renderChartToImageProps(props, theme, servicesConfig, chartFonts, warnings) {
5902
5924
  const config = withChartFontFaces(
5903
5925
  withThemeTypography(withThemeColors(props, theme), theme),
5904
5926
  theme,
5905
5927
  chartFonts
5906
5928
  );
5907
- const chart = await generateChart(config, servicesConfig);
5929
+ const chart = await generateChart(config, servicesConfig, warnings);
5908
5930
  const hasConfigDimensions = config.width !== void 0 || config.height !== void 0;
5909
5931
  return {
5910
5932
  base64: chart.base64DataUri,
@@ -5944,7 +5966,8 @@ async function desugarExternals(document, options) {
5944
5966
  node.props,
5945
5967
  options.theme,
5946
5968
  options.services?.highcharts,
5947
- options.chartFonts
5969
+ options.chartFonts,
5970
+ options.warnings
5948
5971
  )
5949
5972
  });
5950
5973
  }
@@ -8495,6 +8518,9 @@ function parsePlaceholders(normalized, parseOptions) {
8495
8518
  out.push({
8496
8519
  kind: "field",
8497
8520
  instruction: resolved.instruction,
8521
+ ...resolved.cachedText !== void 0 && {
8522
+ cachedText: resolved.cachedText
8523
+ },
8498
8524
  ...formatting ? { formatting } : {}
8499
8525
  });
8500
8526
  }
@@ -8721,6 +8747,7 @@ function compileDocument(structure, layout, warnings = [], images = /* @__PURE__
8721
8747
  nextBookmarkId: CONTENT_BOOKMARK_ID_BASE + 1,
8722
8748
  bookmarkNames: /* @__PURE__ */ new Set(),
8723
8749
  usesStatistic: false,
8750
+ sequences: /* @__PURE__ */ new Map(),
8724
8751
  styleIds: /* @__PURE__ */ new Set([
8725
8752
  ...styles.paragraph.map((s) => s.id),
8726
8753
  ...styles.character.map((s) => s.id)
@@ -10116,7 +10143,20 @@ function compileRuns(props, text, ctx, path3, mode = "inline") {
10116
10143
  return children;
10117
10144
  }
10118
10145
  function placeholderResolver(ctx) {
10119
- return (name) => resolvePlaceholder(name, ctx.generatedAt);
10146
+ return (name) => {
10147
+ const sequence = /^SEQ:([A-Za-z][\w-]*)$/i.exec(name);
10148
+ if (sequence) {
10149
+ const key = sequence[1];
10150
+ const count = (ctx.sequences.get(key) ?? 0) + 1;
10151
+ ctx.sequences.set(key, count);
10152
+ return {
10153
+ kind: "field",
10154
+ instruction: `SEQ ${key} \\* ARABIC`,
10155
+ cachedText: String(count)
10156
+ };
10157
+ }
10158
+ return resolvePlaceholder(name, ctx.generatedAt);
10159
+ };
10120
10160
  }
10121
10161
  function crossReferenceResolver(ctx, path3) {
10122
10162
  return (id, format2, token) => resolveCrossReference(id, format2, token, ctx, path3);
@@ -12180,12 +12220,41 @@ import {
12180
12220
  readBlockDefinitions,
12181
12221
  blockValueAt,
12182
12222
  isBlockRecord,
12183
- toAuthoredBlockPointer
12223
+ toAuthoredBlockPointer,
12224
+ blockPointerKey,
12225
+ blockSlotRoles
12184
12226
  } from "@json-to-office/shared";
12185
- import { blockSlotBudgets } from "@json-to-office/shared";
12227
+ import { blockSlotBudgets, blockSlotRoles as blockSlotRoles2 } from "@json-to-office/shared";
12186
12228
  import { validateDocument as validateDocument2 } from "@json-to-office/shared-docx";
12187
12229
  var toAuthoredPointer = toAuthoredBlockPointer;
12188
- function docxBlockContext(document, theme, path3 = "") {
12230
+ function documentSourceLines(document) {
12231
+ if (!isBlockRecord(document)) return [];
12232
+ const invocations = [];
12233
+ const walk2 = (value, path3) => {
12234
+ if (Array.isArray(value)) {
12235
+ value.forEach((item, index) => walk2(item, `${path3}/${index}`));
12236
+ return;
12237
+ }
12238
+ if (!isBlockRecord(value) || value.enabled === false) return;
12239
+ if (value.name === "block") invocations.push(path3);
12240
+ for (const [key, item] of Object.entries(value)) {
12241
+ if (path3 === "/props" && key === "blocks") continue;
12242
+ walk2(item, `${path3}/${blockPointerKey(key)}`);
12243
+ }
12244
+ };
12245
+ walk2(document, "");
12246
+ const seen = /* @__PURE__ */ new Set();
12247
+ const lines = [];
12248
+ for (const slot of blockSlotRoles(document, invocations)) {
12249
+ if (slot.role !== "source" || typeof slot.value !== "string") continue;
12250
+ const text = slot.value.trim();
12251
+ if (text === "" || seen.has(text)) continue;
12252
+ seen.add(text);
12253
+ lines.push({ text, path: slot.path });
12254
+ }
12255
+ return lines;
12256
+ }
12257
+ function docxBlockContext(document, theme, path3, sources) {
12189
12258
  const index = /^\/children\/(\d+)/.exec(path3)?.[1];
12190
12259
  const section2 = index === void 0 ? void 0 : blockValueAt(document, `/children/${index}`);
12191
12260
  const page = isBlockRecord(section2) && isBlockRecord(section2.props) && isBlockRecord(section2.props.page) ? section2.props.page : {};
@@ -12205,26 +12274,46 @@ function docxBlockContext(document, theme, path3 = "") {
12205
12274
  return {
12206
12275
  document: blockValueAt(document, "/props/metadata") ?? {},
12207
12276
  page: { width, height },
12208
- section: {}
12277
+ section: {},
12278
+ sources: sources.map((line) => line.text)
12279
+ };
12280
+ }
12281
+ function docxBlockContextSources(sources) {
12282
+ return {
12283
+ "/document": "/props/metadata",
12284
+ ...Object.fromEntries(
12285
+ sources.map((line, index) => [`/sources/${index}`, line.path])
12286
+ )
12209
12287
  };
12210
12288
  }
12211
- function createDocxBlockEvaluator(document, theme, extra = {}) {
12289
+ function createDocxBlockEvaluator(document, theme, extra = {}, sources = documentSourceLines(document)) {
12212
12290
  return new JsonBlockEvaluator(readBlockDefinitions(document), {
12213
12291
  format: "docx",
12214
12292
  theme,
12215
- contextAt: (path3) => docxBlockContext(document, theme, path3),
12216
- contextSources: { "/document": "/props/metadata" },
12293
+ contextAt: (path3) => docxBlockContext(document, theme, path3, sources),
12294
+ contextSources: docxBlockContextSources(sources),
12217
12295
  measure: (axis, unit, context) => Number(blockValueAt(context, `/page/${axis}`)) / (unit === "twip" ? 1 : unit === "in" ? 1440 : 20),
12218
12296
  ...extra
12219
12297
  });
12220
12298
  }
12221
12299
  function expandBlocks(document, theme) {
12222
12300
  const effects = [];
12223
- const evaluator = createDocxBlockEvaluator(document, theme, {
12224
- onSection: (effect) => effects.push(effect)
12225
- });
12301
+ const sources = documentSourceLines(document);
12302
+ const evaluator = createDocxBlockEvaluator(
12303
+ document,
12304
+ theme,
12305
+ { onSection: (effect) => effects.push(effect) },
12306
+ sources
12307
+ );
12226
12308
  const expanded = evaluator.expand(document);
12227
- return finishDocxBlocks(expanded, document, theme, evaluator, effects);
12309
+ return finishDocxBlocks(
12310
+ expanded,
12311
+ document,
12312
+ theme,
12313
+ evaluator,
12314
+ effects,
12315
+ sources
12316
+ );
12228
12317
  }
12229
12318
  function validateEffects(document, effects) {
12230
12319
  for (const effect of effects) {
@@ -12245,7 +12334,7 @@ function validateEffects(document, effects) {
12245
12334
  ]);
12246
12335
  }
12247
12336
  }
12248
- function finishDocxBlocks(expanded, document, theme, evaluator, effects, validate = true) {
12337
+ function finishDocxBlocks(expanded, document, theme, evaluator, effects, sources, validate = true) {
12249
12338
  if (isBlockRecord(expanded) && Array.isArray(expanded.children)) {
12250
12339
  let inherited;
12251
12340
  expanded.children.forEach((section2, index) => {
@@ -12283,11 +12372,11 @@ function finishDocxBlocks(expanded, document, theme, evaluator, effects, validat
12283
12372
  const environment = {
12284
12373
  ...chrome.environment,
12285
12374
  context: {
12286
- ...docxBlockContext(document, theme, path3),
12375
+ ...docxBlockContext(document, theme, path3, sources),
12287
12376
  section: { tracker }
12288
12377
  },
12289
12378
  contextSources: {
12290
- "/document": "/props/metadata",
12379
+ ...docxBlockContextSources(sources),
12291
12380
  "/section/tracker": trackerSource
12292
12381
  }
12293
12382
  };
@@ -12331,10 +12420,16 @@ function finishDocxBlocks(expanded, document, theme, evaluator, effects, validat
12331
12420
  }
12332
12421
  async function expandBlocksWithPlugins(document, theme, plugins, render, preserve = /* @__PURE__ */ new Set()) {
12333
12422
  const effects = [];
12334
- const evaluator = createDocxBlockEvaluator(document, theme, {
12335
- reservedNames: [...plugins],
12336
- onSection: (effect) => effects.push(effect)
12337
- });
12423
+ const sources = documentSourceLines(document);
12424
+ const evaluator = createDocxBlockEvaluator(
12425
+ document,
12426
+ theme,
12427
+ {
12428
+ reservedNames: [...plugins],
12429
+ onSection: (effect) => effects.push(effect)
12430
+ },
12431
+ sources
12432
+ );
12338
12433
  const walk2 = (value) => composeBlocksWithPlugins(evaluator, value, {
12339
12434
  plugins,
12340
12435
  render,
@@ -12347,6 +12442,7 @@ async function expandBlocksWithPlugins(document, theme, plugins, render, preserv
12347
12442
  theme,
12348
12443
  evaluator,
12349
12444
  effects,
12445
+ sources,
12350
12446
  false
12351
12447
  );
12352
12448
  const second = await walk2(finished.document);
@@ -12446,7 +12542,8 @@ function chartFact(node, props, path3, paletteTokens) {
12446
12542
  kind: "docx/chart",
12447
12543
  path: path3,
12448
12544
  componentName: typeof node.name === "string" ? node.name : "",
12449
- paletteTokens
12545
+ paletteTokens,
12546
+ generated: false
12450
12547
  };
12451
12548
  if (node.name === "highcharts") {
12452
12549
  const shape = normalizeHighchartsChart(props.options);
@@ -12457,7 +12554,11 @@ function chartFact(node, props, path3, paletteTokens) {
12457
12554
  threeD: shape.threeD,
12458
12555
  seriesCount: shape.seriesCount,
12459
12556
  categoryCount: shape.categoryCount,
12460
- seriesColorsStated: shape.seriesColorsStated,
12557
+ // A config that names no `colors` is painted in the theme's chart
12558
+ // palette at render, so the series are the document's whenever the
12559
+ // theme has a palette to give; only a theme with none leaves them to
12560
+ // the export server's default.
12561
+ seriesColorsStated: shape.seriesColorsStated || paletteTokens.length > 0,
12461
12562
  seriesColorsPath: `${path3}/props/options`,
12462
12563
  ...shape.valueAxisMin !== void 0 && {
12463
12564
  valueAxisMin: shape.valueAxisMin
@@ -12574,6 +12675,7 @@ function tableDesignFact(props, path3, theme, themeName, authored) {
12574
12675
  alignment: alignments.size === 1 ? [...alignments][0] : alignments.size === 0 ? "left" : "mixed",
12575
12676
  hasCellDefaults: asRecord(authoredColumn.cellDefaults) !== void 0,
12576
12677
  hasHeader: asRecord(authoredColumn.header) !== void 0,
12678
+ generated: false,
12577
12679
  cellsWithOwnAlignment: cells.flatMap((cell, cellIndex) => {
12578
12680
  const alignment2 = asRecord(cell)?.horizontalAlignment;
12579
12681
  return typeof alignment2 === "string" && DOCX_ALIGNMENTS.has(alignment2) && alignment2 !== "right" ? [cellIndex] : [];
@@ -12828,6 +12930,11 @@ function prepareDocxQualityDocument(document, options = {}) {
12828
12930
  ...fact.relatedPaths && { relatedPaths: fact.relatedPaths }
12829
12931
  };
12830
12932
  };
12933
+ const annotatedInvocations = new Set(
12934
+ blockSlotRoles2(themed.document, expanded.blocks).filter(
12935
+ (slot) => (slot.role === "takeaway" || slot.role === "source") && typeof slot.value === "string" && slot.value.trim() !== ""
12936
+ ).map((slot) => slot.invocation)
12937
+ );
12831
12938
  for (const budget of blockSlotBudgets(themed.document, expanded.blocks)) {
12832
12939
  addFact({
12833
12940
  id: `docx:block-slot:${budget.path}`,
@@ -12923,11 +13030,43 @@ function prepareDocxQualityDocument(document, options = {}) {
12923
13030
  context.themeName,
12924
13031
  authoredPropsAt(path3)
12925
13032
  );
12926
- if (design) addFact(design);
13033
+ if (design)
13034
+ addFact({
13035
+ ...design,
13036
+ columns: design.columns.map((column) => {
13037
+ const authored = authoredPath(column.path);
13038
+ const table2 = /^(.*)\/props\/columns\/\d+$/.exec(authored)?.[1];
13039
+ return {
13040
+ ...column,
13041
+ path: authored,
13042
+ generated: table2 === void 0 || asRecord(nodeAtPointer(themed.document, table2))?.name !== "table"
13043
+ };
13044
+ })
13045
+ });
12927
13046
  }
12928
13047
  if (node.name === "chart" || node.name === "highcharts") {
12929
13048
  const fact = chartFact(node, props, path3, paletteTokens);
12930
- if (fact) addFact(fact);
13049
+ if (fact) {
13050
+ const authored = authoredPath(path3);
13051
+ const invocation = expanded.blocks.filter(
13052
+ (pointer) => authored === pointer || authored.startsWith(`${pointer}/`)
13053
+ ).sort((a, b) => b.length - a.length)[0];
13054
+ const annotated = invocation !== void 0 && annotatedInvocations.has(invocation);
13055
+ addFact({
13056
+ ...fact,
13057
+ generated: !["chart", "highcharts"].includes(
13058
+ String(asRecord(nodeAtPointer(themed.document, authored))?.name)
13059
+ ),
13060
+ seriesColorsPath: authoredPath(fact.seriesColorsPath),
13061
+ ...fact.annotation && {
13062
+ annotation: {
13063
+ ...fact.annotation,
13064
+ path: authoredPath(fact.annotation.path),
13065
+ stated: fact.annotation.stated || annotated
13066
+ }
13067
+ }
13068
+ });
13069
+ }
12931
13070
  }
12932
13071
  if (node.name === "paragraph" || node.name === "text-box") {
12933
13072
  const floating = asRecord(props.floating);
@@ -13049,7 +13188,8 @@ async function compileDocumentScoped(document, options, warnings) {
13049
13188
  ...options.services ? { services: options.services } : {},
13050
13189
  ...options.baseDir !== void 0 ? { baseDir: options.baseDir } : {},
13051
13190
  ...visualFonts.length > 0 ? { visualFonts } : {},
13052
- ...chartFonts.length > 0 ? { chartFonts } : {}
13191
+ ...chartFonts.length > 0 ? { chartFonts } : {},
13192
+ warnings
13053
13193
  });
13054
13194
  const resolved = desugared === context.document ? prepared.model.document : resolveDocumentTree(desugared, context.theme);
13055
13195
  const structure = await processResolvedDocument(