@a3s-lab/office 0.29.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/README.md +117 -3
  2. package/dist/{0~7043.js → 0~4808.js} +347 -2
  3. package/dist/0~5050.js +10 -1
  4. package/dist/{0~5093.js → 0~7240.js} +465 -55
  5. package/dist/0~document-editor.js +1694 -187
  6. package/dist/0~spreadsheet-editor.js +183 -34
  7. package/dist/0~work-docx-export.js +507 -31
  8. package/dist/0~work-docx-import.js +41 -7
  9. package/dist/0~work-office-diagnostics.js +146 -5
  10. package/dist/1544.js +13 -1
  11. package/dist/4104.js +29 -6
  12. package/dist/4121.js +2340 -1
  13. package/dist/6282.js +1072 -1148
  14. package/dist/internal/features/work/editors/document-command-catalog.d.ts +45 -0
  15. package/dist/internal/features/work/editors/document-dom-selection.d.ts +7 -0
  16. package/dist/internal/features/work/editors/document-editor-support.d.ts +1 -0
  17. package/dist/internal/features/work/editors/document-font-dialog-model.d.ts +5 -2
  18. package/dist/internal/features/work/editors/document-font-dialog-run-shading-model.d.ts +23 -0
  19. package/dist/internal/features/work/editors/document-font-dialog-run-shading-section.d.ts +8 -0
  20. package/dist/internal/features/work/editors/document-index-dialog.d.ts +10 -0
  21. package/dist/internal/features/work/editors/document-index-entry-dialog.d.ts +10 -0
  22. package/dist/internal/features/work/editors/document-page-chrome-ribbon.d.ts +2 -1
  23. package/dist/internal/features/work/editors/document-proofing-dialog-model.d.ts +22 -0
  24. package/dist/internal/features/work/editors/document-proofing-dialog.d.ts +7 -0
  25. package/dist/internal/features/work/editors/document-references-ribbon.d.ts +19 -0
  26. package/dist/internal/features/work/editors/document-table-of-contents-dialog.d.ts +10 -0
  27. package/dist/internal/features/work/editors/document-toolbar.d.ts +6 -1
  28. package/dist/internal/features/work/editors/spreadsheet-data-validation.d.ts +7 -1
  29. package/dist/internal/features/work/editors/use-document-insert-commands.d.ts +5 -0
  30. package/dist/internal/features/work/work-document-character-formatting.d.ts +8 -0
  31. package/dist/internal/features/work/work-document-format-changes.d.ts +6 -0
  32. package/dist/internal/features/work/work-document-highlight.d.ts +9 -0
  33. package/dist/internal/features/work/work-document-index-fields.d.ts +19 -0
  34. package/dist/internal/features/work/work-document-index-nodes.d.ts +32 -0
  35. package/dist/internal/features/work/work-document-index.d.ts +63 -0
  36. package/dist/internal/features/work/work-document-outline.d.ts +1 -0
  37. package/dist/internal/features/work/work-document-paragraph-shading.d.ts +6 -0
  38. package/dist/internal/features/work/work-document-proofing.d.ts +19 -0
  39. package/dist/internal/features/work/work-document-run-shading.d.ts +12 -0
  40. package/dist/internal/features/work/work-document-table-of-contents-node.d.ts +18 -0
  41. package/dist/internal/features/work/work-document-table-of-contents.d.ts +51 -0
  42. package/dist/internal/features/work/work-document-word-line-metrics.d.ts +3 -0
  43. package/dist/internal/features/work/work-docx-field-instructions.d.ts +1 -1
  44. package/dist/internal/features/work/work-docx-import.d.ts +5 -1
  45. package/dist/internal/features/work/work-docx-index-export.d.ts +14 -0
  46. package/dist/internal/features/work/work-docx-index-import.d.ts +23 -0
  47. package/dist/internal/features/work/work-docx-proofing-diagnostics.d.ts +3 -0
  48. package/dist/internal/features/work/work-docx-proofing.d.ts +38 -0
  49. package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +7 -0
  50. package/dist/internal/features/work/work-docx-run-shading-diagnostics.d.ts +3 -0
  51. package/dist/internal/features/work/work-docx-run-shading-export.d.ts +17 -0
  52. package/dist/internal/features/work/work-docx-run-shading.d.ts +20 -0
  53. package/dist/internal/features/work/work-docx-table-of-contents-export.d.ts +11 -0
  54. package/dist/internal/features/work/work-docx-table-of-contents-import.d.ts +15 -0
  55. package/dist/internal/features/work/work-spreadsheet-data-validation.d.ts +7 -0
  56. package/dist/internal/features/work/work-types.d.ts +9 -0
  57. package/dist/internal/kernel/office-kernel-protocol.d.ts +1 -0
  58. package/dist/office-kernel.wasm +0 -0
  59. package/dist/styles.css +607 -4
  60. package/docs/latest/en/browser-editor-architecture.md +64 -1
  61. package/package.json +15 -2
@@ -1,8 +1,8 @@
1
1
  import jszip from "jszip";
