document-cli 1.3.0 → 1.4.0

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
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { a as odbFormSummary, c as writeOutput, d as inferFormatFromExtension, f as isDocumentFormat, i as formatOdbReportLines, l as loadProvidedFonts, n as describeOdbReport, o as readInput, r as formatOdbFormLines, s as resolveDefaultOutputPath, t as describeOdbForm } from "./odb-structure-CX_0zL8_.js";
2
+ import { a as odbFormSummary, c as resolveDefaultOutputPath, f as inferFormatFromExtension, i as formatOdbReportLines, l as writeOutput, n as describeOdbReport, o as formatDocxExtrasLines, p as isDocumentFormat, r as formatOdbFormLines, s as readInput, t as describeOdbForm, u as loadProvidedFonts } from "./odb-structure-DkfNyHGR.js";
3
3
  import { Command, CommanderError, InvalidArgumentError } from "commander";
4
4
  import { writeFile } from "node:fs/promises";
5
- import { HsqldbSqlEvaluationError, HsqldbSqlParseError, HsqldbSqlUnsupportedError, OdbNoEmbeddedDataSourceError, OdbReportNotSpecifiedError, OdbTableNotFoundError, OdbTableNotSpecifiedError, OdbUnsupportedFormatError, OdmUnresolvedSectionError, PdfEncryptedError, PdfParseError, UnrecognizedDocumentSchemaError, buildDocxPackage, buildMarkdownText, buildOdgPackage, buildOdpPackage, buildOdsPackage, buildOdtPackage, buildPptxPackage, convertWordprocessingToLayout, createFontMeasurer, createFontRegistry, createLocalDocumentConverter, documentFromJson, documentPackageWithSchema, encodeMarkdownText, encodePackage, evaluateSelect, hsqldbCellDisplayText, odbToCsv, odbToXlsx, odmToPdf, parseSelect, readOdbForms, readOdbInventory, readOdbReportContent, readOdbReports, readOdbTables, readPdf, writePdf } from "documents.js";
5
+ import { HsqldbSqlEvaluationError, HsqldbSqlParseError, HsqldbSqlUnsupportedError, OdbNoEmbeddedDataSourceError, OdbReportNotSpecifiedError, OdbTableNotFoundError, OdbTableNotSpecifiedError, OdbUnsupportedFormatError, OdmUnresolvedSectionError, PdfEncryptedError, PdfParseError, UnrecognizedDocumentSchemaError, buildDocxPackage, buildMarkdownText, buildOdgPackage, buildOdpPackage, buildOdsPackage, buildOdtPackage, buildPptxPackage, convertWordprocessingToLayout, createFontMeasurer, createFontRegistry, createLocalDocumentConverter, decodePackage, documentFromJson, documentPackageWithSchema, encodeMarkdownText, encodePackage, evaluateSelect, extractSourceFonts, hsqldbCellDisplayText, layoutDocumentWithSchema, odbToCsv, odbToXlsx, odmToPdf, parseSelect, readDocxExtras, readOdbForms, readOdbInventory, readOdbReportContent, readOdbReports, readOdbTables, readPdf, writePdf } from "documents.js";
6
6
  import { basename, dirname, extname, join } from "node:path";
7
- import { decodePackage, encodePackage as encodePackage$1 } from "odf.js";
7
+ import { decodePackage as decodePackage$1, encodePackage as encodePackage$1 } from "odf.js";
8
8
  import { existsSync, readFileSync } from "node:fs";
9
9
  //#region src/runtime/abort.ts
10
10
  function combineSignals(a, b) {
@@ -280,8 +280,100 @@ function registerConversionCommands(program) {
280
280
  });
281
281
  }
282
282
  //#endregion
283
+ //#region src/commands/docx-extras.ts
284
+ async function runDocxExtras(input, options) {
285
+ const command = "docx-extras";
286
+ const { signal, getAbortReason } = createRuntimeSignal({});
287
+ try {
288
+ const inputBytes = await readInput(input, { signal });
289
+ const pkg = decodePackage(new Uint8Array(inputBytes));
290
+ const extras = readDocxExtras(pkg);
291
+ if (options.json) {
292
+ process.stdout.write(`${JSON.stringify(extras)}\n`);
293
+ return 0;
294
+ }
295
+ for (const line of formatDocxExtrasLines(extras)) process.stdout.write(`${line}\n`);
296
+ return 0;
297
+ } catch (error) {
298
+ process.stderr.write(`[${command}] ${formatError(error, false)}\n`);
299
+ return mapErrorToExit(error, getAbortReason());
300
+ }
301
+ }
302
+ function registerDocxExtrasCommand(program) {
303
+ program.command("docx-extras <input>").description("print a docx's own comments, footnotes, headers, footers, and numbering definitions -- data readDocxContent's ContentDocument cannot carry").option("--json", "emit the raw DocxExtras object as JSON instead of a human-readable report", false).action(async (input, options) => {
304
+ process.exitCode = await runDocxExtras(input, options);
305
+ });
306
+ }
307
+ //#endregion
308
+ //#region src/commands/fonts.ts
309
+ const FONT_SOURCE_FORMATS = {
310
+ docx: true,
311
+ pptx: true,
312
+ odt: true,
313
+ odp: true,
314
+ ods: true,
315
+ odg: true
316
+ };
317
+ function isFontSourceFormat(format) {
318
+ return format in FONT_SOURCE_FORMATS;
319
+ }
320
+ function resolveFontSourcePackage(format, bytes) {
321
+ if (format === "docx" || format === "pptx") return {
322
+ kind: format,
323
+ package: decodePackage(bytes)
324
+ };
325
+ return {
326
+ kind: "odf",
327
+ package: decodePackage$1(bytes)
328
+ };
329
+ }
330
+ async function runFonts(input, options) {
331
+ const command = "fonts";
332
+ const { signal, getAbortReason } = createRuntimeSignal({});
333
+ try {
334
+ const format = inferFormatFromExtension(input);
335
+ if (format === void 0) {
336
+ process.stderr.write(`[${command}] cannot infer a document format from '${input}'; expected one of docx, pptx, odt, odp, ods, odg\n`);
337
+ return 2;
338
+ }
339
+ if (!isFontSourceFormat(format)) {
340
+ process.stderr.write(`[${command}] '${format}' documents carry no source-embedded font faces this command can extract; expected one of docx, pptx, odt, odp, ods, odg\n`);
341
+ return 2;
342
+ }
343
+ const inputBytes = await readInput(input, { signal });
344
+ const source = resolveFontSourcePackage(format, new Uint8Array(inputBytes));
345
+ const summaries = extractSourceFonts(source).map((face) => ({
346
+ family: face.family,
347
+ bold: face.bold,
348
+ italic: face.italic,
349
+ byteLength: face.bytes.length
350
+ }));
351
+ if (options.json) {
352
+ process.stdout.write(`${JSON.stringify(summaries)}\n`);
353
+ return 0;
354
+ }
355
+ if (summaries.length === 0) {
356
+ process.stdout.write("This document embeds no source fonts.\n");
357
+ return 0;
358
+ }
359
+ for (const face of summaries) {
360
+ const style = [face.bold ? "bold" : void 0, face.italic ? "italic" : void 0].filter((value) => value !== void 0).join(" ");
361
+ process.stdout.write(`${face.family}${style === "" ? "" : ` (${style})`} -- ${face.byteLength} bytes\n`);
362
+ }
363
+ return 0;
364
+ } catch (error) {
365
+ process.stderr.write(`${formatError(error, false)}\n`);
366
+ return mapErrorToExit(error, getAbortReason());
367
+ }
368
+ }
369
+ function registerFontsCommand(program) {
370
+ program.command("fonts <input>").description("list every source-embedded font face a docx/pptx/odt/odp/ods/odg document carries (family, weight/style, byte length)").option("--json", "emit the face list as a JSON array instead of a human-readable report", false).action(async (input, options) => {
371
+ process.exitCode = await runFonts(input, options);
372
+ });
373
+ }
374
+ //#endregion
283
375
  //#region src/commands/formats.ts
