docrev 0.10.1 → 0.10.2

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 (119) hide show
  1. package/.gitattributes +1 -1
  2. package/CHANGELOG.md +184 -173
  3. package/PLAN-tables-and-postprocess.md +850 -850
  4. package/README.md +431 -431
  5. package/bin/rev.js +11 -11
  6. package/bin/rev.ts +145 -145
  7. package/completions/rev.bash +127 -127
  8. package/completions/rev.ps1 +210 -210
  9. package/completions/rev.zsh +207 -207
  10. package/dist/lib/anchor-match.d.ts +1 -1
  11. package/dist/lib/anchor-match.d.ts.map +1 -1
  12. package/dist/lib/anchor-match.js +47 -17
  13. package/dist/lib/anchor-match.js.map +1 -1
  14. package/dist/lib/build.js +4 -4
  15. package/dist/lib/commands/sync.d.ts.map +1 -1
  16. package/dist/lib/commands/sync.js +78 -100
  17. package/dist/lib/commands/sync.js.map +1 -1
  18. package/dist/lib/commands/utilities.js +164 -164
  19. package/dist/lib/commands/word-tools.js +8 -8
  20. package/dist/lib/grammar.js +3 -3
  21. package/dist/lib/macro-filter.lua +201 -201
  22. package/dist/lib/pdf-comments.js +44 -44
  23. package/dist/lib/plugins.js +57 -57
  24. package/dist/lib/pptx-color-filter.lua +37 -37
  25. package/dist/lib/pptx-themes.js +115 -115
  26. package/dist/lib/sections.d.ts.map +1 -1
  27. package/dist/lib/sections.js +5 -2
  28. package/dist/lib/sections.js.map +1 -1
  29. package/dist/lib/spelling.js +2 -2
  30. package/dist/lib/templates.js +387 -387
  31. package/dist/lib/themes.js +51 -51
  32. package/eslint.config.js +27 -27
  33. package/issues.md +180 -0
  34. package/lib/anchor-match.ts +308 -276
  35. package/lib/annotations.ts +644 -644
  36. package/lib/build.ts +1766 -1766
  37. package/lib/citations.ts +160 -160
  38. package/lib/commands/build.ts +855 -855
  39. package/lib/commands/citations.ts +515 -515
  40. package/lib/commands/comments.ts +1050 -1050
  41. package/lib/commands/context.ts +176 -176
  42. package/lib/commands/core.ts +309 -309
  43. package/lib/commands/doi.ts +435 -435
  44. package/lib/commands/file-ops.ts +372 -372
  45. package/lib/commands/history.ts +320 -320
  46. package/lib/commands/index.ts +87 -87
  47. package/lib/commands/init.ts +259 -259
  48. package/lib/commands/merge-resolve.ts +378 -378
  49. package/lib/commands/preview.ts +178 -178
  50. package/lib/commands/project-info.ts +244 -244
  51. package/lib/commands/quality.ts +517 -517
  52. package/lib/commands/response.ts +454 -454
  53. package/lib/commands/section-boundaries.ts +82 -82
  54. package/lib/commands/sections.ts +451 -451
  55. package/lib/commands/sync.ts +676 -709
  56. package/lib/commands/text-ops.ts +449 -449
  57. package/lib/commands/utilities.ts +448 -448
  58. package/lib/commands/verify-anchors.ts +272 -272
  59. package/lib/commands/word-tools.ts +340 -340
  60. package/lib/comment-realign.ts +517 -517
  61. package/lib/config.ts +84 -84
  62. package/lib/crossref.ts +781 -781
  63. package/lib/csl.ts +191 -191
  64. package/lib/dependencies.ts +98 -98
  65. package/lib/diff-engine.ts +465 -465
  66. package/lib/doi-cache.ts +115 -115
  67. package/lib/doi.ts +897 -897
  68. package/lib/equations.ts +506 -506
  69. package/lib/errors.ts +346 -346
  70. package/lib/format.ts +541 -541
  71. package/lib/git.ts +326 -326
  72. package/lib/grammar.ts +303 -303
  73. package/lib/image-registry.ts +180 -180
  74. package/lib/import.ts +911 -911
  75. package/lib/journals.ts +543 -543
  76. package/lib/macro-filter.lua +201 -201
  77. package/lib/macros.ts +273 -273
  78. package/lib/merge.ts +633 -633
  79. package/lib/orcid.ts +144 -144
  80. package/lib/pdf-comments.ts +263 -263
  81. package/lib/pdf-import.ts +524 -524
  82. package/lib/plugins.ts +362 -362
  83. package/lib/postprocess.ts +188 -188
  84. package/lib/pptx-color-filter.lua +37 -37
  85. package/lib/pptx-template.ts +469 -469
  86. package/lib/pptx-themes.ts +483 -483
  87. package/lib/protect-restore.ts +520 -520
  88. package/lib/rate-limiter.ts +94 -94
  89. package/lib/response.ts +197 -197
  90. package/lib/restore-references.ts +240 -240
  91. package/lib/review.ts +327 -327
  92. package/lib/schema.ts +488 -488
  93. package/lib/scientific-words.ts +73 -73
  94. package/lib/sections.ts +428 -425
  95. package/lib/slides.ts +756 -756
  96. package/lib/spelling.ts +334 -334
  97. package/lib/templates.ts +526 -526
  98. package/lib/themes.ts +742 -742
  99. package/lib/trackchanges.ts +247 -247
  100. package/lib/tui.ts +450 -450
  101. package/lib/types.ts +550 -550
  102. package/lib/undo.ts +250 -250
  103. package/lib/utils.ts +69 -69
  104. package/lib/variables.ts +179 -179
  105. package/lib/word-extraction.ts +806 -806
  106. package/lib/word.ts +643 -643
  107. package/lib/wordcomments.ts +840 -840
  108. package/package.json +137 -137
  109. package/scripts/postbuild.js +47 -47
  110. package/site/assets/extra.css +208 -0
  111. package/site/commands.html +926 -0
  112. package/site/configuration.html +469 -0
  113. package/site/index.html +288 -0
  114. package/site/troubleshooting.html +461 -0
  115. package/site/workflow.html +518 -0
  116. package/skill/REFERENCE.md +539 -539
  117. package/skill/SKILL.md +295 -295
  118. package/tsconfig.json +26 -26
  119. package/types/index.d.ts +525 -525