2
- import { normalizeDocumentBookmarkName, normalizeDocumentEmphasisMark, DOCUMENT_STRIKE_STYLE_ATTRIBUTE, applyDocumentImageIdentityToElement, documentEmphasisMarkFromElement, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_UNDERLINE_STYLE_ATTRIBUTE, documentScriptFontSlotFromElement, normalizeDocumentColumns, createDocumentImageIdentityRegistry, serializeDocumentScriptFonts, documentCharacterSpacingTwipsFromElement, uniqueDocumentParagraphIdentity, documentCharacterPositionHalfPointsFromElement, normalizeDocumentTableVerticalAlign, documentTableColumnPercentagesFromElement, normalizeDocumentTextCase, documentTableCellMarginOverridesFromElement, applyDocumentTableRowIdentityToElement, normalizeDocumentBookmarksHtml, documentImageIdentityFromElement, documentTableGeometryFromElement, normalizeDocumentTableRowHeightRule, normalizeDocumentScriptFonts, documentNoteKey, DOCUMENT_LEGACY_TEXT_EMBOSS_ATTRIBUTE, normalizeDocumentHiddenText, documentLegacyTextEffectsConflict, normalizeDocumentTableBorderWidth, normalizeDocumentCharacterSpacingTwips, normalizeDocumentParagraphId, documentStrikeFormattingFromElement, normalizeDocumentTableBorderStyle, normalizeDocumentBookmarkReferencesHtml, documentCitationInstruction, documentImageWrapContourFromElement, documentImagePositionFromElement, normalizeDocumentCharacterScalePercent, documentScriptFontsFromElement, normalizeDocumentUnderlineStyle, documentPageMarginsForLayout, normalizeDocumentPageChrome, normalizeDocumentImageLayer, documentFontNameFromCssFamily, documentKerningThresholdHalfPointsFromElement, documentImageCropFromElement, documentBookmarkReferenceInstruction, normalizeDocumentPageBorders, documentImageLayerFromElement, normalizeDocumentLegacyTextEffects, documentCaptionLabel, documentCaptionKind, applyDocumentParagraphIdentityToElement, DOCUMENT_LEGACY_TEXT_IMPRINT_ATTRIBUTE, isContourImageLayout, parseDocumentScriptFonts, normalizeDocumentStrikeStyle, normalizeDocumentImageIdentity, createDocumentParagraphIdentityRegistry, documentCitationTags, docxDocumentFieldKind, normalizeTableColor, documentTableBordersFromElement, documentSections, wrapsBesideImage, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentKerningThresholdHalfPoints, defaultDocumentImageWrapContour, normalizeDocumentParagraphIdentity, normalizeDocumentPaperSource, DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE, documentEquationFromElement, documentLegacyTextEffectsFromElement, parseDocumentCharacterFormatting, documentScriptFontFamily, documentParagraphIdentityFromElement, DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE, normalizeDocumentEquation, documentUnderlineFormattingFromElement, normalizeDocumentBookmarkNativeId, parseDocumentParagraphShadingElement, DOCUMENT_PAGE_MARGIN_KEYS, uniqueDocumentImageIdentity, documentHiddenTextFromElement, parseDocumentParagraphFormatting, documentImageLayoutFromElement, documentScriptFontSlotFromHint, documentTableRowIdentityFromElement, documentPageHorizontalMarginTwips, collectDocumentNotes, documentPageGeometryForLayout, normalizeDocumentScriptFontSlot, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, documentCharacterScalePercentFromElement, normalizeDocumentPageMargins, normalizeDocumentLegacyTextEffect, documentNoteKind } from "./6282.js";
3
- import { normalizeDocumentParagraphBorders, serializeUtf8Xml, DOCUMENT_PARAGRAPH_BORDER_EDGES, normalizeDocumentRunBorder, parseDocumentRunBorder, parseXml, decodeXmlBytes, parseDocxThemeReference, patchDocxThemeReferences, descendants, resolvePartTarget, attribute as work_ooxml_package_attribute, parseDocumentParagraphBordersElement, DOCUMENT_RUN_BORDER_ATTRIBUTE, directChildren, xmlNamespacePrefix, parseDocumentRunBorderElement, DocxThemePatchCollector, directChild } from "./4121.js";
2
+ import { normalizeDocumentBookmarkName, normalizeDocumentEmphasisMark, DOCUMENT_STRIKE_STYLE_ATTRIBUTE, applyDocumentImageIdentityToElement, documentEmphasisMarkFromElement, DOCUMENT_PAGE_BORDER_EDGES, DOCUMENT_UNDERLINE_STYLE_ATTRIBUTE, createDocumentImageIdentityRegistry, normalizeDocumentColumns, normalizeDocumentTableVerticalAlign, normalizeDocumentTextCase, documentCharacterSpacingTwipsFromElement, documentCharacterPositionHalfPointsFromElement, documentTableColumnPercentagesFromElement, documentTableCellMarginOverridesFromElement, applyDocumentTableRowIdentityToElement, normalizeDocumentBookmarksHtml, documentImageIdentityFromElement, documentTableGeometryFromElement, normalizeDocumentTableRowHeightRule, documentNoteKey, DOCUMENT_LEGACY_TEXT_EMBOSS_ATTRIBUTE, normalizeDocumentHiddenText, documentLegacyTextEffectsConflict, normalizeDocumentTableBorderWidth, normalizeDocumentCharacterSpacingTwips, documentStrikeFormattingFromElement, normalizeDocumentTableBorderStyle, normalizeDocumentBookmarkReferencesHtml, documentCitationInstruction, documentImageWrapContourFromElement, documentImagePositionFromElement, normalizeDocumentCharacterScalePercent, normalizeDocumentUnderlineStyle, normalizeDocumentPageChrome, documentPageMarginsForLayout, normalizeDocumentImageLayer, documentKerningThresholdHalfPointsFromElement, documentImageCropFromElement, documentBookmarkReferenceInstruction, normalizeDocumentPageBorders, documentImageLayerFromElement, normalizeDocumentLegacyTextEffects, documentCaptionLabel, documentCaptionKind, DOCUMENT_LEGACY_TEXT_IMPRINT_ATTRIBUTE, isContourImageLayout, normalizeDocumentImageIdentity, normalizeTableColor, normalizeDocumentStrikeStyle, documentTableBordersFromElement, documentSections, documentCitationTags, docxDocumentFieldKind, wrapsBesideImage, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentKerningThresholdHalfPoints, defaultDocumentImageWrapContour, normalizeDocumentPaperSource, DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE, documentEquationFromElement, documentLegacyTextEffectsFromElement, parseDocumentCharacterFormatting, documentUnderlineFormattingFromElement, DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE, normalizeDocumentEquation, parseDocumentParagraphFormatting, documentTableRowIdentityFromElement, normalizeDocumentBookmarkNativeId, collectDocumentNotes, DOCUMENT_PAGE_MARGIN_KEYS, uniqueDocumentImageIdentity, documentHiddenTextFromElement, documentImageLayoutFromElement, documentPageHorizontalMarginTwips, documentPageGeometryForLayout, DOCUMENT_LEGACY_TEXT_EFFECT_NAMES, documentCharacterScalePercentFromElement, normalizeDocumentPageMargins, normalizeDocumentLegacyTextEffect, documentNoteKind } from "./6282.js";
3
+ import { normalizeDocumentRunBorder, parseDocumentScriptFonts, normalizeDocumentIndexesHtml, parseXml, parseDocumentRunShading, applyDocumentParagraphIdentityToElement, DOCUMENT_RUN_SHADING_ATTRIBUTE, documentScriptFontSlotFromElement, DOCUMENT_HIGHLIGHT_ATTRIBUTE, parseDocxThemeReference, serializeDocumentScriptFonts, attribute as work_ooxml_package_attribute, createDocumentParagraphIdentityRegistry, uniqueDocumentParagraphIdentity, DOCUMENT_NO_PROOF_ATTRIBUTE, documentHighlightForCssColor, directChildren, documentTableOfContentsValueFromElement, DOCUMENT_PROOFING_LANGUAGES_ATTRIBUTE, DocxThemePatchCollector, normalizeDocumentScriptFonts, normalizeDocumentParagraphIdentity, normalizeDocumentHighlight, normalizeDocumentParagraphBorders, serializeUtf8Xml, DOCUMENT_PARAGRAPH_BORDER_EDGES, parseDocumentRunBorder, normalizeDocumentNoProof, decodeXmlBytes, documentParagraphIdentityFromElement, normalizeDocumentParagraphId, documentIndexValueFromElement, descendants, resolvePartTarget, documentProofingLanguagesFromElement, documentScriptFontFamily, parseDocumentRunShadingElement, parseDocumentProofingLanguages, documentHighlightFromElement, parseDocumentParagraphBordersElement, DOCUMENT_RUN_BORDER_ATTRIBUTE, parseDocumentRunBorderElement, xmlNamespacePrefix, documentScriptFontSlotFromHint, documentNoProofFromElement, documentScriptFontsFromElement, normalizeDocumentRunShading, documentIndexEntryFromElement, directChild, normalizeDocumentScriptFontSlot, patchDocxThemeReferences, parseDocumentParagraphShadingElement, documentFontNameFromCssFamily } from "./4121.js";
4
4
  import { assignDocxNoteIds, patchDocxPageColor, normalizeDocxCommentId, assignDocxCommentThreads } from "./0~4980.js";
5
- import { paragraphTabStops, mergeDocxIgnorableExtensionsAtPairs, patchDocxBibliography, docxKerningThresholdValue, docxCharacterPositionValue, docxCharacterScaleValue, docxEmphasisMarkRunOptions, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, paragraphAlignment, paragraphSpacingOptions, xmlNamespaceUri, hasNonWhitespaceXmlText, patchDocxExplicitZeroCharacterSpacing, cloneXmlElement, cssColorToHex, DocxParagraphDefaultCollapsedPatchCollector, assertXmlRoot, xmlDeclaredPrefix, paragraphIndent, domDirection, DOCX_WORDPROCESSING_NAMESPACES, paragraphBidirectional, XML_NAMESPACE as work_docx_settings_xml_XML_NAMESPACE, patchDocxParagraphDefaultCollapsed, xmlAttributeNamespace, dataBoolean, mergeDocxIgnorableExtensions, patchDocxExplicitZeroKerningThresholds, parseDocxColorSchemeMappingElement, paragraphPaginationOptions, DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, xmlAttributeLocalName, cssFontSize, paragraphDirectionOptions, cssFontFamily, docxCharacterSpacingValue } from "./0~7043.js";
5
+ import { paragraphTabStops, mergeDocxIgnorableExtensionsAtPairs, patchDocxBibliography, docxKerningThresholdValue, docxCharacterPositionValue, documentIndexInstruction, docxCharacterScaleValue, XMLNS_NAMESPACE as work_docx_settings_xml_XMLNS_NAMESPACE, paragraphAlignment, xmlNamespaceUri, paragraphSpacingOptions, docxEmphasisMarkRunOptions, documentIndexEntryInstruction, hasNonWhitespaceXmlText, patchDocxExplicitZeroCharacterSpacing, cloneXmlElement, cssColorToHex, xmlDeclaredPrefix, assertXmlRoot, DOCX_WORDPROCESSING_NAMESPACES, paragraphIndent, domDirection, xmlAttributeNamespace, paragraphBidirectional, XML_NAMESPACE as work_docx_settings_xml_XML_NAMESPACE, mergeDocxIgnorableExtensions, DocxParagraphDefaultCollapsedPatchCollector, dataBoolean, patchDocxParagraphDefaultCollapsed, patchDocxExplicitZeroKerningThresholds, parseDocxColorSchemeMappingElement, paragraphPaginationOptions, DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, documentProofingLanguageDocxOptions, xmlAttributeLocalName, cssFontSize, paragraphDirectionOptions, cssFontFamily, docxCharacterSpacingValue } from "./0~4808.js";
6
6
  import { normalizeDocumentHref } from "./0~work-document-links.js";
7
7
  const WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
