mark-epub-down 0.1.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.
Files changed (80) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +151 -0
  3. package/dist/application/convert-epub-document.d.ts +10 -0
  4. package/dist/application/convert-epub-document.js +80 -0
  5. package/dist/application/convert-epub-document.js.map +1 -0
  6. package/dist/application/convert-epub.d.ts +13 -0
  7. package/dist/application/convert-epub.js +35 -0
  8. package/dist/application/convert-epub.js.map +1 -0
  9. package/dist/cli/confirm-overwrite.d.ts +1 -0
  10. package/dist/cli/confirm-overwrite.js +29 -0
  11. package/dist/cli/confirm-overwrite.js.map +1 -0
  12. package/dist/cli/reporting.d.ts +3 -0
  13. package/dist/cli/reporting.js +24 -0
  14. package/dist/cli/reporting.js.map +1 -0
  15. package/dist/cli/run-convert-command.d.ts +10 -0
  16. package/dist/cli/run-convert-command.js +61 -0
  17. package/dist/cli/run-convert-command.js.map +1 -0
  18. package/dist/cli.d.ts +2 -0
  19. package/dist/cli.js +28 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/domain/errors.d.ts +7 -0
  22. package/dist/domain/errors.js +20 -0
  23. package/dist/domain/errors.js.map +1 -0
  24. package/dist/domain/spec.d.ts +8 -0
  25. package/dist/domain/spec.js +49 -0
  26. package/dist/domain/spec.js.map +1 -0
  27. package/dist/domain/types.d.ts +48 -0
  28. package/dist/domain/types.js +3 -0
  29. package/dist/domain/types.js.map +1 -0
  30. package/dist/domain/warnings.d.ts +8 -0
  31. package/dist/domain/warnings.js +49 -0
  32. package/dist/domain/warnings.js.map +1 -0
  33. package/dist/epub/archive.d.ts +3 -0
  34. package/dist/epub/archive.js +22 -0
  35. package/dist/epub/archive.js.map +1 -0
  36. package/dist/epub/container.d.ts +2 -0
  37. package/dist/epub/container.js +46 -0
  38. package/dist/epub/container.js.map +1 -0
  39. package/dist/epub/content.d.ts +7 -0
  40. package/dist/epub/content.js +34 -0
  41. package/dist/epub/content.js.map +1 -0
  42. package/dist/epub/opf.d.ts +2 -0
  43. package/dist/epub/opf.js +122 -0
  44. package/dist/epub/opf.js.map +1 -0
  45. package/dist/epub/spine.d.ts +2 -0
  46. package/dist/epub/spine.js +25 -0
  47. package/dist/epub/spine.js.map +1 -0
  48. package/dist/epub/toc.d.ts +3 -0
  49. package/dist/epub/toc.js +165 -0
  50. package/dist/epub/toc.js.map +1 -0
  51. package/dist/index.d.ts +4 -0
  52. package/dist/index.js +8 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/output/render.d.ts +9 -0
  55. package/dist/output/render.js +54 -0
  56. package/dist/output/render.js.map +1 -0
  57. package/dist/transform/anchors.d.ts +2 -0
  58. package/dist/transform/anchors.js +18 -0
  59. package/dist/transform/anchors.js.map +1 -0
  60. package/dist/transform/cleanup.d.ts +4 -0
  61. package/dist/transform/cleanup.js +37 -0
  62. package/dist/transform/cleanup.js.map +1 -0
  63. package/dist/transform/links.d.ts +14 -0
  64. package/dist/transform/links.js +174 -0
  65. package/dist/transform/links.js.map +1 -0
  66. package/dist/transform/markdown.d.ts +2 -0
  67. package/dist/transform/markdown.js +102 -0
  68. package/dist/transform/markdown.js.map +1 -0
  69. package/dist/transform/tables.d.ts +5 -0
  70. package/dist/transform/tables.js +130 -0
  71. package/dist/transform/tables.js.map +1 -0
  72. package/dist/utils/epub-path.d.ts +14 -0
  73. package/dist/utils/epub-path.js +56 -0
  74. package/dist/utils/epub-path.js.map +1 -0
  75. package/dist/utils/path.d.ts +2 -0
  76. package/dist/utils/path.js +33 -0
  77. package/dist/utils/path.js.map +1 -0
  78. package/docs/epub-to-md-v1-public-spec.md +176 -0
  79. package/docs/v1-technical-selection.md +106 -0
  80. package/package.json +67 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Thomson
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # mark-epub-down
2
+
3
+ Convert a single EPUB into a single Markdown source document for LLM knowledge bases, wikis, and related ingestion pipelines.
4
+
5
+ ## Why
6
+
7
+ This project focuses on producing semantically useful Markdown from EPUB input. The v1 goal is not visual EPUB reproduction. It prioritizes source order, document structure, TOC preservation, and conservative transformation rules.
8
+
9
+ ## What v1 Does
10
+
11
+ - converts one EPUB into one Markdown file
12
+ - preserves spine order and source heading structure
13
+ - emits a dedicated `## TOC` section from EPUB-native TOC data
14
+ - includes minimal OPF-derived YAML front matter
15
+ - rewrites internal targets conservatively for merged single-file output
16
+
17
+ ## What v1 Does Not Do
18
+
19
+ - visually reproduce EPUB layout or CSS
20
+ - guess missing structure aggressively
21
+ - optimize first for reader-specific Markdown rendering
22
+ - split output by chapter in the v1 baseline
23
+
24
+ ## Requirements
25
+
26
+ - Node.js `20`, `22`, or `24`
27
+ - npm
28
+
29
+ ## Install
30
+
31
+ Install the CLI globally:
32
+
33
+ ```bash
34
+ npm install -g mark-epub-down
35
+ ```
36
+
37
+ Or add the package to a Node.js project:
38
+
39
+ ```bash
40
+ npm install mark-epub-down
41
+ ```
42
+
43
+ ## CLI Usage
44
+
45
+ Convert an EPUB:
46
+
47
+ ```bash
48
+ epub2llm input.epub
49
+ ```
50
+
51
+ Write to an explicit output path:
52
+
53
+ ```bash
54
+ epub2llm input.epub -o output.md
55
+ ```
56
+
57
+ Run without global install:
58
+
59
+ ```bash
60
+ npx --package mark-epub-down epub2llm input.epub
61
+ ```
62
+
63
+ Show CLI help:
64
+
65
+ ```bash
66
+ epub2llm --help
67
+ ```
68
+
69
+ Existing output files are never overwritten silently. In an interactive terminal session, the CLI may ask for explicit overwrite confirmation with a default `No` answer.
70
+
71
+ ## Node API
72
+
73
+ The published package currently exposes a CommonJS API:
74
+
75
+ ```js
76
+ const { convertEpub } = require("mark-epub-down");
77
+
78
+ (async () => {
79
+ const result = await convertEpub({
80
+ inputPath: "input.epub",
81
+ outputPath: "output.md",
82
+ });
83
+
84
+ console.log(result.outputPath);
85
+ console.log(result.warnings);
86
+ })();
87
+ ```
88
+
89
+ If the output path already exists, `convertEpub()` throws unless `overwrite: true` is passed:
90
+
91
+ ```js
92
+ (async () => {
93
+ await convertEpub({
94
+ inputPath: "input.epub",
95
+ outputPath: "output.md",
96
+ overwrite: true,
97
+ });
98
+ })();
99
+ ```
100
+
101
+ ## Output Shape
102
+
103
+ The generated Markdown follows this high-level structure:
104
+
105
+ ```markdown
106
+ ---
107
+ title: Example Book
108
+ creator: Example Author
109
+ language: en
110
+ published: 2026-04-09
111
+ ---
112
+
113
+ # Example Book
114
+
115
+ ## TOC
116
+
117
+ - [Chapter 1](#...)
118
+ - Chapter 2
119
+
120
+ ## Chapter 1
121
+
122
+ ...
123
+ ```
124
+
125
+ ## Docs
126
+
127
+ - Public v1 spec: [docs/epub-to-md-v1-public-spec.md](https://github.com/thomson1973/mark-epub-down/blob/main/docs/epub-to-md-v1-public-spec.md)
128
+ - Technical selection notes: [docs/v1-technical-selection.md](https://github.com/thomson1973/mark-epub-down/blob/main/docs/v1-technical-selection.md)
129
+
130
+ ## Limitations
131
+
132
+ - Fixed Layout EPUB (FXL) is out of scope for the v1 baseline
133
+ - some internal links or TOC targets may degrade to plain text when they cannot be rewritten safely
134
+ - complex tables may remain as HTML instead of being flattened into incorrect Markdown
135
+ - images and other high-confidence non-text media are removed by default in v1
136
+ - output files are never overwritten silently; interactive terminal use may ask for explicit confirmation
137
+
138
+ ## Roadmap
139
+
140
+ - expand real-world sample coverage for malformed or inconsistent EPUB inputs
141
+ - refine deeper footnote and note-topology edge cases beyond explicit source anchors
142
+ - refine richer table fallback boundaries for more complex publisher markup
143
+
144
+ ## Development
145
+
146
+ ```bash
147
+ npm install
148
+ npm run build
149
+ npm run typecheck
150
+ npm test
151
+ ```
@@ -0,0 +1,10 @@
1
+ import type { WarningRecord } from "../domain/types";
2
+ export interface ConvertEpubDocumentOptions {
3
+ inputPath: string;
4
+ }
5
+ export interface ConvertEpubDocumentResult {
6
+ inputPath: string;
7
+ markdown: string;
8
+ warnings: WarningRecord[];
9
+ }
10
+ export declare function convertEpubDocument(options: ConvertEpubDocumentOptions): Promise<ConvertEpubDocumentResult>;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertEpubDocument = convertEpubDocument;
4
+ const archive_1 = require("../epub/archive");
5
+ const content_1 = require("../epub/content");
6
+ const container_1 = require("../epub/container");
7
+ const opf_1 = require("../epub/opf");
8
+ const spine_1 = require("../epub/spine");
9
+ const toc_1 = require("../epub/toc");
10
+ const warnings_1 = require("../domain/warnings");
11
+ const render_1 = require("../output/render");
12
+ const cleanup_1 = require("../transform/cleanup");
13
+ const links_1 = require("../transform/links");
14
+ const markdown_1 = require("../transform/markdown");
15
+ const tables_1 = require("../transform/tables");
16
+ const errors_1 = require("../domain/errors");
17
+ async function convertEpubDocument(options) {
18
+ const warnings = new warnings_1.WarningCollector();
19
+ const workingDirectory = await (0, archive_1.createWorkingDirectory)();
20
+ try {
21
+ await (0, archive_1.extractArchive)(options.inputPath, workingDirectory);
22
+ const container = await (0, container_1.parseContainerDocument)(workingDirectory);
23
+ const packageDocument = await (0, opf_1.parsePackageDocument)(workingDirectory, container.opfPath);
24
+ const toc = await (0, toc_1.parseTocDocument)(workingDirectory, packageDocument, warnings);
25
+ const spineDocuments = (0, spine_1.buildSpineIndex)(packageDocument);
26
+ const loadedDocuments = await (0, content_1.loadSpineDocuments)(workingDirectory, spineDocuments);
27
+ for (const loadedDocument of loadedDocuments) {
28
+ const cleanup = (0, cleanup_1.cleanXhtmlDocument)(loadedDocument.dom.window.document);
29
+ if (cleanup.removedTags.length > 0) {
30
+ const uniqueTags = [...new Set(cleanup.removedTags)].join(", ");
31
+ warnings.add("ELEMENTS_DROPPED", `dropped non-text elements from ${loadedDocument.spineDocument.relativePath}: ${uniqueTags}`);
32
+ }
33
+ const tableResult = (0, tables_1.processTables)(loadedDocument.dom.window.document);
34
+ if (tableResult.complexTableCount > 0) {
35
+ const noun = tableResult.complexTableCount === 1 ? "table" : "tables";
36
+ warnings.add("COMPLEX_TABLE_PRESERVED", `preserved ${tableResult.complexTableCount} complex ${noun} as HTML because Markdown conversion would be lossy: ${loadedDocument.spineDocument.relativePath}`);
37
+ }
38
+ }
39
+ const anchorMap = (0, links_1.buildAnchorMap)(loadedDocuments.map((loadedDocument) => ({
40
+ idref: loadedDocument.spineDocument.idref,
41
+ relativePath: loadedDocument.spineDocument.relativePath,
42
+ document: loadedDocument.dom.window.document,
43
+ })), warnings);
44
+ for (const loadedDocument of loadedDocuments) {
45
+ (0, links_1.rewriteInternalLinks)(loadedDocument.dom.window.document, loadedDocument.spineDocument.relativePath, anchorMap, warnings);
46
+ (0, links_1.injectAnchorTargets)({
47
+ idref: loadedDocument.spineDocument.idref,
48
+ relativePath: loadedDocument.spineDocument.relativePath,
49
+ document: loadedDocument.dom.window.document,
50
+ }, anchorMap);
51
+ }
52
+ const rewrittenToc = (0, links_1.rewriteTocTargets)(toc.items, anchorMap, warnings);
53
+ const markdownConverter = (0, markdown_1.createMarkdownConverter)();
54
+ const body = loadedDocuments
55
+ .filter((loadedDocument) => loadedDocument.spineDocument.linear)
56
+ .map((loadedDocument) => {
57
+ const html = loadedDocument.dom.window.document.body?.innerHTML;
58
+ if (!html) {
59
+ throw errors_1.ConversionError.fatal("CONTENT_BODY_MISSING", `spine content document is missing a body element: ${loadedDocument.spineDocument.relativePath}`);
60
+ }
61
+ return markdownConverter.turndown(html).trim();
62
+ })
63
+ .filter((fragment) => fragment.length > 0)
64
+ .join("\n\n");
65
+ const markdown = (0, render_1.renderDocument)({
66
+ metadata: packageDocument.metadata,
67
+ toc: rewrittenToc,
68
+ body,
69
+ });
70
+ return {
71
+ inputPath: options.inputPath,
72
+ markdown,
73
+ warnings: warnings.list(),
74
+ };
75
+ }
76
+ finally {
77
+ await (0, archive_1.cleanupWorkingDirectory)(workingDirectory);
78
+ }
79
+ }
80
+ //# sourceMappingURL=convert-epub-document.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert-epub-document.js","sourceRoot":"","sources":["../../src/application/convert-epub-document.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { WarningRecord } from "../domain/types";
2
+ export interface ConvertEpubOptions {
3
+ inputPath: string;
4
+ outputPath?: string;
5
+ cwd?: string;
6
+ overwrite?: boolean;
7
+ }
8
+ export interface ConvertEpubResult {
9
+ inputPath: string;
10
+ outputPath: string;
11
+ warnings: WarningRecord[];
12
+ }
13
+ export declare function convertEpub(options: ConvertEpubOptions): Promise<ConvertEpubResult>;
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.convertEpub = convertEpub;
7
+ const promises_1 = require("node:fs/promises");
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const convert_epub_document_1 = require("./convert-epub-document");
10
+ const errors_1 = require("../domain/errors");
11
+ const path_1 = require("../utils/path");
12
+ async function convertEpub(options) {
13
+ const cwd = options.cwd ?? process.cwd();
14
+ const inputPath = node_path_1.default.resolve(cwd, options.inputPath);
15
+ const outputPath = (0, path_1.deriveOutputPath)(inputPath, options.outputPath, cwd);
16
+ await assertInputExists(inputPath);
17
+ await (0, path_1.ensureOutputPathAvailable)(outputPath, options.overwrite === true);
18
+ const result = await (0, convert_epub_document_1.convertEpubDocument)({ inputPath });
19
+ await (0, promises_1.mkdir)(node_path_1.default.dirname(outputPath), { recursive: true });
20
+ await (0, promises_1.writeFile)(outputPath, result.markdown, "utf8");
21
+ return {
22
+ inputPath: result.inputPath,
23
+ outputPath,
24
+ warnings: result.warnings,
25
+ };
26
+ }
27
+ async function assertInputExists(inputPath) {
28
+ try {
29
+ await (0, promises_1.access)(inputPath);
30
+ }
31
+ catch {
32
+ throw errors_1.ConversionError.fatal("INPUT_NOT_FOUND", `input EPUB does not exist: ${inputPath}`);
33
+ }
34
+ }
35
+ //# sourceMappingURL=convert-epub.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert-epub.js","sourceRoot":"","sources":["../../src/application/convert-epub.ts"],"names":[],"mappings":";;;;;AAqBA,kCAkBC;AAvCD,+CAA4D;AAC5D,0DAA6B;AAE7B,mEAA8D;AAC9D,6CAAmD;AAEnD,wCAA4E;AAerE,KAAK,UAAU,WAAW,CAAC,OAA2B;IAC3D,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,mBAAI,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,IAAA,uBAAgB,EAAC,SAAS,EAAE,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IAExE,MAAM,iBAAiB,CAAC,SAAS,CAAC,CAAC;IACnC,MAAM,IAAA,gCAAyB,EAAC,UAAU,EAAE,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,CAAC;IAExE,MAAM,MAAM,GAAG,MAAM,IAAA,2CAAmB,EAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IAExD,MAAM,IAAA,gBAAK,EAAC,mBAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,IAAA,oBAAS,EAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAErD,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,UAAU;QACV,QAAQ,EAAE,MAAM,CAAC,QAAQ;KAC1B,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,SAAiB;IAChD,IAAI,CAAC;QACH,MAAM,IAAA,iBAAM,EAAC,SAAS,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,wBAAe,CAAC,KAAK,CACzB,iBAAiB,EACjB,8BAA8B,SAAS,EAAE,CAC1C,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function confirmOverwrite(outputPath: string, stdin: NodeJS.ReadableStream, stderr: NodeJS.WritableStream): Promise<boolean>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.confirmOverwrite = confirmOverwrite;
4
+ async function confirmOverwrite(outputPath, stdin, stderr) {
5
+ stderr.write(`overwrite existing output file? ${outputPath} (y/N) `);
6
+ try {
7
+ const answer = await readSingleLine(stdin);
8
+ return answer !== null && isAffirmativeAnswer(answer);
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ function isAffirmativeAnswer(value) {
15
+ const normalized = value.trim().toLowerCase();
16
+ return normalized === "y" || normalized === "yes";
17
+ }
18
+ async function readSingleLine(stdin) {
19
+ let buffered = "";
20
+ for await (const chunk of stdin) {
21
+ buffered += chunk.toString();
22
+ const newlineIndex = buffered.indexOf("\n");
23
+ if (newlineIndex >= 0) {
24
+ return buffered.slice(0, newlineIndex).replace(/\r$/, "");
25
+ }
26
+ }
27
+ return buffered.length > 0 ? buffered.replace(/\r$/, "") : null;
28
+ }
29
+ //# sourceMappingURL=confirm-overwrite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm-overwrite.js","sourceRoot":"","sources":["../../src/cli/confirm-overwrite.ts"],"names":[],"mappings":";;AAAA,4CAaC;AAbM,KAAK,UAAU,gBAAgB,CACpC,UAAkB,EAClB,KAA4B,EAC5B,MAA6B;IAE7B,MAAM,CAAC,KAAK,CAAC,mCAAmC,UAAU,SAAS,CAAC,CAAC;IAErE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,KAAK,CAAC,CAAC;QAC3C,OAAO,MAAM,KAAK,IAAI,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,OAAO,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,KAAK,CAAC;AACpD,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,KAA4B;IACxD,IAAI,QAAQ,GAAG,EAAE,CAAC;IAElB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,KAAuC,EAAE,CAAC;QAClE,QAAQ,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QAE7B,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;YACtB,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ConvertEpubResult } from "../application/convert-epub";
2
+ export declare function reportConversionResult(stdout: NodeJS.WritableStream, stderr: NodeJS.WritableStream, result: ConvertEpubResult): void;
3
+ export declare function reportCliError(stderr: NodeJS.WritableStream, message: string): void;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.reportConversionResult = reportConversionResult;
4
+ exports.reportCliError = reportCliError;
5
+ const spec_1 = require("../domain/spec");
6
+ const warnings_1 = require("../domain/warnings");
7
+ function reportConversionResult(stdout, stderr, result) {
8
+ const cliWarnings = (0, warnings_1.summarizeWarnings)((0, warnings_1.getCliVisibleWarnings)(result.warnings));
9
+ emitWarnings(stderr, cliWarnings);
10
+ emitSuccess(stdout, result.outputPath, cliWarnings.length);
11
+ }
12
+ function reportCliError(stderr, message) {
13
+ stderr.write(`${spec_1.CLI_BINARY_NAME}: ${message}\n`);
14
+ }
15
+ function emitWarnings(stderr, warnings) {
16
+ for (const warning of warnings) {
17
+ stderr.write(`warning [${warning.code}]: ${warning.message}\n`);
18
+ }
19
+ }
20
+ function emitSuccess(stdout, outputPath, warningCount) {
21
+ const suffix = warningCount > 0 ? ` (${warningCount === 1 ? "1 warning" : `${warningCount} warnings`})` : "";
22
+ stdout.write(`wrote ${outputPath}${suffix}\n`);
23
+ }
24
+ //# sourceMappingURL=reporting.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporting.js","sourceRoot":"","sources":["../../src/cli/reporting.ts"],"names":[],"mappings":";;AAKA,wDAQC;AAED,wCAEC;AAhBD,yCAAiD;AAEjD,iDAA8E;AAE9E,SAAgB,sBAAsB,CACpC,MAA6B,EAC7B,MAA6B,EAC7B,MAAyB;IAEzB,MAAM,WAAW,GAAG,IAAA,4BAAiB,EAAC,IAAA,gCAAqB,EAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9E,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAClC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;AAC7D,CAAC;AAED,SAAgB,cAAc,CAAC,MAA6B,EAAE,OAAe;IAC3E,MAAM,CAAC,KAAK,CAAC,GAAG,sBAAe,KAAK,OAAO,IAAI,CAAC,CAAC;AACnD,CAAC;AAED,SAAS,YAAY,CAAC,MAA6B,EAAE,QAAyB;IAC5E,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,KAAK,CAAC,YAAY,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,OAAO,IAAI,CAAC,CAAC;IAClE,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,MAA6B,EAAE,UAAkB,EAAE,YAAoB;IAC1F,MAAM,MAAM,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,YAAY,WAAW,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7G,MAAM,CAAC,KAAK,CAAC,SAAS,UAAU,GAAG,MAAM,IAAI,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,10 @@
1
+ export interface RunConvertCommandContext {
2
+ cwd: string;
3
+ stdin: NodeJS.ReadableStream;
4
+ stdout: NodeJS.WritableStream;
5
+ stderr: NodeJS.WritableStream;
6
+ interactive: boolean;
7
+ }
8
+ export declare function runConvertCommand(input: string, options: {
9
+ output?: string;
10
+ }, context: RunConvertCommandContext): Promise<number>;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.runConvertCommand = runConvertCommand;
7
+ const node_path_1 = __importDefault(require("node:path"));
8
+ const convert_epub_1 = require("../application/convert-epub");
9
+ const errors_1 = require("../domain/errors");
10
+ const path_1 = require("../utils/path");
11
+ const confirm_overwrite_1 = require("./confirm-overwrite");
12
+ const reporting_1 = require("./reporting");
13
+ async function runConvertCommand(input, options, context) {
14
+ try {
15
+ const result = await (0, convert_epub_1.convertEpub)({
16
+ inputPath: input,
17
+ outputPath: options.output,
18
+ cwd: context.cwd,
19
+ });
20
+ (0, reporting_1.reportConversionResult)(context.stdout, context.stderr, result);
21
+ return 0;
22
+ }
23
+ catch (error) {
24
+ if (!(error instanceof errors_1.ConversionError)) {
25
+ const message = error instanceof Error ? error.message : String(error);
26
+ (0, reporting_1.reportCliError)(context.stderr, `unexpected error: ${message}`);
27
+ return 1;
28
+ }
29
+ if (error.code === "OUTPUT_EXISTS" && context.interactive) {
30
+ const inputPath = node_path_1.default.resolve(context.cwd, input);
31
+ const outputPath = (0, path_1.deriveOutputPath)(inputPath, options.output, context.cwd);
32
+ const confirmed = await (0, confirm_overwrite_1.confirmOverwrite)(outputPath, context.stdin, context.stderr);
33
+ if (confirmed) {
34
+ try {
35
+ const result = await (0, convert_epub_1.convertEpub)({
36
+ inputPath: input,
37
+ outputPath: options.output,
38
+ cwd: context.cwd,
39
+ overwrite: true,
40
+ });
41
+ (0, reporting_1.reportConversionResult)(context.stdout, context.stderr, result);
42
+ return 0;
43
+ }
44
+ catch (retryError) {
45
+ if (retryError instanceof errors_1.ConversionError) {
46
+ (0, reporting_1.reportCliError)(context.stderr, retryError.message);
47
+ return retryError.exitCode;
48
+ }
49
+ const message = retryError instanceof Error ? retryError.message : String(retryError);
50
+ (0, reporting_1.reportCliError)(context.stderr, `unexpected error: ${message}`);
51
+ return 1;
52
+ }
53
+ }
54
+ (0, reporting_1.reportCliError)(context.stderr, `output file already exists and overwrite was not confirmed: ${outputPath}`);
55
+ return 1;
56
+ }
57
+ (0, reporting_1.reportCliError)(context.stderr, error.message);
58
+ return error.exitCode;
59
+ }
60
+ }
61
+ //# sourceMappingURL=run-convert-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-convert-command.js","sourceRoot":"","sources":["../../src/cli/run-convert-command.ts"],"names":[],"mappings":";;;;;AAgBA,8CAwDC;AAxED,0DAA6B;AAE7B,8DAA0D;AAC1D,6CAAmD;AACnD,wCAAiD;AACjD,2DAAuD;AACvD,2CAAqE;AAU9D,KAAK,UAAU,iBAAiB,CACrC,KAAa,EACb,OAA4B,EAC5B,OAAiC;IAEjC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,IAAA,0BAAW,EAAC;YAC/B,SAAS,EAAE,KAAK;YAChB,UAAU,EAAE,OAAO,CAAC,MAAM;YAC1B,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QACH,IAAA,kCAAsB,EAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/D,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,CAAC,KAAK,YAAY,wBAAe,CAAC,EAAE,CAAC;YACxC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,IAAA,0BAAc,EAAC,OAAO,CAAC,MAAM,EAAE,qBAAqB,OAAO,EAAE,CAAC,CAAC;YAC/D,OAAO,CAAC,CAAC;QACX,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;YAC1D,MAAM,SAAS,GAAG,mBAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACnD,MAAM,UAAU,GAAG,IAAA,uBAAgB,EAAC,SAAS,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC;YAC5E,MAAM,SAAS,GAAG,MAAM,IAAA,oCAAgB,EAAC,UAAU,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;YACpF,IAAI,SAAS,EAAE,CAAC;gBACd,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,IAAA,0BAAW,EAAC;wBAC/B,SAAS,EAAE,KAAK;wBAChB,UAAU,EAAE,OAAO,CAAC,MAAM;wBAC1B,GAAG,EAAE,OAAO,CAAC,GAAG;wBAChB,SAAS,EAAE,IAAI;qBAChB,CAAC,CAAC;oBACH,IAAA,kCAAsB,EAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;oBAC/D,OAAO,CAAC,CAAC;gBACX,CAAC;gBAAC,OAAO,UAAU,EAAE,CAAC;oBACpB,IAAI,UAAU,YAAY,wBAAe,EAAE,CAAC;wBAC1C,IAAA,0BAAc,EAAC,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;wBACnD,OAAO,UAAU,CAAC,QAAQ,CAAC;oBAC7B,CAAC;oBAED,MAAM,OAAO,GAAG,UAAU,YAAY,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;oBACtF,IAAA,0BAAc,EAAC,OAAO,CAAC,MAAM,EAAE,qBAAqB,OAAO,EAAE,CAAC,CAAC;oBAC/D,OAAO,CAAC,CAAC;gBACX,CAAC;YACH,CAAC;YAED,IAAA,0BAAc,EACZ,OAAO,CAAC,MAAM,EACd,+DAA+D,UAAU,EAAE,CAC5E,CAAC;YACF,OAAO,CAAC,CAAC;QACX,CAAC;QAED,IAAA,0BAAc,EAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC,QAAQ,CAAC;IACxB,CAAC;AACH,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const spec_1 = require("./domain/spec");
6
+ const run_convert_command_1 = require("./cli/run-convert-command");
7
+ async function main() {
8
+ const program = new commander_1.Command();
9
+ program
10
+ .name(spec_1.CLI_BINARY_NAME)
11
+ .description("Convert a single EPUB into a single Markdown source document.")
12
+ .version("0.1.0", "-V, --version", "output the version number")
13
+ .argument("<input>", "input EPUB file")
14
+ .option("-o, --output <path>", "output Markdown path")
15
+ .showHelpAfterError("(add -h for usage)")
16
+ .action(async (input, options) => {
17
+ process.exitCode = await (0, run_convert_command_1.runConvertCommand)(input, options, {
18
+ cwd: process.cwd(),
19
+ stdin: process.stdin,
20
+ stdout: process.stdout,
21
+ stderr: process.stderr,
22
+ interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY),
23
+ });
24
+ });
25
+ await program.parseAsync(process.argv);
26
+ }
27
+ void main();
28
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AAEpC,wCAAgD;AAChD,mEAA8D;AAE9D,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,sBAAe,CAAC;SACrB,WAAW,CAAC,+DAA+D,CAAC;SAC5E,OAAO,CAAC,OAAO,EAAE,eAAe,EAAE,2BAA2B,CAAC;SAC9D,QAAQ,CAAC,SAAS,EAAE,iBAAiB,CAAC;SACtC,MAAM,CAAC,qBAAqB,EAAE,sBAAsB,CAAC;SACrD,kBAAkB,CAAC,oBAAoB,CAAC;SACxC,MAAM,CAAC,KAAK,EAAE,KAAa,EAAE,OAA4B,EAAE,EAAE;QAC5D,OAAO,CAAC,QAAQ,GAAG,MAAM,IAAA,uCAAiB,EAAC,KAAK,EAAE,OAAO,EAAE;YACzD,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;YAClB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;SAClE,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEL,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,KAAK,IAAI,EAAE,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare class ConversionError extends Error {
2
+ readonly code: string;
3
+ readonly fatal: boolean;
4
+ readonly exitCode: number;
5
+ constructor(code: string, message: string, fatal?: boolean, exitCode?: number);
6
+ static fatal(code: string, message: string): ConversionError;
7
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConversionError = void 0;
4
+ class ConversionError extends Error {
5
+ code;
6
+ fatal;
7
+ exitCode;
8
+ constructor(code, message, fatal = true, exitCode = 1) {
9
+ super(message);
10
+ this.name = "ConversionError";
11
+ this.code = code;
12
+ this.fatal = fatal;
13
+ this.exitCode = exitCode;
14
+ }
15
+ static fatal(code, message) {
16
+ return new ConversionError(code, message, true, 1);
17
+ }
18
+ }
19
+ exports.ConversionError = ConversionError;
20
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/domain/errors.ts"],"names":[],"mappings":";;;AAAA,MAAa,eAAgB,SAAQ,KAAK;IACxB,IAAI,CAAS;IACb,KAAK,CAAU;IACf,QAAQ,CAAS;IAEjC,YAAmB,IAAY,EAAE,OAAe,EAAE,KAAK,GAAG,IAAI,EAAE,QAAQ,GAAG,CAAC;QAC1E,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;QAC9B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,IAAY,EAAE,OAAe;QAC/C,OAAO,IAAI,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACrD,CAAC;CACF;AAhBD,0CAgBC"}
@@ -0,0 +1,8 @@
1
+ export declare const CLI_BINARY_NAME = "epub2llm";
2
+ export declare const GENERATED_TOC_HEADING = "TOC";
3
+ export declare const FRONT_MATTER_FIELDS: readonly ["title", "creator", "language", "identifier", "publisher", "published"];
4
+ export declare const REMOVABLE_TAGS: Set<string>;
5
+ export declare const NON_BLACKLISTED_STRUCTURAL_CONTAINERS: Set<string>;
6
+ export declare const NOTE_REFERENCE_TYPES: Set<string>;
7
+ export declare const NOTE_BODY_TYPES: Set<string>;
8
+ export declare const NOTE_BACKLINK_TYPES: Set<string>;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NOTE_BACKLINK_TYPES = exports.NOTE_BODY_TYPES = exports.NOTE_REFERENCE_TYPES = exports.NON_BLACKLISTED_STRUCTURAL_CONTAINERS = exports.REMOVABLE_TAGS = exports.FRONT_MATTER_FIELDS = exports.GENERATED_TOC_HEADING = exports.CLI_BINARY_NAME = void 0;
4
+ exports.CLI_BINARY_NAME = "epub2llm";
5
+ exports.GENERATED_TOC_HEADING = "TOC";
6
+ exports.FRONT_MATTER_FIELDS = [
7
+ "title",
8
+ "creator",
9
+ "language",
10
+ "identifier",
11
+ "publisher",
12
+ "published",
13
+ ];
14
+ exports.REMOVABLE_TAGS = new Set([
15
+ "script",
16
+ "style",
17
+ "img",
18
+ "svg",
19
+ "canvas",
20
+ "audio",
21
+ "video",
22
+ "source",
23
+ "track",
24
+ "iframe",
25
+ "object",
26
+ "embed",
27
+ "form",
28
+ "input",
29
+ "button",
30
+ "select",
31
+ "option",
32
+ "textarea",
33
+ "meta",
34
+ "link",
35
+ "noscript",
36
+ ]);
37
+ exports.NON_BLACKLISTED_STRUCTURAL_CONTAINERS = new Set([
38
+ "figure",
39
+ "figcaption",
40
+ "aside",
41
+ "section",
42
+ "nav",
43
+ "div",
44
+ "span",
45
+ ]);
46
+ exports.NOTE_REFERENCE_TYPES = new Set(["noteref"]);
47
+ exports.NOTE_BODY_TYPES = new Set(["footnote", "endnote", "rearnote"]);
48
+ exports.NOTE_BACKLINK_TYPES = new Set(["backlink"]);
49
+ //# sourceMappingURL=spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.js","sourceRoot":"","sources":["../../src/domain/spec.ts"],"names":[],"mappings":";;;AAAa,QAAA,eAAe,GAAG,UAAU,CAAC;AAC7B,QAAA,qBAAqB,GAAG,KAAK,CAAC;AAE9B,QAAA,mBAAmB,GAAG;IACjC,OAAO;IACP,SAAS;IACT,UAAU;IACV,YAAY;IACZ,WAAW;IACX,WAAW;CACH,CAAC;AAEE,QAAA,cAAc,GAAG,IAAI,GAAG,CAAC;IACpC,QAAQ;IACR,OAAO;IACP,KAAK;IACL,KAAK;IACL,QAAQ;IACR,OAAO;IACP,OAAO;IACP,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,MAAM;IACN,OAAO;IACP,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,UAAU;IACV,MAAM;IACN,MAAM;IACN,UAAU;CACX,CAAC,CAAC;AAEU,QAAA,qCAAqC,GAAG,IAAI,GAAG,CAAC;IAC3D,QAAQ;IACR,YAAY;IACZ,OAAO;IACP,SAAS;IACT,KAAK;IACL,KAAK;IACL,MAAM;CACP,CAAC,CAAC;AAEU,QAAA,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAC5C,QAAA,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;AAC/D,QAAA,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC"}