wordinweb 0.1.14 → 0.1.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1363,6 +1363,14 @@ declare class DocxDocument {
1363
1363
  */
1364
1364
  private rememberOriginalXml;
1365
1365
  private writeModeledXml;
1366
+ /**
1367
+ * Canonicalize producer shorthand that Google Docs otherwise interprets as
1368
+ * a fixed, few-twip table. Word treats `tblW="100%"` plus a placeholder
1369
+ * grid as autofit; Google needs the standard pct value and a usable cached
1370
+ * grid. The cached widths follow the same content-dominant shape and do not
1371
+ * change Word's autofit result.
1372
+ */
1373
+ private normalizePercentageTableGrids;
1366
1374
  save(): Uint8Array;
1367
1375
  /** Fresh unique docPr id for inserted drawings. */
1368
1376
  nextDrawingId(): number;
package/dist/index.js CHANGED
@@ -6906,7 +6906,95 @@ var DocxDocument = class _DocxDocument {
6906
6906
  const xml = serializeXml(root, true);
6907
6907
  if (xml !== this.originalModeledXml.get(part)) files[part] = strToU82(xml);
6908
6908
  }
6909
+ /**
6910
+ * Canonicalize producer shorthand that Google Docs otherwise interprets as
6911
+ * a fixed, few-twip table. Word treats `tblW="100%"` plus a placeholder
6912
+ * grid as autofit; Google needs the standard pct value and a usable cached
6913
+ * grid. The cached widths follow the same content-dominant shape and do not
6914
+ * change Word's autofit result.
6915
+ */
6916
+ normalizePercentageTableGrids() {
6917
+ const setAttr = (element, name, value) => {
6918
+ const key = Object.keys(element.attrs).find((item) => localName(item) === name);
6919
+ element.attrs[key ?? `${element.name.includes(":") ? element.name.split(":")[0] + ":" : ""}${name}`] = value;
6920
+ };
6921
+ const textLength = (blocks) => {
6922
+ let length = 0;
6923
+ for (const block of blocks) {
6924
+ if (block.type === "table") {
6925
+ for (const row of block.rows) {
6926
+ for (const cell of row.cells) length += textLength(cell.blocks);
6927
+ }
6928
+ continue;
6929
+ }
6930
+ for (const item of block.children) {
6931
+ const runs = item.type === "run" ? [item] : item.runs;
6932
+ for (const run of runs) {
6933
+ for (const content of run.content) {
6934
+ if (content.kind === "text") length += content.text.length;
6935
+ else if (content.kind === "tab") length += 4;
6936
+ }
6937
+ }
6938
+ }
6939
+ }
6940
+ return length;
6941
+ };
6942
+ const normalize = (table2, available) => {
6943
+ const source = table2.src;
6944
+ if (!source) return;
6945
+ const tableProps = child(source, "tblPr");
6946
+ const tableWidth = child(tableProps, "tblW");
6947
+ const rawWidth = attr(tableWidth, "w")?.trim();
6948
+ if (attr(tableWidth, "type") !== "pct" || !rawWidth?.endsWith("%")) return;
6949
+ const percent = Number.parseFloat(rawWidth);
6950
+ if (!Number.isFinite(percent) || percent <= 0) return;
6951
+ setAttr(tableWidth, "w", String(Math.round(percent * 50)));
6952
+ const grid = child(source, "tblGrid");
6953
+ const columns = children(grid, "gridCol");
6954
+ if (columns.length === 0) return;
6955
+ const target = Math.round(pxToTwips(available) * percent / 100);
6956
+ const authoredTotal = columns.reduce((sum2, column) => sum2 + (intAttr(column, "w") ?? 0), 0);
6957
+ if (target <= 0 || authoredTotal >= target * 0.1) return;
6958
+ const floor = 600;
6959
+ const widths = new Array(columns.length).fill(floor);
6960
+ for (const row of table2.rows) {
6961
+ let column = 0;
6962
+ for (const cell of row.cells) {
6963
+ const span = Math.max(1, Math.min(cell.props.gridSpan, columns.length - column));
6964
+ const demand = Math.max(floor * span, textLength(cell.blocks) * 100 + 300);
6965
+ for (let offset = 0; offset < span; offset++) {
6966
+ widths[column + offset] = Math.max(widths[column + offset], demand / span);
6967
+ }
6968
+ column += cell.props.gridSpan;
6969
+ if (column >= columns.length) break;
6970
+ }
6971
+ }
6972
+ const dominant = widths.indexOf(Math.max(...widths));
6973
+ const total = widths.reduce((sum2, width) => sum2 + width, 0);
6974
+ if (total < target) {
6975
+ widths[dominant] += target - total;
6976
+ } else if (total > target) {
6977
+ const slack = widths.reduce((sum2, width) => sum2 + Math.max(0, width - floor), 0);
6978
+ const scale = slack > 0 ? Math.min(1, (total - target) / slack) : 0;
6979
+ for (let index = 0; index < widths.length; index++) {
6980
+ widths[index] -= Math.max(0, widths[index] - floor) * scale;
6981
+ }
6982
+ }
6983
+ const rounded = widths.map(Math.round);
6984
+ rounded[dominant] += target - rounded.reduce((sum2, width) => sum2 + width, 0);
6985
+ columns.forEach((column, index) => setAttr(column, "w", String(rounded[index])));
6986
+ };
6987
+ for (const section of this.sections) {
6988
+ const contentWidth = section.props.pageWidth - section.props.marginLeft - section.props.marginRight - section.props.gutter;
6989
+ const columnCount = Math.max(1, section.props.columns.count);
6990
+ const available = section.props.columns.widths?.[0] ?? (contentWidth - section.props.columns.space * (columnCount - 1)) / columnCount;
6991
+ for (const block of section.blocks) {
6992
+ if (block.type === "table") normalize(block, available);
6993
+ }
6994
+ }
6995
+ }
6909
6996
  save() {
6997
+ this.normalizePercentageTableGrids();
6910
6998
  const files = { ...this.pkg.raw() };
6911
6999
  if (files["docProps/custom.xml"] && this.contentTypesRoot && !this.contentTypesRoot.children.some(
6912
7000
  (item) => localName(item.name) === "Override" && item.attrs.PartName === "/docProps/custom.xml"