document-cli 5.2.6 → 5.3.1

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![GitHub](https://img.shields.io/badge/GitHub-181717?logo=github&logoColor=white)](https://github.com/ExaDev/documents.js/tree/main/packages/document-cli) [![npm](https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white)](https://www.npmjs.com/package/document-cli) [![npm version](https://img.shields.io/npm/v/document-cli)](https://www.npmjs.com/package/document-cli) [![CI](https://img.shields.io/github/actions/workflow/status/ExaDev/documents.js/ci.yml?branch=main)](https://github.com/ExaDev/documents.js/actions)
4
4
 
5
- > A command-line interface and an interactive terminal (Ink) app for [`documents.js`](https://github.com/ExaDev/documents.js): every docx/pptx/odt/odp/ods/odg/odf/pdf/odm/odb/xlsx/csv/svg/markdown/rtf conversion, bridge, and editor documents.js exposes, plus the outline projection [`document-outline.js`](../document-outline.js/README.md) builds over any readable document, wired up as a scriptable subcommand or a full-screen terminal editor. Installs as either `document-cli` or `doculi`.
5
+ > A command-line interface and an interactive terminal (Ink) app for [`documents.js`](https://github.com/ExaDev/documents.js): every docx/pptx/odt/odp/ods/odg/odf/pdf/odm/odb/xlsx/csv/svg/markdown/rtf/wpd conversion, bridge, and editor documents.js exposes, plus the outline projection [`document-outline.js`](../document-outline.js/README.md) builds over any readable document, wired up as a scriptable subcommand or a full-screen terminal editor. Installs as either `document-cli` or `doculi`.
6
6
 
7
7
  `document-cli` adds no conversion or editing logic of its own — it is a dispatch layer over `documents.js`'s existing conversion functions, `DocumentConverter` port, live-view editors, and `.odb`/PDF readers. What it adds is two ways to drive them without writing TypeScript: a scriptable, Unix-shaped CLI (stdin/stdout, exit codes, `--json` diagnostics) for pipelines, and a full-screen Ink terminal app for browsing and editing a document interactively.
8
8
 
@@ -143,7 +143,7 @@ document-cli pdf-inspect report.pdf
143
143
  document-cli pdf-inspect report.pdf --json
144
144
  ```
145
145
 
146
- **`fonts <input>`** — lists every source-embedded font face a docx/pptx/odt/odp/ods/odg document carries (family, weight/style, byte length) — the same embedded faces every `<format>-to-pdf` conversion already extracts and renders through automatically (see [Real fonts](#real-fonts) below); this command just reports what's there without converting anything. Rejects a format with no source-embedded-font concept at all (xlsx, csv, svg, pdf, markdown, odf, rtf), naming it:
146
+ **`fonts <input>`** — lists every source-embedded font face a docx/pptx/odt/odp/ods/odg document carries (family, weight/style, byte length) — the same embedded faces every `<format>-to-pdf` conversion already extracts and renders through automatically (see [Real fonts](#real-fonts) below); this command just reports what's there without converting anything. Rejects a format with no source-embedded-font concept at all (xlsx, csv, svg, pdf, markdown, odf, rtf, wpd), naming it:
147
147
 
148
148
  ```sh
149
149
  document-cli fonts report.docx
@@ -155,7 +155,7 @@ document-cli fonts report.docx
155
155
  document-cli docx-extras report.docx
156
156
  ```
157
157
 
158
- **`metadata <input>`** — prints a document's own title/author/subject/keywords/creator/producer/created/modified metadata, for any of the thirteen supported formats (docx, pptx, xlsx, odt, odp, ods, odg, svg, odf, csv, markdown, rtf, pdf); csv and svg carry no metadata container of their own, so they always report none. `--json` emits the raw metadata object:
158
+ **`metadata <input>`** — prints a document's own title/author/subject/keywords/creator/producer/created/modified metadata, for any of the fourteen supported formats (docx, pptx, xlsx, odt, odp, ods, odg, svg, odf, csv, markdown, rtf, wpd, pdf); csv and svg carry no metadata container of their own, so they always report none. `--json` emits the raw metadata object:
159
159
 
160
160
  ```sh
161
161
  document-cli metadata report.pdf
@@ -168,7 +168,7 @@ document-cli set-metadata report.docx report.docx --set-title "Q3 Report" --set-
168
168
  document-cli set-metadata report.docx report.odt --set-keywords "draft,internal"
169
169
  ```
170
170
 
171
- **`outline <input>`** — prints a document's outline: the table-of-contents projection over the tree-form `DocumentTree` read straight off the source document's own bytes — headings nested by heading level, list items nested under their heading or slide, one group per slide (labelled `Slide N`), sheet (labelled with the sheet's own name), or draw page (labelled `Page N`) — rendered as indented text, two spaces per nesting depth. Leaves render their own text (a paragraph's runs, a table's cell text, an image's alt text, a formula's LaTeX) or their kind in brackets when they carry none (`[page-break]`, `[vector]`, `[embeddedObject]`). Works on any of the twelve readable formats: the command reads the source's own native tree directly (documents.js's `readNativeDocumentTree`) — no bridging conversion runs and no output bytes are discarded — and projects that tree through [`document-outline.js`](../document-outline.js/README.md)'s own `buildOutline`, this command being that package's first real consumer. `--json` emits the outline tree itself — groups as `{ text, level, children }`, leaves as the package leaves they are — rather than a CLI-private shape; a `pdf` source's own `readPdf` parse diagnostics still reach stderr exactly as they would on the matching `pdf-to-docx` command. `--from <format>` names the source format when the input path carries no recognised extension to infer it from — the only way to outline a document read from stdin (`-`), which otherwise has no extension to read at all. Heading nesting depends on the source document actually carrying a heading-level signal on disk (`w:outlineLvl` for docx, `text:outline-level` for odt) — present in anything authored by Word or LibreOffice, and always present for a markdown source, whose own reader parses `#`/`##` headings directly; a docx or odt this ecosystem's own writers produce does not currently stamp that signal even though the paragraph still carries its `Heading1`/`Heading2`-style reference, so outlining a docx/odt generated by this CLI's own conversions loses heading nesting specifically (list nesting and slide/sheet/page grouping are unaffected):
171
+ **`outline <input>`** — prints a document's outline: the table-of-contents projection over the tree-form `DocumentTree` read straight off the source document's own bytes — headings nested by heading level, list items nested under their heading or slide, one group per slide (labelled `Slide N`), sheet (labelled with the sheet's own name), or draw page (labelled `Page N`) — rendered as indented text, two spaces per nesting depth. Leaves render their own text (a paragraph's runs, a table's cell text, an image's alt text, a formula's LaTeX) or their kind in brackets when they carry none (`[page-break]`, `[vector]`, `[embeddedObject]`). Works on any of the fourteen readable formats: the command reads the source's own native tree directly (documents.js's `readNativeDocumentTree`) — no bridging conversion runs and no output bytes are discarded — and projects that tree through [`document-outline.js`](../document-outline.js/README.md)'s own `buildOutline`, this command being that package's first real consumer. `--json` emits the outline tree itself — groups as `{ text, level, children }`, leaves as the package leaves they are — rather than a CLI-private shape; a `pdf` source's own `readPdf` parse diagnostics still reach stderr exactly as they would on the matching `pdf-to-docx` command. `--from <format>` names the source format when the input path carries no recognised extension to infer it from — the only way to outline a document read from stdin (`-`), which otherwise has no extension to read at all. Heading nesting depends on the source document actually carrying a heading-level signal on disk (`w:outlineLvl` for docx, `text:outline-level` for odt) — present in anything authored by Word or LibreOffice, and always present for a markdown source, whose own reader parses `#`/`##` headings directly; a docx or odt this ecosystem's own writers produce does not currently stamp that signal even though the paragraph still carries its `Heading1`/`Heading2`-style reference, so outlining a docx/odt generated by this CLI's own conversions loses heading nesting specifically (list nesting and slide/sheet/page grouping are unaffected):
172
172
 
173
173
  ```sh
174
174
  document-cli outline report.docx
@@ -231,7 +231,7 @@ It supports the same seven formats documents.js's live-view editors cover — do
231
231
 
232
232
  Markdown (`.md`/`.markdown`) shares the same paragraph/run/table body-list screens docx and odt already use, through documents.js's own `MarkdownEditor` (`openMarkdown`/`createMarkdownEditor`) — a genuine live view over a mutable `ContentDocument`, the same live-view contract every other editor here follows, even though there is no `XmlElement` tree underneath it the way there is for docx/odt (`MarkdownEditor.toMarkdownText()` re-serialises the whole document fresh on every call, rather than exposing a `toBytes()`). Appending a paragraph, appending a run, and toggling bold/italic all go through the identical reducer actions docx/odt use; a markdown run has no underline, colour, font family, or font size at all (CommonMark/GFM has no construct for any of the four), so those keys — along with image insertion, which `MarkdownParagraph` has no counterpart for — are simply absent from a markdown paragraph's own key hints rather than opening a prompt that could only end in a warning. A markdown table can be created and its cells edited through the same 'T' wizard and table-view screens docx/odt use, but GFM tables have no cell-merge concept, so a merge requested alongside table creation still creates the table (unmerged) and reports why the merge itself didn't happen. `:view-source` (markdown documents only) shows the literal text the document was opened with side by side with what a save would write right now — these can genuinely differ even with no edits made this session, from a heading-style, bullet-marker, or line-ending choice the writer normalises. Every save re-serialises the whole document fresh through `buildMarkdownText`, a deliberate, permanent consequence of structured editing rather than something to work around. Diagnostics from the read side (a clamped heading level, a dropped front-matter key, a fenced code block's own info string with nowhere to go, …) now surface into the same diagnostics panel a PDF export's own substitutions already populate, the moment a `.md` file is opened, not only on export. documents.js's own `createMarkdownEditor()` exists now, but this TUI does not yet wire a "new markdown document" flow into `:new`/the new-document picker, so a markdown document can still only be opened from an existing file.
233
233
 
234
- Three further kinds of format open read-only: a `.odb` browses its tables and rows with no write path at all (documents.js's own `.odb` support has no write direction to offer), a `.pdf` browses its pages and positioned items rather than being edited in place, and a `.xlsx`, `.csv`, `.svg`, or `.rtf` opens as a converted PDF preview — documents.js has no spreadsheet, svg, or rtf editor to hold a live view into, so opening one runs `xlsxToPdf`, `csvToPdf`, `svgToPdf`, or `rtfToPdf` once at open time and browses the result through the identical page-list/page-items/item-detail screens a real `.pdf` uses, with the original bytes kept alongside so a later export re-runs the same conversion with the caller's own fonts and diagnostics rather than reusing the fixed preview conversion. A `.odb` additionally browses its _structure_ alongside its data: `f` from the table list opens the form browser and `r` the report browser, each listing what the database declares and opening one to show it in full — a form's own data source and field-bound controls (sub-forms nested under their parent), a report's data-source command, band and group structure, and every `rpt:` formula. Both are rendered through the same `src/odb-structure.ts` the `odb-forms`/`odb-reports` commands print, so the two views cannot drift apart, and search filters by line (`/SUM` narrows a long report to its aggregate expressions). `Enter` on a report's own detail screen renders it — its data-source command resolved, its `rpt:` formulas evaluated, its bands laid out — to a real `docx`/`odt`/`pdf` file, through the same two-field destination-path-then-font-list form the PDF-export screen below uses; the TUI counterpart to the `odb-render-report` command. A standalone `.odf` formula document has no TUI editor either — nothing to edit interactively, only a PDF conversion.
234
+ Three further kinds of format open read-only: a `.odb` browses its tables and rows with no write path at all (documents.js's own `.odb` support has no write direction to offer), a `.pdf` browses its pages and positioned items rather than being edited in place, and a `.xlsx`, `.csv`, `.svg`, `.rtf`, or `.wpd` opens as a converted PDF preview — documents.js has no spreadsheet, svg, rtf, or wpd editor to hold a live view into (wpd-codec ships no writer at all, so a wpd document could never gain one), so opening one runs `xlsxToPdf`, `csvToPdf`, `svgToPdf`, `rtfToPdf`, or `convertDocument("wpd", "pdf", ...)` once at open time and browses the result through the identical page-list/page-items/item-detail screens a real `.pdf` uses, with the original bytes kept alongside so a later export re-runs the same conversion with the caller's own fonts and diagnostics rather than reusing the fixed preview conversion. A `.odb` additionally browses its _structure_ alongside its data: `f` from the table list opens the form browser and `r` the report browser, each listing what the database declares and opening one to show it in full — a form's own data source and field-bound controls (sub-forms nested under their parent), a report's data-source command, band and group structure, and every `rpt:` formula. Both are rendered through the same `src/odb-structure.ts` the `odb-forms`/`odb-reports` commands print, so the two views cannot drift apart, and search filters by line (`/SUM` narrows a long report to its aggregate expressions). `Enter` on a report's own detail screen renders it — its data-source command resolved, its `rpt:` formulas evaluated, its bands laid out — to a real `docx`/`odt`/`pdf` file, through the same two-field destination-path-then-font-list form the PDF-export screen below uses; the TUI counterpart to the `odb-render-report` command. A standalone `.odf` formula document has no TUI editor either — nothing to edit interactively, only a PDF conversion.
235
235
 
236
236
  The export-to-PDF screen (`e` from any editor screen) is a two-field form: a destination path, then an optional comma-separated list of local `.ttf`/`.otf` paths, which are the same `--font-file` faces the CLI takes and are derived the same way — each font's family, weight, and slope come from the file itself. `Enter` on the path field moves to the fonts field and `Enter` there exports, so leaving fonts empty is still "type a path, press Enter twice". Comma-separated rather than space-separated because a font path routinely contains spaces and almost never a comma. A face falling back to a substitute is reported into the same diagnostics panel a character substitution already is, and a bad font path fails the export with the file named, before anything is written to the destination.
237
237
 
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as odbFormSummary, c as formatDocxExtrasLines, d as writeOutput, f as loadProvidedFonts, h as isDocumentFormat, i as formatOdbReportLines, l as readInput, m as inferFormatFromExtension, n as describeOdbReport, o as formatMetadataLines, r as formatOdbFormLines, s as presentMetadataEntries, t as describeOdbForm, u as resolveDefaultOutputPath } from "./odb-structure-DX5OkaeR.js";
2
+ import { a as odbFormSummary, c as formatDocxExtrasLines, d as writeOutput, f as loadProvidedFonts, h as isDocumentFormat, i as formatOdbReportLines, l as readInput, m as inferFormatFromExtension, n as describeOdbReport, o as formatMetadataLines, r as formatOdbFormLines, s as presentMetadataEntries, t as describeOdbForm, u as resolveDefaultOutputPath } from "./odb-structure-Bk3PDk24.js";
3
3
  import { Command, CommanderError, InvalidArgumentError } from "commander";
4
4
  import { writeFile } from "node:fs/promises";
5
5
  import { basename, dirname, extname, join, resolve } from "node:path";
@@ -1199,7 +1199,7 @@ function registerSetMetadataCommand(program) {
1199
1199
  }
1200
1200
  //#endregion
1201
1201
  //#region package.json
1202
- var version = "5.2.6";
1202
+ var version = "5.3.1";
1203
1203
  //#endregion
1204
1204
  //#region src/program.ts
1205
1205
  function createProgram() {
@@ -1227,7 +1227,7 @@ function createProgram() {
1227
1227
  //#region src/cli.ts
1228
1228
  async function launchTui(startPath, signal) {
1229
1229
  try {
1230
- const { runTui } = await import("./tui-BIN_wCkn.js");
1230
+ const { runTui } = await import("./tui-D2anNO4v.js");
1231
1231
  await runTui({
1232
1232
  startPath,
1233
1233
  signal
package/dist/index.cjs CHANGED
@@ -32,6 +32,7 @@ const EXTENSION_TO_FORMAT = {
32
32
  markdown: "markdown",
33
33
  md: "markdown",
34
34
  rtf: "rtf",
35
+ wpd: "wpd",
35
36
  pdf: "pdf"
36
37
  };
37
38
  const FORMAT_TO_EXTENSION = {
@@ -47,6 +48,7 @@ const FORMAT_TO_EXTENSION = {
47
48
  svg: "svg",
48
49
  markdown: "md",
49
50
  rtf: "rtf",
51
+ wpd: "wpd",
50
52
  pdf: "pdf"
51
53
  };
52
54
  function isDocumentFormat(value) {
@@ -1539,7 +1541,7 @@ function registerSetMetadataCommand(program) {
1539
1541
  }
1540
1542
  //#endregion
1541
1543
  //#region package.json
1542
- var version = "5.2.6";
1544
+ var version = "5.3.1";
1543
1545
  //#endregion
1544
1546
  //#region src/program.ts
1545
1547
  function createProgram() {
package/dist/index.js CHANGED
@@ -31,6 +31,7 @@ const EXTENSION_TO_FORMAT = {
31
31
  markdown: "markdown",
32
32
  md: "markdown",
33
33
  rtf: "rtf",
34
+ wpd: "wpd",
34
35
  pdf: "pdf"
35
36
  };
36
37
  const FORMAT_TO_EXTENSION = {
@@ -46,6 +47,7 @@ const FORMAT_TO_EXTENSION = {
46
47
  svg: "svg",
47
48
  markdown: "md",
48
49
  rtf: "rtf",
50
+ wpd: "wpd",
49
51
  pdf: "pdf"
50
52
  };
51
53
  function isDocumentFormat(value) {
@@ -1538,7 +1540,7 @@ function registerSetMetadataCommand(program) {
1538
1540
  }
1539
1541
  //#endregion
1540
1542
  //#region package.json
1541
- var version = "5.2.6";
1543
+ var version = "5.3.1";
1542
1544
  //#endregion
1543
1545
  //#region src/program.ts
1544
1546
  function createProgram() {
@@ -27,6 +27,7 @@ const EXTENSION_TO_FORMAT = {
27
27
  markdown: "markdown",
28
28
  md: "markdown",
29
29
  rtf: "rtf",
30
+ wpd: "wpd",
30
31
  pdf: "pdf"
31
32
  };
32
33
  const FORMAT_TO_EXTENSION = {
@@ -42,6 +43,7 @@ const FORMAT_TO_EXTENSION = {
42
43
  svg: "svg",
43
44
  markdown: "md",
44
45
  rtf: "rtf",
46
+ wpd: "wpd",
45
47
  pdf: "pdf"
46
48
  };
47
49
  function isDocumentFormat(value) {
@@ -1,7 +1,7 @@
1
- import { c as formatDocxExtrasLines, f as loadProvidedFonts, i as formatOdbReportLines, l as readInput, m as inferFormatFromExtension, n as describeOdbReport, o as formatMetadataLines, p as formatToExtension, r as formatOdbFormLines, t as describeOdbForm } from "./odb-structure-DX5OkaeR.js";
1
+ import { c as formatDocxExtrasLines, f as loadProvidedFonts, i as formatOdbReportLines, l as readInput, m as inferFormatFromExtension, n as describeOdbReport, o as formatMetadataLines, p as formatToExtension, r as formatOdbFormLines, t as describeOdbForm } from "./odb-structure-Bk3PDk24.js";
2
2
  import { readFile, writeFile } from "node:fs/promises";
3
3
  import { basename, dirname, extname, join } from "node:path";
4
- import { bytesToBase64, cellReference, columnIndexToLetters, createDocx, createOdg, createOdp, createOds, createOdt, createPdf, createPptx, csvToPdf, decodeMarkdownText, decodeOdbPackage, docxToPdf, encodeMarkdownText, hsqldbCellDisplayText, markdownToPdf, odbReportToDocx, odbReportToOdt, odbReportToPdf, odgToPdf, odpToPdf, odsToPdf, odtToPdf, openDocx, openMarkdown, openOdg, openOdp, openOds, openOdt, openPdf, openPptx, parseXml, pptxToPdf, readDocxContent, readDocxExtras, readMarkdownContent, readOdbForms, readOdbReportContent, readOdbReports, readOdbTables, readOdgContent, readOdpContent, readOdsContent, readOdtContent, readPdf, readPptxContent, rgbHexToColor, rtfToPdf, svgToPdf, xlsxToPdf } from "documents.js";
4
+ import { bytesToBase64, cellReference, columnIndexToLetters, convertDocument, createDocx, createOdg, createOdp, createOds, createOdt, createPdf, createPptx, csvToPdf, decodeMarkdownText, decodeOdbPackage, docxToPdf, encodeMarkdownText, hsqldbCellDisplayText, markdownToPdf, odbReportToDocx, odbReportToOdt, odbReportToPdf, odgToPdf, odpToPdf, odsToPdf, odtToPdf, openDocx, openMarkdown, openOdg, openOdp, openOds, openOdt, openPdf, openPptx, parseXml, pptxToPdf, readDocxContent, readDocxExtras, readMarkdownContent, readOdbForms, readOdbReportContent, readOdbReports, readOdbTables, readOdgContent, readOdpContent, readOdsContent, readOdtContent, readPdf, readPptxContent, rgbHexToColor, rtfToPdf, svgToPdf, xlsxToPdf } from "documents.js";
5
5
  import { readdirSync } from "node:fs";
6
6
  import { Box, Text, render, useApp, useInput, useWindowSize } from "ink";
7
7
  import { createContext, useContext, useEffect, useReducer, useState } from "react";
@@ -62,6 +62,11 @@ async function exportToPdf(openDocument, destinationPath, options) {
62
62
  await writeFile(destinationPath, pdfBytes);
63
63
  return;
64
64
  }
65
+ if (openDocument.format === "wpd") {
66
+ const pdfBytes = convertDocument("wpd", "pdf", openDocument.bytes, pdfOptions);
67
+ await writeFile(destinationPath, pdfBytes);
68
+ return;
69
+ }
65
70
  const bytes = openDocument.editor.toBytes();
66
71
  const pdfBytes = convert(openDocument.format, bytes, pdfOptions);
67
72
  await writeFile(destinationPath, pdfBytes);
@@ -181,6 +186,12 @@ async function openDocumentAtPath(path, options = {}) {
181
186
  bytes,
182
187
  path
183
188
  };
189
+ case "wpd": return {
190
+ format,
191
+ layout: readPdf(convertDocument("wpd", "pdf", bytes)),
192
+ bytes,
193
+ path
194
+ };
184
195
  case "odf": throw new Error("A standalone .odf formula document has no editor; convert it to PDF (odfToPdf) instead");
185
196
  }
186
197
  }
@@ -228,7 +239,7 @@ function createNewDocument(format) {
228
239
  }
229
240
  }
230
241
  async function saveDocumentTo(openDocument, path) {
231
- if (openDocument.format === "odb" || openDocument.format === "xlsx" || openDocument.format === "csv" || openDocument.format === "svg" || openDocument.format === "rtf") throw new Error(`A ${openDocument.format} document is opened read-only and cannot be written back`);
242
+ if (openDocument.format === "odb" || openDocument.format === "xlsx" || openDocument.format === "csv" || openDocument.format === "svg" || openDocument.format === "rtf" || openDocument.format === "wpd") throw new Error(`A ${openDocument.format} document is opened read-only and cannot be written back`);
232
243
  if (openDocument.format === "markdown") {
233
244
  await writeFile(path, encodeMarkdownText(openDocument.editor.toMarkdownText()));
234
245
  return;
@@ -313,7 +324,8 @@ function rootScreenForFormat(format) {
313
324
  case "xlsx":
314
325
  case "csv":
315
326
  case "svg":
316
- case "rtf": return { kind: "pdfPageList" };
327
+ case "rtf":
328
+ case "wpd": return { kind: "pdfPageList" };
317
329
  }
318
330
  }
319
331
  function currentScreen(state) {
@@ -468,6 +480,12 @@ function documentWithPath(doc, path) {
468
480
  bytes: doc.bytes,
469
481
  path
470
482
  };
483
+ case "wpd": return {
484
+ format: "wpd",
485
+ layout: doc.layout,
486
+ bytes: doc.bytes,
487
+ path
488
+ };
471
489
  }
472
490
  }
473
491
  function reopenEditable(doc, bytes) {
@@ -786,7 +804,7 @@ function appReducer(state, action) {
786
804
  selection: {},
787
805
  errorDetail: void 0,
788
806
  stack: [rootScreenForFormat(action.doc.format)]
789
- }, "info", action.doc.format === "xlsx" || action.doc.format === "csv" || action.doc.format === "svg" || action.doc.format === "rtf" ? `Opened ${action.path} as a read-only PDF preview -- press ':' then 'export pdf' to save it as a real PDF` : `Opened ${action.path}`);
807
+ }, "info", action.doc.format === "xlsx" || action.doc.format === "csv" || action.doc.format === "svg" || action.doc.format === "rtf" || action.doc.format === "wpd" ? `Opened ${action.path} as a read-only PDF preview -- press ':' then 'export pdf' to save it as a real PDF` : `Opened ${action.path}`);
790
808
  case "OPEN_FILE_ERROR": return withStatus({
791
809
  ...state,
792
810
  errorDetail: {
@@ -1381,7 +1399,7 @@ function appReducer(state, action) {
1381
1399
  case "UNDO": {
1382
1400
  const doc = state.openDocument;
1383
1401
  if (doc === void 0) return withStatus(state, "info", "There is nothing to undo");
1384
- if (doc.format === "odb" || doc.format === "xlsx" || doc.format === "csv" || doc.format === "svg" || doc.format === "rtf") return withStatus(state, "warning", `A ${doc.format} document is read-only, so it has no history to undo`);
1402
+ if (doc.format === "odb" || doc.format === "xlsx" || doc.format === "csv" || doc.format === "svg" || doc.format === "rtf" || doc.format === "wpd") return withStatus(state, "warning", `A ${doc.format} document is read-only, so it has no history to undo`);
1385
1403
  const snapshot = state.undoStack.at(-1);
1386
1404
  if (snapshot === void 0) return withStatus(state, "info", "There is nothing to undo");
1387
1405
  const restored = doc.format === "markdown" ? {
@@ -7225,7 +7243,7 @@ function OdtBodyListScreen() {
7225
7243
  //#endregion
7226
7244
  //#region src/tui/screens/editors/pdf/shared.ts
7227
7245
  function requirePdfDocument(openDocument) {
7228
- if (openDocument?.format !== "pdf" && openDocument?.format !== "xlsx" && openDocument?.format !== "csv" && openDocument?.format !== "svg" && openDocument?.format !== "rtf") throw new Error("A PDF inspection screen rendered without an open PDF, xlsx, csv, svg, or rtf document; the app router only reaches this screen group from pdfPageList, which is only ever the root screen of one of those five formats.");
7246
+ if (openDocument?.format !== "pdf" && openDocument?.format !== "xlsx" && openDocument?.format !== "csv" && openDocument?.format !== "svg" && openDocument?.format !== "rtf" && openDocument?.format !== "wpd") throw new Error("A PDF inspection screen rendered without an open PDF, xlsx, csv, svg, rtf, or wpd document; the app router only reaches this screen group from pdfPageList, which is only ever the root screen of one of those six formats.");
7229
7247
  return openDocument;
7230
7248
  }
7231
7249
  function isEditablePdfDocument(doc) {
@@ -9057,7 +9075,8 @@ function metadataFor(doc) {
9057
9075
  case "xlsx":
9058
9076
  case "csv":
9059
9077
  case "svg":
9060
- case "rtf": return doc.layout.metadata;
9078
+ case "rtf":
9079
+ case "wpd": return doc.layout.metadata;
9061
9080
  case "odb": throw new Error("A .odb database has no document-level metadata -- it is a table/form/report container, not a single document with its own title/author/etc.");
9062
9081
  }
9063
9082
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "document-cli",
3
- "version": "5.2.6",
3
+ "version": "5.3.1",
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": {
@@ -92,7 +92,7 @@
92
92
  "commander": "^15.0.0",
93
93
  "document-outline.js": "^3.2.2",
94
94
  "document-schema.js": "^5.5.0",
95
- "documents.js": "^6.3.6",
95
+ "documents.js": "^6.4.1",
96
96
  "ink": "^7.1.1",
97
97
  "ink-text-input": "^6.0.0",
98
98
  "react": "^19.2.8"
@@ -106,7 +106,7 @@
106
106
  "eslint": "^10.8.0",
107
107
  "husky": "^9.1.7",
108
108
  "ink-testing-library": "^4.0.0",
109
- "odf.js": "^6.2.1",
109
+ "odf.js": "^6.3.0",
110
110
  "publint": "^0.3.22",
111
111
  "semantic-release": "^25.0.8",
112
112
  "tsdown": "^0.22.14",