@@ -1,263 +1,263 @@
1
- /**
2
- * PDF comment rendering for dual export
3
- *
4
- * Converts CriticMarkup comments to LaTeX margin notes for PDF output
5
- */
6
-
7
- import { escapeLatex } from './utils.js';
8
-
9
- /**
10
- * LaTeX preamble for margin comments
11
- * Uses todonotes package with custom styling
12
- */
13
- export const MARGIN_NOTES_PREAMBLE = `
14
- % Margin notes for comments
15
- \\usepackage[colorinlistoftodos,textsize=scriptsize]{todonotes}
16
- \\usepackage{xcolor}
17
-
18
- % Define comment colors by author
19
- \\definecolor{commentblue}{RGB}{59, 130, 246}
20
- \\definecolor{commentgreen}{RGB}{34, 197, 94}
21
- \\definecolor{commentorange}{RGB}{249, 115, 22}
22
- \\definecolor{commentpurple}{RGB}{168, 85, 247}
23
- \\definecolor{commentgray}{RGB}{107, 114, 128}
24
-
25
- % Custom margin note command
26
- \\newcommand{\\margincomment}[2][]{%
27
- \\todo[linecolor=commentblue,backgroundcolor=commentblue!10,bordercolor=commentblue,size=\\scriptsize,#1]{#2}%
28
- }
29
-
30
- % Author-specific commands
31
- \\newcommand{\\reviewercomment}[2]{%
32
- \\todo[linecolor=commentgreen,backgroundcolor=commentgreen!10,bordercolor=commentgreen,size=\\scriptsize]{\\textbf{#1:} #2}%
33
- }
34
-
35
- % Increase margin for notes (if needed)
36
- % \\setlength{\\marginparwidth}{2.5cm}
37
- `;
38
-
39
- /**
40
- * Simpler preamble using marginpar (no extra packages needed)
41
- */
42
- export const SIMPLE_MARGIN_PREAMBLE = `
43
- % Simple margin notes for comments
44
- \\usepackage{xcolor}
45
- \\definecolor{commentcolor}{RGB}{59, 130, 246}
46
-
47
- \\newcommand{\\margincomment}[1]{%
48
- \\marginpar{\\raggedright\\scriptsize\\textcolor{commentcolor}{#1}}%
49
- }
50
- `;
51
-
52
- /**
53
- * Options for converting comments to margin notes
54
- */
55
- export interface CommentConversionOptions {
56
- useTodonotes?: boolean;
57
- stripResolved?: boolean;
58
- }
59
-
60
- /**
61
- * Result of comment conversion
62
- */
63
- export interface CommentConversionResult {
64
- markdown: string;
65
- commentCount: number;
66
- preamble: string;
67
- }
68
-
69
- /**
70
- * Convert CriticMarkup comments to LaTeX margin notes
71
- * {>>Author: comment text<<} -> \margincomment{Author: comment text}
72
- *
73
- * @param markdown - Markdown with CriticMarkup comments
74
- * @param options - { useTodonotes: boolean, stripResolved: boolean }
75
- * @returns Converted markdown with comment count and preamble
76
- */
77
- export function convertCommentsToMarginNotes(
78
- markdown: string,
79
- options: CommentConversionOptions = {}
80
- ): CommentConversionResult {
81
- const { useTodonotes = true, stripResolved = true } = options;
82
-
83
- let commentCount = 0;
84
-
85
- // Pattern for CriticMarkup comments: {>>author: text<<} or {>>text<<}
86
- // Also handle resolved comments: {>>✓ author: text<<}
87
- const commentPattern = /\{>>(✓\s*)?([^<]+)<<\}/g;
88
-
89
- const converted = markdown.replace(commentPattern, (match, resolved, content) => {
90
- // Skip resolved comments if requested
91
- if (resolved && stripResolved) {
92
- return '';
93
- }
94
-
95
- commentCount++;
96
-
97
- // Escape LaTeX special characters
98
- const escaped = escapeLatex(content.trim());
99
-
100
- if (useTodonotes) {
101
- // Check if content has author prefix (Author: text)
102
- const authorMatch = escaped.match(/^([^:]+):\s*([\s\S]+)$/);
103
- if (authorMatch) {
104
- const [, author, text] = authorMatch;
105
- return `\\reviewercomment{${author}}{${text}}`;
106
- }
107
- return `\\margincomment{${escaped}}`;
108
- } else {
109
- return `\\margincomment{${escaped}}`;
110
- }
111
- });
112
-
113
- const preamble = useTodonotes ? MARGIN_NOTES_PREAMBLE : SIMPLE_MARGIN_PREAMBLE;
114
-
115
- return {
116
- markdown: converted,
117
- commentCount,
118
- preamble,
119
- };
120
- }
121
-
122
- /**
123
- * Result of track changes conversion
124
- */
125
- export interface TrackChangesResult {
126
- markdown: string;
127
- preamble: string;
128
- }
129
-
130
- /**
131
- * Convert track changes to visible LaTeX formatting
132
- * {++inserted++} -> \textcolor{green}{inserted}
133
- * {--deleted--} -> \textcolor{red}{\sout{deleted}}
134
- * {~~old~>new~~} -> \textcolor{red}{\sout{old}}\textcolor{green}{new}
135
- *
136
- * @param markdown - Markdown with track changes
137
- * @returns Converted markdown and preamble
138
- */
139
- export function convertTrackChangesToLatex(markdown: string): TrackChangesResult {
140
- let result = markdown;
141
-
142
- // Insertions: {++text++} -> green text
143
- result = result.replace(/\{\+\+([^+]+)\+\+\}/g, (match, text) => {
144
- return `\\textcolor{green}{${escapeLatex(text)}}`;
145
- });
146
-
147
- // Deletions: {--text--} -> red strikethrough
148
- result = result.replace(/\{--([^-]+)--\}/g, (match, text) => {
149
- return `\\textcolor{red}{\\sout{${escapeLatex(text)}}}`;
150
- });
151
-
152
- // Substitutions: {~~old~>new~~} -> red strikethrough + green new
153
- result = result.replace(/\{~~([^~]+)~>([^~]+)~~\}/g, (match, oldText, newText) => {
154
- return `\\textcolor{red}{\\sout{${escapeLatex(oldText)}}}\\textcolor{green}{${escapeLatex(newText)}}`;
155
- });
156
-
157
- const preamble = `
158
- % Track changes visualization
159
- \\usepackage{xcolor}
160
- \\usepackage[normalem]{ulem}
161
- \\definecolor{green}{RGB}{34, 197, 94}
162
- \\definecolor{red}{RGB}{239, 68, 68}
163
- `;
164
-
165
- return { markdown: result, preamble };
166
- }
167
-
168
- /**
169
- * Options for combined preamble
170
- */
171
- export interface PreambleOptions {
172
- comments?: boolean;
173
- trackChanges?: boolean;
174
- useTodonotes?: boolean;
175
- }
176
-
177
- /**
178
- * Get combined preamble for comments and track changes
179
- * @param options - { comments: boolean, trackChanges: boolean, useTodonotes: boolean }
180
- * @returns Combined LaTeX preamble
181
- */
182
- export function getCombinedPreamble(options: PreambleOptions = {}): string {
183
- const { comments = true, trackChanges = false, useTodonotes = true } = options;
184
-
185
- let preamble = '';
186
-
187
- if (comments) {
188
- preamble += useTodonotes ? MARGIN_NOTES_PREAMBLE : SIMPLE_MARGIN_PREAMBLE;
189
- }
190
-
191
- if (trackChanges) {
192
- preamble += `
193
- % Track changes visualization
194
- \\usepackage[normalem]{ulem}
195
- `;
196
- if (!comments) {
197
- preamble += `\\usepackage{xcolor}\n`;
198
- }
199
- preamble += `
200
- \\definecolor{insertgreen}{RGB}{34, 197, 94}
201
- \\definecolor{deletered}{RGB}{239, 68, 68}
202
- `;
203
- }
204
-
205
- return preamble;
206
- }
207
-
208
- /**
209
- * Options for preparing markdown for annotated PDF
210
- */
211
- export interface AnnotatedPdfOptions {
212
- showTrackChanges?: boolean;
213
- useTodonotes?: boolean;
214
- stripResolved?: boolean;
215
- }
216
-
217
- /**
218
- * Result of preparing markdown for annotated PDF
219
- */
220
- export interface AnnotatedPdfResult {
221
- markdown: string;
222
- preamble: string;
223
- commentCount: number;
224
- }
225
-
226
- /**
227
- * Prepare markdown for PDF with visible comments
228
- * Converts comments to margin notes and optionally shows track changes
229
- *
230
- * @param markdown - Markdown content
231
- * @param options - { showTrackChanges: boolean, useTodonotes: boolean }
232
- * @returns Converted markdown with preamble and comment count
233
- */
234
- export function prepareMarkdownForAnnotatedPdf(
235
- markdown: string,
236
- options: AnnotatedPdfOptions = {}
237
- ): AnnotatedPdfResult {
238
- const { showTrackChanges = false, useTodonotes = true, stripResolved = true } = options;
239
-
240
- let result = markdown;
241
- let preamble = '';
242
- let commentCount = 0;
243
-
244
- // Convert comments to margin notes
245
- const commentResult = convertCommentsToMarginNotes(result, { useTodonotes, stripResolved });
246
- result = commentResult.markdown;
247
- commentCount = commentResult.commentCount;
248
- preamble += commentResult.preamble;
249
-
250
- // Optionally show track changes
251
- if (showTrackChanges) {
252
- const trackResult = convertTrackChangesToLatex(result);
253
- result = trackResult.markdown;
254
- // Add ulem package if not already in todonotes preamble
255
- if (!useTodonotes) {
256
- preamble += trackResult.preamble;
257
- } else {
258
- preamble += `\\usepackage[normalem]{ulem}\n`;
259
- }
260
- }
261
-
262
- return { markdown: result, preamble, commentCount };
263
- }
1
+ /**
2
+ * PDF comment rendering for dual export
3
+ *
4
+ * Converts CriticMarkup comments to LaTeX margin notes for PDF output
5
+ */
6
+
7
+ import { escapeLatex } from './utils.js';
8
+
9
+ /**
10
+ * LaTeX preamble for margin comments
11
+ * Uses todonotes package with custom styling
12
+ */
13
+ export const MARGIN_NOTES_PREAMBLE = `
14
+ % Margin notes for comments
15
+ \\usepackage[colorinlistoftodos,textsize=scriptsize]{todonotes}
16
+ \\usepackage{xcolor}
17
+
18
+ % Define comment colors by author
19
+ \\definecolor{commentblue}{RGB}{59, 130, 246}
20
+ \\definecolor{commentgreen}{RGB}{34, 197, 94}
21
+ \\definecolor{commentorange}{RGB}{249, 115, 22}
22
+ \\definecolor{commentpurple}{RGB}{168, 85, 247}
23
+ \\definecolor{commentgray}{RGB}{107, 114, 128}
24
+
25
+ % Custom margin note command
26
+ \\newcommand{\\margincomment}[2][]{%
27
+ \\todo[linecolor=commentblue,backgroundcolor=commentblue!10,bordercolor=commentblue,size=\\scriptsize,#1]{#2}%
28
+ }
29
+
30
+ % Author-specific commands
31
+ \\newcommand{\\reviewercomment}[2]{%
32
+ \\todo[linecolor=commentgreen,backgroundcolor=commentgreen!10,bordercolor=commentgreen,size=\\scriptsize]{\\textbf{#1:} #2}%
33
+ }
34
+
35
+ % Increase margin for notes (if needed)
36
+ % \\setlength{\\marginparwidth}{2.5cm}
37
+ `;
38
+
39
+ /**
40
+ * Simpler preamble using marginpar (no extra packages needed)
41
+ */
42
+ export const SIMPLE_MARGIN_PREAMBLE = `
43
+ % Simple margin notes for comments
44
+ \\usepackage{xcolor}
45
+ \\definecolor{commentcolor}{RGB}{59, 130, 246}
46
+
47
+ \\newcommand{\\margincomment}[1]{%
48
+ \\marginpar{\\raggedright\\scriptsize\\textcolor{commentcolor}{#1}}%
49
+ }
50
+ `;
51
+
52
+ /**
53
+ * Options for converting comments to margin notes
54
+ */
55
+ export interface CommentConversionOptions {
56
+ useTodonotes?: boolean;
57
+ stripResolved?: boolean;
58
+ }
59
+
60
+ /**
61
+ * Result of comment conversion
62
+ */
63
+ export interface CommentConversionResult {
64
+ markdown: string;
65
+ commentCount: number;
66
+ preamble: string;
67
+ }
68
+
69
+ /**
70
+ * Convert CriticMarkup comments to LaTeX margin notes
71
+ * {>>Author: comment text<<} -> \margincomment{Author: comment text}
72
+ *
73
+ * @param markdown - Markdown with CriticMarkup comments
74
+ * @param options - { useTodonotes: boolean, stripResolved: boolean }
75
+ * @returns Converted markdown with comment count and preamble
76
+ */
77
+ export function convertCommentsToMarginNotes(
78
+ markdown: string,
79
+ options: CommentConversionOptions = {}
80
+ ): CommentConversionResult {
81
+ const { useTodonotes = true, stripResolved = true } = options;
82
+
83
+ let commentCount = 0;
84
+
85
+ // Pattern for CriticMarkup comments: {>>author: text<<} or {>>text<<}
86
+ // Also handle resolved comments: {>>✓ author: text<<}
87
+ const commentPattern = /\{>>(✓\s*)?([^<]+)<<\}/g;
88
+
89
+ const converted = markdown.replace(commentPattern, (match, resolved, content) => {
90
+ // Skip resolved comments if requested
91
+ if (resolved && stripResolved) {
92
+ return '';
93
+ }
94
+
95
+ commentCount++;
96
+
97
+ // Escape LaTeX special characters
98
+ const escaped = escapeLatex(content.trim());
99
+
100
+ if (useTodonotes) {
101
+ // Check if content has author prefix (Author: text)
102
+ const authorMatch = escaped.match(/^([^:]+):\s*([\s\S]+)$/);
103
+ if (authorMatch) {
104
+ const [, author, text] = authorMatch;
105
+ return `\\reviewercomment{${author}}{${text}}`;
106
+ }
107
+ return `\\margincomment{${escaped}}`;
108
+ } else {
109
+ return `\\margincomment{${escaped}}`;
110
+ }
111
+ });
112
+
113
+ const preamble = useTodonotes ? MARGIN_NOTES_PREAMBLE : SIMPLE_MARGIN_PREAMBLE;
114
+
115
+ return {
116
+ markdown: converted,
117
+ commentCount,
118
+ preamble,
119
+ };
120
+ }
121
+
122
+ /**
123
+ * Result of track changes conversion
124
+ */
125
+ export interface TrackChangesResult {
126
+ markdown: string;
127
+ preamble: string;
128
+ }
129
+
130
+ /**
131
+ * Convert track changes to visible LaTeX formatting
132
+ * {++inserted++} -> \textcolor{green}{inserted}
133
+ * {--deleted--} -> \textcolor{red}{\sout{deleted}}
134
+ * {~~old~>new~~} -> \textcolor{red}{\sout{old}}\textcolor{green}{new}
135
+ *
136
+ * @param markdown - Markdown with track changes
137
+ * @returns Converted markdown and preamble
138
+ */
139
+ export function convertTrackChangesToLatex(markdown: string): TrackChangesResult {
140
+ let result = markdown;
141
+
142
+ // Insertions: {++text++} -> green text
143
+ result = result.replace(/\{\+\+([^+]+)\+\+\}/g, (match, text) => {
144
+ return `\\textcolor{green}{${escapeLatex(text)}}`;
145
+ });
146
+
147
+ // Deletions: {--text--} -> red strikethrough
148
+ result = result.replace(/\{--([^-]+)--\}/g, (match, text) => {
149
+ return `\\textcolor{red}{\\sout{${escapeLatex(text)}}}`;
150
+ });
151
+
152
+ // Substitutions: {~~old~>new~~} -> red strikethrough + green new
153
+ result = result.replace(/\{~~([^~]+)~>([^~]+)~~\}/g, (match, oldText, newText) => {
154
+ return `\\textcolor{red}{\\sout{${escapeLatex(oldText)}}}\\textcolor{green}{${escapeLatex(newText)}}`;
155
+ });
156
+
157
+ const preamble = `
158
+ % Track changes visualization
159
+ \\usepackage{xcolor}
160
+ \\usepackage[normalem]{ulem}
161
+ \\definecolor{green}{RGB}{34, 197, 94}
162
+ \\definecolor{red}{RGB}{239, 68, 68}
163
+ `;
164
+
165
+ return { markdown: result, preamble };
166
+ }
167
+
168
+ /**
169
+ * Options for combined preamble
170
+ */
171
+ export interface PreambleOptions {
172
+ comments?: boolean;
173
+ trackChanges?: boolean;
174
+ useTodonotes?: boolean;
175
+ }
176
+
177
+ /**
178
+ * Get combined preamble for comments and track changes
179
+ * @param options - { comments: boolean, trackChanges: boolean, useTodonotes: boolean }
180
+ * @returns Combined LaTeX preamble
181
+ */
182
+ export function getCombinedPreamble(options: PreambleOptions = {}): string {
183
+ const { comments = true, trackChanges = false, useTodonotes = true } = options;
184
+
185
+ let preamble = '';
186
+
187
+ if (comments) {
188
+ preamble += useTodonotes ? MARGIN_NOTES_PREAMBLE : SIMPLE_MARGIN_PREAMBLE;
189
+ }
190
+
191
+ if (trackChanges) {
192
+ preamble += `
193
+ % Track changes visualization
194
+ \\usepackage[normalem]{ulem}
195
+ `;
196
+ if (!comments) {
197
+ preamble += `\\usepackage{xcolor}\n`;
198
+ }
199
+ preamble += `
200
+ \\definecolor{insertgreen}{RGB}{34, 197, 94}
201
+ \\definecolor{deletered}{RGB}{239, 68, 68}
202
+ `;
203
+ }
204
+
205
+ return preamble;
206
+ }
207
+
208
+ /**
209
+ * Options for preparing markdown for annotated PDF
210
+ */
211
+ export interface AnnotatedPdfOptions {
212
+ showTrackChanges?: boolean;
213
+ useTodonotes?: boolean;
214
+ stripResolved?: boolean;
215
+ }
216
+
217
+ /**
218
+ * Result of preparing markdown for annotated PDF
219
+ */
220
+ export interface AnnotatedPdfResult {
221
+ markdown: string;
222
+ preamble: string;
223
+ commentCount: number;
224
+ }
225
+
226
+ /**
227
+ * Prepare markdown for PDF with visible comments
228
+ * Converts comments to margin notes and optionally shows track changes
229
+ *
230
+ * @param markdown - Markdown content
231
+ * @param options - { showTrackChanges: boolean, useTodonotes: boolean }
232
+ * @returns Converted markdown with preamble and comment count
233
+ */
234
+ export function prepareMarkdownForAnnotatedPdf(
235
+ markdown: string,
236
+ options: AnnotatedPdfOptions = {}
237
+ ): AnnotatedPdfResult {
238
+ const { showTrackChanges = false, useTodonotes = true, stripResolved = true } = options;
239
+
240
+ let result = markdown;
241
+ let preamble = '';
242
+ let commentCount = 0;
243
+
244
+ // Convert comments to margin notes
245
+ const commentResult = convertCommentsToMarginNotes(result, { useTodonotes, stripResolved });
246
+ result = commentResult.markdown;
247
+ commentCount = commentResult.commentCount;
248
+ preamble += commentResult.preamble;
249
+
250
+ // Optionally show track changes
251
+ if (showTrackChanges) {
252
+ const trackResult = convertTrackChangesToLatex(result);
253
+ result = trackResult.markdown;
254
+ // Add ulem package if not already in todonotes preamble
255
+ if (!useTodonotes) {
256
+ preamble += trackResult.preamble;
257
+ } else {
258
+ preamble += `\\usepackage[normalem]{ulem}\n`;
259
+ }
260
+ }
261
+
262
+ return { markdown: result, preamble, commentCount };
263
+ }