8
8
  class DocxBookmarkPatchCollector {
@@ -2374,6 +2374,292 @@ function docxDocumentFieldRun(element, docx) {
2374
2374
  if (!docxDocumentFieldKind(instruction)) return new docx.TextRun(display);
2375
2375
  return new docx.SimpleField(instruction, display);
2376
2376
  }
2377
+ const work_docx_index_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
2378
+ const work_docx_index_export_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
2379
+ class DocxIndexPatchCollector {
2380
+ patches = [];
2381
+ add(element) {
2382
+ const value = documentIndexValueFromElement(element);
2383
+ const patch = {
2384
+ marker: `__A3S_WORK_DOCUMENT_INDEX_${this.patches.length + 1}__`,
2385
+ options: value.options,
2386
+ entries: value.entries
2387
+ };
2388
+ this.patches.push(patch);
2389
+ return patch;
2390
+ }
2391
+ }
2392
+ function docxDocumentIndex(element, docx, collector) {
2393
+ const patch = collector.add(element);
2394
+ return [
2395
+ new docx.Paragraph({
2396
+ children: [
2397
+ new docx.TextRun(patch.marker)
2398
+ ]
2399
+ })
2400
+ ];
2401
+ }
2402
+ function docxIndexEntryRun(element, docx) {
2403
+ const value = documentIndexEntryFromElement(element);
2404
+ return value ? new docx.SimpleField(documentIndexEntryInstruction(value)) : null;
2405
+ }
2406
+ async function patchDocxIndexes(buffer, patches) {
2407
+ if (!patches.length) return buffer;
2408
+ const archive = await jszip.loadAsync(buffer);
2409
+ const entry = archive.file('word/document.xml');
2410
+ if (!entry) return buffer;
2411
+ const document = parseXml(await entry.async('text'), 'generated DOCX word/document.xml');
2412
+ const paragraphs = descendants(document, 'p');
2413
+ for (const patch of patches){
2414
+ const paragraph = paragraphs.find((candidate)=>descendants(candidate, 't').some((text)=>(text.textContent ?? '').includes(patch.marker)));
2415
+ if (!paragraph) throw new Error(`Generated DOCX did not emit the marker for document index ${patch.marker}.`);
2416
+ paragraph.replaceWith(createIndexContentControl(document, patch));
2417
+ }
2418
+ archive.file('word/document.xml', new XMLSerializer().serializeToString(document));
2419
+ return archive.generateAsync({
2420
+ type: 'arraybuffer'
2421
+ });
2422
+ }
2423
+ function createIndexContentControl(document, patch) {
2424
+ const control = wordElement(document, 'sdt');
2425
+ const properties = wordElement(document, 'sdtPr');
2426
+ const documentPart = wordElement(document, 'docPartObj');
2427
+ const gallery = wordElement(document, 'docPartGallery');
2428
+ work_docx_index_export_setWordAttribute(document, gallery, 'val', 'Indexes');
2429
+ documentPart.append(gallery, wordElement(document, 'docPartUnique'));
2430
+ properties.append(documentPart);
2431
+ const content = wordElement(document, 'sdtContent');
2432
+ const fieldStart = indexFieldStartParagraph(document, patch.options);
2433
+ content.append(fieldStart);
2434
+ const cached = cachedIndexParagraphs(document, patch);
2435
+ if (!cached.length) cached.push(emptyIndexParagraph(document));
2436
+ const last = cached.at(-1);
2437
+ last?.append(fieldCharacterRun(document, 'end'));
2438
+ content.append(...cached);
2439
+ control.append(properties, content);
2440
+ return control;
2441
+ }
2442
+ function indexFieldStartParagraph(document, options) {
2443
+ const paragraph = wordElement(document, 'p');
2444
+ paragraph.append(fieldCharacterRun(document, 'begin'));
2445
+ const instructionRun = wordElement(document, 'r');
2446
+ const instruction = wordElement(document, 'instrText');
2447
+ instruction.setAttributeNS(work_docx_index_export_XML_NAMESPACE, 'xml:space', 'preserve');
2448
+ instruction.textContent = ` ${documentIndexInstruction(options)} `;
2449
+ instructionRun.append(instruction);
2450
+ paragraph.append(instructionRun, fieldCharacterRun(document, 'separate'));
2451
+ return paragraph;
2452
+ }
2453
+ function cachedIndexParagraphs(document, patch) {
2454
+ const paragraphs = [];
2455
+ let currentMain = '';
2456
+ for (const entry of patch.entries){
2457
+ if (entry.subEntry && entry.mainEntry !== currentMain) paragraphs.push(cachedIndexParagraph(document, patch.options, {
2458
+ style: 'Index1',
2459
+ term: entry.mainEntry,
2460
+ crossReference: '',
2461
+ pages: []
2462
+ }));
2463
+ paragraphs.push(cachedIndexParagraph(document, patch.options, {
2464
+ style: entry.subEntry ? 'Index2' : 'Index1',
2465
+ term: entry.subEntry || entry.mainEntry,
2466
+ crossReference: entry.crossReference,
2467
+ pages: entry.pages
2468
+ }));
2469
+ currentMain = entry.mainEntry;
2470
+ }
2471
+ return paragraphs;
2472
+ }
2473
+ function cachedIndexParagraph(document, options, source) {
2474
+ const paragraph = wordElement(document, 'p');
2475
+ const properties = wordElement(document, 'pPr');
2476
+ const style = wordElement(document, 'pStyle');
2477
+ work_docx_index_export_setWordAttribute(document, style, 'val', source.style);
2478
+ properties.append(style);
2479
+ if (source.pages.length && options.rightAlignPageNumbers) {
2480
+ const tabs = wordElement(document, 'tabs');
2481
+ const tab = wordElement(document, 'tab');
2482
+ work_docx_index_export_setWordAttribute(document, tab, 'val', 'right');
2483
+ const leader = docxIndexLeader(options.leader);
2484
+ if (leader) work_docx_index_export_setWordAttribute(document, tab, 'leader', leader);
2485
+ work_docx_index_export_setWordAttribute(document, tab, 'pos', '9360');
2486
+ tabs.append(tab);
2487
+ properties.append(tabs);
2488
+ }
2489
+ paragraph.append(properties, textRun(document, source.term));
2490
+ if (source.crossReference) {
2491
+ paragraph.append(textRun(document, `, See ${source.crossReference}`));
2492
+ return paragraph;
2493
+ }
2494
+ if (!source.pages.length) return paragraph;
2495
+ paragraph.append(options.rightAlignPageNumbers ? tabRun(document) : textRun(document, ', '));
2496
+ for (const [index, page] of source.pages.entries()){
2497
+ if (index > 0) paragraph.append(textRun(document, ', '));
2498
+ paragraph.append(textRun(document, String(page.pageNumber), {
2499
+ bold: page.pageBold,
2500
+ italic: page.pageItalic
2501
+ }));
2502
+ }
2503
+ return paragraph;
2504
+ }
2505
+ function emptyIndexParagraph(document) {
2506
+ const paragraph = wordElement(document, 'p');
2507
+ const properties = wordElement(document, 'pPr');
2508
+ const style = wordElement(document, 'pStyle');
2509
+ work_docx_index_export_setWordAttribute(document, style, 'val', 'Index1');
2510
+ properties.append(style);
2511
+ paragraph.append(properties);
2512
+ return paragraph;
2513
+ }
2514
+ function textRun(document, value, style = {}) {
2515
+ const run = wordElement(document, 'r');
2516
+ if (style.bold || style.italic) {
2517
+ const properties = wordElement(document, 'rPr');
2518
+ if (style.bold) properties.append(wordElement(document, 'b'));
2519
+ if (style.italic) properties.append(wordElement(document, 'i'));
2520
+ run.append(properties);
2521
+ }
2522
+ const text = wordElement(document, 't');
2523
+ if (/^\s|\s$/.test(value)) text.setAttributeNS(work_docx_index_export_XML_NAMESPACE, 'xml:space', 'preserve');
2524
+ text.textContent = value;
2525
+ run.append(text);
2526
+ return run;
2527
+ }
2528
+ function tabRun(document) {
2529
+ const run = wordElement(document, 'r');
2530
+ run.append(wordElement(document, 'tab'));
2531
+ return run;
2532
+ }
2533
+ function fieldCharacterRun(document, type) {
2534
+ const run = wordElement(document, 'r');
2535
+ const character = wordElement(document, 'fldChar');
2536
+ work_docx_index_export_setWordAttribute(document, character, 'fldCharType', type);
2537
+ run.append(character);
2538
+ return run;
2539
+ }
2540
+ function docxIndexLeader(value) {
2541
+ if ('dash' === value) return 'hyphen';
2542
+ if ('underline' === value) return 'underscore';
2543
+ if ('dot' === value) return 'dot';
2544
+ return null;
2545
+ }
2546
+ function wordElement(document, localName) {
2547
+ return document.createElementNS(work_docx_index_export_WORD_NAMESPACE, wordQualifiedName(document.documentElement, localName));
2548
+ }
2549
+ function work_docx_index_export_setWordAttribute(document, element, localName, value) {
2550
+ for (const candidate of Array.from(element.attributes))if (candidate.localName === localName && (candidate.namespaceURI === work_docx_index_export_WORD_NAMESPACE || !candidate.namespaceURI)) element.removeAttributeNode(candidate);
2551
+ element.setAttributeNS(work_docx_index_export_WORD_NAMESPACE, wordQualifiedName(document.documentElement, localName), value);
2552
+ }
2553
+ function wordQualifiedName(root, localName) {
2554
+ return `${xmlNamespacePrefix(root, work_docx_index_export_WORD_NAMESPACE) ?? 'w'}:${localName}`;
2555
+ }
2556
+ const work_docx_run_shading_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
2557
+ class DocxRunShadingPatchCollector {
2558
+ patches = [];
2559
+ nextMarker = 1;
2560
+ usedColors;
2561
+ constructor(sourceHtml){
2562
+ this.usedColors = work_docx_run_shading_export_sourceColors(sourceHtml);
2563
+ }
2564
+ marker(source) {
2565
+ const shading = normalizeDocumentRunShading(source);
2566
+ if (!shading) return null;
2567
+ let marker = '';
2568
+ do {
2569
+ const value = 0xd00000 + this.nextMarker;
2570
+ if (value > 0xdfffff) throw new Error('DOCX character shading marker space is exhausted.');
2571
+ marker = value.toString(16).padStart(6, '0').toUpperCase();
2572
+ this.nextMarker += 1;
2573
+ }while (this.usedColors.has(marker))
2574
+ this.usedColors.add(marker);
2575
+ this.patches.push({
2576
+ marker,
2577
+ shading
2578
+ });
2579
+ return marker;
2580
+ }
2581
+ hasMarker(value) {
2582
+ const marker = value?.toUpperCase();
2583
+ return Boolean(marker && this.patches.some((patch)=>patch.marker === marker));
2584
+ }
2585
+ }
2586
+ function documentRunShadingDocxOptions(source, collector) {
2587
+ const marker = collector.marker(source);
2588
+ return marker ? {
2589
+ shading: {
2590
+ type: 'clear',
2591
+ color: 'auto',
2592
+ fill: marker
2593
+ }
2594
+ } : {};
2595
+ }
2596
+ async function patchDocxRunShading(buffer, patches) {
2597
+ if (!patches.length) return buffer;
2598
+ const archive = await jszip.loadAsync(buffer);
2599
+ const byMarker = new Map(patches.map((patch)=>[
2600
+ patch.marker,
2601
+ patch
2602
+ ]));
2603
+ const applied = new Set();
2604
+ for (const entry of Object.values(archive.files)){
2605
+ if (entry.dir || !/^word\/(?:document|header\d+|footer\d+|footnotes|endnotes|comments)\.xml$/i.test(entry.name)) continue;
2606
+ const document = parseXml(await entry.async('text'), entry.name);
2607
+ let changed = false;
2608
+ for (const element of Array.from(document.getElementsByTagName('*'))){
2609
+ if ('shd' !== element.localName || element.namespaceURI !== work_docx_run_shading_export_WORD_NAMESPACE || element.parentElement?.localName !== 'rPr') continue;
2610
+ const marker = work_docx_run_shading_export_wordAttribute(element, 'fill')?.toUpperCase();
2611
+ const patch = marker ? byMarker.get(marker) : void 0;
2612
+ if (marker && patch) {
2613
+ replaceRunShadingAttributes(document, element, patch.shading);
2614
+ applied.add(marker);
2615
+ changed = true;
2616
+ }
2617
+ }
2618
+ if (changed) archive.file(entry.name, serializeUtf8Xml(document));
2619
+ }
2620
+ const missing = patches.filter((patch)=>!applied.has(patch.marker));
2621
+ if (missing.length) throw new Error(`Generated DOCX is missing ${missing.length} character shading marker(s).`);
2622
+ return archive.generateAsync({
2623
+ type: 'arraybuffer'
2624
+ });
2625
+ }
2626
+ function setDocxRunShadingAttributes(document, element, source) {
2627
+ const shading = normalizeDocumentRunShading(source);
2628
+ if (!shading) return false;
2629
+ work_docx_run_shading_export_setWordAttribute(document, element, 'val', shading.pattern);
2630
+ setShadingColorAttributes(document, element, shading.color, 'color');
2631
+ setShadingColorAttributes(document, element, shading.fill, 'fill');
2632
+ return true;
2633
+ }
2634
+ function replaceRunShadingAttributes(document, element, shading) {
2635
+ for (const attribute of Array.from(element.attributes))if ('xmlns' !== attribute.name && !attribute.name.startsWith('xmlns:')) element.removeAttributeNode(attribute);
2636
+ element.replaceChildren();
2637
+ setDocxRunShadingAttributes(document, element, shading);
2638
+ }
2639
+ function setShadingColorAttributes(document, element, color, kind) {
2640
+ if (!color) return;
2641
+ work_docx_run_shading_export_setWordAttribute(document, element, kind, 'auto' === color.value ? 'auto' : color.value.slice(1).toUpperCase());
2642
+ if (!color.theme) return;
2643
+ const themeName = 'color' === kind ? 'themeColor' : 'themeFill';
2644
+ const tintName = 'color' === kind ? 'themeTint' : 'themeFillTint';
2645
+ const shadeName = 'color' === kind ? 'themeShade' : 'themeFillShade';
2646
+ work_docx_run_shading_export_setWordAttribute(document, element, themeName, color.theme.theme);
2647
+ if (color.theme.tint) work_docx_run_shading_export_setWordAttribute(document, element, tintName, color.theme.tint);
2648
+ if (color.theme.shade) work_docx_run_shading_export_setWordAttribute(document, element, shadeName, color.theme.shade);
2649
+ }
2650
+ function work_docx_run_shading_export_sourceColors(source) {
2651
+ const colors = new Set();
2652
+ for (const match of source.matchAll(/#([0-9a-f]{6})\b/gi))if (match[1]) colors.add(match[1].toUpperCase());
2653
+ return colors;
2654
+ }
2655
+ function work_docx_run_shading_export_wordAttribute(element, name) {
2656
+ return element.getAttributeNS(element.namespaceURI ?? work_docx_run_shading_export_WORD_NAMESPACE, name) ?? element.getAttribute(`${element.prefix ?? 'w'}:${name}`);
2657
+ }
2658
+ function work_docx_run_shading_export_setWordAttribute(document, element, name, value) {
2659
+ const namespace = element.namespaceURI ?? work_docx_run_shading_export_WORD_NAMESPACE;
2660
+ const prefix = element.prefix ?? xmlNamespacePrefix(document.documentElement, namespace) ?? 'w';
2661
+ element.setAttributeNS(namespace, `${prefix}:${name}`, value);
2662
+ }
2377
2663
  const MAX_RUN_FORMATTING_CHANGE_PATCHES = 65536;
2378
2664
  const RUN_FORMATTING_PART_PATTERN = /^word\/(?:document|header\d*|footer\d*|footnotes|endnotes)\.xml$/i;
2379
2665
  class DocxRunFormattingChangePatchCollector {
@@ -2474,17 +2760,17 @@ function setRunFormattingChange(document, run, patch) {
2474
2760
  if (existing.length > 1) throw new Error('Generated DOCX run contains duplicate properties.');
2475
2761
  const properties = existing[0] ?? insertRunProperties(document, run, wordNamespace, prefix);
2476
2762
  if (directChildren(properties, 'rPrChange').some((element)=>element.namespaceURI === wordNamespace)) throw new Error('Generated DOCX run already contains a formatting revision.');
2477
- const change = wordElement(document, wordNamespace, prefix, 'rPrChange');
2763
+ const change = work_docx_format_change_export_wordElement(document, wordNamespace, prefix, 'rPrChange');
2478
2764
  work_docx_format_change_export_setWordAttribute(change, wordNamespace, prefix, 'id', String(patch.id));
2479
2765
  work_docx_format_change_export_setWordAttribute(change, wordNamespace, prefix, 'author', patch.author);
2480
2766
  work_docx_format_change_export_setWordAttribute(change, wordNamespace, prefix, 'date', patch.date);
2481
- const before = wordElement(document, wordNamespace, prefix, 'rPr');
2767
+ const before = work_docx_format_change_export_wordElement(document, wordNamespace, prefix, 'rPr');
2482
2768
  appendFormattingProperties(document, before, wordNamespace, prefix, patch.before);
2483
2769
  change.append(before);
2484
2770
  properties.append(change);
2485
2771
  }
2486
2772
  function insertRunProperties(document, run, namespace, prefix) {
2487
- const properties = wordElement(document, namespace, prefix, 'rPr');
2773
+ const properties = work_docx_format_change_export_wordElement(document, namespace, prefix, 'rPr');
2488
2774
  run.insertBefore(properties, run.firstChild);
2489
2775
  return properties;
2490
2776
  }
@@ -2503,6 +2789,7 @@ function appendFormattingProperties(document, properties, namespace, prefix, ser
2503
2789
  appendTextCaseProperties(document, properties, namespace, prefix, byType.get('textStyle'));
2504
2790
  appendStrikeProperties(document, properties, namespace, prefix, byType.get('strike'));
2505
2791
  appendLegacyTextEffectsProperties(document, properties, namespace, prefix, byType.get('textStyle'));
2792
+ appendNoProofProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2506
2793
  appendSnapToGridProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2507
2794
  appendHiddenTextProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2508
2795
  appendColorProperty(document, properties, namespace, prefix, byType.get('textStyle'));
@@ -2511,16 +2798,33 @@ function appendFormattingProperties(document, properties, namespace, prefix, ser
2511
2798
  appendKerningThresholdProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2512
2799
  appendCharacterPositionProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2513
2800
  appendFontSizeProperties(document, properties, namespace, prefix, byType.get('textStyle'));
2514
- appendHighlightProperty(document, properties, namespace, prefix, byType.get('highlight'));
2801
+ appendHighlightProperty(document, properties, namespace, prefix, byType.get('highlight'), !parseDocumentRunShading(byType.get('textStyle')?.attrs?.runShading));
2515
2802
  appendUnderlineProperty(document, properties, namespace, prefix, byType.get('underline'));
2516
2803
  appendRunBorderProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2804
+ appendRunShadingProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2517
2805
  appendVerticalAlignProperty(document, properties, namespace, prefix, byType);
2518
2806
  appendEmphasisMarkProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2807
+ appendProofingLanguagesProperty(document, properties, namespace, prefix, byType.get('textStyle'));
2808
+ }
2809
+ function appendNoProofProperty(document, properties, namespace, prefix, mark) {
2810
+ const noProof = normalizeDocumentNoProof(mark?.attrs?.noProof);
2811
+ if (null === noProof) return;
2812
+ if (noProof) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, 'noProof'));
2813
+ else appendValuedProperty(document, properties, namespace, prefix, 'noProof', '0');
2814
+ }
2815
+ function appendProofingLanguagesProperty(document, properties, namespace, prefix, mark) {
2816
+ const languages = parseDocumentProofingLanguages(mark?.attrs?.proofingLanguages);
2817
+ if (!languages) return;
2818
+ const element = work_docx_format_change_export_wordElement(document, namespace, prefix, 'lang');
2819
+ if (languages.latin) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'val', languages.latin);
2820
+ if (languages.eastAsia) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'eastAsia', languages.eastAsia);
2821
+ if (languages.bidi) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'bidi', languages.bidi);
2822
+ properties.append(element);
2519
2823
  }
