@a3s-lab/office 0.1.0 → 0.2.2

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 (69) hide show
  1. package/README.md +101 -24
  2. package/dist/0~2582.js +485 -0
  3. package/dist/0~4595.js +14 -7
  4. package/dist/0~4750.js +939 -0
  5. package/dist/{0~work-document-paragraph-formatting.js → 0~5861.js} +174 -3
  6. package/dist/0~7048.js +8 -6
  7. package/dist/0~9512.js +7 -4
  8. package/dist/0~document-editor.js +3147 -531
  9. package/dist/0~markdown-editor.js +26 -1
  10. package/dist/0~presentation-editor.js +68 -12
  11. package/dist/0~spreadsheet-editor.js +37 -17
  12. package/dist/0~work-document-extensions.js +588 -13
  13. package/dist/0~work-document-model-codec.js +1 -1
  14. package/dist/0~work-docx-bibliography.js +1 -1
  15. package/dist/0~work-docx-export.js +116 -55
  16. package/dist/0~work-docx-import.js +766 -107
  17. package/dist/0~work-office-diagnostics.js +2 -2
  18. package/dist/{4704.js → 2881.js} +162 -71
  19. package/dist/4104.js +2 -62
  20. package/dist/internal/features/work/editors/document-comment-window.d.ts +37 -0
  21. package/dist/internal/features/work/editors/document-navigation-panel.d.ts +3 -1
  22. package/dist/internal/features/work/editors/document-navigation-window.d.ts +64 -0
  23. package/dist/internal/features/work/editors/document-outline-navigation.d.ts +11 -0
  24. package/dist/internal/features/work/editors/document-page-navigation.d.ts +11 -1
  25. package/dist/internal/features/work/editors/document-page-thumbnail.d.ts +31 -0
  26. package/dist/internal/features/work/editors/document-picture-properties-dialog-model.d.ts +28 -0
  27. package/dist/internal/features/work/editors/document-picture-properties-dialog.d.ts +4 -0
  28. package/dist/internal/features/work/editors/document-search-navigation.d.ts +12 -0
  29. package/dist/internal/features/work/editors/document-table-margins-popover.d.ts +4 -0
  30. package/dist/internal/features/work/editors/document-table-properties-dialog-model.d.ts +51 -0
  31. package/dist/internal/features/work/editors/document-table-properties-dialog-sections.d.ts +19 -0
  32. package/dist/internal/features/work/editors/document-table-properties-dialog.d.ts +8 -0
  33. package/dist/internal/features/work/editors/office-task-pane.d.ts +1 -1
  34. package/dist/internal/features/work/editors/presentation-chart-panel.d.ts +2 -1
  35. package/dist/internal/features/work/editors/presentation-comments-panel.d.ts +2 -1
  36. package/dist/internal/features/work/editors/spreadsheet-workbook-panel.d.ts +2 -1
  37. package/dist/internal/features/work/editors/use-document-pagination.d.ts +6 -0
  38. package/dist/internal/features/work/editors/use-presentation-review-commands.d.ts +1 -1
  39. package/dist/internal/features/work/work-document-image-layout.d.ts +11 -0
  40. package/dist/internal/features/work/work-document-page-capture.d.ts +15 -0
  41. package/dist/internal/features/work/work-document-paragraph-formatting.d.ts +4 -0
  42. package/dist/internal/features/work/work-document-section.d.ts +3 -1
  43. package/dist/internal/features/work/work-document-table-borders.d.ts +20 -0
  44. package/dist/internal/features/work/work-document-table-cell-formatting.d.ts +8 -5
  45. package/dist/internal/features/work/work-document-table-geometry.d.ts +41 -0
  46. package/dist/internal/features/work/work-document-table-property-changes.d.ts +25 -0
  47. package/dist/internal/features/work/work-document-table-sizing.d.ts +15 -2
  48. package/dist/internal/features/work/work-document-word-line-metrics.d.ts +11 -0
  49. package/dist/internal/features/work/work-docx-document-layout.d.ts +2 -0
  50. package/dist/internal/features/work/work-docx-paragraph-alignment-import.d.ts +2 -1
  51. package/dist/internal/features/work/work-docx-paragraph-direction-import.d.ts +2 -1
  52. package/dist/internal/features/work/work-docx-paragraph-indent-import.d.ts +2 -1
  53. package/dist/internal/features/work/work-docx-paragraph-pagination-import.d.ts +2 -1
  54. package/dist/internal/features/work/work-docx-paragraph-spacing-import.d.ts +3 -2
  55. package/dist/internal/features/work/work-docx-paragraph-styles.d.ts +2 -2
  56. package/dist/internal/features/work/work-docx-run-formatting-import.d.ts +8 -1
  57. package/dist/internal/features/work/work-docx-tab-stop-import.d.ts +2 -1
  58. package/dist/internal/features/work/work-docx-table-cell-export.d.ts +1 -1
  59. package/dist/internal/features/work/work-docx-table-cell-import.d.ts +14 -4
  60. package/dist/internal/features/work/work-docx-table-sizing-export.d.ts +1 -1
  61. package/dist/internal/features/work/work-docx-table-sizing-import.d.ts +4 -3
  62. package/dist/internal/features/work/work-docx-table-styles.d.ts +22 -0
  63. package/dist/internal/features/work/work-types.d.ts +6 -0
  64. package/dist/office-kernel.wasm +0 -0
  65. package/dist/styles.css +1288 -233
  66. package/docs/{browser-editor-architecture.md → latest/en/browser-editor-architecture.md} +144 -35
  67. package/package.json +9 -5
  68. package/dist/0~6552.js +0 -787
  69. package/dist/0~8155.js +0 -299
@@ -1,9 +1,9 @@
1
1
  import jszip from "jszip";
2
2
  import { contentTypeForPart, directChildren, bytesToDataUrl, OoxmlPackage, firstDescendant, descendants, directChild, childPath, attribute } from "./8715.js";
3
3
  import { docxCaptionSequenceKind, docxFieldOccurrences, docxCaptionBookmark, docxFieldResultText, docxCaptionReferenceTarget } from "./0~152.js";
4
- import { documentContentLayoutProperties, documentPageChromeLegacyFields, normalizeDocumentFieldsHtml, documentInitialSectionLayout, documentSectionDomAttributes, documentCaptionLabel, normalizeDocumentPageChrome, normalizeDocumentCitationsHtml, normalizeDocumentColumns, normalizeDocumentCaptionsHtml, normalizeDocumentNotesHtml, documentCitationTagsFromInstruction, docxDocumentFieldKind, createDocumentNoteElement } from "./4704.js";
5
- import { normalizeDocumentImageAlignment, serializeDocumentTabStops, normalizeDocumentImageLayoutOptions, normalizeDocumentTabStops } from "./0~8155.js";
6
- import { normalizeDocumentParagraphIndent } from "./0~work-document-paragraph-formatting.js";
4
+ import { documentContentLayoutProperties, documentPageChromeLegacyFields, normalizeDocumentFieldsHtml, documentInitialSectionLayout, documentSectionDomAttributes, documentCaptionLabel, normalizeDocumentPageChrome, normalizeDocumentCitationsHtml, normalizeDocumentColumns, normalizeDocumentCaptionsHtml, normalizeDocumentNotesHtml, documentCitationTagsFromInstruction, docxDocumentFieldKind, createDocumentNoteElement } from "./2881.js";
5
+ import { renderDocumentTableBorders, renderDocumentTableCellMarginOverrides, normalizeDocumentImageAlignment, documentTableBordersFromElement, normalizeDocumentImageLayoutOptions, normalizeDocumentTabStops, DEFAULT_DOCUMENT_TABLE_GEOMETRY, DEFAULT_DOCUMENT_TABLE_CELL_MARGINS, serializeDocumentTabStops, applyDocumentTableGeometryToElement } from "./0~4750.js";
6
+ import { normalizeDocumentParagraphIndent, documentAutoLineHeight, documentWordLineHeightFactor, renderDocumentAutoLineHeight } from "./0~5861.js";
7
7
  import { readDocxBibliography } from "./0~work-docx-bibliography.js";
8
8
  import { importDocxPageColor } from "./0~work-docx-page-color.js";
9
9
  const WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
