doculi 5.11.38 → 5.11.40

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/cli.js CHANGED
@@ -1195,7 +1195,7 @@ function registerSetMetadataCommand(program) {
1195
1195
  }
1196
1196
  //#endregion
1197
1197
  //#region package.json
1198
- var version = "5.11.38";
1198
+ var version = "5.11.40";
1199
1199
  //#endregion
1200
1200
  //#region src/program.ts
1201
1201
  function createProgram() {
@@ -1223,7 +1223,7 @@ function createProgram() {
1223
1223
  //#region src/cli-main.ts
1224
1224
  async function launchTui(startPath, signal) {
1225
1225
  try {
1226
- const { runTui } = await import("./tui-3Ib43SWz.js");
1226
+ const { runTui } = await import("./tui-B2SvQVHR.js");
1227
1227
  await runTui({
1228
1228
  startPath,
1229
1229
  signal
package/dist/index.cjs CHANGED
@@ -1546,7 +1546,7 @@ function registerSetMetadataCommand(program) {
1546
1546
  }
1547
1547
  //#endregion
1548
1548
  //#region package.json
1549
- var version = "5.11.38";
1549
+ var version = "5.11.40";
1550
1550
  //#endregion
1551
1551
  //#region src/program.ts
1552
1552
  function createProgram() {
package/dist/index.js CHANGED
@@ -1545,7 +1545,7 @@ function registerSetMetadataCommand(program) {
1545
1545
  }
1546
1546
  //#endregion
1547
1547
  //#region package.json
1548
- var version = "5.11.38";
1548
+ var version = "5.11.40";
1549
1549
  //#endregion
1550
1550
  //#region src/program.ts
1551
1551
  function createProgram() {
@@ -3,6 +3,7 @@ import { readFile, writeFile } from "node:fs/promises";
3
3
  import { basename, dirname, extname, join } from "node:path";
4
4
  import { bytesToBase64, cellReference, columnIndexToLetters, convertDocument, createDoc, createDocx, createMarkdownEditor, createOdg, createOdp, createOds, createOdt, createPdf, createPpt, createPptx, createXls, csvToPdf, decodeMarkdownText, decodeOdbPackage, docToPdf, docxToPdf, encodeMarkdownText, epubToPdf, hsqldbCellDisplayText, markdownToPdf, odbReportToDocx, odbReportToOdt, odbReportToPdf, odgToPdf, odpToPdf, odsToPdf, odtToPdf, openDoc, openDocx, openMarkdown, openOdg, openOdp, openOds, openOdt, openPdf, openPpt, openPptx, openXls, parseXml, pptToPdf, pptxToPdf, readDocxContent, readDocxExtras, readMarkdownContent, readOdbForms, readOdbReportContent, readOdbReports, readOdbTables, readOdgContent, readOdpContent, readOdsContent, readOdtContent, readPdf, readPptxContent, rgbHexToColor, rtfToPdf, svgToPdf, xlsToPdf, xlsxToPdf } from "documents.js";
5
5
  import { readdirSync } from "node:fs";
6
+ import { tableCellColumnSpan, tableGridColumnCount, walkTableGrid } from "document-schema.js";
6
7
  import { Box, Text, render, useApp, useInput, useWindowSize } from "ink";
7
8
  import { createContext, useContext, useEffect, useReducer, useState } from "react";
8
9
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
@@ -678,6 +679,7 @@ function mergePptxTableCells(table, startRow, startColumn, rowSpan, colSpan) {
678
679
  }
679
680
  if (columnOffset > 0) cell.horizontalMerge = true;
680
681
  if (rowOffset > 0) cell.verticalMerge = true;
682
+ cell.setParagraphs([{ runs: [] }]);
681
683
  }
682
684
  }
683
685
  }
@@ -5621,16 +5623,70 @@ function ShapeEditorScreen(props) {
5621
5623
  //#endregion
5622
5624
  //#region src/tui/screens/shared/slide-table.ts
5623
5625
  function resolveSlideTable(doc, slideIndex, tableIndex) {
5626
+ return readSlideTables(doc, slideIndex)[tableIndex];
5627
+ }
5628
+ function readSlideTables(doc, slideIndex) {
5624
5629
  const content = doc.format === "odp" ? readOdpContent(doc.editor.toPackage()) : readPptxContent(doc.editor.toPackage());
5625
5630
  if (content.kind !== "presentation") throw new Error("readPptxContent/readOdpContent always resolve a presentation package to the presentation ContentDocument variant.");
5626
5631
  const slide = content.slides[slideIndex];
5627
- if (slide === void 0) return;
5628
- return slide.shapes.flatMap((shape) => shape.blocks.filter((block) => block.kind === "table"))[tableIndex];
5632
+ if (slide === void 0) return [];
5633
+ return slide.shapes.flatMap((shape) => shape.blocks.filter((block) => block.kind === "table"));
5629
5634
  }
5630
5635
  function slideTableCellText(cell) {
5631
5636
  return cell.blocks.filter((block) => block.kind === "paragraph").map((paragraph) => paragraph.runs.map((run) => run.text).join("")).join("\n");
5632
5637
  }
5633
- function summarizeGridTable(table, index) {
5638
+ /**
5639
+ * The boxes to draw for each row of a slide table. A ContentTable row is dense (one entry per grid column, a merged region's covered positions being real, block-less entries), so drawing every entry would show a merged region as several separate empty cells. Instead a region's anchor is drawn once at its full width, and the positions it covers to its right in the same row are absorbed into that box. Positions a region covers in later rows are drawn as continuation boxes, adjacent positions of one region sharing one box, so the region reads as one block spanning the rows it occupies. Grid columns stay addressable by index: a cursor on any covered position lies within the box that contains it.
5640
+ */
5641
+ function slideTableRowSegments(table) {
5642
+ return walkTableGrid(table).map((positions, rowIndex) => {
5643
+ const segments = [];
5644
+ let continuedFrom;
5645
+ for (const position of positions) {
5646
+ if (position.anchorRowIndex === void 0) {
5647
+ continuedFrom = void 0;
5648
+ segments.push({
5649
+ rowIndex,
5650
+ columnIndex: position.columnIndex,
5651
+ columnSpan: tableCellColumnSpan(position.cell),
5652
+ cell: position.cell
5653
+ });
5654
+ continue;
5655
+ }
5656
+ if (position.anchorRowIndex === rowIndex) continue;
5657
+ const previous = segments[segments.length - 1];
5658
+ if (previous !== void 0 && continuedFrom?.row === position.anchorRowIndex && continuedFrom.column === position.anchorColumnIndex) {
5659
+ segments[segments.length - 1] = {
5660
+ ...previous,
5661
+ columnSpan: previous.columnSpan + 1
5662
+ };
5663
+ continue;
5664
+ }
5665
+ continuedFrom = {
5666
+ row: position.anchorRowIndex,
5667
+ column: position.anchorColumnIndex
5668
+ };
5669
+ segments.push({
5670
+ rowIndex,
5671
+ columnIndex: position.columnIndex,
5672
+ columnSpan: 1,
5673
+ cell: void 0
5674
+ });
5675
+ }
5676
+ return segments;
5677
+ });
5678
+ }
5679
+ /**
5680
+ * The text drawn inside a box that is `width` terminal columns wide, borders excluded. An anchor or unmerged cell shows its own text, truncated to fit; a continuation box shows an up arrow, since the region's text is displayed once, at its anchor.
5681
+ */
5682
+ function segmentText(segment, width) {
5683
+ return segment.cell === void 0 ? "↑" : truncatePreview(slideTableCellText(segment.cell), width);
5684
+ }
5685
+ /** Whether a grid position lies inside a box: on the box's own row and in one of the grid columns it occupies. A cursor on any position a merged region covers therefore selects the region's whole box. */
5686
+ function segmentContains(segment, position) {
5687
+ return position?.row === segment.rowIndex && position.column >= segment.columnIndex && position.column < segment.columnIndex + segment.columnSpan;
5688
+ }
5689
+ function summarizePptxTable(table, index) {
5634
5690
  const rows = table.rows();
5635
5691
  return {
5636
5692
  index,
@@ -5639,8 +5695,12 @@ function summarizeGridTable(table, index) {
5639
5695
  };
5640
5696
  }
5641
5697
  function summarizeSlideTables(doc, slideIndex) {
5642
- if (doc.format === "odp") return (doc.editor.slides()[slideIndex]?.tables() ?? []).map((entry, index) => summarizeGridTable(entry.table, index));
5643
- return (doc.editor.slides()[slideIndex]?.tables() ?? []).map((table, index) => summarizeGridTable(table, index));
5698
+ if (doc.format === "odp") return readSlideTables(doc, slideIndex).map((table, index) => ({
5699
+ index,
5700
+ rowCount: table.rows.length,
5701
+ columnCount: tableGridColumnCount(table)
5702
+ }));
5703
+ return (doc.editor.slides()[slideIndex]?.tables() ?? []).map((table, index) => summarizePptxTable(table, index));
5644
5704
  }
5645
5705
  //#endregion
5646
5706
  //#region src/tui/screens/editors/pptx/slide-detail.tsx
@@ -6107,6 +6167,7 @@ function SlideDetailScreen(props) {
6107
6167
  //#endregion
6108
6168
  //#region src/tui/screens/editors/pptx/slide-table-detail.tsx
6109
6169
  const CELL_WIDTH$1 = 16;
6170
+ const BORDER_COLUMNS = 2;
6110
6171
  function SlideTableDetailScreen(props) {
6111
6172
  const state = useAppState();
6112
6173
  const dispatch = useAppDispatch();
@@ -6226,19 +6287,22 @@ function SlideTableDetailScreen(props) {
6226
6287
  rows.length === 0 ? /* @__PURE__ */ jsx(Text, {
6227
6288
  dimColor: true,
6228
6289
  children: "This table has no rows."
6229
- }) : rows.map((row, rowIndex) => /* @__PURE__ */ jsx(Box, { children: row.cells.map((cell, columnIndex) => {
6230
- const isCursor = rowIndex === clampedRow && columnIndex === clampedColumn;
6231
- const isAnchor = rowIndex === mergeAnchor?.row && columnIndex === mergeAnchor.column;
6290
+ }) : slideTableRowSegments(table).map((segments, rowIndex) => /* @__PURE__ */ jsx(Box, { children: segments.map((segment) => {
6291
+ const isCursor = segmentContains(segment, {
6292
+ row: clampedRow,
6293
+ column: clampedColumn
6294
+ });
6295
+ const isAnchor = segmentContains(segment, mergeAnchor);
6232
6296
  return /* @__PURE__ */ jsx(Box, {
6233
- width: CELL_WIDTH$1,
6297
+ width: CELL_WIDTH$1 * segment.columnSpan,
6234
6298
  borderStyle: "single",
6235
6299
  borderColor: isCursor ? "cyan" : isAnchor ? "yellow" : "gray",
6236
6300
  children: /* @__PURE__ */ jsx(Text, {
6237
6301
  color: isCursor ? "cyan" : void 0,
6238
6302
  inverse: isCursor,
6239
- children: truncatePreview(slideTableCellText(cell), 14)
6303
+ children: segmentText(segment, CELL_WIDTH$1 * segment.columnSpan - BORDER_COLUMNS)
6240
6304
  })
6241
- }, columnIndex);
6305
+ }, segment.columnIndex);
6242
6306
  }) }, rowIndex)),
6243
6307
  /* @__PURE__ */ jsx(Text, {
6244
6308
  dimColor: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doculi",
3
- "version": "5.11.38",
3
+ "version": "5.11.40",
4
4
  "description": "CLI and interactive Ink TUI for documents.js: every docx/pptx/odt/odp/ods/odg/odf/pdf/odm/odb/xlsx/csv/svg/markdown/rtf conversion, bridge, and editor as a scriptable command or a terminal app.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -68,9 +68,9 @@
68
68
  "license": "MIT",
69
69
  "dependencies": {
70
70
  "commander": "15.0.0",
71
- "document-outline.js": "3.9.18",
72
- "document-schema.js": "7.11.5",
73
- "documents.js": "7.20.36",
71
+ "document-outline.js": "3.9.20",
72
+ "document-schema.js": "7.12.0",
73
+ "documents.js": "8.0.1",
74
74
  "ink": "7.1.1",
75
75
  "ink-text-input": "6.0.0",
76
76
  "react": "19.2.8"
@@ -87,7 +87,7 @@
87
87
  "eslint": "10.8.1",
88
88
  "husky": "9.1.7",
89
89
  "ink-testing-library": "4.0.0",
90
- "odf.js": "8.0.1",
90
+ "odf.js": "8.0.3",
91
91
  "publint": "0.3.22",
92
92
  "semantic-release": "25.0.9",
93
93
  "tsdown": "0.22.14",