document-cli 5.5.3 → 5.6.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/wpd/doc/xls/ppt 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/doc/xls/ppt/epub 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, wpd, doc, xls, ppt), 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, doc, xls, ppt) or with no font-embedding support in this ecosystem's own reader yet (epub — EPUB 3 can embed fonts via CSS `@font-face`, but epub-codec's own reader doesn't extract them), 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 seventeen supported formats (docx, pptx, xlsx, odt, odp, ods, odg, svg, odf, csv, markdown, rtf, wpd, doc, xls, ppt, pdf); csv, svg, doc, xls, and ppt carry no metadata container of their own (doc-codec/xls-codec/ppt-codec don't read one yet — see each package's own README), 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 eighteen supported formats (docx, pptx, xlsx, odt, odp, ods, odg, svg, odf, csv, markdown, rtf, wpd, doc, xls, ppt, epub, pdf); csv, svg, doc, xls, and ppt carry no metadata container of their own (doc-codec/xls-codec/ppt-codec don't read one yet — see each package's own README), so they always report none, and epub reports title/author/keywords but never subject (epub-codec's OPF reader has no Dublin Core mapping for it). `--json` emits the raw metadata object:
159
159
 
160
160
  ```sh
161
161
  document-cli metadata report.pdf
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as odbFormSummary, c as presentMetadataEntries, d as resolveDefaultOutputPath, f as writeOutput, g as isDocumentFormat, h as inferFormatFromExtension, i as formatOdbReportLines, l as formatDocxExtrasLines, n as describeOdbReport, o as formatMetadataLines, p as loadProvidedFonts, r as formatOdbFormLines, t as describeOdbForm, u as readInput } from "./odb-structure-DKJ3vi6l.js";
2
+ import { a as odbFormSummary, c as presentMetadataEntries, d as resolveDefaultOutputPath, f as writeOutput, g as isDocumentFormat, h as inferFormatFromExtension, i as formatOdbReportLines, l as formatDocxExtrasLines, n as describeOdbReport, o as formatMetadataLines, p as loadProvidedFonts, r as formatOdbFormLines, t as describeOdbForm, u as readInput } from "./odb-structure-CItnH50p.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";
@@ -139,7 +139,7 @@ function createFilesystemMarkdownImageResolver(baseDir) {
139
139
  }
140
140
  //#endregion
141
141
  //#region src/commands/shared.ts
142
- const KNOWN_DOCUMENT_FORMATS = "docx, pptx, xlsx, odt, odp, ods, odg, svg, odf, csv, markdown, rtf, pdf";
142
+ const KNOWN_DOCUMENT_FORMATS = "docx, pptx, xlsx, odt, odp, ods, odg, svg, odf, csv, markdown, rtf, wpd, doc, xls, ppt, epub, pdf";
143
143
  function resolveTargetFormat(output, out, to) {
144
144
  if (to !== void 0) {
145
145
  if (!isDocumentFormat(to)) return { errorMessage: `unknown --to format '${to}'; expected one of ${KNOWN_DOCUMENT_FORMATS}` };
@@ -1199,7 +1199,7 @@ function registerSetMetadataCommand(program) {
1199
1199
  }
1200
1200
  //#endregion
1201
1201
  //#region package.json
1202
- var version = "5.5.3";
1202
+ var version = "5.6.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-C_It5tfz.js");
1230
+ const { runTui } = await import("./tui-FXazDCHg.js");
1231
1231
  await runTui({
1232
1232
  startPath,
1233
1233
  signal
package/dist/index.cjs CHANGED
@@ -36,6 +36,7 @@ const EXTENSION_TO_FORMAT = {
36
36
  doc: "doc",
37
37
  xls: "xls",
38
38
  ppt: "ppt",
39
+ epub: "epub",
39
40
  pdf: "pdf"
40
41
  };
41
42
  const FORMAT_TO_EXTENSION = {
@@ -55,6 +56,7 @@ const FORMAT_TO_EXTENSION = {
55
56
  doc: "doc",
56
57
  xls: "xls",
57
58
  ppt: "ppt",
59
+ epub: "epub",
58
60
  pdf: "pdf"
59
61
  };
60
62
  function isDocumentFormat(value) {
@@ -267,7 +269,7 @@ function resolveDefaultOutputPath(inputPath, targetFormat) {
267
269
  }
268
270
  //#endregion
269
271
  //#region src/commands/shared.ts
270
- const KNOWN_DOCUMENT_FORMATS = "docx, pptx, xlsx, odt, odp, ods, odg, svg, odf, csv, markdown, rtf, pdf";
272
+ const KNOWN_DOCUMENT_FORMATS = "docx, pptx, xlsx, odt, odp, ods, odg, svg, odf, csv, markdown, rtf, wpd, doc, xls, ppt, epub, pdf";
271
273
  function resolveTargetFormat(output, out, to) {
272
274
  if (to !== void 0) {
273
275
  if (!isDocumentFormat(to)) return { errorMessage: `unknown --to format '${to}'; expected one of ${KNOWN_DOCUMENT_FORMATS}` };
@@ -1547,7 +1549,7 @@ function registerSetMetadataCommand(program) {
1547
1549
  }
1548
1550
  //#endregion
1549
1551
  //#region package.json
1550
- var version = "5.5.3";
1552
+ var version = "5.6.1";
1551
1553
  //#endregion
1552
1554
  //#region src/program.ts
1553
1555
  function createProgram() {
package/dist/index.js CHANGED
@@ -35,6 +35,7 @@ const EXTENSION_TO_FORMAT = {
35
35
  doc: "doc",
36
36
  xls: "xls",
37
37
  ppt: "ppt",
38
+ epub: "epub",
38
39
  pdf: "pdf"
39
40
  };
40
41
  const FORMAT_TO_EXTENSION = {
@@ -54,6 +55,7 @@ const FORMAT_TO_EXTENSION = {
54
55
  doc: "doc",
55
56
  xls: "xls",
56
57
  ppt: "ppt",
58
+ epub: "epub",
57
59
  pdf: "pdf"
58
60
  };
59
61
  function isDocumentFormat(value) {
@@ -266,7 +268,7 @@ function resolveDefaultOutputPath(inputPath, targetFormat) {
266
268
  }
267
269
  //#endregion
268
270
  //#region src/commands/shared.ts
269
- const KNOWN_DOCUMENT_FORMATS = "docx, pptx, xlsx, odt, odp, ods, odg, svg, odf, csv, markdown, rtf, pdf";
271
+ const KNOWN_DOCUMENT_FORMATS = "docx, pptx, xlsx, odt, odp, ods, odg, svg, odf, csv, markdown, rtf, wpd, doc, xls, ppt, epub, pdf";
270
272
  function resolveTargetFormat(output, out, to) {
271
273
  if (to !== void 0) {
272
274
  if (!isDocumentFormat(to)) return { errorMessage: `unknown --to format '${to}'; expected one of ${KNOWN_DOCUMENT_FORMATS}` };
@@ -1546,7 +1548,7 @@ function registerSetMetadataCommand(program) {
1546
1548
  }
1547
1549
  //#endregion
1548
1550
  //#region package.json
1549
- var version = "5.5.3";
1551
+ var version = "5.6.1";
1550
1552
  //#endregion
1551
1553
  //#region src/program.ts
1552
1554
  function createProgram() {
@@ -31,6 +31,7 @@ const EXTENSION_TO_FORMAT = {
31
31
  doc: "doc",
32
32
  xls: "xls",
33
33
  ppt: "ppt",
34
+ epub: "epub",
34
35
  pdf: "pdf"
35
36
  };
36
37
  const FORMAT_TO_EXTENSION = {
@@ -50,6 +51,7 @@ const FORMAT_TO_EXTENSION = {
50
51
  doc: "doc",
51
52
  xls: "xls",
52
53
  ppt: "ppt",
54
+ epub: "epub",
53
55
  pdf: "pdf"
54
56
  };
55
57
  function isDocumentFormat(value) {
@@ -1,7 +1,7 @@
1
- import { h as inferFormatFromExtension, i as formatOdbReportLines, l as formatDocxExtrasLines, m as formatToExtension, n as describeOdbReport, o as formatMetadataLines, p as loadProvidedFonts, r as formatOdbFormLines, s as formatMetadataValue, t as describeOdbForm, u as readInput } from "./odb-structure-DKJ3vi6l.js";
1
+ import { h as inferFormatFromExtension, i as formatOdbReportLines, l as formatDocxExtrasLines, m as formatToExtension, n as describeOdbReport, o as formatMetadataLines, p as loadProvidedFonts, r as formatOdbFormLines, s as formatMetadataValue, t as describeOdbForm, u as readInput } from "./odb-structure-CItnH50p.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, convertDocument, createDocx, createMarkdownEditor, createOdg, createOdp, createOds, createOdt, createPdf, createPptx, csvToPdf, decodeMarkdownText, decodeOdbPackage, docToPdf, docxToPdf, encodeMarkdownText, hsqldbCellDisplayText, markdownToPdf, odbReportToDocx, odbReportToOdt, odbReportToPdf, odgToPdf, odpToPdf, odsToPdf, odtToPdf, openDocx, openMarkdown, openOdg, openOdp, openOds, openOdt, openPdf, openPptx, parseXml, pptToPdf, pptxToPdf, readDocxContent, readDocxExtras, readMarkdownContent, readOdbForms, readOdbReportContent, readOdbReports, readOdbTables, readOdgContent, readOdpContent, readOdsContent, readOdtContent, readPdf, readPptxContent, rgbHexToColor, rtfToPdf, svgToPdf, xlsToPdf, xlsxToPdf } from "documents.js";
4
+ import { bytesToBase64, cellReference, columnIndexToLetters, convertDocument, createDocx, createMarkdownEditor, createOdg, createOdp, createOds, createOdt, createPdf, createPptx, csvToPdf, decodeMarkdownText, decodeOdbPackage, docToPdf, docxToPdf, encodeMarkdownText, epubToPdf, hsqldbCellDisplayText, markdownToPdf, odbReportToDocx, odbReportToOdt, odbReportToPdf, odgToPdf, odpToPdf, odsToPdf, odtToPdf, openDocx, openMarkdown, openOdg, openOdp, openOds, openOdt, openPdf, openPptx, 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
6
  import { Box, Text, render, useApp, useInput, useWindowSize } from "ink";
7
7
  import { createContext, useContext, useEffect, useReducer, useState } from "react";
@@ -82,6 +82,11 @@ async function exportToPdf(openDocument, destinationPath, options) {
82
82
  await writeFile(destinationPath, pdfBytes);
83
83
  return;
84
84
  }
85
+ if (openDocument.format === "epub") {
86
+ const pdfBytes = epubToPdf(openDocument.bytes, pdfOptions);
87
+ await writeFile(destinationPath, pdfBytes);
88
+ return;
89
+ }
85
90
  const bytes = openDocument.editor.toBytes();
86
91
  const pdfBytes = convert(openDocument.format, bytes, pdfOptions);
87
92
  await writeFile(destinationPath, pdfBytes);
@@ -225,6 +230,12 @@ async function openDocumentAtPath(path, options = {}) {
225
230
  bytes,
226
231
  path
227
232
  };
233
+ case "epub": return {
234
+ format,
235
+ layout: readPdf(epubToPdf(bytes)),
236
+ bytes,
237
+ path
238
+ };
228
239
  case "odf": throw new Error("A standalone .odf formula document has no editor; convert it to PDF (odfToPdf) instead");
229
240
  }
230
241
  }
@@ -278,7 +289,7 @@ function createNewDocument(format) {
278
289
  }
279
290
  }
280
291
  async function saveDocumentTo(openDocument, path) {
281
- if (openDocument.format === "odb" || openDocument.format === "xlsx" || openDocument.format === "csv" || openDocument.format === "svg" || openDocument.format === "rtf" || openDocument.format === "wpd" || openDocument.format === "doc" || openDocument.format === "xls" || openDocument.format === "ppt") throw new Error(`A ${openDocument.format} document is opened read-only and cannot be written back`);
292
+ if (openDocument.format === "odb" || openDocument.format === "xlsx" || openDocument.format === "csv" || openDocument.format === "svg" || openDocument.format === "rtf" || openDocument.format === "wpd" || openDocument.format === "doc" || openDocument.format === "xls" || openDocument.format === "ppt" || openDocument.format === "epub") throw new Error(`A ${openDocument.format} document is opened read-only and cannot be written back`);
282
293
  if (openDocument.format === "markdown") {
283
294
  await writeFile(path, encodeMarkdownText(openDocument.editor.toMarkdownText()));
284
295
  return;
@@ -370,7 +381,8 @@ function rootScreenForFormat(format) {
370
381
  case "wpd":
371
382
  case "doc":
372
383
  case "xls":
373
- case "ppt": return { kind: "pdfPageList" };
384
+ case "ppt":
385
+ case "epub": return { kind: "pdfPageList" };
374
386
  }
375
387
  }
376
388
  function currentScreen(state) {
@@ -549,6 +561,12 @@ function documentWithPath(doc, path) {
549
561
  bytes: doc.bytes,
550
562
  path
551
563
  };
564
+ case "epub": return {
565
+ format: "epub",
566
+ layout: doc.layout,
567
+ bytes: doc.bytes,
568
+ path
569
+ };
552
570
  }
553
571
  }
554
572
  function reopenEditable(doc, bytes) {
@@ -867,7 +885,7 @@ function appReducer(state, action) {
867
885
  selection: {},
868
886
  errorDetail: void 0,
869
887
  stack: [rootScreenForFormat(action.doc.format)]
870
- }, "info", action.doc.format === "xlsx" || action.doc.format === "csv" || action.doc.format === "svg" || action.doc.format === "rtf" || action.doc.format === "wpd" || action.doc.format === "doc" || action.doc.format === "xls" || action.doc.format === "ppt" ? `Opened ${action.path} as a read-only PDF preview -- press ':' then 'export pdf' to save it as a real PDF` : `Opened ${action.path}`);
888
+ }, "info", action.doc.format === "xlsx" || action.doc.format === "csv" || action.doc.format === "svg" || action.doc.format === "rtf" || action.doc.format === "wpd" || action.doc.format === "doc" || action.doc.format === "xls" || action.doc.format === "ppt" || action.doc.format === "epub" ? `Opened ${action.path} as a read-only PDF preview -- press ':' then 'export pdf' to save it as a real PDF` : `Opened ${action.path}`);
871
889
  case "OPEN_FILE_ERROR": return withStatus({
872
890
  ...state,
873
891
  errorDetail: {
@@ -1479,7 +1497,7 @@ function appReducer(state, action) {
1479
1497
  case "UNDO": {
1480
1498
  const doc = state.openDocument;
1481
1499
  if (doc === void 0) return withStatus(state, "info", "There is nothing to undo");
1482
- if (doc.format === "odb" || doc.format === "xlsx" || doc.format === "csv" || doc.format === "svg" || doc.format === "rtf" || doc.format === "wpd" || doc.format === "doc" || doc.format === "xls" || doc.format === "ppt") return withStatus(state, "warning", `A ${doc.format} document is read-only, so it has no history to undo`);
1500
+ if (doc.format === "odb" || doc.format === "xlsx" || doc.format === "csv" || doc.format === "svg" || doc.format === "rtf" || doc.format === "wpd" || doc.format === "doc" || doc.format === "xls" || doc.format === "ppt" || doc.format === "epub") return withStatus(state, "warning", `A ${doc.format} document is read-only, so it has no history to undo`);
1483
1501
  const snapshot = state.undoStack.at(-1);
1484
1502
  if (snapshot === void 0) return withStatus(state, "info", "There is nothing to undo");
1485
1503
  const restored = doc.format === "markdown" ? {
@@ -9171,7 +9189,8 @@ function metadataFor(doc) {
9171
9189
  case "wpd":
9172
9190
  case "doc":
9173
9191
  case "xls":
9174
- case "ppt": return doc.layout.metadata;
9192
+ case "ppt":
9193
+ case "epub": return doc.layout.metadata;
9175
9194
  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.");
9176
9195
  }
9177
9196
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "document-cli",
3
- "version": "5.5.3",
3
+ "version": "5.6.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": {
@@ -94,7 +94,7 @@
94
94
  "commander": "^15.0.0",
95
95
  "document-outline.js": "^3.5.5",
96
96
  "document-schema.js": "^7.1.0",
97
- "documents.js": "^7.6.3",
97
+ "documents.js": "^7.7.1",
98
98
  "ink": "^7.1.1",
99
99
  "ink-text-input": "^6.0.0",
100
100
  "react": "^19.2.8"
@@ -111,7 +111,7 @@
111
111
  "eslint": "^10.8.0",
112
112
  "husky": "^9.1.7",
113
113
  "ink-testing-library": "^4.0.0",
114
- "odf.js": "^7.4.1",
114
+ "odf.js": "^7.5.0",
115
115
  "publint": "^0.3.22",
116
116
  "semantic-release": "^25.0.8",
117
117
  "tsdown": "^0.22.14",