@@ -1332,21 +1332,23 @@ function createDocxParagraphStyleResolver(stylesDocument) {
1332
1332
  function resolveDocxParagraphStyleResolver(source) {
1333
1333
  return source && 'styles' in source ? source : createDocxParagraphStyleResolver(source);
1334
1334
  }
1335
- function docxParagraphPropertySources(directProperties, resolver) {
1335
+ function docxParagraphPropertySources(directProperties, resolver, contextualProperties = []) {
1336
1336
  const sources = [];
1337
1337
  if (resolver.defaultProperties) sources.push(resolver.defaultProperties);
1338
1338
  const styleReference = directProperties ? directChild(directProperties, 'pStyle') : void 0;
1339
1339
  const styleId = (styleReference ? wordAttribute(styleReference, 'val')?.trim() : void 0) || resolver.defaultStyleId;
1340
1340
  if (styleId) sources.push(...stylePropertySources(resolver.styles, styleId, 'paragraphProperties'));
1341
+ sources.push(...contextualProperties);
1341
1342
  if (directProperties) sources.push(directProperties);
1342
1343
  return sources;
1343
1344
  }
1344
- function docxRunPropertySources(paragraphProperties, runProperties, resolver) {
1345
+ function docxRunPropertySources(paragraphProperties, runProperties, resolver, contextualProperties = []) {
1345
1346
  const sources = [];
1346
1347
  if (resolver.defaultRunProperties) sources.push(resolver.defaultRunProperties);
1347
1348
  const paragraphStyleReference = paragraphProperties ? directChild(paragraphProperties, 'pStyle') : void 0;
1348
1349
  const paragraphStyleId = (paragraphStyleReference ? wordAttribute(paragraphStyleReference, 'val')?.trim() : void 0) || resolver.defaultStyleId;
1349
1350
  if (paragraphStyleId) sources.push(...stylePropertySources(resolver.styles, paragraphStyleId, 'runProperties'));
1351
+ sources.push(...contextualProperties);
1350
1352
  const paragraphRunProperties = paragraphProperties ? directChild(paragraphProperties, 'rPr') : void 0;
1351
1353
  if (paragraphRunProperties) sources.push(paragraphRunProperties);
1352
1354
  const characterStyleReference = runProperties ? directChild(runProperties, 'rStyle') : void 0;
@@ -1379,15 +1381,266 @@ function onOffAttribute(element, name) {
1379
1381
  function wordAttribute(element, name) {
1380
1382
  return attribute(element, name) ?? attribute(element, `w:${name}`);
1381
1383
  }
1384
+ const work_docx_table_styles_MAX_STYLE_INHERITANCE_DEPTH = 64;
1385
+ const DEFAULT_TABLE_LOOK = {
1386
+ firstRow: true,
1387
+ lastRow: false,
1388
+ firstColumn: true,
1389
+ lastColumn: false,
1390
+ noHorizontalBand: false,
1391
+ noVerticalBand: true
1392
+ };
1393
+ const TABLE_LOOK_BITS = {
1394
+ firstRow: 0x0020,
1395
+ lastRow: 0x0040,
1396
+ firstColumn: 0x0080,
1397
+ lastColumn: 0x0100,
1398
+ noHorizontalBand: 0x0200,
1399
+ noVerticalBand: 0x0400
1400
+ };
1401
+ function createDocxTableStyleResolver(stylesDocument) {
1402
+ if (!stylesDocument) return {
1403
+ tableStyles: new Map()
1404
+ };
1405
+ const tableStyles = new Map();
1406
+ let defaultStyleId;
1407
+ for (const style of descendants(stylesDocument, 'style')){
1408
+ if ('table' !== work_docx_table_styles_wordAttribute(style, 'type')) continue;
1409
+ const styleId = work_docx_table_styles_wordAttribute(style, 'styleId')?.trim();
1410
+ if (!styleId) continue;
1411
+ const basedOn = directChild(style, 'basedOn');
1412
+ const conditional = new Map();
1413
+ for (const conditionalStyle of directChildren(style, 'tblStylePr')){
1414
+ const type = work_docx_table_styles_wordAttribute(conditionalStyle, 'type')?.trim();
1415
+ if (type) conditional.set(type, styleLayer(conditionalStyle));
1416
+ }
1417
+ tableStyles.set(styleId, {
1418
+ ...styleLayer(style),
1419
+ basedOn: basedOn ? work_docx_table_styles_wordAttribute(basedOn, 'val')?.trim() || void 0 : void 0,
1420
+ conditional
1421
+ });
1422
+ if (!defaultStyleId && work_docx_table_styles_onOffAttribute(style, 'default')) defaultStyleId = styleId;
1423
+ }
1424
+ return {
1425
+ defaultStyleId,
1426
+ tableStyles
1427
+ };
1428
+ }
1429
+ function resolveDocxTableStyleResolver(source) {
1430
+ return source && 'tableStyles' in source ? source : createDocxTableStyleResolver(source);
1431
+ }
1432
+ function docxTablePropertySources(table, resolver) {
1433
+ const directTableProperties = directChild(table, 'tblPr');
1434
+ const styleReference = directTableProperties ? directChild(directTableProperties, 'tblStyle') : void 0;
1435
+ const styleId = (styleReference ? work_docx_table_styles_wordAttribute(styleReference, 'val')?.trim() : void 0) || resolver.defaultStyleId;
1436
+ const sources = styleId ? tableStyleChain(resolver.tableStyles, styleId).map(({ tableProperties })=>tableProperties).filter((properties)=>Boolean(properties)) : [];
1437
+ if (directTableProperties) sources.push(directTableProperties);
1438
+ return sources;
1439
+ }
1440
+ function docxTableCellStyleLayers(cell, resolver) {
1441
+ const table = work_docx_table_styles_closestAncestor(cell, 'tbl');
1442
+ if (!table) return [];
1443
+ const directTableProperties = directChild(table, 'tblPr');
1444
+ const styleReference = directTableProperties ? directChild(directTableProperties, 'tblStyle') : void 0;
1445
+ const styleId = (styleReference ? work_docx_table_styles_wordAttribute(styleReference, 'val')?.trim() : void 0) || resolver.defaultStyleId;
1446
+ if (!styleId) return [];
1447
+ const styles = tableStyleChain(resolver.tableStyles, styleId);
1448
+ if (!styles.length) return [];
1449
+ const unconditionalLayers = styles.map(styleLayerFromStyle);
1450
+ const propertySources = unconditionalLayers.map(({ tableProperties })=>tableProperties).filter((properties)=>Boolean(properties));
1451
+ if (directTableProperties) propertySources.push(directTableProperties);
1452
+ const position = tableCellPosition(table, cell);
1453
+ if (!position) return unconditionalLayers;
1454
+ const look = resolveTableLook(propertySources);
1455
+ const rowBandSize = resolveBandSize(propertySources, 'tblStyleRowBandSize');
1456
+ const columnBandSize = resolveBandSize(propertySources, 'tblStyleColBandSize');
1457
+ const layers = [
1458
+ ...unconditionalLayers
1459
+ ];
1460
+ for (const condition of applicableConditions(position, look, rowBandSize, columnBandSize))for (const style of styles){
1461
+ const layer = style.conditional.get(condition);
1462
+ if (layer) layers.push(layer);
1463
+ }
1464
+ return layers;
1465
+ }
1466
+ function docxTableRunPropertySources(element, resolver) {
1467
+ const cell = work_docx_table_styles_closestAncestor(element, 'tc');
1468
+ if (!cell) return [];
1469
+ const sources = [];
1470
+ for (const layer of docxTableCellStyleLayers(cell, resolver)){
1471
+ const paragraphRunProperties = layer.paragraphProperties ? directChild(layer.paragraphProperties, 'rPr') : void 0;
1472
+ if (paragraphRunProperties) sources.push(paragraphRunProperties);
1473
+ if (layer.runProperties) sources.push(layer.runProperties);
1474
+ }
1475
+ return sources;
1476
+ }
1477
+ function docxTableParagraphPropertySources(element, resolver) {
1478
+ const cell = work_docx_table_styles_closestAncestor(element, 'tc');
1479
+ if (!cell) return [];
1480
+ return docxTableCellStyleLayers(cell, resolver).map(({ paragraphProperties })=>paragraphProperties).filter((properties)=>Boolean(properties));
1481
+ }
1482
+ function styleLayer(parent) {
1483
+ return {
1484
+ tableProperties: directChild(parent, 'tblPr'),
1485
+ cellProperties: directChild(parent, 'tcPr'),
1486
+ paragraphProperties: directChild(parent, 'pPr'),
1487
+ runProperties: directChild(parent, 'rPr')
1488
+ };
1489
+ }
1490
+ function styleLayerFromStyle(style) {
1491
+ return {
1492
+ tableProperties: style.tableProperties,
1493
+ cellProperties: style.cellProperties,
1494
+ paragraphProperties: style.paragraphProperties,
1495
+ runProperties: style.runProperties
1496
+ };
1497
+ }
1498
+ function tableStyleChain(styles, styleId) {
1499
+ const inherited = [];
1500
+ const visited = new Set();
1501
+ let currentStyleId = styleId;
1502
+ let depth = 0;
1503
+ while(currentStyleId && depth < work_docx_table_styles_MAX_STYLE_INHERITANCE_DEPTH && !visited.has(currentStyleId)){
1504
+ depth += 1;
1505
+ visited.add(currentStyleId);
1506
+ const style = styles.get(currentStyleId);
1507
+ if (!style) break;
1508
+ inherited.push(style);
1509
+ currentStyleId = style.basedOn;
1510
+ }
1511
+ return inherited.reverse();
1512
+ }
1513
+ function applicableConditions(position, look, rowBandSize, columnBandSize) {
1514
+ const conditions = [
1515
+ 'wholeTable'
1516
+ ];
1517
+ const isFirstRow = 0 === position.rowIndex;
1518
+ const isLastRow = position.rowIndex === position.rowCount - 1;
1519
+ const isFirstColumn = 0 === position.columnStart;
1520
+ const isLastColumn = position.columnEnd === position.columnCount - 1;
1521
+ if (!look.noVerticalBand) {
1522
+ const offset = look.firstColumn ? 1 : 0;
1523
+ const bandIndex = position.columnStart - offset;
1524
+ if (bandIndex >= 0) conditions.push(Math.floor(bandIndex / columnBandSize) % 2 === 0 ? 'band1Vert' : 'band2Vert');
1525
+ }
1526
+ if (!look.noHorizontalBand) {
1527
+ const offset = look.firstRow ? 1 : 0;
1528
+ const bandIndex = position.rowIndex - offset;
1529
+ if (bandIndex >= 0) conditions.push(Math.floor(bandIndex / rowBandSize) % 2 === 0 ? 'band1Horz' : 'band2Horz');
1530
+ }
1531
+ if (look.firstColumn && isFirstColumn) conditions.push('firstCol');
1532
+ if (look.lastColumn && isLastColumn) conditions.push('lastCol');
1533
+ if (look.firstRow && isFirstRow) conditions.push('firstRow');
1534
+ if (look.lastRow && isLastRow) conditions.push('lastRow');
1535
+ if (look.firstRow && isFirstRow && look.firstColumn && isFirstColumn) conditions.push('nwCell');
1536
+ if (look.firstRow && isFirstRow && look.lastColumn && isLastColumn) conditions.push('neCell');
1537
+ if (look.lastRow && isLastRow && look.firstColumn && isFirstColumn) conditions.push('swCell');
1538
+ if (look.lastRow && isLastRow && look.lastColumn && isLastColumn) conditions.push('seCell');
1539
+ return conditions;
1540
+ }
1541
+ function resolveTableLook(propertySources) {
1542
+ const look = {
1543
+ ...DEFAULT_TABLE_LOOK
1544
+ };
1545
+ for (const properties of propertySources){
1546
+ const element = directChild(properties, 'tblLook');
1547
+ if (!element) continue;
1548
+ const encoded = work_docx_table_styles_wordAttribute(element, 'val')?.trim();
1549
+ if (encoded && /^[0-9a-f]{1,4}$/i.test(encoded)) {
1550
+ const value = Number.parseInt(encoded, 16);
1551
+ look.firstRow = Boolean(value & TABLE_LOOK_BITS.firstRow);
1552
+ look.lastRow = Boolean(value & TABLE_LOOK_BITS.lastRow);
1553
+ look.firstColumn = Boolean(value & TABLE_LOOK_BITS.firstColumn);
1554
+ look.lastColumn = Boolean(value & TABLE_LOOK_BITS.lastColumn);
1555
+ look.noHorizontalBand = Boolean(value & TABLE_LOOK_BITS.noHorizontalBand);
1556
+ look.noVerticalBand = Boolean(value & TABLE_LOOK_BITS.noVerticalBand);
1557
+ }
1558
+ assignLookFlag(look, 'firstRow', element, 'firstRow');
1559
+ assignLookFlag(look, 'lastRow', element, 'lastRow');
1560
+ assignLookFlag(look, 'firstColumn', element, 'firstColumn');
1561
+ assignLookFlag(look, 'lastColumn', element, 'lastColumn');
1562
+ assignLookFlag(look, 'noHorizontalBand', element, 'noHBand');
1563
+ assignLookFlag(look, 'noVerticalBand', element, 'noVBand');
1564
+ }
1565
+ return look;
1566
+ }
1567
+ function assignLookFlag(look, key, element, attributeName) {
1568
+ const value = onOffValue(work_docx_table_styles_wordAttribute(element, attributeName));
1569
+ if (void 0 !== value) look[key] = value;
1570
+ }
1571
+ function resolveBandSize(propertySources, propertyName) {
1572
+ let size = 1;
1573
+ for (const properties of propertySources){
1574
+ const element = directChild(properties, propertyName);
1575
+ const value = Number(element ? work_docx_table_styles_wordAttribute(element, 'val') : void 0);
1576
+ if (Number.isInteger(value) && value > 0 && value <= 64) size = value;
1577
+ }
1578
+ return size;
1579
+ }
1580
+ function tableCellPosition(table, targetCell) {
1581
+ const rows = descendants(table, 'tr').filter((row)=>work_docx_table_styles_closestAncestor(row, 'tbl') === table);
1582
+ const targetRow = work_docx_table_styles_closestAncestor(targetCell, 'tr');
1583
+ if (!targetRow) return null;
1584
+ const rowIndex = rows.indexOf(targetRow);
1585
+ if (rowIndex < 0) return null;
1586
+ const cells = rowCells(targetRow);
1587
+ const cellIndex = cells.indexOf(targetCell);
1588
+ if (cellIndex < 0) return null;
1589
+ const columnStart = rowGridOffset(targetRow, 'gridBefore') + cells.slice(0, cellIndex).reduce((total, cell)=>total + cellGridSpan(cell), 0);
1590
+ const columnEnd = columnStart + cellGridSpan(targetCell) - 1;
1591
+ const columnCount = Math.max(1, ...rows.map((row)=>rowGridOffset(row, 'gridBefore') + rowCells(row).reduce((total, cell)=>total + cellGridSpan(cell), 0) + rowGridOffset(row, 'gridAfter')));
1592
+ return {
1593
+ rowIndex,
1594
+ rowCount: rows.length,
1595
+ columnStart,
1596
+ columnEnd,
1597
+ columnCount
1598
+ };
1599
+ }
1600
+ function rowCells(row) {
1601
+ return descendants(row, 'tc').filter((cell)=>work_docx_table_styles_closestAncestor(cell, 'tr') === row);
1602
+ }
1603
+ function cellGridSpan(cell) {
1604
+ const properties = directChild(cell, 'tcPr');
1605
+ const gridSpan = properties ? directChild(properties, 'gridSpan') : void 0;
1606
+ const value = Number(gridSpan ? work_docx_table_styles_wordAttribute(gridSpan, 'val') : void 0);
1607
+ return Number.isInteger(value) && value > 0 && value <= 256 ? value : 1;
1608
+ }
1609
+ function rowGridOffset(row, propertyName) {
1610
+ const properties = directChild(row, 'trPr');
1611
+ const element = properties ? directChild(properties, propertyName) : void 0;
1612
+ const value = Number(element ? work_docx_table_styles_wordAttribute(element, 'val') : void 0);
1613
+ return Number.isInteger(value) && value > 0 && value <= 256 ? value : 0;
1614
+ }
1615
+ function work_docx_table_styles_closestAncestor(element, localName) {
1616
+ let current = element;
1617
+ while(current){
1618
+ if (current.localName === localName) return current;
1619
+ current = current.parentElement;
1620
+ }
1621
+ return null;
1622
+ }
1623
+ function work_docx_table_styles_onOffAttribute(element, name) {
1624
+ return onOffValue(work_docx_table_styles_wordAttribute(element, name)) ?? false;
1625
+ }
1626
+ function onOffValue(value) {
1627
+ if (null == value) return;
1628
+ const normalized = value.trim().toLowerCase();
1629
+ return '0' !== normalized && 'false' !== normalized && 'off' !== normalized;
1630
+ }
1631
+ function work_docx_table_styles_wordAttribute(element, name) {
1632
+ return attribute(element, name) ?? attribute(element, `w:${name}`);
1633
+ }
1382
1634
  const work_docx_paragraph_direction_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
1383
1635
  const work_docx_paragraph_direction_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
1384
1636
  const PARAGRAPH_DIRECTION_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_DIRECTION_\d+__/g;
1385
- function markDocxParagraphDirections(document, styleSource) {
1637
+ function markDocxParagraphDirections(document, styleSource, tableStyleSource) {
1386
1638
  const paragraphs = [];
1387
1639
  const styles = resolveDocxParagraphStyleResolver(styleSource);
1640
+ const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
1388
1641
  for (const paragraph of descendants(document, 'p')){
1389
1642
  let properties = directChild(paragraph, 'pPr');
1390
- const sources = docxParagraphPropertySources(properties, styles);
1643
+ const sources = docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles));
1391
1644
  const direction = paragraphDirection(sources);
1392
1645
  if (!direction) continue;
1393
1646
  properties ??= insertParagraphProperties(document, paragraph);
@@ -1425,11 +1678,11 @@ function paragraphDirection(propertySources) {
1425
1678
  let direction = null;
1426
1679
  for (const properties of propertySources){
1427
1680
  const bidi = directChild(properties, 'bidi');
1428
- if (bidi) direction = onOffValue(bidi) ? 'rtl' : 'ltr';
1681
+ if (bidi) direction = work_docx_paragraph_direction_import_onOffValue(bidi) ? 'rtl' : 'ltr';
1429
1682
  }
1430
1683
  return direction;
1431
1684
  }
1432
- function onOffValue(element) {
1685
+ function work_docx_paragraph_direction_import_onOffValue(element) {
1433
1686
  const value = (attribute(element, 'val') ?? attribute(element, 'w:val'))?.trim().toLowerCase();
1434
1687
  return '0' !== value && 'false' !== value && 'off' !== value;
1435
1688
  }
@@ -1461,12 +1714,13 @@ function work_docx_paragraph_direction_import_textNodes(root) {
1461
1714
  const work_docx_paragraph_alignment_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
1462
1715
  const work_docx_paragraph_alignment_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
1463
1716
  const PARAGRAPH_ALIGNMENT_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_ALIGNMENT_\d+__/g;
1464
- function markDocxParagraphAlignments(document, styleSource) {
1717
+ function markDocxParagraphAlignments(document, styleSource, tableStyleSource) {
1465
1718
  const paragraphs = [];
1466
1719
  const styles = resolveDocxParagraphStyleResolver(styleSource);
1720
+ const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
1467
1721
  for (const paragraph of descendants(document, 'p')){
1468
1722
  let properties = directChild(paragraph, 'pPr');
1469
- const sources = docxParagraphPropertySources(properties, styles);
1723
+ const sources = docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles));
1470
1724
  const alignment = paragraphAlignment(sources);
1471
1725
  if (!alignment) continue;
1472
1726
  properties ??= work_docx_paragraph_alignment_import_insertParagraphProperties(document, paragraph);
@@ -1591,12 +1845,13 @@ const work_docx_paragraph_indent_import_WORD_NAMESPACE = 'http://schemas.openxml
1591
1845
  const work_docx_paragraph_indent_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
1592
1846
  const TWIPS_PER_CSS_PIXEL = 15;
1593
1847
  const PARAGRAPH_INDENT_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_INDENT_\d+__/g;
1594
- function markDocxParagraphIndents(document, styleSource) {
1848
+ function markDocxParagraphIndents(document, styleSource, tableStyleSource) {
1595
1849
  const paragraphs = [];
1596
1850
  const styles = resolveDocxParagraphStyleResolver(styleSource);
1851
+ const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
1597
1852
  for (const paragraph of descendants(document, 'p')){
1598
1853
  let properties = directChild(paragraph, 'pPr');
1599
- const sources = docxParagraphPropertySources(properties, styles);
1854
+ const sources = docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles));
1600
1855
  if (sources.some((source)=>directChild(source, 'numPr'))) continue;
1601
1856
  const indent = paragraphIndent(sources);
1602
1857
  if (!indent.left && !indent.right && !indent.firstLine) continue;
@@ -1709,13 +1964,14 @@ function work_docx_paragraph_indent_import_textNodes(root) {
1709
1964
  const work_docx_paragraph_pagination_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
1710
1965
  const work_docx_paragraph_pagination_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
1711
1966
  const PARAGRAPH_PAGINATION_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_PAGINATION_\d+__/g;
1712
- function markDocxParagraphPagination(document, styleSource) {
1967
+ function markDocxParagraphPagination(document, styleSource, tableStyleSource) {
1713
1968
  const paragraphs = [];
1714
1969
  const styles = resolveDocxParagraphStyleResolver(styleSource);
1970
+ const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
1715
1971
  for (const paragraph of descendants(document, 'p')){
1716
1972
  let properties = directChild(paragraph, 'pPr');
1717
1973
  if (properties && directChild(properties, 'numPr')) continue;
1718
- const pagination = paragraphPagination(docxParagraphPropertySources(properties, styles));
1974
+ const pagination = paragraphPagination(docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles)));
1719
1975
  if (!Object.keys(pagination).length) continue;
1720
1976
  properties ??= work_docx_paragraph_pagination_import_insertParagraphProperties(document, paragraph);
1721
1977
  const marker = `__A3S_WORK_PARAGRAPH_PAGINATION_${paragraphs.length + 1}__`;
@@ -1803,12 +2059,13 @@ function work_docx_paragraph_pagination_import_textNodes(root) {
1803
2059
  const work_docx_paragraph_spacing_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
1804
2060
  const work_docx_paragraph_spacing_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
1805
2061
  const PARAGRAPH_SPACING_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_SPACING_\d+__/g;
1806
- function markDocxParagraphSpacing(document, styleSource) {
2062
+ function markDocxParagraphSpacing(document, styleSource, tableStyleSource) {
1807
2063
  const paragraphs = [];
1808
2064
  const styles = resolveDocxParagraphStyleResolver(styleSource);
2065
+ const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
1809
2066
  for (const paragraph of descendants(document, 'p')){
1810
2067
  let properties = directChild(paragraph, 'pPr');
1811
- const sources = docxParagraphPropertySources(properties, styles);
2068
+ const sources = docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles));
1812
2069
  if (sources.some((source)=>directChild(source, 'numPr'))) continue;
1813
2070
  const spacing = paragraphSpacing(sources);
1814
2071
  if (!Object.keys(spacing).length) continue;
@@ -1885,6 +2142,14 @@ function applyParagraphSpacing(element, spacing) {
1885
2142
  }
1886
2143
  if (spacing.lineHeight) element.style.lineHeight = spacing.lineHeight;
1887
2144
  if (spacing.lineRule) element.dataset.officeLineRule = spacing.lineRule;
2145
+ if ('auto' === spacing.lineRule) {
2146
+ const autoLineHeight = documentAutoLineHeight(spacing.lineHeight);
2147
+ for (const [name, value] of Object.entries(renderDocumentAutoLineHeight(spacing.lineHeight, autoLineHeight)))if ('style' === name) for (const declaration of value.split(';')){
2148
+ const separator = declaration.indexOf(':');
2149
+ if (!(separator < 0)) element.style.setProperty(declaration.slice(0, separator).trim(), declaration.slice(separator + 1).trim());
2150
+ }
2151
+ else element.setAttribute(name, value);
2152
+ }
1888
2153
  }
1889
2154
  function work_docx_paragraph_spacing_import_insertParagraphMarker(document, paragraph, properties, marker) {
1890
2155
  const run = document.createElementNS(work_docx_paragraph_spacing_import_WORD_NAMESPACE, 'w:r');
@@ -2020,10 +2285,11 @@ function isDocxThemeResolver(source) {
2020
2285
  const work_docx_run_formatting_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
2021
2286
  const work_docx_run_formatting_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
2022
2287
  const RUN_FORMATTING_MARKER_PATTERN = /__A3S_WORK_RUN_(?:START|END)_\d+__/g;
2023
- function markDocxRunFormatting(document, styleSource, themeSource) {
2288
+ function markDocxRunFormatting(document, styleSource, themeSource, tableStyleSource) {
2024
2289
  const runs = [];
2025
2290
  const styles = resolveDocxParagraphStyleResolver(styleSource);
2026
2291
  const theme = resolveDocxThemeResolver(themeSource);
2292
+ const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
2027
2293
  for (const run of descendants(document, 'r')){
2028
2294
  const runText = directRunText(run);
2029
2295
  if (!runText || runText.includes('__A3S_')) continue;
@@ -2031,7 +2297,7 @@ function markDocxRunFormatting(document, styleSource, themeSource) {
2031
2297
  if (!paragraph) continue;
2032
2298
  const paragraphProperties = directChild(paragraph, 'pPr');
2033
2299
  const runProperties = directChild(run, 'rPr');
2034
- const formatting = resolvedRunFormatting(docxRunPropertySources(paragraphProperties, runProperties, styles), theme);
2300
+ const formatting = resolvedRunFormatting(docxRunPropertySources(paragraphProperties, runProperties, styles, docxTableRunPropertySources(run, tableStyles)), theme, runText);
2035
2301
  if (!Object.keys(formatting).length) continue;
2036
2302
  const index = runs.length + 1;
2037
2303
  const startMarker = `__A3S_WORK_RUN_START_${index}__`;
@@ -2050,22 +2316,45 @@ function markDocxRunFormatting(document, styleSource, themeSource) {
2050
2316
  function applyImportedDocxRunFormattingMarkers(document, markers) {
2051
2317
  const replacements = new Map();
2052
2318
  for (const marker of markers.runs){
2053
- replacements.set(marker.startMarker, formattingSpanStart(document, marker.formatting));
2054
- replacements.set(marker.endMarker, '</span>');
2319
+ const markup = formattingMarkup(document, marker.formatting);
2320
+ replacements.set(marker.startMarker, markup.start);
2321
+ replacements.set(marker.endMarker, markup.end);
2055
2322
  }
2056
2323
  document.body.innerHTML = document.body.innerHTML.replace(RUN_FORMATTING_MARKER_PATTERN, (marker)=>replacements.get(marker) ?? '');
2057
2324
  }
2058
2325
  function hasImportedDocxRunFormattingMarkers(markers) {
2059
2326
  return markers.runs.length > 0;
2060
2327
  }
2061
- function resolvedRunFormatting(propertySources, theme) {
2328
+ function resolvedRunFormatting(propertySources, theme, runText) {
2062
2329
  const fonts = {};
2063
2330
  let fontSize;
2331
+ let complexFontSize;
2064
2332
  let color;
2065
2333
  let backgroundColor;
2334
+ let bold;
2335
+ let complexBold;
2336
+ let italic;
2337
+ let complexItalic;
2338
+ let underline;
2339
+ let strike;
2340
+ let snapToGrid;
2341
+ let complexScriptFormatting;
2342
+ let rightToLeft;
2343
+ let fontHint;
2066
2344
  for (const properties of propertySources){
2345
+ bold = overriddenBoolean(bold, onOffProperty(properties, 'b'));
2346
+ complexBold = overriddenBoolean(complexBold, onOffProperty(properties, 'bCs'));
2347
+ italic = overriddenBoolean(italic, onOffProperty(properties, 'i'));
2348
+ complexItalic = overriddenBoolean(complexItalic, onOffProperty(properties, 'iCs'));
2349
+ underline = overriddenBoolean(underline, underlineProperty(properties));
2350
+ strike = overriddenBoolean(strike, onOffProperty(properties, 'strike'));
2351
+ strike = overriddenBoolean(strike, onOffProperty(properties, 'dstrike'));
2352
+ snapToGrid = overriddenBoolean(snapToGrid, onOffProperty(properties, 'snapToGrid'));
2353
+ complexScriptFormatting = overriddenBoolean(complexScriptFormatting, onOffProperty(properties, 'cs'));
2354
+ rightToLeft = overriddenBoolean(rightToLeft, onOffProperty(properties, 'rtl'));
2067
2355
  const runFonts = directChild(properties, 'rFonts');
2068
2356
  if (runFonts) {
2357
+ fontHint = resolvedFontHint(runFonts) ?? fontHint;
2069
2358
  assignFont(fonts, 'ascii', resolvedFont(runFonts, 'ascii', 'asciiTheme', theme));
2070
2359
  assignFont(fonts, 'hAnsi', resolvedFont(runFonts, 'hAnsi', 'hAnsiTheme', theme));
2071
2360
  assignFont(fonts, 'eastAsia', resolvedFont(runFonts, 'eastAsia', 'eastAsiaTheme', theme));
@@ -2073,6 +2362,8 @@ function resolvedRunFormatting(propertySources, theme) {
2073
2362
  }
2074
2363
  const size = work_docx_run_formatting_import_numericAttribute(directChild(properties, 'sz'), 'val');
2075
2364
  if (void 0 !== size && size > 0) fontSize = Math.min(512, size / 2);
2365
+ const complexSize = work_docx_run_formatting_import_numericAttribute(directChild(properties, 'szCs'), 'val');
2366
+ if (void 0 !== complexSize && complexSize > 0) complexFontSize = Math.min(512, complexSize / 2);
2076
2367
  const colorElement = directChild(properties, 'color');
2077
2368
  if (colorElement) {
2078
2369
  const value = work_docx_run_formatting_import_wordAttribute(colorElement, 'val')?.trim();
@@ -2094,18 +2385,41 @@ function resolvedRunFormatting(propertySources, theme) {
2094
2385
  else if (fill && /^[0-9a-f]{6}$/i.test(fill)) backgroundColor = `#${fill.toLowerCase()}`;
2095
2386
  }
2096
2387
  }
2097
- const fontFamily = uniqueFonts([
2098
- fonts.eastAsia,
2099
- fonts.hAnsi,
2100
- fonts.ascii,
2101
- fonts.complex
2102
- ]);
2388
+ const fontSlot = true === complexScriptFormatting || true === rightToLeft ? 'complex' : docxFontSlotForText(runText, fontHint);
2389
+ const usesComplexFormatting = 'complex' === fontSlot;
2390
+ const resolvedBold = usesComplexFormatting ? complexBold ?? bold : bold;
2391
+ const resolvedItalic = usesComplexFormatting ? complexItalic ?? italic : italic;
2392
+ const resolvedFontSize = usesComplexFormatting ? complexFontSize ?? fontSize : fontSize;
2393
+ let fontFamily = uniqueFonts(orderedFonts(fonts, fontSlot));
2394
+ if (!fontFamily) fontFamily = uniqueFonts(orderedFonts({
2395
+ ascii: docxThemeFont(theme, 'minorAscii'),
2396
+ hAnsi: docxThemeFont(theme, 'minorHAnsi'),
2397
+ eastAsia: docxThemeFont(theme, 'minorEastAsia'),
2398
+ complex: docxThemeFont(theme, 'minorBidi')
2399
+ }, fontSlot));
2400
+ const hasRunPropertySource = propertySources.length > 0;
2103
2401
  return {
2402
+ ...void 0 !== resolvedBold || hasRunPropertySource ? {
2403
+ bold: resolvedBold ?? false
2404
+ } : {},
2405
+ ...void 0 !== resolvedItalic || hasRunPropertySource ? {
2406
+ italic: resolvedItalic ?? false
2407
+ } : {},
2408
+ ...void 0 !== underline || hasRunPropertySource ? {
2409
+ underline: underline ?? false
2410
+ } : {},
2411
+ ...void 0 !== strike || hasRunPropertySource ? {
2412
+ strike: strike ?? false
2413
+ } : {},
2104
2414
  ...fontFamily ? {
2105
- fontFamily
2415
+ fontFamily,
2416
+ wordLineHeightFactor: documentWordLineHeightFactor(fontFamily)
2106
2417
  } : {},
2107
- ...void 0 !== fontSize ? {
2108
- fontSize
2418
+ ...void 0 !== resolvedFontSize ? {
2419
+ fontSize: resolvedFontSize
2420
+ } : {},
2421
+ ...void 0 !== snapToGrid ? {
2422
+ wordSnapToGrid: snapToGrid
2109
2423
  } : {},
2110
2424
  ...color ? {
2111
2425
  color
@@ -2127,14 +2441,57 @@ function work_docx_run_formatting_import_markerText(document, marker) {
2127
2441
  text.textContent = marker;
2128
2442
  return text;
2129
2443
  }
2130
- function formattingSpanStart(document, formatting) {
2444
+ function formattingMarkup(document, formatting) {
2131
2445
  const span = document.createElement('span');
2446
+ if (false === formatting.bold) span.style.fontWeight = 'normal';
2447
+ if (false === formatting.italic) span.style.fontStyle = 'normal';
2448
+ if ((false === formatting.underline || false === formatting.strike) && !formatting.underline && !formatting.strike) span.style.textDecorationLine = 'none';
2132
2449
  if (formatting.fontFamily) span.style.fontFamily = formatting.fontFamily;
2450
+ if (void 0 !== formatting.wordLineHeightFactor) {
2451
+ const factor = formatLineHeightFactor(formatting.wordLineHeightFactor);
2452
+ span.dataset.officeWordLineHeightFactor = factor;
2453
+ span.style.setProperty('--work-document-word-line-height-factor', factor);
2454
+ }
2455
+ if (void 0 !== formatting.wordSnapToGrid) span.dataset.officeWordSnapToGrid = String(formatting.wordSnapToGrid);
2133
2456
  if (void 0 !== formatting.fontSize) span.style.fontSize = `${work_docx_run_formatting_import_formatNumber(formatting.fontSize)}pt`;
2134
2457
  if (formatting.color) span.style.color = formatting.color;
2135
2458
  if (formatting.backgroundColor) span.style.backgroundColor = formatting.backgroundColor;
2136
2459
  const html = span.outerHTML;
2137
- return html.slice(0, html.indexOf('>') + 1);
2460
+ const tags = [
2461
+ ...formatting.bold ? [
2462
+ 'strong'
2463
+ ] : [],
2464
+ ...formatting.italic ? [
2465
+ 'em'
2466
+ ] : [],
2467
+ ...formatting.underline ? [
2468
+ 'u'
2469
+ ] : [],
2470
+ ...formatting.strike ? [
2471
+ 's'
2472
+ ] : []
2473
+ ];
2474
+ return {
2475
+ start: `${html.slice(0, html.indexOf('>') + 1)}${tags.map((tag)=>`<${tag}>`).join('')}`,
2476
+ end: `${[
2477
+ ...tags
2478
+ ].reverse().map((tag)=>`</${tag}>`).join('')}</span>`
2479
+ };
2480
+ }
2481
+ function overriddenBoolean(current, next) {
2482
+ return void 0 === next ? current : next;
2483
+ }
2484
+ function onOffProperty(properties, propertyName) {
2485
+ const element = directChild(properties, propertyName);
2486
+ if (!element) return;
2487
+ const value = work_docx_run_formatting_import_wordAttribute(element, 'val')?.trim().toLowerCase();
2488
+ return '0' !== value && 'false' !== value && 'off' !== value;
2489
+ }
2490
+ function underlineProperty(properties) {
2491
+ const element = directChild(properties, 'u');
2492
+ if (!element) return;
2493
+ const value = work_docx_run_formatting_import_wordAttribute(element, 'val')?.trim().toLowerCase();
2494
+ return '0' !== value && 'false' !== value && 'off' !== value && 'none' !== value;
2138
2495
  }
2139
2496
  function directRunText(run) {
2140
2497
  return Array.from(run.children).filter((child)=>'t' === child.localName || 'delText' === child.localName).map((child)=>child.textContent ?? '').join('');
@@ -2151,6 +2508,61 @@ function assignFont(fonts, key, value) {
2151
2508
  const normalized = value?.trim();
2152
2509
  if (normalized) fonts[key] = normalized;
2153
2510
  }
2511
+ function resolvedFontHint(element) {
2512
+ const hint = work_docx_run_formatting_import_wordAttribute(element, 'hint')?.trim().toLowerCase();
2513
+ if ('eastasia' === hint) return 'eastAsia';
2514
+ if ('cs' === hint) return 'complex';
2515
+ if ('default' === hint) return 'ascii';
2516
+ }
2517
+ function orderedFonts(fonts, preferred) {
2518
+ const order = {
2519
+ ascii: [
2520
+ 'ascii',
2521
+ 'hAnsi',
2522
+ 'eastAsia',
2523
+ 'complex'
2524
+ ],
2525
+ hAnsi: [
2526
+ 'hAnsi',
2527
+ 'ascii',
2528
+ 'eastAsia',
2529
+ 'complex'
2530
+ ],
2531
+ eastAsia: [
2532
+ 'eastAsia',
2533
+ 'hAnsi',
2534
+ 'ascii',
2535
+ 'complex'
2536
+ ],
2537
+ complex: [
2538
+ 'complex',
2539
+ 'hAnsi',
2540
+ 'ascii',
2541
+ 'eastAsia'
2542
+ ]
2543
+ };
2544
+ return order[preferred].map((slot)=>fonts[slot]);
2545
+ }
2546
+ function docxFontSlotForText(text, hint) {
2547
+ for (const character of text){
2548
+ const codePoint = character.codePointAt(0);
2549
+ if (!(void 0 === codePoint || isNeutralCodePoint(codePoint))) {
2550
+ if (isComplexScriptCodePoint(codePoint)) return 'complex';
2551
+ if (isEastAsianCodePoint(codePoint)) return 'eastAsia';
2552
+ return codePoint <= 0x7f ? 'ascii' : 'hAnsi';
2553
+ }
2554
+ }
2555
+ return hint ?? 'ascii';
2556
+ }
2557
+ function isNeutralCodePoint(codePoint) {
2558
+ return codePoint <= 0x20 || codePoint <= 0x7f && !(codePoint >= 0x41 && codePoint <= 0x5a || codePoint >= 0x61 && codePoint <= 0x7a) || codePoint >= 0x300 && codePoint <= 0x36f || codePoint >= 0x2000 && codePoint <= 0x206f;
2559
+ }
2560
+ function isComplexScriptCodePoint(codePoint) {
2561
+ return codePoint >= 0x0590 && codePoint <= 0x08ff || codePoint >= 0xfb1d && codePoint <= 0xfdff || codePoint >= 0xfe70 && codePoint <= 0xfeff || codePoint >= 0x1ee00 && codePoint <= 0x1eeff;
2562
+ }
2563
+ function isEastAsianCodePoint(codePoint) {
2564
+ return codePoint >= 0x1100 && codePoint <= 0x11ff || codePoint >= 0x2e80 && codePoint <= 0xa4cf || codePoint >= 0xac00 && codePoint <= 0xd7af || codePoint >= 0xf900 && codePoint <= 0xfaff || codePoint >= 0xfe10 && codePoint <= 0xfe6f || codePoint >= 0xff00 && codePoint <= 0xffef || codePoint >= 0x20000 && codePoint <= 0x323af;
2565
+ }
2154
2566
  function resolvedFont(element, explicitName, themeName, theme) {
2155
2567
  const explicit = work_docx_run_formatting_import_wordAttribute(element, explicitName);
2156
2568
  if (explicit?.trim()) return explicit;
@@ -2200,18 +2612,22 @@ function wordHighlightColor(value) {
2200
2612
  function work_docx_run_formatting_import_formatNumber(value) {
2201
2613
  return Number(value.toFixed(2)).toString();
2202
2614
  }
2615
+ function formatLineHeightFactor(value) {
2616
+ return Number(value.toFixed(4)).toString();
2617
+ }
2203
2618
  const work_docx_tab_stop_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
2204
2619
  const work_docx_tab_stop_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
2205
2620
  const work_docx_tab_stop_import_TWIPS_PER_CSS_PIXEL = 15;
2206
2621
  const PARAGRAPH_TAB_STOP_MARKER_PATTERN = /__A3S_WORK_PARAGRAPH_TAB_STOPS_\d+__/g;
2207
2622
  const INLINE_TAB_MARKER_PATTERN = /__A3S_WORK_INLINE_TAB_\d+__/g;
2208
- function markDocxParagraphTabStops(document, styleSource) {
2623
+ function markDocxParagraphTabStops(document, styleSource, tableStyleSource) {
2209
2624
  const paragraphs = [];
2210
2625
  const inlineTabs = [];
2211
2626
  const styles = resolveDocxParagraphStyleResolver(styleSource);
2627
+ const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
2212
2628
  for (const paragraph of descendants(document, 'p')){
2213
2629
  let properties = directChild(paragraph, 'pPr');
2214
- const tabStops = resolvedParagraphTabStops(docxParagraphPropertySources(properties, styles));
2630
+ const tabStops = resolvedParagraphTabStops(docxParagraphPropertySources(properties, styles, docxTableParagraphPropertySources(paragraph, tableStyles)));
2215
2631
  if (tabStops.length) {
2216
2632
  properties ??= work_docx_tab_stop_import_insertParagraphProperties(document, paragraph);
2217
2633
  const marker = `__A3S_WORK_PARAGRAPH_TAB_STOPS_${paragraphs.length + 1}__`;
@@ -2357,20 +2773,42 @@ function work_docx_tab_stop_import_textNodes(root) {
2357
2773
  while(walker.nextNode())nodes.push(walker.currentNode);
2358
2774
  return nodes;
2359
2775
  }
2776
+ const TABLE_BORDER_EDGES = [
2777
+ 'top',
2778
+ 'right',
2779
+ 'bottom',
2780
+ 'left'
2781
+ ];
2360
2782
  const work_docx_table_cell_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
2361
2783
  const work_docx_table_cell_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
2362
2784
  const TABLE_CELL_MARKER_PATTERN = /__A3S_WORK_TABLE_CELL_\d+__/g;
2363
- function markDocxTableCells(document) {
2785
+ const PIXELS_PER_TWIP = 96 / 1440;
2786
+ function markDocxTableCells(document, themeSource, tableStyleSource) {
2364
2787
  const cells = [];
2788
+ const theme = resolveDocxThemeResolver(themeSource);
2789
+ const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
2365
2790
  for (const cell of descendants(document, 'tc')){
2366
2791
  const properties = directChild(cell, 'tcPr');
2367
- const shading = properties ? directChild(properties, 'shd') : void 0;
2368
- const verticalAlignment = properties ? directChild(properties, 'vAlign') : void 0;
2369
- const directBorders = properties ? uniformBorders(directChild(properties, 'tcBorders')) : null;
2370
- const border = directBorders ?? uniformTableBorders(cell);
2371
- const backgroundColor = ooxmlColor(attribute(shading ?? cell, 'fill'));
2372
- const verticalAlign = tableVerticalAlign(attribute(verticalAlignment ?? cell, 'val'));
2373
- if (!backgroundColor && !verticalAlign && !border) continue;
2792
+ const table = work_docx_table_cell_import_closestAncestor(cell, 'tbl');
2793
+ const directTableProperties = table ? directChild(table, 'tblPr') : void 0;
2794
+ const layers = [
2795
+ ...docxTableCellStyleLayers(cell, tableStyles),
2796
+ ...directTableProperties ? [
2797
+ {
2798
+ tableProperties: directTableProperties
2799
+ }
2800
+ ] : [],
2801
+ ...properties ? [
2802
+ {
2803
+ cellProperties: properties
2804
+ }
2805
+ ] : []
2806
+ ];
2807
+ const borders = importedTableCellBorders(cell, layers, theme);
2808
+ const backgroundColor = importedTableCellBackgroundColor(layers, theme);
2809
+ const verticalAlign = importedTableCellVerticalAlign(layers);
2810
+ const margins = importedTableCellMargins(layers);
2811
+ if (!backgroundColor && !verticalAlign && !borders && !margins) continue;
2374
2812
  const paragraph = firstTableCellParagraph(document, cell);
2375
2813
  if (!paragraph) continue;
2376
2814
  const marker = `__A3S_WORK_TABLE_CELL_${cells.length + 1}__`;
@@ -2383,10 +2821,11 @@ function markDocxTableCells(document) {
2383
2821
  ...verticalAlign ? {
2384
2822
  verticalAlign
2385
2823
  } : {},
2386
- ...border ? {
2387
- borderColor: border.color,
2388
- borderStyle: border.style,
2389
- borderWidth: border.width
2824
+ ...borders ? {
2825
+ borders
2826
+ } : {},
2827
+ ...margins ? {
2828
+ margins
2390
2829
  } : {}
2391
2830
  });
2392
2831
  }
@@ -2422,44 +2861,130 @@ function applyCellFormat(cell, format) {
2422
2861
  cell.dataset.officeCellVerticalAlign = format.verticalAlign;
2423
2862
  cell.style.verticalAlign = format.verticalAlign;
2424
2863
  }
2425
- if (format.borderColor && format.borderStyle && void 0 !== format.borderWidth) {
2426
- cell.dataset.officeCellBorderColor = format.borderColor;
2427
- cell.dataset.officeCellBorderStyle = format.borderStyle;
2428
- cell.dataset.officeCellBorderWidth = String(format.borderWidth);
2429
- cell.style.border = 'none' === format.borderStyle || 0 === format.borderWidth ? '0px none transparent' : `${format.borderWidth}px ${format.borderStyle} ${format.borderColor}`;
2864
+ if (format.borders) {
2865
+ const borders = documentTableBordersFromElement(cell, {
2866
+ color: '#cfd5df',
2867
+ style: 'solid',
2868
+ width: 1
2869
+ });
2870
+ for (const edge of TABLE_BORDER_EDGES){
2871
+ const border = format.borders[edge];
2872
+ if (border) borders[edge] = {
2873
+ ...border
2874
+ };
2875
+ }
2876
+ const rendered = renderDocumentTableBorders(borders);
2877
+ for (const [name, value] of Object.entries(rendered))if ('style' !== name) cell.setAttribute(name, value);
2878
+ cell.style.cssText = `${cell.style.cssText}; ${rendered.style}`;
2879
+ }
2880
+ if (format.margins) {
2881
+ const rendered = renderDocumentTableCellMarginOverrides(format.margins);
2882
+ for (const [name, value] of Object.entries(rendered))if ('style' !== name) cell.setAttribute(name, value);
2883
+ if (rendered.style) cell.style.cssText = `${cell.style.cssText}; ${rendered.style}`;
2884
+ }
2885
+ }
2886
+ function importedTableCellMargins(layers) {
2887
+ const margins = {};
2888
+ for (const layer of layers){
2889
+ const marginElement = layer.cellProperties ? directChild(layer.cellProperties, 'tcMar') : void 0;
2890
+ if (!marginElement) continue;
2891
+ const children = new Map(directChildren(marginElement).map((margin)=>[
2892
+ margin.localName,
2893
+ margin
2894
+ ]));
2895
+ assignCellMargin(margins, 'top', children.get('top'));
2896
+ assignCellMargin(margins, 'right', children.get('right') ?? children.get('end'));
2897
+ assignCellMargin(margins, 'bottom', children.get('bottom'));
2898
+ assignCellMargin(margins, 'left', children.get('left') ?? children.get('start'));
2899
+ }
2900
+ return Object.keys(margins).length ? margins : null;
2901
+ }
2902
+ function assignCellMargin(target, side, element) {
2903
+ if (!element) return;
2904
+ const type = attribute(element, 'type');
2905
+ if (type && 'dxa' !== type) return;
2906
+ const twips = Number(attribute(element, 'w'));
2907
+ if (!Number.isFinite(twips) || twips < 0) return;
2908
+ target[side] = Math.round(twips * PIXELS_PER_TWIP * 100) / 100;
2909
+ }
2910
+ function importedTableCellBorders(cell, layers, theme) {
2911
+ const borders = {};
2912
+ for (const layer of layers){
2913
+ if (layer.tableProperties) mergeBorders(borders, tableBordersForCell(cell, layer.tableProperties, theme));
2914
+ if (layer.cellProperties) mergeBorders(borders, borderEdges(directChild(layer.cellProperties, 'tcBorders'), theme));
2430
2915
  }
2916
+ return Object.keys(borders).length ? borders : null;
2431
2917
  }
2432
- function uniformTableBorders(cell) {
2918
+ function tableBordersForCell(cell, properties, theme) {
2433
2919
  const table = work_docx_table_cell_import_closestAncestor(cell, 'tbl');
2434
- const properties = table ? directChild(table, 'tblPr') : void 0;
2435
- return properties ? uniformBorders(directChild(properties, 'tblBorders'), true) : null;
2436
- }
2437
- function uniformBorders(borders, includeInside = false) {
2438
- if (!borders) return null;
2439
- const edgeNames = includeInside ? [
2440
- 'top',
2441
- 'right',
2442
- 'bottom',
2443
- 'left',
2444
- 'insideH',
2445
- 'insideV'
2446
- ] : [
2447
- 'top',
2448
- 'right',
2449
- 'bottom',
2450
- 'left'
2451
- ];
2452
- const edgeElements = new Map(directChildren(borders).map((edge)=>[
2920
+ const borders = borderElementMap(directChild(properties, 'tblBorders'));
2921
+ if (!table || !borders.size) return {};
2922
+ const row = work_docx_table_cell_import_closestAncestor(cell, 'tr');
2923
+ if (!row) return {};
2924
+ const rows = descendants(table, 'tr').filter((candidate)=>work_docx_table_cell_import_closestAncestor(candidate, 'tbl') === table);
2925
+ const cells = descendants(row, 'tc').filter((candidate)=>work_docx_table_cell_import_closestAncestor(candidate, 'tr') === row);
2926
+ const rowIndex = rows.indexOf(row);
2927
+ const cellIndex = cells.indexOf(cell);
2928
+ if (rowIndex < 0 || cellIndex < 0) return {};
2929
+ return compactBorders({
2930
+ top: parseBorder(borders.get(0 === rowIndex ? 'top' : 'insideH'), theme),
2931
+ right: parseBorder(borderElement(borders, cellIndex === cells.length - 1 ? [
2932
+ 'right',
2933
+ 'end'
2934
+ ] : [
2935
+ 'insideV'
2936
+ ]), theme),
2937
+ bottom: parseBorder(borders.get(rowIndex === rows.length - 1 ? 'bottom' : 'insideH'), theme),
2938
+ left: parseBorder(borderElement(borders, 0 === cellIndex ? [
2939
+ 'left',
2940
+ 'start'
2941
+ ] : [
2942
+ 'insideV'
2943
+ ]), theme)
2944
+ });
2945
+ }
2946
+ function mergeBorders(target, source) {
2947
+ for (const edge of TABLE_BORDER_EDGES){
2948
+ const border = source[edge];
2949
+ if (border) target[edge] = border;
2950
+ }
2951
+ }
2952
+ function borderEdges(borders, theme) {
2953
+ const edges = borderElementMap(borders);
2954
+ return compactBorders({
2955
+ top: parseBorder(edges.get('top'), theme),
2956
+ right: parseBorder(borderElement(edges, [
2957
+ 'right',
2958
+ 'end'
2959
+ ]), theme),
2960
+ bottom: parseBorder(edges.get('bottom'), theme),
2961
+ left: parseBorder(borderElement(edges, [
2962
+ 'left',
2963
+ 'start'
2964
+ ]), theme)
2965
+ });
2966
+ }
2967
+ function borderElementMap(borders) {
2968
+ return new Map(borders ? directChildren(borders).map((edge)=>[
2453
2969
  edge.localName,
2454
2970
  edge
2455
- ]));
2456
- const formats = edgeNames.map((name)=>parseBorder(edgeElements.get(name)));
2457
- if (formats.some((format)=>!format)) return null;
2458
- const first = formats[0];
2459
- if (!first) return null;
2460
- return formats.every((format)=>format?.color === first.color && format.style === first.style && format.width === first.width) ? first : null;
2971
+ ]) : []);
2972
+ }
2973
+ function borderElement(borders, names) {
2974
+ for (const name of names){
2975
+ const edge = borders.get(name);
2976
+ if (edge) return edge;
2977
+ }
2461
2978
  }
2462
- function parseBorder(edge) {
2979
+ function compactBorders(borders) {
2980
+ const result = {};
2981
+ for (const edge of TABLE_BORDER_EDGES){
2982
+ const border = borders[edge];
2983
+ if (border) result[edge] = border;
2984
+ }
2985
+ return result;
2986
+ }
2987
+ function parseBorder(edge, theme) {
2463
2988
  if (!edge) return null;
2464
2989
  const style = tableBorderStyle(attribute(edge, 'val'));
2465
2990
  if (!style) return null;
@@ -2468,7 +2993,8 @@ function parseBorder(edge) {
2468
2993
  style,
2469
2994
  width: 0
2470
2995
  };
2471
- const color = ooxmlColor(attribute(edge, 'color')) ?? '#000000';
2996
+ const themed = docxThemeColor(theme, attribute(edge, 'themeColor'), attribute(edge, 'themeTint'), attribute(edge, 'themeShade'));
2997
+ const color = themed ? `#${themed}` : ooxmlColor(attribute(edge, 'color')) ?? '#000000';
2472
2998
  const size = Number(attribute(edge, 'sz'));
2473
2999
  const width = Number.isFinite(size) && size > 0 ? size / 6 : 1;
2474
3000
  return {
@@ -2477,6 +3003,30 @@ function parseBorder(edge) {
2477
3003
  width: Math.max(0.5, Math.min(6, Math.round(2 * width) / 2))
2478
3004
  };
2479
3005
  }
3006
+ function importedTableCellBackgroundColor(layers, theme) {
3007
+ let color = null;
3008
+ for (const layer of layers){
3009
+ const tableShading = layer.tableProperties ? directChild(layer.tableProperties, 'shd') : void 0;
3010
+ const cellShading = layer.cellProperties ? directChild(layer.cellProperties, 'shd') : void 0;
3011
+ if (tableShading) color = tableCellBackgroundColor(tableShading, theme);
3012
+ if (cellShading) color = tableCellBackgroundColor(cellShading, theme);
3013
+ }
3014
+ return color;
3015
+ }
3016
+ function tableCellBackgroundColor(shading, theme) {
3017
+ const themed = docxThemeColor(theme, attribute(shading, 'themeFill'), attribute(shading, 'themeFillTint'), attribute(shading, 'themeFillShade'));
3018
+ return themed ? `#${themed}` : ooxmlColor(attribute(shading, 'fill'));
3019
+ }
3020
+ function importedTableCellVerticalAlign(layers) {
3021
+ let alignment = null;
3022
+ for (const layer of layers){
3023
+ const element = layer.cellProperties ? directChild(layer.cellProperties, 'vAlign') : void 0;
3024
+ if (!element) continue;
3025
+ const value = tableVerticalAlign(attribute(element, 'val'));
3026
+ if (value) alignment = value;
3027
+ }
3028
+ return alignment;
3029
+ }
2480
3030
  function tableBorderStyle(value) {
2481
3031
  const normalized = value?.trim();
2482
3032
  if (!normalized) return null;
@@ -2532,7 +3082,7 @@ function work_docx_table_cell_import_textNodes(root) {
2532
3082
  const work_docx_table_row_import_WORD_NAMESPACE = 'http://schemas.openxmlformats.org/wordprocessingml/2006/main';
2533
3083
  const work_docx_table_row_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
2534
3084
  const TABLE_ROW_MARKER_PATTERN = /__A3S_WORK_TABLE_ROW_\d+__/g;
2535
- const PIXELS_PER_TWIP = 96 / 1440;
3085
+ const work_docx_table_row_import_PIXELS_PER_TWIP = 96 / 1440;
2536
3086
  function markDocxTableRows(document) {
2537
3087
  const rows = [];
2538
3088
  for (const row of descendants(document, 'tr')){
@@ -2625,7 +3175,7 @@ function tableRowHeightRule(value) {
2625
3175
  }
2626
3176
  function work_docx_table_row_import_twipsToPixels(value) {
2627
3177
  if (!Number.isFinite(value) || value <= 0) return null;
2628
- return Math.round(value * PIXELS_PER_TWIP * 100) / 100;
3178
+ return Math.round(value * work_docx_table_row_import_PIXELS_PER_TWIP * 100) / 100;
2629
3179
  }
2630
3180
  function work_docx_table_row_import_closestAncestor(element, localName) {
2631
3181
  let current = element;
@@ -2647,21 +3197,19 @@ const work_docx_table_sizing_import_WORD_NAMESPACE = 'http://schemas.openxmlform
2647
3197
  const work_docx_table_sizing_import_XML_NAMESPACE = 'http://www.w3.org/XML/1998/namespace';
2648
3198
  const TABLE_SIZING_MARKER_PATTERN = /__A3S_WORK_TABLE_SIZING_\d+__/g;
2649
3199
  const work_docx_table_sizing_import_PIXELS_PER_TWIP = 96 / 1440;
2650
- function markDocxTableSizing(document) {
3200
+ function markDocxTableSizing(document, tableStyleSource) {
2651
3201
  const tables = [];
3202
+ const tableStyles = resolveDocxTableStyleResolver(tableStyleSource);
2652
3203
  for (const table of descendants(document, 'tbl')){
2653
3204
  const paragraph = firstTableParagraph(document, table);
2654
3205
  if (!paragraph) continue;
2655
- const properties = directChild(table, 'tblPr');
2656
- const layout = properties ? directChild(properties, 'tblLayout') : void 0;
2657
- const preferredWidth = properties ? directChild(properties, 'tblW') : void 0;
2658
3206
  const grid = directChild(table, 'tblGrid');
2659
- const columnWidths = grid ? directChildren(grid, 'gridCol').map((column)=>work_docx_table_sizing_import_twipsToPixels(Number(attribute(column, 'w')))).filter((width)=>null !== width) : [];
3207
+ const columnWidths = grid ? directChildren(grid, 'gridCol').map((column)=>work_docx_table_sizing_import_twipsToPixels(Number(attribute(column, 'w')), false)).filter((width)=>null !== width) : [];
2660
3208
  const marker = `__A3S_WORK_TABLE_SIZING_${tables.length + 1}__`;
2661
3209
  insertMarker(document, paragraph, marker);
2662
3210
  tables.push({
2663
3211
  marker,
2664
- layoutMode: importedTableLayoutMode(layout, preferredWidth),
3212
+ geometry: importedTableGeometry(docxTablePropertySources(table, tableStyles)),
2665
3213
  columnWidths
2666
3214
  });
2667
3215
  }
@@ -2680,8 +3228,9 @@ function applyImportedDocxTableSizingMarkers(document, markers) {
2680
3228
  node.data = node.data.replace(TABLE_SIZING_MARKER_PATTERN, (marker)=>{
2681
3229
  const sizing = tableByMarker.get(marker);
2682
3230
  if (table instanceof HTMLTableElement && sizing) {
2683
- table.dataset.officeTableLayout = sizing.layoutMode;
2684
- if ('fixed' === sizing.layoutMode && sizing.columnWidths.length) applyColumnWidths(table, sizing.columnWidths);
3231
+ table.dataset.officeTableImported = 'true';
3232
+ applyDocumentTableGeometryToElement(table, sizing.geometry);
3233
+ if (sizing.columnWidths.length) applyColumnWidths(table, sizing.columnWidths);
2685
3234
  }
2686
3235
  return '';
2687
3236
  });
@@ -2691,12 +3240,104 @@ function applyImportedDocxTableSizingMarkers(document, markers) {
2691
3240
  function hasImportedDocxTableSizingMarkers(markers) {
2692
3241
  return markers.tables.length > 0;
2693
3242
  }
2694
- function importedTableLayoutMode(layout, preferredWidth) {
2695
- const layoutType = layout ? attribute(layout, 'type') : null;
2696
- const widthType = preferredWidth ? attribute(preferredWidth, 'type') : null;
2697
- if ('autofit' === layoutType || 'auto' === widthType) return 'contents';
2698
- if ('pct' === widthType) return 'window';
2699
- return 'fixed';
3243
+ function importedTableGeometry(propertySources) {
3244
+ let layout = DEFAULT_DOCUMENT_TABLE_GEOMETRY.layout;
3245
+ let width = {
3246
+ type: 'auto',
3247
+ value: null
3248
+ };
3249
+ let alignment = DEFAULT_DOCUMENT_TABLE_GEOMETRY.alignment;
3250
+ let indent = DEFAULT_DOCUMENT_TABLE_GEOMETRY.indent;
3251
+ let cellMargins = {
3252
+ ...DEFAULT_DOCUMENT_TABLE_CELL_MARGINS
3253
+ };
3254
+ for (const properties of propertySources){
3255
+ const layoutElement = directChild(properties, 'tblLayout');
3256
+ const layoutValue = layoutElement ? importedTableLayout(attribute(layoutElement, 'type')) : null;
3257
+ if (layoutValue) layout = layoutValue;
3258
+ const widthElement = directChild(properties, 'tblW');
3259
+ const widthValue = widthElement ? importedTablePreferredWidth(widthElement) : null;
3260
+ if (widthValue) width = widthValue;
3261
+ const alignmentElement = directChild(properties, 'jc');
3262
+ const alignmentValue = alignmentElement ? importedTableAlignment(attribute(alignmentElement, 'val')) : null;
3263
+ if (alignmentValue) alignment = alignmentValue;
3264
+ const indentElement = directChild(properties, 'tblInd');
3265
+ const indentValue = indentElement ? tableWidthPixels(indentElement, true) : null;
3266
+ if (null !== indentValue) indent = indentValue;
3267
+ const marginElement = directChild(properties, 'tblCellMar');
3268
+ if (marginElement) cellMargins = {
3269
+ ...cellMargins,
3270
+ ...importedCellMargins(marginElement)
3271
+ };
3272
+ }
3273
+ return {
3274
+ layout,
3275
+ width,
3276
+ alignment,
3277
+ indent,
3278
+ cellMargins
3279
+ };
3280
+ }
3281
+ function importedTableLayout(value) {
3282
+ if ('fixed' === value) return 'fixed';
3283
+ return 'autofit' === value ? 'autofit' : null;
3284
+ }
3285
+ function importedTablePreferredWidth(width) {
3286
+ const type = attribute(width, 'type');
3287
+ if ('auto' === type || 'nil' === type) return {
3288
+ type: 'auto',
3289
+ value: null
3290
+ };
3291
+ if ('pct' === type) {
3292
+ const value = percentageValue(attribute(width, 'w'));
3293
+ return null === value ? null : {
3294
+ type: 'percent',
3295
+ value
3296
+ };
3297
+ }
3298
+ if ('dxa' === type) {
3299
+ const value = tableWidthPixels(width, false);
3300
+ return null === value ? null : {
3301
+ type: 'pixels',
3302
+ value
3303
+ };
3304
+ }
3305
+ return null;
3306
+ }
3307
+ function importedTableAlignment(value) {
3308
+ if ('center' === value) return 'center';
3309
+ if ('right' === value || 'end' === value) return 'right';
3310
+ if ('left' === value || 'start' === value) return 'left';
3311
+ return null;
3312
+ }
3313
+ function importedCellMargins(margins) {
3314
+ const children = new Map(directChildren(margins).map((margin)=>[
3315
+ margin.localName,
3316
+ margin
3317
+ ]));
3318
+ const result = {};
3319
+ assignMargin(result, 'top', children.get('top'));
3320
+ assignMargin(result, 'right', children.get('right') ?? children.get('end'));
3321
+ assignMargin(result, 'bottom', children.get('bottom'));
3322
+ assignMargin(result, 'left', children.get('left') ?? children.get('start'));
3323
+ return result;
3324
+ }
3325
+ function assignMargin(target, side, element) {
3326
+ if (!element) return;
3327
+ const value = tableWidthPixels(element, true);
3328
+ if (null !== value) target[side] = value;
3329
+ }
3330
+ function tableWidthPixels(element, allowZero) {
3331
+ const type = attribute(element, 'type');
3332
+ if (type && 'dxa' !== type) return null;
3333
+ return work_docx_table_sizing_import_twipsToPixels(Number(attribute(element, 'w')), allowZero);
3334
+ }
3335
+ function percentageValue(value) {
3336
+ const normalized = value?.trim();
3337
+ if (!normalized) return null;
3338
+ const percentage = normalized.endsWith('%') ? Number(normalized.slice(0, -1)) : Number(normalized) / 50;
3339
+ if (!Number.isFinite(percentage) || percentage <= 0) return null;
3340
+ return Math.round(100 * percentage) / 100;
2700
3341
  }
2701
3342
  function applyColumnWidths(table, columnWidths) {
2702
3343
  const occupiedUntilRow = [];
@@ -2729,8 +3370,8 @@ function insertMarker(document, paragraph, marker) {
2729
3370
  const properties = directChild(paragraph, 'pPr');
2730
3371
  paragraph.insertBefore(run, properties?.nextSibling ?? paragraph.firstChild);
2731
3372
  }
2732
- function work_docx_table_sizing_import_twipsToPixels(value) {
2733
- if (!Number.isFinite(value) || value <= 0) return null;
3373
+ function work_docx_table_sizing_import_twipsToPixels(value, allowZero) {
3374
+ if (!Number.isFinite(value) || value < 0 || !allowZero && 0 === value) return null;
2734
3375
  return Math.round(value * work_docx_table_sizing_import_PIXELS_PER_TWIP * 100) / 100;
2735
3376
  }
2736
3377
  function work_docx_table_sizing_import_closestAncestor(element, localName) {
@@ -2838,18 +3479,19 @@ async function prepareDocxImport(buffer) {
2838
3479
  const imageLayoutMarkers = markDocxImageLayouts(document);
2839
3480
  const paragraphStylesDocument = archive.has('word/styles.xml') ? await archive.xml('word/styles.xml') : null;
2840
3481
  const paragraphStyles = createDocxParagraphStyleResolver(paragraphStylesDocument);
2841
- const paragraphDirectionMarkers = markDocxParagraphDirections(document, paragraphStyles);
2842
- const paragraphAlignmentMarkers = markDocxParagraphAlignments(document, paragraphStyles);
2843
- const paragraphIndentMarkers = markDocxParagraphIndents(document, paragraphStyles);
2844
- const paragraphSpacingMarkers = markDocxParagraphSpacing(document, paragraphStyles);
2845
- const paragraphPaginationMarkers = markDocxParagraphPagination(document, paragraphStyles);
3482
+ const tableStyles = createDocxTableStyleResolver(paragraphStylesDocument);
3483
+ const paragraphDirectionMarkers = markDocxParagraphDirections(document, paragraphStyles, tableStyles);
3484
+ const paragraphAlignmentMarkers = markDocxParagraphAlignments(document, paragraphStyles, tableStyles);
3485
+ const paragraphIndentMarkers = markDocxParagraphIndents(document, paragraphStyles, tableStyles);
3486
+ const paragraphSpacingMarkers = markDocxParagraphSpacing(document, paragraphStyles, tableStyles);
3487
+ const paragraphPaginationMarkers = markDocxParagraphPagination(document, paragraphStyles, tableStyles);
2846
3488
  const themePath = archive.paths('word/theme/').find((path)=>/\/theme\d*\.xml$/i.test(path));
2847
3489
  const themeDocument = themePath ? await archive.xml(themePath) : null;
2848
- const runFormattingMarkers = markDocxRunFormatting(document, paragraphStyles, themeDocument);
2849
- const tabStopMarkers = markDocxParagraphTabStops(document, paragraphStyles);
2850
- const tableCellMarkers = markDocxTableCells(document);
3490
+ const runFormattingMarkers = markDocxRunFormatting(document, paragraphStyles, themeDocument, tableStyles);
3491
+ const tabStopMarkers = markDocxParagraphTabStops(document, paragraphStyles, tableStyles);
3492
+ const tableCellMarkers = markDocxTableCells(document, themeDocument, tableStyles);
2851
3493
  const tableRowMarkers = markDocxTableRows(document);
2852
- const tableSizingMarkers = markDocxTableSizing(document);
3494
+ const tableSizingMarkers = markDocxTableSizing(document, tableStyles);
2853
3495
  const settings = archive.has('word/settings.xml') ? await archive.xml('word/settings.xml') : null;
2854
3496
  const trackChanges = Boolean(settings && firstDescendant(settings, 'trackRevisions')) || changeMarkers.changes.length > 0;
2855
3497
  const sectionElements = effectiveSectionProperties(document);
@@ -3021,6 +3663,7 @@ async function parseSectionLayout(section, archive, relationships, previous, odd
3021
3663
  const size = pageSize ? Math.abs(shortEdge - 12240) < Math.abs(shortEdge - 11906) ? 'letter' : 'a4' : previous.pageSize;
3022
3664
  const marginsElement = firstDescendant(section, 'pgMar');
3023
3665
  const columnsElement = firstDescendant(section, 'cols');
3666
+ const documentGridElement = directChild(section, 'docGrid');
3024
3667
  const pageChrome = await importSectionPageChrome(section, archive, relationships, previous, oddEvenPageChrome);
3025
3668
  const pageNumberStart = work_docx_import_numberAttribute(firstDescendant(section, 'pgNumType'), 'start');
3026
3669
  return {
@@ -3032,11 +3675,27 @@ async function parseSectionLayout(section, archive, relationships, previous, odd
3032
3675
  columns: columnsElement ? importDocxColumns(columnsElement, previous.columns) : {
3033
3676
  ...previous.columns
3034
3677
  },
3678
+ ...documentGridElement ? {
3679
+ documentGrid: parseDocumentGrid(documentGridElement)
3680
+ } : previous.documentGrid ? {
3681
+ documentGrid: {
3682
+ ...previous.documentGrid
3683
+ }
3684
+ } : {},
3035
3685
  breakAfter: parseSectionBreak(firstDescendant(section, 'type')),
3036
3686
  ...pageChrome,
3037
3687
  pageNumberStart: pageNumberStart > 0 ? pageNumberStart : void 0
3038
3688
  };
3039
3689
  }
3690
+ function parseDocumentGrid(element) {
3691
+ const sourceType = attribute(element, 'type');
3692
+ const type = 'lines' === sourceType || 'linesAndChars' === sourceType || 'snapToChars' === sourceType ? sourceType : 'default';
3693
+ const sourceLinePitch = work_docx_import_numberAttribute(element, 'linePitch');
3694
+ return {
3695
+ type,
3696
+ linePitch: sourceLinePitch > 0 ? Number((sourceLinePitch / 20).toFixed(2)) : 18
3697
+ };
3698
+ }
3040
3699
  function addSectionMarkers(document, sectionElements) {
3041
3700
  for(let index = 0; index < sectionElements.length - 1; index += 1){
3042
3701
  const paragraph = work_docx_import_closestAncestor(sectionElements[index], 'p');