284
- const COMMANDS_NOT_LISTED = "odm-to-pdf, odb-to-csv, odb-to-xlsx, odb-tables, odb-forms, odb-reports, pdf-inspect, from-package";
376
+ const COMMANDS_NOT_LISTED = "odm-to-pdf, odb-to-csv, odb-to-xlsx, odb-tables, odb-forms, odb-reports, pdf-inspect, from-package, fonts, docx-extras";
285
377
  function registerFormatsCommand(program) {
286
378
  program.command("formats").description("list every source -> target conversion this CLI supports via a <source>-to-<target> command").option("--json", "emit the conversion list as a JSON array instead of a human-readable table", false).action((options) => {
287
379
  const { conversions } = createLocalDocumentConverter();
@@ -483,7 +575,7 @@ async function runOdbTables(input, options) {
483
575
  const { signal, getAbortReason } = createRuntimeSignal({});
484
576
  try {
485
577
  const inputBytes = await readInput(input, { signal });
486
- const pkg = decodePackage(new Uint8Array(inputBytes));
578
+ const pkg = decodePackage$1(new Uint8Array(inputBytes));
487
579
  const tables = readOdbTables(pkg);
488
580
  if (options.json) {
489
581
  const summary = tables.map((table) => ({
@@ -528,7 +620,7 @@ async function runOdbQuery(input, options) {
528
620
  const { signal, getAbortReason } = createRuntimeSignal({});
529
621
  try {
530
622
  const inputBytes = await readInput(input, { signal });
531
- const pkg = decodePackage(new Uint8Array(inputBytes));
623
+ const pkg = decodePackage$1(new Uint8Array(inputBytes));
532
624
  const resolved = resolveQuerySql(pkg, options);
533
625
  if ("errorMessage" in resolved) {
534
626
  process.stderr.write(`[${command}] ${resolved.errorMessage}\n`);
@@ -550,7 +642,7 @@ async function runOdbForms(input, options) {
550
642
  const { signal, getAbortReason } = createRuntimeSignal({});
551
643
  try {
552
644
  const inputBytes = await readInput(input, { signal });
553
- const forms = readOdbForms(decodePackage(new Uint8Array(inputBytes)));
645
+ const forms = readOdbForms(decodePackage$1(new Uint8Array(inputBytes)));
554
646
  if (options.json) {
555
647
  process.stdout.write(`${JSON.stringify(forms.map((form) => odbFormSummary(form)))}\n`);
556
648
  return 0;
@@ -573,7 +665,7 @@ async function runOdbReports(input, options) {
573
665
  const { signal, getAbortReason } = createRuntimeSignal({});
574
666
  try {
575
667
  const inputBytes = await readInput(input, { signal });
576
- const reports = readOdbReports(decodePackage(new Uint8Array(inputBytes)));
668
+ const reports = readOdbReports(decodePackage$1(new Uint8Array(inputBytes)));
577
669
  if (options.json) {
578
670
  process.stdout.write(`${JSON.stringify(reports)}\n`);
579
671
  return 0;
@@ -657,7 +749,7 @@ async function runOdbRenderReport(input, output, options) {
657
749
  try {
658
750
  const inputBytes = await readInput(input, { signal });
659
751
  const fonts = await loadProvidedFonts(options.fontFile ?? [], { signal });
660
- const pkg = decodePackage(new Uint8Array(inputBytes));
752
+ const pkg = decodePackage$1(new Uint8Array(inputBytes));
661
753
  const bytes = renderOdbReportBytes(readOdbReportContent(pkg, { report: options.report }), targetFormat, {
662
754
  fonts,
663
755
  signal,
@@ -868,7 +960,7 @@ async function runPdfInspect(input, options) {
868
960
  }
869
961
  });
870
962
  if (options.full) {
871
- process.stdout.write(`${JSON.stringify(layout, void 0, 2)}\n`);
963
+ process.stdout.write(`${JSON.stringify(layoutDocumentWithSchema(layout), void 0, 2)}\n`);
872
964
  return 0;
873
965
  }
874
966
  const imagesByFormat = countImagesByFormat(layout.images);
@@ -923,7 +1015,7 @@ function registerPdfInspectCommand(program) {
923
1015
  }
924
1016
  //#endregion
925
1017
  //#region package.json
926
- var version = "1.3.0";
1018
+ var version = "1.4.0";
927
1019
  //#endregion
928
1020
  //#region src/program.ts
929
1021
  function createProgram() {
@@ -940,13 +1032,15 @@ function createProgram() {
940
1032
  registerOdmCommand(program);
941
1033
  registerOdbCommands(program);
942
1034
  registerPdfInspectCommand(program);
1035
+ registerFontsCommand(program);
1036
+ registerDocxExtrasCommand(program);
943
1037
  return program;
944
1038
  }
945
1039
  //#endregion
946
1040
  //#region src/cli.ts
947
1041
  async function launchTui(startPath, signal) {
948
1042
  try {
949
- const { runTui } = await import("./tui-C8ITn1zQ.js");
1043
+ const { runTui } = await import("./tui-CQCLalYe.js");
950
1044
  await runTui({
951
1045
  startPath,
952
1046
  signal
package/dist/index.cjs CHANGED
@@ -533,8 +533,158 @@ function registerConversionCommands(program) {
533
533
  });
534
534
  }
535
535
  //#endregion
536
+ //#region src/docx-extras-format.ts
537
+ const INDENT$1 = " ";
538
+ function indent$1(depth) {
539
+ return INDENT$1.repeat(depth);
540
+ }
541
+ function commentLine(comment, position) {
542
+ const author = comment.author ?? "(no author)";
543
+ return `${indent$1(1)}[${position}] ${author}: ${comment.text}`;
544
+ }
545
+ function footnoteLine(footnote, position) {
546
+ const typeSuffix = footnote.type === void 0 ? "" : ` (${footnote.type})`;
547
+ return `${indent$1(1)}[${position}]${typeSuffix} ${footnote.text}`;
548
+ }
549
+ function commentsSection(comments) {
550
+ if (comments.length === 0) return [];
551
+ return ["comments", ...comments.map((comment, index) => commentLine(comment, index + 1))];
552
+ }
553
+ function footnotesSection(footnotes) {
554
+ if (footnotes.length === 0) return [];
555
+ return ["footnotes", ...footnotes.map((footnote, index) => footnoteLine(footnote, index + 1))];
556
+ }
557
+ function headerOrFooterSection(label, values) {
558
+ if (values.length === 0) return [];
559
+ return [label, ...values.map((text, index) => `${indent$1(1)}[${index + 1}] ${text}`)];
560
+ }
561
+ function numberingLevelLine(ilvl, level) {
562
+ const restartSuffix = level.restart === void 0 ? "" : `, restarts at level ${level.restart}`;
563
+ return `${indent$1(2)}level ${ilvl}: ${level.format} ${JSON.stringify(level.text)} starting at ${level.startAt}${restartSuffix}`;
564
+ }
565
+ function numberingSection(numbering) {
566
+ const numIds = Object.keys(numbering);
567
+ if (numIds.length === 0) return [];
568
+ const lines = ["numbering"];
569
+ for (const numId of numIds) {
570
+ const definition = numbering[numId];
571
+ if (definition === void 0) continue;
572
+ lines.push(`${indent$1(1)}numId ${numId}`);
573
+ const ilvls = Object.keys(definition.levels).sort((a, b) => Number(a) - Number(b));
574
+ for (const ilvl of ilvls) {
575
+ const level = definition.levels[ilvl];
576
+ if (level === void 0) continue;
577
+ lines.push(numberingLevelLine(ilvl, level));
578
+ }
579
+ }
580
+ return lines;
581
+ }
582
+ function formatDocxExtrasLines(extras) {
583
+ const nonEmptySections = [
584
+ commentsSection(extras.comments),
585
+ footnotesSection(extras.footnotes),
586
+ headerOrFooterSection("headers", extras.headers),
587
+ headerOrFooterSection("footers", extras.footers),
588
+ numberingSection(extras.numbering)
589
+ ].filter((section) => section.length > 0);
590
+ if (nonEmptySections.length === 0) return ["This document carries no comments, footnotes, headers, footers, or numbering definitions."];
591
+ return nonEmptySections.flatMap((section, index) => index === 0 ? section : ["", ...section]);
592
+ }
593
+ //#endregion
594
+ //#region src/commands/docx-extras.ts
595
+ async function runDocxExtras(input, options) {
596
+ const command = "docx-extras";
597
+ const { signal, getAbortReason } = createRuntimeSignal({});
598
+ try {
599
+ const inputBytes = await readInput(input, { signal });
600
+ const pkg = (0, documents_js.decodePackage)(new Uint8Array(inputBytes));
601
+ const extras = (0, documents_js.readDocxExtras)(pkg);
602
+ if (options.json) {
603
+ process.stdout.write(`${JSON.stringify(extras)}\n`);
604
+ return 0;
605
+ }
606
+ for (const line of formatDocxExtrasLines(extras)) process.stdout.write(`${line}\n`);
607
+ return 0;
608
+ } catch (error) {
609
+ process.stderr.write(`[${command}] ${formatError(error, false)}\n`);
610
+ return mapErrorToExit(error, getAbortReason());
611
+ }
612
+ }
613
+ function registerDocxExtrasCommand(program) {
614
+ program.command("docx-extras <input>").description("print a docx's own comments, footnotes, headers, footers, and numbering definitions -- data readDocxContent's ContentDocument cannot carry").option("--json", "emit the raw DocxExtras object as JSON instead of a human-readable report", false).action(async (input, options) => {
615
+ process.exitCode = await runDocxExtras(input, options);
616
+ });
617
+ }
618
+ //#endregion
619
+ //#region src/commands/fonts.ts
620
+ const FONT_SOURCE_FORMATS = {
621
+ docx: true,
622
+ pptx: true,
623
+ odt: true,
624
+ odp: true,
625
+ ods: true,
626
+ odg: true
627
+ };
628
+ function isFontSourceFormat(format) {
629
+ return format in FONT_SOURCE_FORMATS;
630
+ }
631
+ function resolveFontSourcePackage(format, bytes) {
632
+ if (format === "docx" || format === "pptx") return {
633
+ kind: format,
634
+ package: (0, documents_js.decodePackage)(bytes)
635
+ };
636
+ return {
637
+ kind: "odf",
638
+ package: (0, odf_js.decodePackage)(bytes)
639
+ };
640
+ }
641
+ async function runFonts(input, options) {
642
+ const command = "fonts";
643
+ const { signal, getAbortReason } = createRuntimeSignal({});
644
+ try {
645
+ const format = inferFormatFromExtension(input);
646
+ if (format === void 0) {
647
+ process.stderr.write(`[${command}] cannot infer a document format from '${input}'; expected one of docx, pptx, odt, odp, ods, odg\n`);
648
+ return 2;
649
+ }
650
+ if (!isFontSourceFormat(format)) {
651
+ process.stderr.write(`[${command}] '${format}' documents carry no source-embedded font faces this command can extract; expected one of docx, pptx, odt, odp, ods, odg\n`);
652
+ return 2;
653
+ }
654
+ const inputBytes = await readInput(input, { signal });
655
+ const source = resolveFontSourcePackage(format, new Uint8Array(inputBytes));
656
+ const summaries = (0, documents_js.extractSourceFonts)(source).map((face) => ({
657
+ family: face.family,
658
+ bold: face.bold,
659
+ italic: face.italic,
660
+ byteLength: face.bytes.length
661
+ }));
662
+ if (options.json) {
663
+ process.stdout.write(`${JSON.stringify(summaries)}\n`);
664
+ return 0;
665
+ }
666
+ if (summaries.length === 0) {
667
+ process.stdout.write("This document embeds no source fonts.\n");
668
+ return 0;
669
+ }
670
+ for (const face of summaries) {
671
+ const style = [face.bold ? "bold" : void 0, face.italic ? "italic" : void 0].filter((value) => value !== void 0).join(" ");
672
+ process.stdout.write(`${face.family}${style === "" ? "" : ` (${style})`} -- ${face.byteLength} bytes\n`);
673
+ }
674
+ return 0;
675
+ } catch (error) {
676
+ process.stderr.write(`${formatError(error, false)}\n`);
677
+ return mapErrorToExit(error, getAbortReason());
678
+ }
679
+ }
680
+ function registerFontsCommand(program) {
681
+ program.command("fonts <input>").description("list every source-embedded font face a docx/pptx/odt/odp/ods/odg document carries (family, weight/style, byte length)").option("--json", "emit the face list as a JSON array instead of a human-readable report", false).action(async (input, options) => {
682
+ process.exitCode = await runFonts(input, options);
683
+ });
684
+ }
685
+ //#endregion
536
686
  //#region src/commands/formats.ts
537
- const COMMANDS_NOT_LISTED = "odm-to-pdf, odb-to-csv, odb-to-xlsx, odb-tables, odb-forms, odb-reports, pdf-inspect, from-package";
687
+ const COMMANDS_NOT_LISTED = "odm-to-pdf, odb-to-csv, odb-to-xlsx, odb-tables, odb-forms, odb-reports, pdf-inspect, from-package, fonts, docx-extras";
538
688
  function registerFormatsCommand(program) {
539
689
  program.command("formats").description("list every source -> target conversion this CLI supports via a <source>-to-<target> command").option("--json", "emit the conversion list as a JSON array instead of a human-readable table", false).action((options) => {
540
690
  const { conversions } = (0, documents_js.createLocalDocumentConverter)();
@@ -1253,7 +1403,7 @@ async function runPdfInspect(input, options) {
1253
1403
  }
1254
1404
  });
1255
1405
  if (options.full) {
1256
- process.stdout.write(`${JSON.stringify(layout, void 0, 2)}\n`);
1406
+ process.stdout.write(`${JSON.stringify((0, documents_js.layoutDocumentWithSchema)(layout), void 0, 2)}\n`);
1257
1407
  return 0;
1258
1408
  }
1259
1409
  const imagesByFormat = countImagesByFormat(layout.images);
@@ -1308,7 +1458,7 @@ function registerPdfInspectCommand(program) {
1308
1458
  }
1309
1459
  //#endregion
1310
1460
  //#region package.json
1311
- var version = "1.3.0";
1461
+ var version = "1.4.0";
1312
1462
  //#endregion
1313
1463
  //#region src/program.ts
1314
1464
  function createProgram() {
@@ -1325,6 +1475,8 @@ function createProgram() {
1325
1475
  registerOdmCommand(program);
1326
1476
  registerOdbCommands(program);
1327
1477
  registerPdfInspectCommand(program);
1478
+ registerFontsCommand(program);
1479
+ registerDocxExtrasCommand(program);
1328
1480
  return program;
1329
1481
  }
1330
1482
  //#endregion
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { readFile, writeFile } from "node:fs/promises";
2
- import { HsqldbSqlEvaluationError, HsqldbSqlParseError, HsqldbSqlUnsupportedError, OdbNoEmbeddedDataSourceError, OdbReportNotSpecifiedError, OdbTableNotFoundError, OdbTableNotSpecifiedError, OdbUnsupportedFormatError, OdmUnresolvedSectionError, PdfEncryptedError, PdfParseError, UnrecognizedDocumentSchemaError, buildDocxPackage, buildMarkdownText, buildOdgPackage, buildOdpPackage, buildOdsPackage, buildOdtPackage, buildPptxPackage, convertWordprocessingToLayout, createFontMeasurer, createFontRegistry, createLocalDocumentConverter, documentFromJson, documentPackageWithSchema, encodeMarkdownText, encodePackage, evaluateSelect, hsqldbCellDisplayText, odbToCsv, odbToXlsx, odmToPdf, parseSelect, readOdbForms, readOdbInventory, readOdbReportContent, readOdbReports, readOdbTables, readPdf, writePdf } from "documents.js";
2
+ import { HsqldbSqlEvaluationError, HsqldbSqlParseError, HsqldbSqlUnsupportedError, OdbNoEmbeddedDataSourceError, OdbReportNotSpecifiedError, OdbTableNotFoundError, OdbTableNotSpecifiedError, OdbUnsupportedFormatError, OdmUnresolvedSectionError, PdfEncryptedError, PdfParseError, UnrecognizedDocumentSchemaError, buildDocxPackage, buildMarkdownText, buildOdgPackage, buildOdpPackage, buildOdsPackage, buildOdtPackage, buildPptxPackage, convertWordprocessingToLayout, createFontMeasurer, createFontRegistry, createLocalDocumentConverter, decodePackage, documentFromJson, documentPackageWithSchema, encodeMarkdownText, encodePackage, evaluateSelect, extractSourceFonts, hsqldbCellDisplayText, layoutDocumentWithSchema, odbToCsv, odbToXlsx, odmToPdf, parseSelect, readDocxExtras, readOdbForms, readOdbInventory, readOdbReportContent, readOdbReports, readOdbTables, readPdf, writePdf } from "documents.js";
3
3
  import { basename, dirname, extname, join } from "node:path";
4
4
  import { Command, InvalidArgumentError } from "commander";
5
- import { decodePackage, encodePackage as encodePackage$1 } from "odf.js";
5
+ import { decodePackage as decodePackage$1, encodePackage as encodePackage$1 } from "odf.js";
6
6
  import { existsSync, readFileSync } from "node:fs";
7
7
  //#region src/format.ts
8
8
  const EXTENSION_TO_FORMAT = {
@@ -532,8 +532,158 @@ function registerConversionCommands(program) {
532
532
  });
533
533
  }
534
534
  //#endregion
535
+ //#region src/docx-extras-format.ts
536
+ const INDENT$1 = " ";
537
+ function indent$1(depth) {
538
+ return INDENT$1.repeat(depth);
539
+ }
540
+ function commentLine(comment, position) {
541
+ const author = comment.author ?? "(no author)";
542
+ return `${indent$1(1)}[${position}] ${author}: ${comment.text}`;
543
+ }
544
+ function footnoteLine(footnote, position) {
545
+ const typeSuffix = footnote.type === void 0 ? "" : ` (${footnote.type})`;
546
+ return `${indent$1(1)}[${position}]${typeSuffix} ${footnote.text}`;
547
+ }
548
+ function commentsSection(comments) {
549
+ if (comments.length === 0) return [];
550
+ return ["comments", ...comments.map((comment, index) => commentLine(comment, index + 1))];
551
+ }
552
+ function footnotesSection(footnotes) {
553
+ if (footnotes.length === 0) return [];
554
+ return ["footnotes", ...footnotes.map((footnote, index) => footnoteLine(footnote, index + 1))];
555
+ }
556
+ function headerOrFooterSection(label, values) {
557
+ if (values.length === 0) return [];
558
+ return [label, ...values.map((text, index) => `${indent$1(1)}[${index + 1}] ${text}`)];
559
+ }
560
+ function numberingLevelLine(ilvl, level) {
561
+ const restartSuffix = level.restart === void 0 ? "" : `, restarts at level ${level.restart}`;
562
+ return `${indent$1(2)}level ${ilvl}: ${level.format} ${JSON.stringify(level.text)} starting at ${level.startAt}${restartSuffix}`;
563
+ }
564
+ function numberingSection(numbering) {
565
+ const numIds = Object.keys(numbering);
566
+ if (numIds.length === 0) return [];
567
+ const lines = ["numbering"];
568
+ for (const numId of numIds) {
569
+ const definition = numbering[numId];
570
+ if (definition === void 0) continue;
571
+ lines.push(`${indent$1(1)}numId ${numId}`);
572
+ const ilvls = Object.keys(definition.levels).sort((a, b) => Number(a) - Number(b));
573
+ for (const ilvl of ilvls) {
574
+ const level = definition.levels[ilvl];
575
+ if (level === void 0) continue;
576
+ lines.push(numberingLevelLine(ilvl, level));
577
+ }
578
+ }
579
+ return lines;
580
+ }
581
+ function formatDocxExtrasLines(extras) {
582
+ const nonEmptySections = [
583
+ commentsSection(extras.comments),
584
+ footnotesSection(extras.footnotes),
585
+ headerOrFooterSection("headers", extras.headers),
586
+ headerOrFooterSection("footers", extras.footers),
587
+ numberingSection(extras.numbering)
588
+ ].filter((section) => section.length > 0);
589
+ if (nonEmptySections.length === 0) return ["This document carries no comments, footnotes, headers, footers, or numbering definitions."];
590
+ return nonEmptySections.flatMap((section, index) => index === 0 ? section : ["", ...section]);
591
+ }
592
+ //#endregion
593
+ //#region src/commands/docx-extras.ts
594
+ async function runDocxExtras(input, options) {
595
+ const command = "docx-extras";
596
+ const { signal, getAbortReason } = createRuntimeSignal({});
597
+ try {
598
+ const inputBytes = await readInput(input, { signal });
599
+ const pkg = decodePackage(new Uint8Array(inputBytes));
600
+ const extras = readDocxExtras(pkg);
601
+ if (options.json) {
602
+ process.stdout.write(`${JSON.stringify(extras)}\n`);
603
+ return 0;
604
+ }
605
+ for (const line of formatDocxExtrasLines(extras)) process.stdout.write(`${line}\n`);
606
+ return 0;
607
+ } catch (error) {
608
+ process.stderr.write(`[${command}] ${formatError(error, false)}\n`);
609
+ return mapErrorToExit(error, getAbortReason());
610
+ }
611
+ }
612
+ function registerDocxExtrasCommand(program) {
613
+ program.command("docx-extras <input>").description("print a docx's own comments, footnotes, headers, footers, and numbering definitions -- data readDocxContent's ContentDocument cannot carry").option("--json", "emit the raw DocxExtras object as JSON instead of a human-readable report", false).action(async (input, options) => {
614
+ process.exitCode = await runDocxExtras(input, options);
615
+ });
616
+ }
617
+ //#endregion
618
+ //#region src/commands/fonts.ts
619
+ const FONT_SOURCE_FORMATS = {
620
+ docx: true,
621
+ pptx: true,
622
+ odt: true,
623
+ odp: true,
624
+ ods: true,
625
+ odg: true
626
+ };
627
+ function isFontSourceFormat(format) {
628
+ return format in FONT_SOURCE_FORMATS;
629
+ }
630
+ function resolveFontSourcePackage(format, bytes) {
631
+ if (format === "docx" || format === "pptx") return {
632
+ kind: format,
633
+ package: decodePackage(bytes)
634
+ };
635
+ return {
636
+ kind: "odf",
637
+ package: decodePackage$1(bytes)
638
+ };
639
+ }
640
+ async function runFonts(input, options) {
641
+ const command = "fonts";
642
+ const { signal, getAbortReason } = createRuntimeSignal({});
643
+ try {
644
+ const format = inferFormatFromExtension(input);
645
+ if (format === void 0) {
646
+ process.stderr.write(`[${command}] cannot infer a document format from '${input}'; expected one of docx, pptx, odt, odp, ods, odg\n`);
647
+ return 2;
648
+ }
649
+ if (!isFontSourceFormat(format)) {
650
+ process.stderr.write(`[${command}] '${format}' documents carry no source-embedded font faces this command can extract; expected one of docx, pptx, odt, odp, ods, odg\n`);
651
+ return 2;
652
+ }
653
+ const inputBytes = await readInput(input, { signal });
654
+ const source = resolveFontSourcePackage(format, new Uint8Array(inputBytes));
655
+ const summaries = extractSourceFonts(source).map((face) => ({
656
+ family: face.family,
657
+ bold: face.bold,
658
+ italic: face.italic,
659
+ byteLength: face.bytes.length
660
+ }));
661
+ if (options.json) {
662
+ process.stdout.write(`${JSON.stringify(summaries)}\n`);
663
+ return 0;
664
+ }
665
+ if (summaries.length === 0) {
666
+ process.stdout.write("This document embeds no source fonts.\n");
667
+ return 0;
668
+ }
669
+ for (const face of summaries) {
670
+ const style = [face.bold ? "bold" : void 0, face.italic ? "italic" : void 0].filter((value) => value !== void 0).join(" ");
671
+ process.stdout.write(`${face.family}${style === "" ? "" : ` (${style})`} -- ${face.byteLength} bytes\n`);
672
+ }
673
+ return 0;
674
+ } catch (error) {
675
+ process.stderr.write(`${formatError(error, false)}\n`);
676
+ return mapErrorToExit(error, getAbortReason());
677
+ }
678
+ }
679
+ function registerFontsCommand(program) {
680
+ program.command("fonts <input>").description("list every source-embedded font face a docx/pptx/odt/odp/ods/odg document carries (family, weight/style, byte length)").option("--json", "emit the face list as a JSON array instead of a human-readable report", false).action(async (input, options) => {
681
+ process.exitCode = await runFonts(input, options);
682
+ });
683
+ }
684
+ //#endregion
535
685
  //#region src/commands/formats.ts
536
- const COMMANDS_NOT_LISTED = "odm-to-pdf, odb-to-csv, odb-to-xlsx, odb-tables, odb-forms, odb-reports, pdf-inspect, from-package";
686
+ const COMMANDS_NOT_LISTED = "odm-to-pdf, odb-to-csv, odb-to-xlsx, odb-tables, odb-forms, odb-reports, pdf-inspect, from-package, fonts, docx-extras";
537
687
  function registerFormatsCommand(program) {
538
688
  program.command("formats").description("list every source -> target conversion this CLI supports via a <source>-to-<target> command").option("--json", "emit the conversion list as a JSON array instead of a human-readable table", false).action((options) => {
539
689
  const { conversions } = createLocalDocumentConverter();
@@ -867,7 +1017,7 @@ async function runOdbTables(input, options) {
867
1017
  const { signal, getAbortReason } = createRuntimeSignal({});
868
1018
  try {
869
1019
  const inputBytes = await readInput(input, { signal });
870
- const pkg = decodePackage(new Uint8Array(inputBytes));
1020
+ const pkg = decodePackage$1(new Uint8Array(inputBytes));
871
1021
  const tables = readOdbTables(pkg);
872
1022
  if (options.json) {
873
1023
  const summary = tables.map((table) => ({
@@ -912,7 +1062,7 @@ async function runOdbQuery(input, options) {
912
1062
  const { signal, getAbortReason } = createRuntimeSignal({});
913
1063
  try {
914
1064
  const inputBytes = await readInput(input, { signal });
915
- const pkg = decodePackage(new Uint8Array(inputBytes));
1065
+ const pkg = decodePackage$1(new Uint8Array(inputBytes));
916
1066
  const resolved = resolveQuerySql(pkg, options);
917
1067
  if ("errorMessage" in resolved) {
918
1068
  process.stderr.write(`[${command}] ${resolved.errorMessage}\n`);
@@ -934,7 +1084,7 @@ async function runOdbForms(input, options) {
934
1084
  const { signal, getAbortReason } = createRuntimeSignal({});
935
1085
  try {
936
1086
  const inputBytes = await readInput(input, { signal });
937
- const forms = readOdbForms(decodePackage(new Uint8Array(inputBytes)));
1087
+ const forms = readOdbForms(decodePackage$1(new Uint8Array(inputBytes)));
938
1088
  if (options.json) {
939
1089
  process.stdout.write(`${JSON.stringify(forms.map((form) => odbFormSummary(form)))}\n`);
940
1090
  return 0;
@@ -957,7 +1107,7 @@ async function runOdbReports(input, options) {
957
1107
  const { signal, getAbortReason } = createRuntimeSignal({});
958
1108
  try {
959
1109
  const inputBytes = await readInput(input, { signal });
960
- const reports = readOdbReports(decodePackage(new Uint8Array(inputBytes)));
1110
+ const reports = readOdbReports(decodePackage$1(new Uint8Array(inputBytes)));
961
1111
  if (options.json) {
962
1112
  process.stdout.write(`${JSON.stringify(reports)}\n`);
963
1113
  return 0;
@@ -1041,7 +1191,7 @@ async function runOdbRenderReport(input, output, options) {
1041
1191
  try {
1042
1192
  const inputBytes = await readInput(input, { signal });
1043
1193
  const fonts = await loadProvidedFonts(options.fontFile ?? [], { signal });
1044
- const pkg = decodePackage(new Uint8Array(inputBytes));
1194
+ const pkg = decodePackage$1(new Uint8Array(inputBytes));
1045
1195
  const bytes = renderOdbReportBytes(readOdbReportContent(pkg, { report: options.report }), targetFormat, {
1046
1196
  fonts,
1047
1197
  signal,
@@ -1252,7 +1402,7 @@ async function runPdfInspect(input, options) {
1252
1402
  }
1253
1403
  });
1254
1404
  if (options.full) {
1255
- process.stdout.write(`${JSON.stringify(layout, void 0, 2)}\n`);
1405
+ process.stdout.write(`${JSON.stringify(layoutDocumentWithSchema(layout), void 0, 2)}\n`);
1256
1406
  return 0;
1257
1407
  }
1258
1408
  const imagesByFormat = countImagesByFormat(layout.images);
@@ -1307,7 +1457,7 @@ function registerPdfInspectCommand(program) {
1307
1457
  }
1308
1458
  //#endregion
1309
1459
  //#region package.json
1310
- var version = "1.3.0";
1460
+ var version = "1.4.0";
1311
1461
  //#endregion
1312
1462
  //#region src/program.ts
1313
1463
  function createProgram() {
@@ -1324,6 +1474,8 @@ function createProgram() {
1324
1474
  registerOdmCommand(program);
1325
1475
  registerOdbCommands(program);
1326
1476
  registerPdfInspectCommand(program);
1477
+ registerFontsCommand(program);
1478
+ registerDocxExtrasCommand(program);
1327
1479
  return program;
1328
1480
  }
1329
1481
  //#endregion
@@ -247,6 +247,64 @@ function resolveDefaultOutputPath(inputPath, targetFormat) {
247
247
  return join(directory, `${stem}.${formatToExtension(targetFormat)}`);
248
248
  }
249
249
  //#endregion
250
+ //#region src/docx-extras-format.ts
251
+ const INDENT$1 = " ";
252
+ function indent$1(depth) {
253
+ return INDENT$1.repeat(depth);
254
+ }
255
+ function commentLine(comment, position) {
256
+ const author = comment.author ?? "(no author)";
257
+ return `${indent$1(1)}[${position}] ${author}: ${comment.text}`;
258
+ }
259
+ function footnoteLine(footnote, position) {
260
+ const typeSuffix = footnote.type === void 0 ? "" : ` (${footnote.type})`;
261
+ return `${indent$1(1)}[${position}]${typeSuffix} ${footnote.text}`;
262
+ }
263
+ function commentsSection(comments) {
264
+ if (comments.length === 0) return [];
265
+ return ["comments", ...comments.map((comment, index) => commentLine(comment, index + 1))];
266
+ }
267
+ function footnotesSection(footnotes) {
268
+ if (footnotes.length === 0) return [];
269
+ return ["footnotes", ...footnotes.map((footnote, index) => footnoteLine(footnote, index + 1))];
270
+ }
271
+ function headerOrFooterSection(label, values) {
272
+ if (values.length === 0) return [];
273
+ return [label, ...values.map((text, index) => `${indent$1(1)}[${index + 1}] ${text}`)];
274
+ }
275
+ function numberingLevelLine(ilvl, level) {
276
+ const restartSuffix = level.restart === void 0 ? "" : `, restarts at level ${level.restart}`;
277
+ return `${indent$1(2)}level ${ilvl}: ${level.format} ${JSON.stringify(level.text)} starting at ${level.startAt}${restartSuffix}`;
278
+ }
279
+ function numberingSection(numbering) {
280
+ const numIds = Object.keys(numbering);
281
+ if (numIds.length === 0) return [];
282
+ const lines = ["numbering"];
283
+ for (const numId of numIds) {
284
+ const definition = numbering[numId];
285
+ if (definition === void 0) continue;
286
+ lines.push(`${indent$1(1)}numId ${numId}`);
287
+ const ilvls = Object.keys(definition.levels).sort((a, b) => Number(a) - Number(b));
288
+ for (const ilvl of ilvls) {
289
+ const level = definition.levels[ilvl];
290
+ if (level === void 0) continue;
291
+ lines.push(numberingLevelLine(ilvl, level));
292
+ }
293
+ }
294
+ return lines;
295
+ }
296
+ function formatDocxExtrasLines(extras) {
297
+ const nonEmptySections = [
298
+ commentsSection(extras.comments),
299
+ footnotesSection(extras.footnotes),
300
+ headerOrFooterSection("headers", extras.headers),
301
+ headerOrFooterSection("footers", extras.footers),
302
+ numberingSection(extras.numbering)
303
+ ].filter((section) => section.length > 0);
304
+ if (nonEmptySections.length === 0) return ["This document carries no comments, footnotes, headers, footers, or numbering definitions."];
305
+ return nonEmptySections.flatMap((section, index) => index === 0 ? section : ["", ...section]);
306
+ }
307
+ //#endregion
250
308
  //#region src/odb-structure.ts
251
309
  const INDENT = " ";
252
310
  function indent(depth) {
@@ -379,4 +437,4 @@ function formatOdbReportLines(report) {
379
437
  return lines;
380
438
  }
381
439
  //#endregion
382
- export { odbFormSummary as a, writeOutput as c, inferFormatFromExtension as d, isDocumentFormat as f, formatOdbReportLines as i, loadProvidedFonts as l, describeOdbReport as n, readInput as o, formatOdbFormLines as r, resolveDefaultOutputPath as s, describeOdbForm as t, formatToExtension as u };
440
+ export { odbFormSummary as a, resolveDefaultOutputPath as c, formatToExtension as d, inferFormatFromExtension as f, formatOdbReportLines as i, writeOutput as l, describeOdbReport as n, formatDocxExtrasLines as o, isDocumentFormat as p, formatOdbFormLines as r, readInput as s, describeOdbForm as t, loadProvidedFonts as u };
@@ -1,8 +1,8 @@
1
- import { d as inferFormatFromExtension, i as formatOdbReportLines, l as loadProvidedFonts, n as describeOdbReport, o as readInput, r as formatOdbFormLines, t as describeOdbForm, u as formatToExtension } from "./odb-structure-CX_0zL8_.js";
1
+ import { d as formatToExtension, f as inferFormatFromExtension, i as formatOdbReportLines, n as describeOdbReport, o as formatDocxExtrasLines, r as formatOdbFormLines, s as readInput, t as describeOdbForm, u as loadProvidedFonts } from "./odb-structure-DkfNyHGR.js";
2
2
  import { readFile, writeFile } from "node:fs/promises";
3
- import { buildDocxPackage, buildOdtPackage, convertWordprocessingToLayout, createDocx, createFontMeasurer, createFontRegistry, createOdg, createOdp, createOds, createOdt, createPptx, decodeMarkdownText, docxToPdf, encodeMarkdownText, encodePackage, hsqldbCellDisplayText, markdownToPdf, odgToPdf, odpToPdf, odsToPdf, odtToPdf, openDocx, openOdg, openOdp, openOds, openOdt, openPptx, pptxToPdf, readOdbForms, readOdbReportContent, readOdbReports, readOdbTables, readOdgContent, readOdsContent, readPdf, rgbHexToColor, writePdf, xlsxToPdf } from "documents.js";
3
+ import { buildDocxPackage, buildOdtPackage, convertWordprocessingToLayout, createDocx, createFontMeasurer, createFontRegistry, createOdg, createOdp, createOds, createOdt, createPptx, decodeMarkdownText, docxToPdf, encodeMarkdownText, encodePackage, hsqldbCellDisplayText, markdownToPdf, odgToPdf, odpToPdf, odsToPdf, odtToPdf, openDocx, openOdg, openOdp, openOds, openOdt, openPptx, pptxToPdf, readDocxExtras, readOdbForms, readOdbReportContent, readOdbReports, readOdbTables, readOdgContent, readOdsContent, readPdf, rgbHexToColor, writePdf, xlsxToPdf } from "documents.js";
4
4
  import { basename, dirname, extname, join } from "node:path";
5
- import { cellReference, columnIndexToLetters, decodePackage, encodePackage as encodePackage$1 } from "odf.js";
5
+ import { cellReference, columnIndexToLetters, decodePackage as decodePackage$1, encodePackage as encodePackage$1 } from "odf.js";
6
6
  import { readdirSync } from "node:fs";
7
7
  import { Box, Text, render, useApp, useInput, useWindowSize } from "ink";
8
8
  import { createContext, useContext, useEffect, useReducer, useState } from "react";
@@ -78,7 +78,7 @@ const ODB_EXTENSION = ".odb";
78
78
  async function openDocumentAtPath(path) {
79
79
  const bytes = new Uint8Array(await readFile(path));
80
80
  if (path.toLowerCase().endsWith(ODB_EXTENSION)) {
81
- const pkg = decodePackage(bytes);
81
+ const pkg = decodePackage$1(bytes);
82
82
  return {
83
83
  format: "odb",
84
84
  tables: readOdbTables(pkg),
@@ -209,6 +209,7 @@ function selectionKeyFor(screen) {
209
209
  case "launcher":
210
210
  case "newDocumentPicker":
211
211
  case "bodyList":
212
+ case "docxExtras":
212
213
  case "slideList":
213
214
  case "sheetList":
214
215
  case "pageList":
@@ -2261,6 +2262,12 @@ function DocxBodyListScreen() {
2261
2262
  const state = useAppState();
2262
2263
  const dispatch = useAppDispatch();
2263
2264
  const doc = state.openDocument;
2265
+ useInput((input) => {
2266
+ if (input === "x" && doc?.format === "docx") dispatch({
2267
+ type: "PUSH_SCREEN",
2268
+ screen: { kind: "docxExtras" }
2269
+ });
2270
+ }, { isActive: doc?.format === "docx" && !anyOverlayOpen(state) });
2264
2271
  if (doc?.format !== "docx") return /* @__PURE__ */ jsxs(Text, {
2265
2272
  color: "red",
2266
2273
  children: [
@@ -2278,6 +2285,65 @@ function DocxBodyListScreen() {
2278
2285
  return /* @__PURE__ */ jsx(ParagraphFamilyBodyList, { adapter });
2279
2286
  }
2280
2287
  //#endregion
2288
+ //#region src/tui/screens/editors/docx/extras.tsx
2289
+ const DOCX_EXTRAS_RESERVED_ROWS = 5;
2290
+ function DocxExtrasScreen() {
2291
+ const state = useAppState();
2292
+ const dispatch = useAppDispatch();
2293
+ const doc = state.openDocument;
2294
+ const isDocx = doc?.format === "docx";
2295
+ const extras = doc?.format === "docx" ? readDocxExtras(doc.editor.toPackage()) : void 0;
2296
+ const allLines = extras === void 0 ? [] : formatDocxExtrasLines(extras);
2297
+ const query = state.searchQuery.trim().toLowerCase();
2298
+ const lines = query === "" ? allLines : allLines.filter((line) => line.toLowerCase().includes(query));
2299
+ const { selectedIndex } = useNavigationInput({
2300
+ itemCount: lines.length,
2301
+ onSelect: () => {},
2302
+ onBack: () => {
2303
+ dispatch({ type: "POP_SCREEN" });
2304
+ },
2305
+ isActive: isDocx && !anyOverlayOpen(state)
2306
+ });
2307
+ if (!isDocx) return /* @__PURE__ */ jsxs(Text, {
2308
+ color: "red",
2309
+ children: [
2310
+ "DocxExtrasScreen requires an open docx document, found ",
2311
+ doc === void 0 ? "no open document" : doc.format,
2312
+ "."
2313
+ ]
2314
+ });
2315
+ return /* @__PURE__ */ jsxs(Box, {
2316
+ flexDirection: "column",
2317
+ children: [
2318
+ /* @__PURE__ */ jsxs(Text, {
2319
+ bold: true,
2320
+ children: [
2321
+ "Comments, footnotes, headers, footers, numbering (",
2322
+ lines.length,
2323
+ " of ",
2324
+ allLines.length,
2325
+ " lines)"
2326
+ ]
2327
+ }),
2328
+ /* @__PURE__ */ jsx(ListView, {
2329
+ items: lines,
2330
+ selectedIndex,
2331
+ reservedRows: DOCX_EXTRAS_RESERVED_ROWS,
2332
+ emptyMessage: query === "" ? "This document carries no comments, footnotes, headers, footers, or numbering definitions." : `No lines match "${state.searchQuery}".`,
2333
+ renderItem: (line, isSelected) => /* @__PURE__ */ jsx(Text, {
2334
+ color: isSelected ? "cyan" : void 0,
2335
+ inverse: isSelected,
2336
+ children: line
2337
+ })
2338
+ }),
2339
+ /* @__PURE__ */ jsx(Text, {
2340
+ dimColor: true,
2341
+ children: "Esc to go back to the body list"
2342
+ })
2343
+ ]
2344
+ });
2345
+ }
2346
+ //#endregion
2281
2347
  //#region src/tui/screens/editors/markdown/shared.ts
2282
2348
  function requireMarkdownDocument(openDocument) {
2283
2349
  if (openDocument?.format !== "markdown") throw new Error("A markdown editing screen rendered without an open markdown document; the app router only reaches this screen group from markdownLineList, which is only ever the root screen of an open markdown document.");
@@ -2686,7 +2752,7 @@ async function renderOdbReportTo(doc, destinationPath, options) {
2686
2752
  const format = detectFormat(destinationPath);
2687
2753
  if (!isReportRenderTargetFormat(format)) throw new Error(`Cannot tell whether to render "${options.reportName}" as docx, odt, or pdf from '${destinationPath}' -- give the destination one of those three extensions`);
2688
2754
  const fonts = await loadProvidedFonts(options.fontFiles ?? [], { signal: options.signal });
2689
- const pkg = decodePackage(new Uint8Array(await readFile(doc.path)));
2755
+ const pkg = decodePackage$1(new Uint8Array(await readFile(doc.path)));
2690
2756
  const bytes = renderReportBytes(readOdbReportContent(pkg, { report: options.reportName }), format, fonts, options);
2691
2757
  await writeFile(destinationPath, bytes);
2692
2758
  }
@@ -6188,6 +6254,7 @@ function ScreenBody({ screen }) {
6188
6254
  case "filePicker": return /* @__PURE__ */ jsx(FilePickerScreen, {});
6189
6255
  case "newDocumentPicker": return /* @__PURE__ */ jsx(NewDocumentPickerScreen, {});
6190
6256
  case "bodyList": return format === "odt" ? /* @__PURE__ */ jsx(OdtBodyListScreen, {}) : /* @__PURE__ */ jsx(DocxBodyListScreen, {});
6257
+ case "docxExtras": return /* @__PURE__ */ jsx(DocxExtrasScreen, {});
6191
6258
  case "paragraphDetail": return /* @__PURE__ */ jsx(ParagraphDetailScreen, {});
6192
6259
  case "runEditor": return /* @__PURE__ */ jsx(RunEditorScreen, {});
6193
6260
  case "tableView": return /* @__PURE__ */ jsx(TableViewScreen, {});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "document-cli",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "CLI and interactive Ink TUI for documents.js: every docx/pptx/odt/odp/ods/odg/odf/pdf/odm/odb/xlsx/markdown conversion, bridge, and editor as a scriptable command or a terminal app.",
5
5
  "type": "module",
6
6
  "repository": {