2520
2824
  function appendRunBorderProperty(document, properties, namespace, prefix, mark) {
2521
2825
  const border = parseDocumentRunBorder(mark?.attrs?.runBorder);
2522
2826
  if (!border) return;
2523
- const element = wordElement(document, namespace, prefix, 'bdr');
2827
+ const element = work_docx_format_change_export_wordElement(document, namespace, prefix, 'bdr');
2524
2828
  work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'val', border.style);
2525
2829
  if (border.color) {
2526
2830
  work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'color', 'auto' === border.color.value ? 'auto' : border.color.value.slice(1).toUpperCase());
@@ -2536,6 +2840,13 @@ function appendRunBorderProperty(document, properties, namespace, prefix, mark)
2536
2840
  if (void 0 !== border.frame) work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'frame', border.frame ? '1' : '0');
2537
2841
  properties.append(element);
2538
2842
  }
2843
+ function appendRunShadingProperty(document, properties, namespace, prefix, mark) {
2844
+ const shading = parseDocumentRunShading(mark?.attrs?.runShading);
2845
+ if (!shading) return;
2846
+ const element = work_docx_format_change_export_wordElement(document, namespace, prefix, 'shd');
2847
+ if (!setDocxRunShadingAttributes(document, element, shading)) return;
2848
+ properties.append(element);
2849
+ }
2539
2850
  function appendLegacyTextEffectsProperties(document, properties, namespace, prefix, mark) {
2540
2851
  const effects = {};
2541
2852
  const attributes = [
@@ -2563,14 +2874,14 @@ function appendLegacyTextEffectsProperties(document, properties, namespace, pref
2563
2874
  if (documentLegacyTextEffectsConflict(effects)) throw new Error('Document contains conflicting legacy text effects.');
2564
2875
  for (const name of DOCUMENT_LEGACY_TEXT_EFFECT_NAMES){
2565
2876
  const value = effects[name];
2566
- if (void 0 !== value) if (value) properties.append(wordElement(document, namespace, prefix, name));
2877
+ if (void 0 !== value) if (value) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, name));
2567
2878
  else appendValuedProperty(document, properties, namespace, prefix, name, '0');
2568
2879
  }
2569
2880
  }
