docrev 0.8.1 → 0.8.5
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/.claude/settings.local.json +9 -0
- package/PLAN-tables-and-postprocess.md +850 -0
- package/README.md +33 -0
- package/bin/rev.js +12 -131
- package/bin/rev.ts +145 -0
- package/dist/bin/rev.d.ts +9 -0
- package/dist/bin/rev.d.ts.map +1 -0
- package/dist/bin/rev.js +118 -0
- package/dist/bin/rev.js.map +1 -0
- package/dist/lib/annotations.d.ts +91 -0
- package/dist/lib/annotations.d.ts.map +1 -0
- package/dist/lib/annotations.js +554 -0
- package/dist/lib/annotations.js.map +1 -0
- package/dist/lib/build.d.ts +171 -0
- package/dist/lib/build.d.ts.map +1 -0
- package/dist/lib/build.js +755 -0
- package/dist/lib/build.js.map +1 -0
- package/dist/lib/citations.d.ts +34 -0
- package/dist/lib/citations.d.ts.map +1 -0
- package/dist/lib/citations.js +140 -0
- package/dist/lib/citations.js.map +1 -0
- package/dist/lib/commands/build.d.ts +13 -0
- package/dist/lib/commands/build.d.ts.map +1 -0
- package/dist/lib/commands/build.js +678 -0
- package/dist/lib/commands/build.js.map +1 -0
- package/dist/lib/commands/citations.d.ts +11 -0
- package/dist/lib/commands/citations.d.ts.map +1 -0
- package/dist/lib/commands/citations.js +428 -0
- package/dist/lib/commands/citations.js.map +1 -0
- package/dist/lib/commands/comments.d.ts +11 -0
- package/dist/lib/commands/comments.d.ts.map +1 -0
- package/dist/lib/commands/comments.js +883 -0
- package/dist/lib/commands/comments.js.map +1 -0
- package/dist/lib/commands/context.d.ts +35 -0
- package/dist/lib/commands/context.d.ts.map +1 -0
- package/dist/lib/commands/context.js +59 -0
- package/dist/lib/commands/context.js.map +1 -0
- package/dist/lib/commands/core.d.ts +11 -0
- package/dist/lib/commands/core.d.ts.map +1 -0
- package/dist/lib/commands/core.js +246 -0
- package/dist/lib/commands/core.js.map +1 -0
- package/dist/lib/commands/doi.d.ts +11 -0
- package/dist/lib/commands/doi.d.ts.map +1 -0
- package/dist/lib/commands/doi.js +373 -0
- package/dist/lib/commands/doi.js.map +1 -0
- package/dist/lib/commands/history.d.ts +11 -0
- package/dist/lib/commands/history.d.ts.map +1 -0
- package/dist/lib/commands/history.js +245 -0
- package/dist/lib/commands/history.js.map +1 -0
- package/dist/lib/commands/index.d.ts +28 -0
- package/dist/lib/commands/index.d.ts.map +1 -0
- package/dist/lib/commands/index.js +35 -0
- package/dist/lib/commands/index.js.map +1 -0
- package/dist/lib/commands/init.d.ts +11 -0
- package/dist/lib/commands/init.d.ts.map +1 -0
- package/dist/lib/commands/init.js +209 -0
- package/dist/lib/commands/init.js.map +1 -0
- package/dist/lib/commands/response.d.ts +11 -0
- package/dist/lib/commands/response.d.ts.map +1 -0
- package/dist/lib/commands/response.js +317 -0
- package/dist/lib/commands/response.js.map +1 -0
- package/dist/lib/commands/sections.d.ts +11 -0
- package/dist/lib/commands/sections.d.ts.map +1 -0
- package/dist/lib/commands/sections.js +1071 -0
- package/dist/lib/commands/sections.js.map +1 -0
- package/dist/lib/commands/utilities.d.ts +19 -0
- package/dist/lib/commands/utilities.d.ts.map +1 -0
- package/dist/lib/commands/utilities.js +2009 -0
- package/dist/lib/commands/utilities.js.map +1 -0
- package/dist/lib/comment-realign.d.ts +50 -0
- package/dist/lib/comment-realign.d.ts.map +1 -0
- package/dist/lib/comment-realign.js +372 -0
- package/dist/lib/comment-realign.js.map +1 -0
- package/dist/lib/config.d.ts +41 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +76 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/crossref.d.ts +108 -0
- package/dist/lib/crossref.d.ts.map +1 -0
- package/dist/lib/crossref.js +597 -0
- package/dist/lib/crossref.js.map +1 -0
- package/dist/lib/dependencies.d.ts +30 -0
- package/dist/lib/dependencies.d.ts.map +1 -0
- package/dist/lib/dependencies.js +95 -0
- package/dist/lib/dependencies.js.map +1 -0
- package/dist/lib/doi-cache.d.ts +29 -0
- package/dist/lib/doi-cache.d.ts.map +1 -0
- package/dist/lib/doi-cache.js +104 -0
- package/dist/lib/doi-cache.js.map +1 -0
- package/dist/lib/doi.d.ts +65 -0
- package/dist/lib/doi.d.ts.map +1 -0
- package/dist/lib/doi.js +710 -0
- package/dist/lib/doi.js.map +1 -0
- package/dist/lib/equations.d.ts +61 -0
- package/dist/lib/equations.d.ts.map +1 -0
- package/dist/lib/equations.js +445 -0
- package/dist/lib/equations.js.map +1 -0
- package/dist/lib/errors.d.ts +60 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +303 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/format.d.ts +104 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +416 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/git.d.ts +88 -0
- package/dist/lib/git.d.ts.map +1 -0
- package/dist/lib/git.js +304 -0
- package/dist/lib/git.js.map +1 -0
- package/dist/lib/grammar.d.ts +62 -0
- package/dist/lib/grammar.d.ts.map +1 -0
- package/dist/lib/grammar.js +244 -0
- package/dist/lib/grammar.js.map +1 -0
- package/dist/lib/image-registry.d.ts +68 -0
- package/dist/lib/image-registry.d.ts.map +1 -0
- package/dist/lib/image-registry.js +112 -0
- package/dist/lib/image-registry.js.map +1 -0
- package/dist/lib/import.d.ts +184 -0
- package/dist/lib/import.d.ts.map +1 -0
- package/dist/lib/import.js +1581 -0
- package/dist/lib/import.js.map +1 -0
- package/dist/lib/journals.d.ts +55 -0
- package/dist/lib/journals.d.ts.map +1 -0
- package/dist/lib/journals.js +417 -0
- package/dist/lib/journals.js.map +1 -0
- package/dist/lib/merge.d.ts +138 -0
- package/dist/lib/merge.d.ts.map +1 -0
- package/dist/lib/merge.js +603 -0
- package/dist/lib/merge.js.map +1 -0
- package/dist/lib/orcid.d.ts +36 -0
- package/dist/lib/orcid.d.ts.map +1 -0
- package/dist/lib/orcid.js +117 -0
- package/dist/lib/orcid.js.map +1 -0
- package/dist/lib/pdf-comments.d.ts +95 -0
- package/dist/lib/pdf-comments.d.ts.map +1 -0
- package/dist/lib/pdf-comments.js +192 -0
- package/dist/lib/pdf-comments.js.map +1 -0
- package/dist/lib/pdf-import.d.ts +118 -0
- package/dist/lib/pdf-import.d.ts.map +1 -0
- package/dist/lib/pdf-import.js +397 -0
- package/dist/lib/pdf-import.js.map +1 -0
- package/dist/lib/plugins.d.ts +76 -0
- package/dist/lib/plugins.d.ts.map +1 -0
- package/dist/lib/plugins.js +235 -0
- package/dist/lib/plugins.js.map +1 -0
- package/dist/lib/postprocess.d.ts +42 -0
- package/dist/lib/postprocess.d.ts.map +1 -0
- package/dist/lib/postprocess.js +138 -0
- package/dist/lib/postprocess.js.map +1 -0
- package/dist/lib/pptx-template.d.ts +59 -0
- package/dist/lib/pptx-template.d.ts.map +1 -0
- package/dist/lib/pptx-template.js +613 -0
- package/dist/lib/pptx-template.js.map +1 -0
- package/dist/lib/pptx-themes.d.ts +80 -0
- package/dist/lib/pptx-themes.d.ts.map +1 -0
- package/dist/lib/pptx-themes.js +818 -0
- package/dist/lib/pptx-themes.js.map +1 -0
- package/dist/lib/protect-restore.d.ts +137 -0
- package/dist/lib/protect-restore.d.ts.map +1 -0
- package/dist/lib/protect-restore.js +394 -0
- package/dist/lib/protect-restore.js.map +1 -0
- package/dist/lib/rate-limiter.d.ts +27 -0
- package/dist/lib/rate-limiter.d.ts.map +1 -0
- package/dist/lib/rate-limiter.js +79 -0
- package/dist/lib/rate-limiter.js.map +1 -0
- package/dist/lib/response.d.ts +41 -0
- package/dist/lib/response.d.ts.map +1 -0
- package/dist/lib/response.js +150 -0
- package/dist/lib/response.js.map +1 -0
- package/dist/lib/review.d.ts +35 -0
- package/dist/lib/review.d.ts.map +1 -0
- package/dist/lib/review.js +263 -0
- package/dist/lib/review.js.map +1 -0
- package/dist/lib/schema.d.ts +66 -0
- package/dist/lib/schema.d.ts.map +1 -0
- package/dist/lib/schema.js +339 -0
- package/dist/lib/schema.js.map +1 -0
- package/dist/lib/scientific-words.d.ts +6 -0
- package/dist/lib/scientific-words.d.ts.map +1 -0
- package/dist/lib/scientific-words.js +66 -0
- package/dist/lib/scientific-words.js.map +1 -0
- package/dist/lib/sections.d.ts +40 -0
- package/dist/lib/sections.d.ts.map +1 -0
- package/dist/lib/sections.js +288 -0
- package/dist/lib/sections.js.map +1 -0
- package/dist/lib/slides.d.ts +86 -0
- package/dist/lib/slides.d.ts.map +1 -0
- package/dist/lib/slides.js +676 -0
- package/dist/lib/slides.js.map +1 -0
- package/dist/lib/spelling.d.ts +76 -0
- package/dist/lib/spelling.d.ts.map +1 -0
- package/dist/lib/spelling.js +272 -0
- package/dist/lib/spelling.js.map +1 -0
- package/dist/lib/templates.d.ts +30 -0
- package/dist/lib/templates.d.ts.map +1 -0
- package/dist/lib/templates.js +504 -0
- package/dist/lib/templates.js.map +1 -0
- package/dist/lib/themes.d.ts +85 -0
- package/dist/lib/themes.d.ts.map +1 -0
- package/dist/lib/themes.js +652 -0
- package/dist/lib/themes.js.map +1 -0
- package/dist/lib/trackchanges.d.ts +51 -0
- package/dist/lib/trackchanges.d.ts.map +1 -0
- package/dist/lib/trackchanges.js +202 -0
- package/dist/lib/trackchanges.js.map +1 -0
- package/dist/lib/tui.d.ts +76 -0
- package/dist/lib/tui.d.ts.map +1 -0
- package/dist/lib/tui.js +377 -0
- package/dist/lib/tui.js.map +1 -0
- package/dist/lib/types.d.ts +447 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +6 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/undo.d.ts +57 -0
- package/dist/lib/undo.d.ts.map +1 -0
- package/dist/lib/undo.js +185 -0
- package/dist/lib/undo.js.map +1 -0
- package/dist/lib/utils.d.ts +16 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +40 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/lib/variables.d.ts +42 -0
- package/dist/lib/variables.d.ts.map +1 -0
- package/dist/lib/variables.js +141 -0
- package/dist/lib/variables.js.map +1 -0
- package/dist/lib/word.d.ts +80 -0
- package/dist/lib/word.d.ts.map +1 -0
- package/dist/lib/word.js +360 -0
- package/dist/lib/word.js.map +1 -0
- package/dist/lib/wordcomments.d.ts +51 -0
- package/dist/lib/wordcomments.d.ts.map +1 -0
- package/dist/lib/wordcomments.js +587 -0
- package/dist/lib/wordcomments.js.map +1 -0
- package/eslint.config.js +27 -0
- package/lib/annotations.ts +622 -0
- package/lib/apply-buildup-colors.py +88 -0
- package/lib/build.ts +1013 -0
- package/lib/{citations.js → citations.ts} +38 -27
- package/lib/commands/{build.js → build.ts} +80 -27
- package/lib/commands/{citations.js → citations.ts} +36 -18
- package/lib/commands/{comments.js → comments.ts} +187 -54
- package/lib/commands/{context.js → context.ts} +18 -8
- package/lib/commands/{core.js → core.ts} +34 -20
- package/lib/commands/{doi.js → doi.ts} +32 -16
- package/lib/commands/{history.js → history.ts} +25 -12
- package/lib/commands/{index.js → index.ts} +9 -5
- package/lib/commands/{init.js → init.ts} +20 -8
- package/lib/commands/{response.js → response.ts} +47 -20
- package/lib/commands/{sections.js → sections.ts} +273 -68
- package/lib/commands/{utilities.js → utilities.ts} +338 -158
- package/lib/{comment-realign.js → comment-realign.ts} +117 -45
- package/lib/config.ts +84 -0
- package/lib/{crossref.js → crossref.ts} +213 -138
- package/lib/dependencies.ts +106 -0
- package/lib/doi-cache.ts +115 -0
- package/lib/{doi.js → doi.ts} +115 -281
- package/lib/{equations.js → equations.ts} +60 -64
- package/lib/{errors.js → errors.ts} +56 -48
- package/lib/{format.js → format.ts} +137 -63
- package/lib/{git.js → git.ts} +66 -63
- package/lib/{grammar.js → grammar.ts} +45 -32
- package/lib/image-registry.ts +180 -0
- package/lib/import.ts +2060 -0
- package/lib/journals.ts +505 -0
- package/lib/{merge.js → merge.ts} +185 -135
- package/lib/{orcid.js → orcid.ts} +17 -22
- package/lib/{pdf-comments.js → pdf-comments.ts} +76 -18
- package/lib/{pdf-import.js → pdf-import.ts} +148 -70
- package/lib/{plugins.js → plugins.ts} +82 -39
- package/lib/postprocess.ts +188 -0
- package/lib/pptx-color-filter.lua +37 -0
- package/lib/pptx-template.ts +625 -0
- package/lib/pptx-themes/academic.pptx +0 -0
- package/lib/pptx-themes/corporate.pptx +0 -0
- package/lib/pptx-themes/dark.pptx +0 -0
- package/lib/pptx-themes/default.pptx +0 -0
- package/lib/pptx-themes/minimal.pptx +0 -0
- package/lib/pptx-themes/plant.pptx +0 -0
- package/lib/pptx-themes.ts +896 -0
- package/lib/protect-restore.ts +516 -0
- package/lib/rate-limiter.ts +94 -0
- package/lib/{response.js → response.ts} +36 -21
- package/lib/{review.js → review.ts} +53 -43
- package/lib/{schema.js → schema.ts} +70 -25
- package/lib/{sections.js → sections.ts} +71 -76
- package/lib/slides.ts +793 -0
- package/lib/{spelling.js → spelling.ts} +43 -59
- package/lib/{templates.js → templates.ts} +20 -17
- package/lib/themes.ts +742 -0
- package/lib/{trackchanges.js → trackchanges.ts} +52 -23
- package/lib/types.ts +509 -0
- package/lib/{undo.js → undo.ts} +75 -52
- package/lib/utils.ts +41 -0
- package/lib/{variables.js → variables.ts} +60 -54
- package/lib/word.ts +428 -0
- package/lib/{wordcomments.js → wordcomments.ts} +94 -40
- package/package.json +15 -5
- package/skill/REFERENCE.md +67 -0
- package/tsconfig.json +26 -0
- package/lib/annotations.js +0 -414
- package/lib/build.js +0 -639
- package/lib/config.js +0 -79
- package/lib/import.js +0 -1145
- package/lib/journals.js +0 -629
- package/lib/word.js +0 -225
- /package/lib/{scientific-words.js → scientific-words.ts} +0 -0
|
@@ -5,15 +5,17 @@
|
|
|
5
5
|
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
8
|
+
import type { Citation, CitationValidation, CitationStats } from './types.js';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Extract all citation keys from markdown text
|
|
11
12
|
* Handles: [@Key], [@Key1; @Key2], @Key (inline)
|
|
12
|
-
* @param
|
|
13
|
-
* @
|
|
13
|
+
* @param text - Markdown text to parse
|
|
14
|
+
* @param file - Optional filename for context
|
|
15
|
+
* @returns Array of citation objects
|
|
14
16
|
*/
|
|
15
|
-
export function extractCitations(text, file = '') {
|
|
16
|
-
const citations = [];
|
|
17
|
+
export function extractCitations(text: string, file: string = ''): Citation[] {
|
|
18
|
+
const citations: Citation[] = [];
|
|
17
19
|
const lines = text.split('\n');
|
|
18
20
|
|
|
19
21
|
// Pattern for bracketed citations: [@Key] or [@Key1; @Key2]
|
|
@@ -23,15 +25,18 @@ export function extractCitations(text, file = '') {
|
|
|
23
25
|
|
|
24
26
|
for (let lineNum = 0; lineNum < lines.length; lineNum++) {
|
|
25
27
|
const line = lines[lineNum];
|
|
28
|
+
if (!line) continue;
|
|
26
29
|
|
|
27
30
|
// Skip code blocks and comments
|
|
28
31
|
if (line.trim().startsWith('```') || line.trim().startsWith('<!--')) continue;
|
|
29
32
|
|
|
30
33
|
// Bracketed citations
|
|
31
|
-
let match;
|
|
34
|
+
let match: RegExpExecArray | null;
|
|
32
35
|
while ((match = bracketPattern.exec(line)) !== null) {
|
|
33
36
|
// Split by ; for multiple citations
|
|
34
|
-
const
|
|
37
|
+
const citationGroup = match[1];
|
|
38
|
+
if (!citationGroup) continue;
|
|
39
|
+
const keys = citationGroup.split(';').map(k => k.trim().replace(/^@/, ''));
|
|
35
40
|
for (const key of keys) {
|
|
36
41
|
if (key) {
|
|
37
42
|
citations.push({ key, line: lineNum + 1, file });
|
|
@@ -42,7 +47,10 @@ export function extractCitations(text, file = '') {
|
|
|
42
47
|
// Inline citations (reset lastIndex)
|
|
43
48
|
inlinePattern.lastIndex = 0;
|
|
44
49
|
while ((match = inlinePattern.exec(line)) !== null) {
|
|
45
|
-
|
|
50
|
+
const citationKey = match[1];
|
|
51
|
+
if (citationKey) {
|
|
52
|
+
citations.push({ key: citationKey, line: lineNum + 1, file });
|
|
53
|
+
}
|
|
46
54
|
}
|
|
47
55
|
}
|
|
48
56
|
|
|
@@ -51,11 +59,11 @@ export function extractCitations(text, file = '') {
|
|
|
51
59
|
|
|
52
60
|
/**
|
|
53
61
|
* Parse .bib file and extract all entry keys
|
|
54
|
-
* @param
|
|
55
|
-
* @returns
|
|
62
|
+
* @param bibPath - Path to bibliography file
|
|
63
|
+
* @returns Set of citation keys found in the bib file
|
|
56
64
|
*/
|
|
57
|
-
export function parseBibFile(bibPath) {
|
|
58
|
-
const keys = new Set();
|
|
65
|
+
export function parseBibFile(bibPath: string): Set<string> {
|
|
66
|
+
const keys = new Set<string>();
|
|
59
67
|
|
|
60
68
|
if (!fs.existsSync(bibPath)) {
|
|
61
69
|
return keys;
|
|
@@ -66,9 +74,12 @@ export function parseBibFile(bibPath) {
|
|
|
66
74
|
// Pattern for bib entries: @type{key,
|
|
67
75
|
const entryPattern = /@\w+\s*\{\s*([^,\s]+)\s*,/g;
|
|
68
76
|
|
|
69
|
-
let match;
|
|
77
|
+
let match: RegExpExecArray | null;
|
|
70
78
|
while ((match = entryPattern.exec(content)) !== null) {
|
|
71
|
-
|
|
79
|
+
const key = match[1];
|
|
80
|
+
if (key) {
|
|
81
|
+
keys.add(key);
|
|
82
|
+
}
|
|
72
83
|
}
|
|
73
84
|
|
|
74
85
|
return keys;
|
|
@@ -76,13 +87,13 @@ export function parseBibFile(bibPath) {
|
|
|
76
87
|
|
|
77
88
|
/**
|
|
78
89
|
* Validate citations against bib file
|
|
79
|
-
* @param
|
|
80
|
-
* @param
|
|
81
|
-
* @returns
|
|
90
|
+
* @param mdFiles - Markdown files to check
|
|
91
|
+
* @param bibPath - Path to .bib file
|
|
92
|
+
* @returns Validation result with valid, missing, unused, and duplicate citations
|
|
82
93
|
*/
|
|
83
|
-
export function validateCitations(mdFiles, bibPath) {
|
|
94
|
+
export function validateCitations(mdFiles: string[], bibPath: string): CitationValidation {
|
|
84
95
|
// Collect all citations from markdown
|
|
85
|
-
const allCitations = [];
|
|
96
|
+
const allCitations: Citation[] = [];
|
|
86
97
|
for (const file of mdFiles) {
|
|
87
98
|
if (!fs.existsSync(file)) continue;
|
|
88
99
|
const text = fs.readFileSync(file, 'utf-8');
|
|
@@ -94,10 +105,10 @@ export function validateCitations(mdFiles, bibPath) {
|
|
|
94
105
|
const bibKeys = parseBibFile(bibPath);
|
|
95
106
|
|
|
96
107
|
// Categorize
|
|
97
|
-
const valid = [];
|
|
98
|
-
const missing = [];
|
|
99
|
-
const citedKeys = new Set();
|
|
100
|
-
const keyOccurrences = new Map();
|
|
108
|
+
const valid: Citation[] = [];
|
|
109
|
+
const missing: Citation[] = [];
|
|
110
|
+
const citedKeys = new Set<string>();
|
|
111
|
+
const keyOccurrences = new Map<string, Citation[]>();
|
|
101
112
|
|
|
102
113
|
for (const citation of allCitations) {
|
|
103
114
|
citedKeys.add(citation.key);
|
|
@@ -106,7 +117,7 @@ export function validateCitations(mdFiles, bibPath) {
|
|
|
106
117
|
if (!keyOccurrences.has(citation.key)) {
|
|
107
118
|
keyOccurrences.set(citation.key, []);
|
|
108
119
|
}
|
|
109
|
-
keyOccurrences.get(citation.key)
|
|
120
|
+
keyOccurrences.get(citation.key)!.push(citation);
|
|
110
121
|
|
|
111
122
|
if (bibKeys.has(citation.key)) {
|
|
112
123
|
valid.push(citation);
|
|
@@ -128,11 +139,11 @@ export function validateCitations(mdFiles, bibPath) {
|
|
|
128
139
|
|
|
129
140
|
/**
|
|
130
141
|
* Get citation statistics
|
|
131
|
-
* @param
|
|
132
|
-
* @param
|
|
133
|
-
* @returns
|
|
142
|
+
* @param mdFiles - Markdown files to analyze
|
|
143
|
+
* @param bibPath - Path to bibliography file
|
|
144
|
+
* @returns Statistics object
|
|
134
145
|
*/
|
|
135
|
-
export function getCitationStats(mdFiles, bibPath) {
|
|
146
|
+
export function getCitationStats(mdFiles: string[], bibPath: string): CitationStats {
|
|
136
147
|
const result = validateCitations(mdFiles, bibPath);
|
|
137
148
|
const bibKeys = parseBibFile(bibPath);
|
|
138
149
|
|
|
@@ -23,13 +23,40 @@ import {
|
|
|
23
23
|
formatBuildResults,
|
|
24
24
|
getUserName,
|
|
25
25
|
} from './context.js';
|
|
26
|
+
import type { Command } from 'commander';
|
|
27
|
+
import * as readline from 'readline';
|
|
28
|
+
|
|
29
|
+
interface RefsOptions {
|
|
30
|
+
dir: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
interface MigrateOptions {
|
|
34
|
+
dir: string;
|
|
35
|
+
auto?: boolean;
|
|
36
|
+
dryRun?: boolean;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
interface InstallOptions {
|
|
40
|
+
check?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
interface BuildOptions {
|
|
44
|
+
dir: string;
|
|
45
|
+
crossref?: boolean;
|
|
46
|
+
toc?: boolean;
|
|
47
|
+
showChanges?: boolean;
|
|
48
|
+
dual?: boolean;
|
|
49
|
+
reference?: string;
|
|
50
|
+
theme?: string;
|
|
51
|
+
colortheme?: string;
|
|
52
|
+
aspectratio?: string;
|
|
53
|
+
verbose?: boolean;
|
|
54
|
+
}
|
|
26
55
|
|
|
27
56
|
/**
|
|
28
57
|
* Register build commands with the program
|
|
29
|
-
* @param {import('commander').Command} program
|
|
30
|
-
* @param {object} pkg - Package.json object for version info
|
|
31
58
|
*/
|
|
32
|
-
export function register(program, pkg) {
|
|
59
|
+
export function register(program: Command, pkg?: { version?: string }): void {
|
|
33
60
|
// ==========================================================================
|
|
34
61
|
// REFS command - Show figure/table reference status
|
|
35
62
|
// ==========================================================================
|
|
@@ -39,7 +66,7 @@ export function register(program, pkg) {
|
|
|
39
66
|
.description('Show figure/table reference registry and status')
|
|
40
67
|
.argument('[file]', 'Optional file to analyze for references')
|
|
41
68
|
.option('-d, --dir <directory>', 'Directory to scan for anchors', '.')
|
|
42
|
-
.action((file, options) => {
|
|
69
|
+
.action((file: string | undefined, options: RefsOptions) => {
|
|
43
70
|
const dir = path.resolve(options.dir);
|
|
44
71
|
|
|
45
72
|
if (!fs.existsSync(dir)) {
|
|
@@ -103,7 +130,7 @@ export function register(program, pkg) {
|
|
|
103
130
|
.option('-d, --dir <directory>', 'Directory for registry', '.')
|
|
104
131
|
.option('--auto', 'Auto-convert without prompting')
|
|
105
132
|
.option('--dry-run', 'Preview without saving')
|
|
106
|
-
.action(async (file, options) => {
|
|
133
|
+
.action(async (file: string, options: MigrateOptions) => {
|
|
107
134
|
if (!fs.existsSync(file)) {
|
|
108
135
|
console.error(chalk.red(`File not found: ${file}`));
|
|
109
136
|
process.exit(1);
|
|
@@ -141,8 +168,7 @@ export function register(program, pkg) {
|
|
|
141
168
|
console.log(chalk.green(`\nConverted ${conversions.length} reference(s) in ${file}`));
|
|
142
169
|
}
|
|
143
170
|
} else {
|
|
144
|
-
const rl =
|
|
145
|
-
const readline = rl.createInterface({
|
|
171
|
+
const rl = readline.createInterface({
|
|
146
172
|
input: process.stdin,
|
|
147
173
|
output: process.stdout,
|
|
148
174
|
});
|
|
@@ -151,8 +177,8 @@ export function register(program, pkg) {
|
|
|
151
177
|
let converted = 0;
|
|
152
178
|
let skipped = 0;
|
|
153
179
|
|
|
154
|
-
const askQuestion = (prompt) =>
|
|
155
|
-
new Promise((resolve) =>
|
|
180
|
+
const askQuestion = (prompt: string): Promise<string> =>
|
|
181
|
+
new Promise((resolve) => rl.question(prompt, resolve));
|
|
156
182
|
|
|
157
183
|
const sortedRefs = [...refs].sort((a, b) => b.position - a.position);
|
|
158
184
|
|
|
@@ -198,7 +224,7 @@ export function register(program, pkg) {
|
|
|
198
224
|
}
|
|
199
225
|
}
|
|
200
226
|
|
|
201
|
-
|
|
227
|
+
rl.close();
|
|
202
228
|
|
|
203
229
|
console.log(chalk.cyan(`\nConverted: ${converted}, Skipped: ${skipped}`));
|
|
204
230
|
|
|
@@ -219,7 +245,7 @@ export function register(program, pkg) {
|
|
|
219
245
|
.command('install')
|
|
220
246
|
.description('Check and install dependencies (pandoc-crossref)')
|
|
221
247
|
.option('--check', 'Only check, don\'t install')
|
|
222
|
-
.action(async (options) => {
|
|
248
|
+
.action(async (options: InstallOptions) => {
|
|
223
249
|
const os = await import('os');
|
|
224
250
|
const { execSync } = await import('child_process');
|
|
225
251
|
const platform = os.platform();
|
|
@@ -303,7 +329,7 @@ export function register(program, pkg) {
|
|
|
303
329
|
execSync('conda --version', { encoding: 'utf-8', stdio: 'pipe' });
|
|
304
330
|
console.log(chalk.cyan('Conda detected. Install missing dependencies? [y/N] '));
|
|
305
331
|
|
|
306
|
-
const rl =
|
|
332
|
+
const rl = readline.createInterface({
|
|
307
333
|
input: process.stdin,
|
|
308
334
|
output: process.stdout,
|
|
309
335
|
});
|
|
@@ -323,7 +349,8 @@ export function register(program, pkg) {
|
|
|
323
349
|
}
|
|
324
350
|
console.log(chalk.green('\nDone! Run "rev install --check" to verify.'));
|
|
325
351
|
} catch (err) {
|
|
326
|
-
|
|
352
|
+
const error = err as Error;
|
|
353
|
+
console.log(chalk.red(`\nInstallation failed: ${error.message}`));
|
|
327
354
|
console.log(chalk.dim('Try installing manually with the commands above.'));
|
|
328
355
|
}
|
|
329
356
|
}
|
|
@@ -421,7 +448,8 @@ export function register(program, pkg) {
|
|
|
421
448
|
}
|
|
422
449
|
}
|
|
423
450
|
} catch (e) {
|
|
424
|
-
|
|
451
|
+
const error = e as Error;
|
|
452
|
+
console.log(chalk.red(' ✗') + ` rev.yaml parse error: ${error.message}`);
|
|
425
453
|
issues++;
|
|
426
454
|
}
|
|
427
455
|
} else {
|
|
@@ -453,15 +481,19 @@ export function register(program, pkg) {
|
|
|
453
481
|
program
|
|
454
482
|
.command('build')
|
|
455
483
|
.alias('b')
|
|
456
|
-
.description('Build PDF/DOCX/TEX from sections')
|
|
457
|
-
.argument('[formats...]', 'Output formats: pdf, docx, tex, all', ['pdf', 'docx'])
|
|
484
|
+
.description('Build PDF/DOCX/TEX/PPTX/Beamer from sections')
|
|
485
|
+
.argument('[formats...]', 'Output formats: pdf, docx, tex, beamer, pptx, all', ['pdf', 'docx'])
|
|
458
486
|
.option('-d, --dir <directory>', 'Project directory', '.')
|
|
459
487
|
.option('--no-crossref', 'Skip pandoc-crossref filter')
|
|
460
488
|
.option('--toc', 'Include table of contents')
|
|
461
489
|
.option('--show-changes', 'Export DOCX with visible track changes (audit mode)')
|
|
462
490
|
.option('--dual', 'Output both clean version and annotated version (with comments)')
|
|
463
491
|
.option('--reference <docx>', 'Reference DOCX for comment position alignment (use with --dual)')
|
|
464
|
-
.
|
|
492
|
+
.option('--theme <name>', 'Beamer theme (default, metropolis, etc.)')
|
|
493
|
+
.option('--colortheme <name>', 'Beamer color theme')
|
|
494
|
+
.option('--aspectratio <ratio>', 'Beamer aspect ratio (169, 43)')
|
|
495
|
+
.option('--verbose', 'Show detailed output including postprocess scripts')
|
|
496
|
+
.action(async (formats: string[], options: BuildOptions) => {
|
|
465
497
|
const dir = path.resolve(options.dir);
|
|
466
498
|
|
|
467
499
|
if (!fs.existsSync(dir)) {
|
|
@@ -496,14 +528,31 @@ export function register(program, pkg) {
|
|
|
496
528
|
console.log('');
|
|
497
529
|
|
|
498
530
|
if (options.toc) {
|
|
531
|
+
config.pdf = config.pdf || {};
|
|
499
532
|
config.pdf.toc = true;
|
|
533
|
+
config.docx = config.docx || {};
|
|
500
534
|
config.docx.toc = true;
|
|
501
535
|
}
|
|
502
536
|
|
|
503
537
|
if (options.dual) {
|
|
538
|
+
config.docx = config.docx || {};
|
|
504
539
|
config.docx.keepComments = false;
|
|
505
540
|
}
|
|
506
541
|
|
|
542
|
+
// Apply beamer CLI options
|
|
543
|
+
if (options.theme) {
|
|
544
|
+
config.beamer = config.beamer || {};
|
|
545
|
+
config.beamer.theme = options.theme;
|
|
546
|
+
}
|
|
547
|
+
if (options.colortheme) {
|
|
548
|
+
config.beamer = config.beamer || {};
|
|
549
|
+
config.beamer.colortheme = options.colortheme;
|
|
550
|
+
}
|
|
551
|
+
if (options.aspectratio) {
|
|
552
|
+
config.beamer = config.beamer || {};
|
|
553
|
+
config.beamer.aspectratio = options.aspectratio;
|
|
554
|
+
}
|
|
555
|
+
|
|
507
556
|
if (options.showChanges) {
|
|
508
557
|
if (!targetFormats.includes('docx') && !targetFormats.includes('all')) {
|
|
509
558
|
console.error(fmt.status('error', '--show-changes only applies to DOCX output'));
|
|
@@ -545,8 +594,9 @@ export function register(program, pkg) {
|
|
|
545
594
|
}
|
|
546
595
|
} catch (err) {
|
|
547
596
|
spin.stop();
|
|
548
|
-
|
|
549
|
-
|
|
597
|
+
const error = err as Error;
|
|
598
|
+
console.error(fmt.status('error', error.message));
|
|
599
|
+
if (process.env.DEBUG) console.error(error.stack);
|
|
550
600
|
process.exit(1);
|
|
551
601
|
}
|
|
552
602
|
return;
|
|
@@ -558,6 +608,7 @@ export function register(program, pkg) {
|
|
|
558
608
|
const { results, paperPath, forwardRefsResolved, refsAutoInjected } = await build(dir, targetFormats, {
|
|
559
609
|
crossref: options.crossref,
|
|
560
610
|
config,
|
|
611
|
+
verbose: options.verbose,
|
|
561
612
|
});
|
|
562
613
|
|
|
563
614
|
spin.stop();
|
|
@@ -632,7 +683,7 @@ export function register(program, pkg) {
|
|
|
632
683
|
if (!pandocResult.success) {
|
|
633
684
|
console.error(chalk.yellow(`\nWarning: Could not build marked DOCX: ${pandocResult.error}`));
|
|
634
685
|
} else {
|
|
635
|
-
const commentsDocxPath = docxResult.outputPath
|
|
686
|
+
const commentsDocxPath = docxResult.outputPath!.replace(/\.docx$/, '_comments.docx');
|
|
636
687
|
const spinInject = fmt.spinner('Injecting comments at markers...').start();
|
|
637
688
|
const commentResult = await injectCommentsAtMarkers(markedDocxPath, comments, commentsDocxPath);
|
|
638
689
|
spinInject.stop();
|
|
@@ -646,7 +697,7 @@ export function register(program, pkg) {
|
|
|
646
697
|
|
|
647
698
|
if (commentResult.success) {
|
|
648
699
|
console.log(chalk.cyan('\nDual output:'));
|
|
649
|
-
console.log(` Clean: ${path.basename(docxResult.outputPath)}`);
|
|
700
|
+
console.log(` Clean: ${path.basename(docxResult.outputPath!)}`);
|
|
650
701
|
console.log(` Comments: ${path.basename(commentsDocxPath)} (${commentResult.commentCount} comments)`);
|
|
651
702
|
if (commentResult.skippedComments > 0) {
|
|
652
703
|
console.log(chalk.yellow(` Warning: ${commentResult.skippedComments} comments could not be anchored (markers not found)`));
|
|
@@ -684,7 +735,7 @@ export function register(program, pkg) {
|
|
|
684
735
|
annotatedConfig.pdf['header-includes'] = (annotatedConfig.pdf['header-includes'] || '') + preamble;
|
|
685
736
|
annotatedConfig.pdf.geometry = 'left=2.5cm,right=4.5cm,top=2.5cm,bottom=2.5cm,marginparwidth=3.5cm';
|
|
686
737
|
|
|
687
|
-
const annotatedPdfPath = pdfResult.outputPath
|
|
738
|
+
const annotatedPdfPath = pdfResult.outputPath!.replace(/\.pdf$/, '_comments.pdf');
|
|
688
739
|
spinPdf.text = 'Building annotated PDF...';
|
|
689
740
|
const pandocResult = await runPandoc(annotatedPath, 'pdf', annotatedConfig, { ...options, outputPath: annotatedPdfPath });
|
|
690
741
|
spinPdf.stop();
|
|
@@ -695,7 +746,7 @@ export function register(program, pkg) {
|
|
|
695
746
|
|
|
696
747
|
if (pandocResult.success) {
|
|
697
748
|
console.log(chalk.cyan('\nPDF dual output:'));
|
|
698
|
-
console.log(` Clean: ${path.basename(pdfResult.outputPath)}`);
|
|
749
|
+
console.log(` Clean: ${path.basename(pdfResult.outputPath!)}`);
|
|
699
750
|
console.log(` Comments: ${path.basename(annotatedPdfPath)} (${commentCount} margin notes)`);
|
|
700
751
|
} else {
|
|
701
752
|
console.error(chalk.yellow(`\nWarning: Could not create annotated PDF: ${pandocResult.error}`));
|
|
@@ -709,12 +760,13 @@ export function register(program, pkg) {
|
|
|
709
760
|
if (docxResult && !options.dual) {
|
|
710
761
|
try {
|
|
711
762
|
const { storeBaseDocument } = await import('../merge.js');
|
|
712
|
-
storeBaseDocument(dir, docxResult.outputPath);
|
|
763
|
+
storeBaseDocument(dir, docxResult.outputPath!);
|
|
713
764
|
console.log(chalk.dim(`\n Saved as .rev/base.docx for merge`));
|
|
714
765
|
} catch (err) {
|
|
715
766
|
// Non-fatal - just log if DEBUG
|
|
716
767
|
if (process.env.DEBUG) {
|
|
717
|
-
|
|
768
|
+
const error = err as Error;
|
|
769
|
+
console.log(chalk.dim(`\n Could not store base document: ${error.message}`));
|
|
718
770
|
}
|
|
719
771
|
}
|
|
720
772
|
}
|
|
@@ -722,8 +774,9 @@ export function register(program, pkg) {
|
|
|
722
774
|
console.log(chalk.green('\nBuild complete!'));
|
|
723
775
|
} catch (err) {
|
|
724
776
|
spin.stop();
|
|
725
|
-
|
|
726
|
-
|
|
777
|
+
const error = err as Error;
|
|
778
|
+
console.error(fmt.status('error', error.message));
|
|
779
|
+
if (process.env.DEBUG) console.error(error.stack);
|
|
727
780
|
process.exit(1);
|
|
728
781
|
}
|
|
729
782
|
});
|
|
@@ -10,12 +10,28 @@ import {
|
|
|
10
10
|
path,
|
|
11
11
|
fmt,
|
|
12
12
|
} from './context.js';
|
|
13
|
+
import type { Command } from 'commander';
|
|
14
|
+
|
|
15
|
+
interface CitationsOptions {
|
|
16
|
+
bib: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface EquationsOptions {
|
|
20
|
+
output?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface PdfCommentsOptions {
|
|
24
|
+
append?: string;
|
|
25
|
+
json?: boolean;
|
|
26
|
+
byPage?: boolean;
|
|
27
|
+
byAuthor?: boolean;
|
|
28
|
+
withText?: boolean;
|
|
29
|
+
}
|
|
13
30
|
|
|
14
31
|
/**
|
|
15
32
|
* Register citation commands with the program
|
|
16
|
-
* @param {import('commander').Command} program
|
|
17
33
|
*/
|
|
18
|
-
export function register(program) {
|
|
34
|
+
export function register(program: Command): void {
|
|
19
35
|
// ==========================================================================
|
|
20
36
|
// CITATIONS command - Validate citations against .bib file
|
|
21
37
|
// ==========================================================================
|
|
@@ -26,7 +42,7 @@ export function register(program) {
|
|
|
26
42
|
.description('Validate citations against bibliography')
|
|
27
43
|
.argument('[files...]', 'Markdown files to check (default: all section files)')
|
|
28
44
|
.option('-b, --bib <file>', 'Bibliography file', 'references.bib')
|
|
29
|
-
.action(async (files, options) => {
|
|
45
|
+
.action(async (files: string[], options: CitationsOptions) => {
|
|
30
46
|
const { getCitationStats } = await import('../citations.js');
|
|
31
47
|
|
|
32
48
|
// If no files specified, find all .md files
|
|
@@ -48,7 +64,7 @@ export function register(program) {
|
|
|
48
64
|
console.log();
|
|
49
65
|
|
|
50
66
|
// Summary table
|
|
51
|
-
const rows = [
|
|
67
|
+
const rows: string[][] = [
|
|
52
68
|
['Total citations', stats.totalCitations.toString()],
|
|
53
69
|
['Unique keys cited', stats.uniqueCited.toString()],
|
|
54
70
|
['Bib entries', stats.bibEntries.toString()],
|
|
@@ -97,7 +113,7 @@ export function register(program) {
|
|
|
97
113
|
.alias('figs')
|
|
98
114
|
.description('List all figures and tables with reference counts')
|
|
99
115
|
.argument('[files...]', 'Markdown files to scan')
|
|
100
|
-
.action(async (files) => {
|
|
116
|
+
.action(async (files: string[]) => {
|
|
101
117
|
const { buildRegistry } = await import('../crossref.js');
|
|
102
118
|
|
|
103
119
|
// If no files specified, find all .md files
|
|
@@ -112,7 +128,7 @@ export function register(program) {
|
|
|
112
128
|
const registry = buildRegistry('.');
|
|
113
129
|
|
|
114
130
|
// Count references in files
|
|
115
|
-
const refCounts = new Map();
|
|
131
|
+
const refCounts = new Map<string, number>();
|
|
116
132
|
for (const file of mdFiles) {
|
|
117
133
|
if (!fs.existsSync(file)) continue;
|
|
118
134
|
const text = fs.readFileSync(file, 'utf-8');
|
|
@@ -174,7 +190,7 @@ export function register(program) {
|
|
|
174
190
|
}
|
|
175
191
|
|
|
176
192
|
// Warn about unreferenced
|
|
177
|
-
const unreferenced = [];
|
|
193
|
+
const unreferenced: string[] = [];
|
|
178
194
|
for (const [label] of registry.figures) {
|
|
179
195
|
if (!refCounts.get(`fig:${label}`)) unreferenced.push(`@fig:${label}`);
|
|
180
196
|
}
|
|
@@ -198,7 +214,7 @@ export function register(program) {
|
|
|
198
214
|
.argument('<action>', 'Action: list, extract, convert, from-word')
|
|
199
215
|
.argument('[input]', 'Input file (.md for extract/convert, .docx for from-word)')
|
|
200
216
|
.option('-o, --output <file>', 'Output file')
|
|
201
|
-
.action(async (action, input, options) => {
|
|
217
|
+
.action(async (action: string, input: string | undefined, options: EquationsOptions) => {
|
|
202
218
|
const { extractEquations, getEquationStats, createEquationsDoc, extractEquationsFromWord, getWordEquationStats } = await import('../equations.js');
|
|
203
219
|
|
|
204
220
|
if (action === 'from-word') {
|
|
@@ -218,7 +234,7 @@ export function register(program) {
|
|
|
218
234
|
const result = await extractEquationsFromWord(input);
|
|
219
235
|
|
|
220
236
|
if (!result.success) {
|
|
221
|
-
spin.error(result.error);
|
|
237
|
+
spin.error(result.error!);
|
|
222
238
|
process.exit(1);
|
|
223
239
|
}
|
|
224
240
|
|
|
@@ -243,10 +259,10 @@ export function register(program) {
|
|
|
243
259
|
const typeLabel = eq.type === 'display' ? chalk.cyan('[display]') : chalk.yellow('[inline]');
|
|
244
260
|
|
|
245
261
|
if (eq.latex) {
|
|
246
|
-
console.log(`${chalk.bold(i + 1)}. ${typeLabel}`);
|
|
262
|
+
console.log(`${chalk.bold((i + 1).toString())}. ${typeLabel}`);
|
|
247
263
|
console.log(chalk.dim(' LaTeX:'), eq.latex.length > 80 ? eq.latex.substring(0, 77) + '...' : eq.latex);
|
|
248
264
|
} else {
|
|
249
|
-
console.log(`${chalk.bold(i + 1)}. ${typeLabel} ${chalk.red('[conversion failed]')}`);
|
|
265
|
+
console.log(`${chalk.bold((i + 1).toString())}. ${typeLabel} ${chalk.red('[conversion failed]')}`);
|
|
250
266
|
}
|
|
251
267
|
}
|
|
252
268
|
|
|
@@ -302,7 +318,7 @@ export function register(program) {
|
|
|
302
318
|
|
|
303
319
|
if (result.success) {
|
|
304
320
|
console.log(fmt.status('success', result.message));
|
|
305
|
-
console.log(chalk.dim(` ${result.stats
|
|
321
|
+
console.log(chalk.dim(` ${result.stats!.display} display, ${result.stats!.inline} inline equations`));
|
|
306
322
|
} else {
|
|
307
323
|
console.error(fmt.status('error', result.message));
|
|
308
324
|
process.exit(1);
|
|
@@ -326,7 +342,8 @@ export function register(program) {
|
|
|
326
342
|
await execAsync(`pandoc "${input}" -o "${output}" --mathml`);
|
|
327
343
|
spin.success(`Created ${output}`);
|
|
328
344
|
} catch (err) {
|
|
329
|
-
|
|
345
|
+
const error = err as Error;
|
|
346
|
+
spin.error(error.message);
|
|
330
347
|
process.exit(1);
|
|
331
348
|
}
|
|
332
349
|
} else {
|
|
@@ -350,7 +367,7 @@ export function register(program) {
|
|
|
350
367
|
.option('--by-page', 'Group comments by page')
|
|
351
368
|
.option('--by-author', 'Group comments by author')
|
|
352
369
|
.option('--with-text', 'Extract highlighted text (slower but shows what was highlighted)')
|
|
353
|
-
.action(async (pdf, options) => {
|
|
370
|
+
.action(async (pdf: string, options: PdfCommentsOptions) => {
|
|
354
371
|
if (!fs.existsSync(pdf)) {
|
|
355
372
|
console.error(fmt.status('error', `File not found: ${pdf}`));
|
|
356
373
|
process.exit(1);
|
|
@@ -373,7 +390,7 @@ export function register(program) {
|
|
|
373
390
|
const spin = fmt.spinner(`Extracting comments from ${path.basename(pdf)}...`).start();
|
|
374
391
|
|
|
375
392
|
try {
|
|
376
|
-
let comments;
|
|
393
|
+
let comments: any[];
|
|
377
394
|
|
|
378
395
|
if (options.withText) {
|
|
379
396
|
// Use the new text extraction feature
|
|
@@ -435,7 +452,7 @@ export function register(program) {
|
|
|
435
452
|
|
|
436
453
|
if (options.byAuthor) {
|
|
437
454
|
// Group by author
|
|
438
|
-
const byAuthor = {};
|
|
455
|
+
const byAuthor: Record<string, any[]> = {};
|
|
439
456
|
for (const c of comments) {
|
|
440
457
|
const author = c.author || 'Unknown';
|
|
441
458
|
if (!byAuthor[author]) byAuthor[author] = [];
|
|
@@ -489,8 +506,9 @@ export function register(program) {
|
|
|
489
506
|
|
|
490
507
|
} catch (err) {
|
|
491
508
|
spin.stop();
|
|
492
|
-
|
|
493
|
-
|
|
509
|
+
const error = err as Error;
|
|
510
|
+
console.error(fmt.status('error', `Failed to extract PDF comments: ${error.message}`));
|
|
511
|
+
if (process.env.DEBUG) console.error(error.stack);
|
|
494
512
|
process.exit(1);
|
|
495
513
|
}
|
|
496
514
|
});
|