2570
2881
  function appendHiddenTextProperty(document, properties, namespace, prefix, mark) {
2571
2882
  const hiddenText = normalizeDocumentHiddenText(mark?.attrs?.hiddenText);
2572
2883
  if (null === hiddenText) return;
2573
- if (hiddenText) properties.append(wordElement(document, namespace, prefix, 'vanish'));
2884
+ if (hiddenText) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, 'vanish'));
2574
2885
  else appendValuedProperty(document, properties, namespace, prefix, 'vanish', '0');
2575
2886
  }
2576
2887
  function appendEmphasisMarkProperty(document, properties, namespace, prefix, mark) {
@@ -2601,7 +2912,7 @@ function appendCharacterSpacingProperty(document, properties, namespace, prefix,
2601
2912
  function appendFontProperties(document, properties, namespace, prefix, mark) {
2602
2913
  const scriptFonts = parseDocumentScriptFonts('string' == typeof mark?.attrs?.scriptFonts ? mark.attrs.scriptFonts : void 0);
2603
2914
  if (scriptFonts) {
2604
- const fonts = wordElement(document, namespace, prefix, 'rFonts');
2915
+ const fonts = work_docx_format_change_export_wordElement(document, namespace, prefix, 'rFonts');
2605
2916
  for (const [name, value] of [
2606
2917
  [
2607
2918
  'ascii',
@@ -2645,7 +2956,7 @@ function appendFontProperties(document, properties, namespace, prefix, mark) {
2645
2956
  }
2646
2957
  const family = firstFontFamily(mark?.attrs?.fontFamily);
2647
2958
  if (!family) return;
2648
- const fonts = wordElement(document, namespace, prefix, 'rFonts');
2959
+ const fonts = work_docx_format_change_export_wordElement(document, namespace, prefix, 'rFonts');
2649
2960
  for (const name of [
2650
2961
  'ascii',
2651
2962
  'hAnsi',
@@ -2659,7 +2970,7 @@ function appendUnderlineProperty(document, properties, namespace, prefix, mark)
2659
2970
  const style = normalizeDocumentUnderlineStyle(mark.attrs?.underlineStyle) ?? 'single';
2660
2971
  const color = normalizedHex(mark.attrs?.underlineColor);
2661
2972
  const theme = themeReference(mark.attrs?.underlineThemeColor);
2662
- const underline = wordElement(document, namespace, prefix, 'u');
2973
+ const underline = work_docx_format_change_export_wordElement(document, namespace, prefix, 'u');
2663
2974
  work_docx_format_change_export_setWordAttribute(underline, namespace, prefix, 'val', style);
2664
2975
  const resolved = color ?? normalizedHex(theme?.resolved);
2665
2976
  if (resolved) work_docx_format_change_export_setWordAttribute(underline, namespace, prefix, 'color', resolved);
@@ -2667,7 +2978,7 @@ function appendUnderlineProperty(document, properties, namespace, prefix, mark)
2667
2978
  properties.append(underline);
2668
2979
  }
2669
2980
  function appendBooleanProperty(document, properties, namespace, prefix, marks, mark, property) {
2670
- if (marks.has(mark)) properties.append(wordElement(document, namespace, prefix, property));
2981
+ if (marks.has(mark)) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, property));
2671
2982
  }
2672
2983
  function appendStrikeProperties(document, properties, namespace, prefix, mark) {
2673
2984
  if (!mark) return;
@@ -2676,14 +2987,14 @@ function appendStrikeProperties(document, properties, namespace, prefix, mark) {
2676
2987
  appendValuedProperty(document, properties, namespace, prefix, 'dstrike', 'double' === style ? '1' : '0');
2677
2988
  }
2678
2989
  function appendValuedProperty(document, properties, namespace, prefix, property, value) {
2679
- const element = wordElement(document, namespace, prefix, property);
2990
+ const element = work_docx_format_change_export_wordElement(document, namespace, prefix, property);
2680
2991
  work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'val', value);
2681
2992
  properties.append(element);
2682
2993
  }
2683
2994
  function appendTextCaseProperties(document, properties, namespace, prefix, mark) {
2684
2995
  const textCase = mark?.attrs?.textCase;
2685
- if ('all-caps' === textCase) properties.append(wordElement(document, namespace, prefix, 'caps'));
2686
- else if ('small-caps' === textCase) properties.append(wordElement(document, namespace, prefix, 'smallCaps'));
2996
+ if ('all-caps' === textCase) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, 'caps'));
2997
+ else if ('small-caps' === textCase) properties.append(work_docx_format_change_export_wordElement(document, namespace, prefix, 'smallCaps'));
2687
2998
  else if ('none' === textCase) {
2688
2999
  appendValuedProperty(document, properties, namespace, prefix, 'caps', '0');
2689
3000
  appendValuedProperty(document, properties, namespace, prefix, 'smallCaps', '0');
@@ -2693,7 +3004,7 @@ function appendColorProperty(document, properties, namespace, prefix, mark) {
2693
3004
  const color = normalizedHex(mark?.attrs?.color);
2694
3005
  const theme = themeReference(mark?.attrs?.themeColor);
2695
3006
  if (!color && !theme) return;
2696
- const element = wordElement(document, namespace, prefix, 'color');
3007
+ const element = work_docx_format_change_export_wordElement(document, namespace, prefix, 'color');
2697
3008
  work_docx_format_change_export_setWordAttribute(element, namespace, prefix, 'val', color ?? normalizedHex(theme?.resolved) ?? '000000');
2698
3009
  if (theme) setThemeAttributes(element, namespace, prefix, theme, 'themeColor');
2699
3010
  properties.append(element);
@@ -2704,11 +3015,14 @@ function appendFontSizeProperties(document, properties, namespace, prefix, mark)
2704
3015
  appendValuedProperty(document, properties, namespace, prefix, 'sz', String(halfPoints));
2705
3016
  appendValuedProperty(document, properties, namespace, prefix, 'szCs', String(halfPoints));
2706
3017
  }
2707
- function appendHighlightProperty(document, properties, namespace, prefix, mark) {
3018
+ function appendHighlightProperty(document, properties, namespace, prefix, mark, allowFallbackShading) {
3019
+ const nativeHighlight = normalizeDocumentHighlight(mark?.attrs?.nativeHighlight) ?? documentHighlightForCssColor(mark?.attrs?.color);
3020
+ if (nativeHighlight) return void appendValuedProperty(document, properties, namespace, prefix, 'highlight', nativeHighlight);
3021
+ if (!allowFallbackShading) return;
2708
3022
  const fill = normalizedHex(mark?.attrs?.color);
2709
3023
  const theme = themeReference(mark?.attrs?.themeFill);
2710
3024
  if (!fill && !theme) return;
2711
- const shading = wordElement(document, namespace, prefix, 'shd');
3025
+ const shading = work_docx_format_change_export_wordElement(document, namespace, prefix, 'shd');
2712
3026
  work_docx_format_change_export_setWordAttribute(shading, namespace, prefix, 'val', 'clear');
2713
3027
  work_docx_format_change_export_setWordAttribute(shading, namespace, prefix, 'color', 'auto');
2714
3028
  work_docx_format_change_export_setWordAttribute(shading, namespace, prefix, 'fill', fill ?? normalizedHex(theme?.resolved) ?? 'FFFFFF');
@@ -2756,7 +3070,7 @@ function normalizedHex(value) {
2756
3070
  const match = /^#?([0-9a-f]{6})$/i.exec(value.trim());
2757
3071
  return match?.[1]?.toUpperCase() ?? null;
2758
3072
  }
2759
- function wordElement(document, namespace, prefix, name) {
3073
+ function work_docx_format_change_export_wordElement(document, namespace, prefix, name) {
2760
3074
  return document.createElementNS(namespace, `${prefix}:${name}`);
2761
3075
  }
2762
3076
  function work_docx_format_change_export_setWordAttribute(element, namespace, prefix, name, value) {
@@ -3530,10 +3844,10 @@ async function patchDocxNumberingRestartRules(buffer, rules) {
3530
3844
  if (!definition) continue;
3531
3845
  let restart = directChild(definition, 'lvlRestart');
3532
3846
  if (!restart) {
3533
- restart = document.createElementNS(work_docx_numbering_WORD_NAMESPACE, wordQualifiedName(document.documentElement, 'lvlRestart'));
3847
+ restart = document.createElementNS(work_docx_numbering_WORD_NAMESPACE, work_docx_numbering_wordQualifiedName(document.documentElement, 'lvlRestart'));
3534
3848
  definition.insertBefore(restart, directChild(definition, 'pPr') ?? null);
3535
3849
  }
3536
- restart.setAttributeNS(work_docx_numbering_WORD_NAMESPACE, wordQualifiedName(document.documentElement, 'val'), String(restartAfterLevel));
3850
+ restart.setAttributeNS(work_docx_numbering_WORD_NAMESPACE, work_docx_numbering_wordQualifiedName(document.documentElement, 'val'), String(restartAfterLevel));
3537
3851
  }
3538
3852
  }
3539
3853
  archive.file('word/numbering.xml', new XMLSerializer().serializeToString(document));
@@ -3541,7 +3855,7 @@ async function patchDocxNumberingRestartRules(buffer, rules) {
3541
3855
  type: 'arraybuffer'
3542
3856
  });
3543
3857
  }
3544
- function wordQualifiedName(root, localName) {
3858
+ function work_docx_numbering_wordQualifiedName(root, localName) {
3545
3859
  return `${xmlNamespacePrefix(root, work_docx_numbering_WORD_NAMESPACE) ?? root.prefix ?? 'w'}:${localName}`;
3546
3860
  }
3547
3861
  const work_docx_paragraph_format_change_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
@@ -3971,6 +4285,127 @@ function docxBorderStyle(style, docx) {
3971
4285
  function docxColor(color) {
3972
4286
  return color.replace(/^#/, '').toUpperCase();
3973
4287
  }
4288
+ const work_docx_table_of_contents_export_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
4289
+ const work_docx_table_of_contents_export_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
4290
+ class DocxTableOfContentsPatchCollector {
4291
+ patches = [];
4292
+ add(element) {
4293
+ const value = documentTableOfContentsValueFromElement(element);
4294
+ const patch = {
4295
+ options: value.options,
4296
+ entries: value.entries
4297
+ };
4298
+ this.patches.push(patch);
4299
+ return patch;
4300
+ }
4301
+ }
4302
+ function docxTableOfContents(element, docx, collector) {
4303
+ const patch = collector.add(element);
4304
+ const options = patch.options;
4305
+ return new docx.TableOfContents('Table of Contents', {
4306
+ hyperlink: options.hyperlinks,
4307
+ headingStyleRange: `${options.minLevel}-${options.maxLevel}`,
4308
+ pageNumbersEntryLevelsRange: options.showPageNumbers ? void 0 : `${options.minLevel}-${options.maxLevel}`,
4309
+ entryAndPageNumberSeparator: options.showPageNumbers && !options.rightAlignPageNumbers ? ' ' : void 0,
4310
+ useAppliedParagraphOutlineLevel: true,
4311
+ hideTabAndPageNumbersInWebView: true,
4312
+ cachedEntries: patch.entries.map((entry)=>({
4313
+ title: entry.title,
4314
+ level: entry.level,
4315
+ page: options.showPageNumbers ? entry.pageNumber : void 0,
4316
+ href: options.hyperlinks ? entry.targetId : void 0
4317
+ }))
4318
+ });
4319
+ }
4320
+ async function patchDocxTableOfContents(buffer, patches) {
4321
+ if (!patches.length) return buffer;
4322
+ const archive = await jszip.loadAsync(buffer);
4323
+ const entry = archive.file('word/document.xml');
4324
+ if (!entry) return buffer;
4325
+ const document = parseXml(await entry.async('text'), 'generated DOCX word/document.xml');
4326
+ const tables = descendants(document, 'sdt').filter((element)=>descendants(element, 'instrText').some((instruction)=>/^\s*TOC\b/i.test(instruction.textContent ?? '')));
4327
+ if (tables.length !== patches.length) throw new Error(`Generated DOCX emitted ${tables.length} table(s) of contents for ${patches.length} source block(s).`);
4328
+ for (const [index, table] of tables.entries()){
4329
+ const patch = patches[index];
4330
+ if (patch) patchTableOfContents(document, table, patch.options);
4331
+ }
4332
+ addTableOfContentsBookmarks(document, patches);
4333
+ archive.file('word/document.xml', new XMLSerializer().serializeToString(document));
4334
+ return archive.generateAsync({
4335
+ type: 'arraybuffer'
4336
+ });
4337
+ }
4338
+ function patchTableOfContents(document, table, options) {
4339
+ for (const tabStop of descendants(table, 'tab')){
4340
+ if (tabStop.parentElement?.localName !== 'tabs') continue;
4341
+ const value = work_ooxml_package_attribute(tabStop, 'val');
4342
+ if ('right' !== value) continue;
4343
+ if (!options.showPageNumbers || !options.rightAlignPageNumbers) {
4344
+ const parent = tabStop.parentElement;
4345
+ tabStop.remove();
4346
+ if (parent && !directChildren(parent, 'tab').length) parent.remove();
4347
+ continue;
4348
+ }
4349
+ const leader = docxTableOfContentsLeader(options.leader);
4350
+ if (leader) work_docx_table_of_contents_export_setWordAttribute(document, tabStop, 'leader', leader);
4351
+ else removeWordAttribute(tabStop, 'leader');
4352
+ }
4353
+ if (options.showPageNumbers && options.rightAlignPageNumbers) return;
4354
+ for (const tab of descendants(table, 'tab')){
4355
+ if (tab.parentElement?.localName === 'tabs') continue;
4356
+ if (!options.showPageNumbers) {
4357
+ tab.remove();
4358
+ continue;
4359
+ }
4360
+ const text = document.createElementNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, 't'));
4361
+ text.setAttributeNS(work_docx_table_of_contents_export_XML_NAMESPACE, 'xml:space', 'preserve');
4362
+ text.textContent = ' ';
4363
+ tab.replaceWith(text);
4364
+ }
4365
+ }
4366
+ function addTableOfContentsBookmarks(document, patches) {
4367
+ const names = new Set(descendants(document, 'bookmarkStart').flatMap((bookmark)=>{
4368
+ const name = work_ooxml_package_attribute(bookmark, 'name')?.trim();
4369
+ return name ? [
4370
+ name
4371
+ ] : [];
4372
+ }));
4373
+ let nextId = Math.max(0, ...descendants(document, 'bookmarkStart').map((bookmark)=>Number(work_ooxml_package_attribute(bookmark, 'id') ?? 0))) + 1;
4374
+ const targets = new Set(patches.flatMap((patch)=>patch.options.hyperlinks ? patch.entries.map((candidate)=>candidate.targetId) : []));
4375
+ for (const target of targets){
4376
+ if (names.has(target)) continue;
4377
+ const paragraphId = /^heading-([0-9a-f]{8})$/i.exec(target)?.[1];
4378
+ if (!paragraphId) continue;
4379
+ const paragraph = descendants(document, 'p').find((candidate)=>work_ooxml_package_attribute(candidate, 'paraId')?.toLowerCase() === paragraphId.toLowerCase());
4380
+ if (!paragraph) continue;
4381
+ const start = document.createElementNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, 'bookmarkStart'));
4382
+ const end = document.createElementNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, 'bookmarkEnd'));
4383
+ work_docx_table_of_contents_export_setWordAttribute(document, start, 'id', String(nextId));
4384
+ work_docx_table_of_contents_export_setWordAttribute(document, start, 'name', target);
4385
+ work_docx_table_of_contents_export_setWordAttribute(document, end, 'id', String(nextId));
4386
+ nextId += 1;
4387
+ const properties = directChild(paragraph, 'pPr');
4388
+ paragraph.insertBefore(start, properties?.nextSibling ?? paragraph.firstChild);
4389
+ paragraph.append(end);
4390
+ names.add(target);
4391
+ }
4392
+ }
4393
+ function docxTableOfContentsLeader(value) {
4394
+ if ('dash' === value) return 'hyphen';
4395
+ if ('underline' === value) return 'underscore';
4396
+ if ('dot' === value) return 'dot';
4397
+ return null;
4398
+ }
4399
+ function work_docx_table_of_contents_export_setWordAttribute(document, element, localName, value) {
4400
+ removeWordAttribute(element, localName);
4401
+ element.setAttributeNS(work_docx_table_of_contents_export_WORD_NAMESPACE, work_docx_table_of_contents_export_wordQualifiedName(document.documentElement, localName), value);
4402
+ }
4403
+ function removeWordAttribute(element, localName) {
4404
+ for (const candidate of Array.from(element.attributes))if (candidate.localName === localName && (candidate.namespaceURI === work_docx_table_of_contents_export_WORD_NAMESPACE || !candidate.namespaceURI)) element.removeAttributeNode(candidate);
4405
+ }
4406
+ function work_docx_table_of_contents_export_wordQualifiedName(root, localName) {
4407
+ return `${xmlNamespacePrefix(root, work_docx_table_of_contents_export_WORD_NAMESPACE) ?? 'w'}:${localName}`;
4408
+ }
3974
4409
  const work_docx_table_sizing_export_TWIPS_PER_PIXEL = 15;
3975
4410
  function documentTableSizingDocxOptions(table, docx) {
3976
4411
  const geometry = documentTableGeometryFromElement(table);
@@ -7956,7 +8391,7 @@ async function createDocxBlob(content, sourcePackage) {
7956
8391
  const docx = await import("docx");
7957
8392
  const normalizedContent = {
7958
8393
  ...content,
7959
- html: normalizeDocumentBookmarkReferencesHtml(normalizeDocumentBookmarksHtml(content.html))
8394
+ html: normalizeDocumentIndexesHtml(normalizeDocumentBookmarkReferencesHtml(normalizeDocumentBookmarksHtml(content.html)))
7960
8395
  };
7961
8396
  const noteCollection = collectDocumentNotes(normalizedContent.html);
7962
8397
  const comments = anchoredDocumentComments(normalizedContent);
@@ -7991,8 +8426,12 @@ async function createDocxBlob(content, sourcePackage) {
7991
8426
  legacyTextEffectsPatches: new DocxLegacyTextEffectsPatchCollector(JSON.stringify(normalizedContent)),
7992
8427
  runBorderPatches: new DocxRunBorderPatchCollector(JSON.stringify(normalizedContent)),
7993
8428
  usedRunBorderMarkers: new Set(),
8429
+ runShadingPatches: new DocxRunShadingPatchCollector(JSON.stringify(normalizedContent)),
8430
+ usedRunShadingMarkers: new Set(),
7994
8431
  usedNativeTextEffectMarkers: new Set(),
7995
8432
  paragraphFormattingChangePatches: new DocxParagraphFormattingChangePatchCollector(),
8433
+ tableOfContentsPatches: new DocxTableOfContentsPatchCollector(),
8434
+ indexPatches: new DocxIndexPatchCollector(),
7996
8435
  hasExplicitZeroCharacterSpacing: false,
7997
8436
  hasExplicitZeroKerningThreshold: false
7998
8437
  };
@@ -8047,7 +8486,8 @@ async function createDocxBlob(content, sourcePackage) {
8047
8486
  const hiddenTextPatched = await patchDocxHiddenText(runFontsPatched, noteContext.hiddenTextPatches.patches.filter((patch)=>noteContext.usedNativeTextEffectMarkers.has(patch.marker)));
8048
8487
  const legacyTextEffectsPatched = await patchDocxLegacyTextEffects(hiddenTextPatched, noteContext.legacyTextEffectsPatches.patches.filter((patch)=>noteContext.usedNativeTextEffectMarkers.has(patch.marker)));
8049
8488
  const runBordersPatched = await patchDocxRunBorders(legacyTextEffectsPatched, noteContext.runBorderPatches.patches.filter((patch)=>noteContext.usedRunBorderMarkers.has(patch.marker)));
8050
- const formattingChangesPatched = await patchDocxRunFormattingChanges(runBordersPatched, noteContext.formattingChangePatches.patches);
8489
+ const runShadingPatched = await patchDocxRunShading(runBordersPatched, noteContext.runShadingPatches.patches.filter((patch)=>noteContext.usedRunShadingMarkers.has(patch.marker)));
8490
+ const formattingChangesPatched = await patchDocxRunFormattingChanges(runShadingPatched, noteContext.formattingChangePatches.patches);
8051
8491
  const noteImageRelationshipsPatched = await patchDocxNoteImageRelationships(formattingChangesPatched);
8052
8492
  const commentMetadataPatched = await patchDocxCommentMetadata(noteImageRelationshipsPatched, commentThreads);
8053
8493
  const numberingPatched = await patchDocxNumberingRestartRules(commentMetadataPatched, noteContext.numberingRestartRules);
@@ -8062,7 +8502,9 @@ async function createDocxBlob(content, sourcePackage) {
8062
8502
  const bookmarkPatched = await patchDocxBookmarks(imageIdentityPatched, noteContext.bookmarkPatches.patches);
8063
8503
  const paragraphDefaultCollapsedPatched = await patchDocxParagraphDefaultCollapsed(bookmarkPatched, noteContext.paragraphDefaultCollapsedPatches.patches);
8064
8504
  const paragraphIdentityPatched = await patchDocxParagraphIdentities(paragraphDefaultCollapsedPatched, noteContext.paragraphIdentityPatches.patches);
8065
- const paragraphFormattingChangesPatched = await patchDocxParagraphFormattingChanges(paragraphIdentityPatched, noteContext.paragraphFormattingChangePatches.patches);
8505
+ const tableOfContentsPatched = await patchDocxTableOfContents(paragraphIdentityPatched, noteContext.tableOfContentsPatches.patches);
8506
+ const indexPatched = await patchDocxIndexes(tableOfContentsPatched, noteContext.indexPatches.patches);
8507
+ const paragraphFormattingChangesPatched = await patchDocxParagraphFormattingChanges(indexPatched, noteContext.paragraphFormattingChangePatches.patches);
8066
8508
  const equationPatched = await patchDocxEquations(paragraphFormattingChangesPatched, noteContext.equationPatches.patches);
8067
8509
  const patched = await patchDocxPageColor(equationPatched, normalizedContent.pageColor);
8068
8510
  const preserved = sourcePackage ? await preserveDocxSourcePackage(patched, sourcePackage, {
@@ -8132,6 +8574,10 @@ function markDocxRunBorderUsed(border, context) {
8132
8574
  const marker = border?.color?.toUpperCase();
8133
8575
  if (context.runBorderPatches.hasMarker(marker)) context.usedRunBorderMarkers.add(marker);
8134
8576
  }
8577
+ function markDocxRunShadingUsed(shading, context) {
8578
+ const marker = shading?.fill?.toUpperCase();
8579
+ if (context.runShadingPatches.hasMarker(marker)) context.usedRunShadingMarkers.add(marker);
8580
+ }
8135
8581
  function work_docx_export_sectionProperties(layout, docx) {
8136
8582
  const landscape = 'landscape' === layout.orientation;
8137
8583
  const dimensions = documentPageGeometryForLayout(layout);
@@ -8229,6 +8675,10 @@ async function blockToFileChildren(element, docx, noteContext) {
8229
8675
  if (element.hasAttribute('data-document-bibliography')) return [
8230
8676
  docxBibliographyParagraph(element, docx, paragraphBidirectional(element))
8231
8677
  ];
8678
+ if (element.hasAttribute('data-document-table-of-contents')) return [
8679
+ docxTableOfContents(element, docx, noteContext.tableOfContentsPatches)
8680
+ ];
8681
+ if (element.hasAttribute('data-document-index')) return docxDocumentIndex(element, docx, noteContext.indexPatches);
8232
8682
  if (element.hasAttribute('data-document-caption')) return [
8233
8683
  docxCaptionParagraph(element, await paragraphRuns(element, docx, noteContext), docx, paragraphBidirectional(element))
8234
8684
  ];
@@ -8303,6 +8753,7 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8303
8753
  if (!node.textContent) return [];
8304
8754
  markDocxNativeTextEffectStyleUsed(inherited.style, noteContext);
8305
8755
  markDocxRunBorderUsed(inherited.border, noteContext);
8756
+ markDocxRunShadingUsed(inherited.shading, noteContext);
8306
8757
  if (revision?.kind === 'insertion') return [
8307
8758
  new docx.InsertedTextRun({
8308
8759
  ...inherited,
@@ -8339,6 +8790,12 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8339
8790
  if (node.hasAttribute('data-document-field')) return [
8340
8791
  docxDocumentFieldRun(node, docx)
8341
8792
  ];
8793
+ if (node.hasAttribute('data-document-index-entry')) {
8794
+ const entry = docxIndexEntryRun(node, docx);
8795
+ return entry ? [
8796
+ entry
8797
+ ] : [];
8798
+ }
8342
8799
  if (node.hasAttribute('data-document-equation')) {
8343
8800
  const equation = noteContext.equationPatches.marker(node);
8344
8801
  return [
@@ -8360,19 +8817,32 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8360
8817
  const formattingChange = node.hasAttribute('data-document-change') && 'formatting' === node.dataset.changeKind ? noteContext.formattingChangePatches.register(node, docxRevisionId(node, noteContext)) : null;
8361
8818
  const commentBoundary = node.hasAttribute('data-document-comment') ? nextDocxCommentBoundary(node.dataset.commentId, noteContext) : null;
8362
8819
  const backgroundColor = cssColorToHex(node.style.backgroundColor);
8820
+ const hasExplicitRunShading = 'span' === tag && node.hasAttribute(DOCUMENT_RUN_SHADING_ATTRIBUTE);
8821
+ const explicitRunShading = hasExplicitRunShading ? parseDocumentRunShadingElement(node) : null;
8822
+ if (hasExplicitRunShading && !explicitRunShading) throw new Error('Document contains invalid character shading.');
8823
+ const hasHighlightSemantics = node.hasAttribute(DOCUMENT_HIGHLIGHT_ATTRIBUTE) || node.hasAttribute('data-color') || 'mark' === tag || Boolean(backgroundColor) && !hasExplicitRunShading;
8824
+ const explicitHighlight = hasHighlightSemantics ? documentHighlightFromElement(node) : null;
8363
8825
  const direction = domDirection(node);
8364
8826
  const resolvedColor = cssColorToHex(node.style.color) ?? inherited.color;
8365
8827
  const themeColorMarker = noteContext.themePatches.marker('color', parseDocxThemeReference(node.dataset.officeThemeColor), resolvedColor ? `#${resolvedColor}` : null);
8366
- const resolvedShading = backgroundColor ? {
8367
- fill: backgroundColor
8368
- } : inherited.shading;
8369
- const themeFillMarker = noteContext.themePatches.marker('fill', parseDocxThemeReference(node.dataset.officeThemeFill), resolvedShading?.fill ? `#${resolvedShading.fill}` : null);
8828
+ const runShading = explicitRunShading ? documentRunShadingDocxOptions(explicitRunShading, noteContext.runShadingPatches).shading : void 0;
8829
+ const customHighlightFill = hasHighlightSemantics && !explicitHighlight ? backgroundColor : null;
8830
+ const resolvedShading = runShading ?? (customHighlightFill ? {
8831
+ fill: customHighlightFill
8832
+ } : inherited.shading);
8833
+ const themeFillMarker = !runShading && customHighlightFill ? noteContext.themePatches.marker('fill', parseDocxThemeReference(node.dataset.officeThemeFill), `#${customHighlightFill}`) : null;
8370
8834
  const explicitTextCase = normalizeDocumentTextCase(node.dataset.officeTextCase);
8371
8835
  const explicitCharacterSpacing = documentCharacterSpacingTwipsFromElement(node);
8372
8836
  const explicitCharacterScale = documentCharacterScalePercentFromElement(node);
8373
8837
  const explicitKerningThreshold = documentKerningThresholdHalfPointsFromElement(node);
8374
8838
  const explicitEmphasisMark = documentEmphasisMarkFromElement(node);
8375
8839
  const explicitHiddenText = documentHiddenTextFromElement(node);
8840
+ const hasExplicitProofingLanguages = 'span' === tag && node.hasAttribute(DOCUMENT_PROOFING_LANGUAGES_ATTRIBUTE);
8841
+ const explicitProofingLanguages = hasExplicitProofingLanguages ? documentProofingLanguagesFromElement(node) : null;
8842
+ if (hasExplicitProofingLanguages && !explicitProofingLanguages) throw new Error('Document contains invalid proofing languages.');
8843
+ const hasExplicitNoProof = 'span' === tag && node.hasAttribute(DOCUMENT_NO_PROOF_ATTRIBUTE);
8844
+ const explicitNoProof = hasExplicitNoProof ? documentNoProofFromElement(node) : null;
8845
+ if (hasExplicitNoProof && null === explicitNoProof) throw new Error('Document contains invalid proofing state.');
8376
8846
  const hasExplicitLegacyTextEffects = 'span' === tag && [
8377
8847
  DOCUMENT_LEGACY_TEXT_OUTLINE_ATTRIBUTE,
8378
8848
  DOCUMENT_LEGACY_TEXT_SHADOW_ATTRIBUTE,
@@ -8410,6 +8880,8 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8410
8880
  const strike = docxStrikeRunOptions(node, inherited);
8411
8881
  const scriptFontMarker = noteContext.runFontPatches.marker(documentScriptFontsFromElement(node), documentScriptFontSlotFromElement(node), node.style.fontFamily);
8412
8882
  const runBorder = explicitRunBorder ? documentRunBorderDocxOptions(explicitRunBorder, noteContext.runBorderPatches).border : inherited.border;
8883
+ const language = hasExplicitProofingLanguages ? documentProofingLanguageDocxOptions(explicitProofingLanguages) : inherited.language;
8884
+ const noProof = hasExplicitNoProof ? explicitNoProof ?? false : inherited.noProof;
8413
8885
  const style = {
8414
8886
  ...inherited,
8415
8887
  style: nativeTextEffectStyle,
@@ -8429,10 +8901,13 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8429
8901
  kern,
8430
8902
  position,
8431
8903
  emphasisMark,
8904
+ language,
8905
+ noProof,
8432
8906
  border: runBorder,
8433
8907
  shading: themeFillMarker ? {
8434
8908
  fill: themeFillMarker
8435
8909
  } : resolvedShading,
8910
+ highlight: hasHighlightSemantics ? explicitHighlight ?? (customHighlightFill ? 'none' : void 0) : inherited.highlight,
8436
8911
  snapToGrid: dataBoolean(node.dataset.officeWordSnapToGrid) ?? inherited.snapToGrid,
8437
8912
  rightToLeft: void 0 === direction ? inherited.rightToLeft : 'rtl' === direction,
8438
8913
  ...textCaseOptions
@@ -8440,6 +8915,7 @@ async function work_docx_export_inlineRuns(root, docx, noteContext) {
8440
8915
  if ('br' === tag) {
8441
8916
  markDocxNativeTextEffectStyleUsed(style.style, noteContext);
8442
8917
  markDocxRunBorderUsed(style.border, noteContext);
8918
+ markDocxRunShadingUsed(style.shading, noteContext);
8443
8919
  return [
8444
8920
  new docx.TextRun({
8445
8921
  ...style,