docrev 0.9.13 → 0.9.15

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 (126) hide show
  1. package/.claude/settings.local.json +9 -9
  2. package/.gitattributes +1 -1
  3. package/CHANGELOG.md +149 -149
  4. package/PLAN-tables-and-postprocess.md +850 -850
  5. package/README.md +411 -391
  6. package/bin/rev.js +11 -11
  7. package/bin/rev.ts +145 -145
  8. package/completions/rev.bash +127 -127
  9. package/completions/rev.ps1 +210 -210
  10. package/completions/rev.zsh +207 -207
  11. package/dev_notes/stress2/build_adversarial.ts +186 -186
  12. package/dev_notes/stress2/drift_matcher.ts +62 -62
  13. package/dev_notes/stress2/probe_anchors.ts +35 -35
  14. package/dev_notes/stress2/project/discussion.before.md +3 -3
  15. package/dev_notes/stress2/project/discussion.md +3 -3
  16. package/dev_notes/stress2/project/methods.before.md +20 -20
  17. package/dev_notes/stress2/project/methods.md +20 -20
  18. package/dev_notes/stress2/project/rev.yaml +5 -5
  19. package/dev_notes/stress2/project/sections.yaml +4 -4
  20. package/dev_notes/stress2/sections.yaml +5 -5
  21. package/dev_notes/stress2/trace_placement.ts +50 -50
  22. package/dev_notes/stresstest_boundaries.ts +27 -27
  23. package/dev_notes/stresstest_drift_apply.ts +43 -43
  24. package/dev_notes/stresstest_drift_compare.ts +43 -43
  25. package/dev_notes/stresstest_drift_v2.ts +54 -54
  26. package/dev_notes/stresstest_inspect.ts +54 -54
  27. package/dev_notes/stresstest_pstyle.ts +55 -55
  28. package/dev_notes/stresstest_section_debug.ts +23 -23
  29. package/dev_notes/stresstest_split.ts +70 -70
  30. package/dev_notes/stresstest_trace.ts +19 -19
  31. package/dev_notes/stresstest_verify_no_overwrite.ts +40 -40
  32. package/dist/lib/build.d.ts +38 -1
  33. package/dist/lib/build.d.ts.map +1 -1
  34. package/dist/lib/build.js +68 -30
  35. package/dist/lib/build.js.map +1 -1
  36. package/dist/lib/commands/build.d.ts.map +1 -1
  37. package/dist/lib/commands/build.js +38 -5
  38. package/dist/lib/commands/build.js.map +1 -1
  39. package/dist/lib/commands/utilities.js +164 -164
  40. package/dist/lib/commands/word-tools.js +8 -8
  41. package/dist/lib/grammar.js +3 -3
  42. package/dist/lib/pdf-comments.js +44 -44
  43. package/dist/lib/plugins.js +57 -57
  44. package/dist/lib/pptx-themes.js +115 -115
  45. package/dist/lib/spelling.js +2 -2
  46. package/dist/lib/templates.js +387 -387
  47. package/dist/lib/themes.js +51 -51
  48. package/eslint.config.js +27 -27
  49. package/lib/anchor-match.ts +276 -276
  50. package/lib/annotations.ts +644 -644
  51. package/lib/build.ts +1300 -1251
  52. package/lib/citations.ts +160 -160
  53. package/lib/commands/build.ts +833 -801
  54. package/lib/commands/citations.ts +515 -515
  55. package/lib/commands/comments.ts +1050 -1050
  56. package/lib/commands/context.ts +174 -174
  57. package/lib/commands/core.ts +309 -309
  58. package/lib/commands/doi.ts +435 -435
  59. package/lib/commands/file-ops.ts +372 -372
  60. package/lib/commands/history.ts +320 -320
  61. package/lib/commands/index.ts +87 -87
  62. package/lib/commands/init.ts +259 -259
  63. package/lib/commands/merge-resolve.ts +378 -378
  64. package/lib/commands/preview.ts +178 -178
  65. package/lib/commands/project-info.ts +244 -244
  66. package/lib/commands/quality.ts +517 -517
  67. package/lib/commands/response.ts +454 -454
  68. package/lib/commands/section-boundaries.ts +82 -82
  69. package/lib/commands/sections.ts +451 -451
  70. package/lib/commands/sync.ts +706 -706
  71. package/lib/commands/text-ops.ts +449 -449
  72. package/lib/commands/utilities.ts +448 -448
  73. package/lib/commands/verify-anchors.ts +272 -272
  74. package/lib/commands/word-tools.ts +340 -340
  75. package/lib/comment-realign.ts +517 -517
  76. package/lib/config.ts +84 -84
  77. package/lib/crossref.ts +781 -781
  78. package/lib/csl.ts +191 -191
  79. package/lib/dependencies.ts +98 -98
  80. package/lib/diff-engine.ts +465 -465
  81. package/lib/doi-cache.ts +115 -115
  82. package/lib/doi.ts +897 -897
  83. package/lib/equations.ts +506 -506
  84. package/lib/errors.ts +346 -346
  85. package/lib/format.ts +541 -541
  86. package/lib/git.ts +326 -326
  87. package/lib/grammar.ts +303 -303
  88. package/lib/image-registry.ts +180 -180
  89. package/lib/import.ts +911 -911
  90. package/lib/journals.ts +543 -543
  91. package/lib/merge.ts +633 -633
  92. package/lib/orcid.ts +144 -144
  93. package/lib/pdf-comments.ts +263 -263
  94. package/lib/pdf-import.ts +524 -524
  95. package/lib/plugins.ts +362 -362
  96. package/lib/postprocess.ts +188 -188
  97. package/lib/pptx-color-filter.lua +37 -37
  98. package/lib/pptx-template.ts +469 -469
  99. package/lib/pptx-themes.ts +483 -483
  100. package/lib/protect-restore.ts +520 -520
  101. package/lib/rate-limiter.ts +94 -94
  102. package/lib/response.ts +197 -197
  103. package/lib/restore-references.ts +240 -240
  104. package/lib/review.ts +327 -327
  105. package/lib/schema.ts +417 -417
  106. package/lib/scientific-words.ts +73 -73
  107. package/lib/sections.ts +335 -335
  108. package/lib/slides.ts +756 -756
  109. package/lib/spelling.ts +334 -334
  110. package/lib/templates.ts +526 -526
  111. package/lib/themes.ts +742 -742
  112. package/lib/trackchanges.ts +247 -247
  113. package/lib/tui.ts +450 -450
  114. package/lib/types.ts +550 -550
  115. package/lib/undo.ts +250 -250
  116. package/lib/utils.ts +69 -69
  117. package/lib/variables.ts +179 -179
  118. package/lib/word-extraction.ts +806 -806
  119. package/lib/word.ts +643 -643
  120. package/lib/wordcomments.ts +817 -817
  121. package/package.json +137 -137
  122. package/scripts/postbuild.js +28 -28
  123. package/skill/REFERENCE.md +473 -431
  124. package/skill/SKILL.md +274 -258
  125. package/tsconfig.json +26 -26
  126. package/types/index.d.ts +525 -525
@@ -229,179 +229,179 @@ export function register(program, pkg) {
229
229
  }
230
230
  // Helper functions for help text
231
231
  function showFullHelp(pkg) {
232
- console.log(`
233
- ${chalk.bold.cyan('rev')} ${chalk.dim(`v${pkg?.version || 'unknown'}`)} - Revision workflow for Word ↔ Markdown round-trips
234
-
235
- ${chalk.bold('DESCRIPTION')}
236
- Handle reviewer feedback when collaborating on academic papers.
237
- Import changes from Word, review them interactively, and preserve
238
- comments for discussion with Claude.
239
-
240
- ${chalk.bold('GLOBAL OPTIONS')}
241
-
242
- ${chalk.bold('--no-color')} Disable colored output
243
- ${chalk.bold('-q, --quiet')} Suppress non-essential output
244
- ${chalk.bold('--json')} Output in JSON format (for scripting)
245
-
246
- ${chalk.bold('TYPICAL WORKFLOW')}
247
-
248
- ${chalk.dim('1.')} Build and send: ${chalk.green('rev build docx')} ${chalk.dim('(or rev b docx)')}
249
- ${chalk.dim('2.')} Reviewers return ${chalk.yellow('reviewed.docx')} with edits and comments
250
- ${chalk.dim('3.')} Sync their feedback: ${chalk.green('rev sync reviewed.docx')}
251
- ${chalk.dim('4.')} Work through comments: ${chalk.green('rev next')} ${chalk.dim('(n)')} / ${chalk.green('rev todo')} ${chalk.dim('(t)')}
252
- ${chalk.dim('5.')} Accept/reject changes: ${chalk.green('rev accept -a')} ${chalk.dim('(a)')} or ${chalk.green('rev review')}
253
- ${chalk.dim('6.')} Rebuild: ${chalk.green('rev build docx')}
254
- ${chalk.dim('7.')} Archive old files: ${chalk.green('rev archive')}
255
-
256
- ${chalk.bold('MORE HELP')}
257
-
258
- rev help workflow Detailed workflow guide
259
- rev help syntax Annotation syntax reference
260
- rev help commands All commands with options
232
+ console.log(`
233
+ ${chalk.bold.cyan('rev')} ${chalk.dim(`v${pkg?.version || 'unknown'}`)} - Revision workflow for Word ↔ Markdown round-trips
234
+
235
+ ${chalk.bold('DESCRIPTION')}
236
+ Handle reviewer feedback when collaborating on academic papers.
237
+ Import changes from Word, review them interactively, and preserve
238
+ comments for discussion with Claude.
239
+
240
+ ${chalk.bold('GLOBAL OPTIONS')}
241
+
242
+ ${chalk.bold('--no-color')} Disable colored output
243
+ ${chalk.bold('-q, --quiet')} Suppress non-essential output
244
+ ${chalk.bold('--json')} Output in JSON format (for scripting)
245
+
246
+ ${chalk.bold('TYPICAL WORKFLOW')}
247
+
248
+ ${chalk.dim('1.')} Build and send: ${chalk.green('rev build docx')} ${chalk.dim('(or rev b docx)')}
249
+ ${chalk.dim('2.')} Reviewers return ${chalk.yellow('reviewed.docx')} with edits and comments
250
+ ${chalk.dim('3.')} Sync their feedback: ${chalk.green('rev sync reviewed.docx')}
251
+ ${chalk.dim('4.')} Work through comments: ${chalk.green('rev next')} ${chalk.dim('(n)')} / ${chalk.green('rev todo')} ${chalk.dim('(t)')}
252
+ ${chalk.dim('5.')} Accept/reject changes: ${chalk.green('rev accept -a')} ${chalk.dim('(a)')} or ${chalk.green('rev review')}
253
+ ${chalk.dim('6.')} Rebuild: ${chalk.green('rev build docx')}
254
+ ${chalk.dim('7.')} Archive old files: ${chalk.green('rev archive')}
255
+
256
+ ${chalk.bold('MORE HELP')}
257
+
258
+ rev help workflow Detailed workflow guide
259
+ rev help syntax Annotation syntax reference
260
+ rev help commands All commands with options
261
261
  `);
262
262
  }
263
263
  function showWorkflowHelp() {
264
- console.log(`
265
- ${chalk.bold.cyan('rev')} ${chalk.dim('- Workflow Guide')}
266
-
267
- ${chalk.bold('OVERVIEW')}
268
-
269
- The rev workflow solves a common problem: you write in Markdown,
270
- but collaborators review in Word. When they return edited documents,
271
- you need to merge their changes back into your source files.
272
-
273
- ${chalk.bold('STEP 1: BUILD & SEND')}
274
-
275
- ${chalk.green('rev build docx')}
276
- ${chalk.dim('# Send the .docx to reviewers')}
277
-
278
- ${chalk.bold('STEP 2: RECEIVE FEEDBACK')}
279
-
280
- Reviewers edit the document, adding:
281
- ${chalk.dim('•')} Track changes (insertions, deletions)
282
- ${chalk.dim('•')} Comments (questions, suggestions)
283
-
284
- ${chalk.bold('STEP 3: SYNC CHANGES')}
285
-
286
- ${chalk.green('rev sync reviewed.docx')}
287
- ${chalk.dim('# Or just: rev sync (auto-detects most recent .docx)')}
288
-
289
- Your markdown files now contain their feedback as annotations.
290
-
291
- ${chalk.bold('STEP 4: WORK THROUGH COMMENTS')}
292
-
293
- ${chalk.green('rev todo')} ${chalk.dim('# See all pending comments')}
294
- ${chalk.green('rev next')} ${chalk.dim('# Show next pending comment')}
295
- ${chalk.green('rev reply file.md -n 1 -m "Done"')}
296
- ${chalk.green('rev resolve file.md -n 1')}
297
-
298
- ${chalk.bold('STEP 5: ACCEPT/REJECT CHANGES')}
299
-
300
- ${chalk.green('rev accept file.md -a')} ${chalk.dim('# Accept all changes')}
301
- ${chalk.green('rev reject file.md -n 2')} ${chalk.dim('# Reject specific change')}
302
- ${chalk.dim('# Or use interactive mode:')}
303
- ${chalk.green('rev review file.md')}
304
-
305
- ${chalk.bold('STEP 6: REBUILD')}
306
-
307
- ${chalk.green('rev build docx')}
308
- ${chalk.green('rev build docx --dual')} ${chalk.dim('# Clean + comments version')}
309
-
310
- ${chalk.bold('STEP 7: ARCHIVE & REPEAT')}
311
-
312
- ${chalk.green('rev archive')} ${chalk.dim('# Move reviewer files to archive/')}
313
- ${chalk.dim('# Send new .docx, repeat cycle')}
264
+ console.log(`
265
+ ${chalk.bold.cyan('rev')} ${chalk.dim('- Workflow Guide')}
266
+
267
+ ${chalk.bold('OVERVIEW')}
268
+
269
+ The rev workflow solves a common problem: you write in Markdown,
270
+ but collaborators review in Word. When they return edited documents,
271
+ you need to merge their changes back into your source files.
272
+
273
+ ${chalk.bold('STEP 1: BUILD & SEND')}
274
+
275
+ ${chalk.green('rev build docx')}
276
+ ${chalk.dim('# Send the .docx to reviewers')}
277
+
278
+ ${chalk.bold('STEP 2: RECEIVE FEEDBACK')}
279
+
280
+ Reviewers edit the document, adding:
281
+ ${chalk.dim('•')} Track changes (insertions, deletions)
282
+ ${chalk.dim('•')} Comments (questions, suggestions)
283
+
284
+ ${chalk.bold('STEP 3: SYNC CHANGES')}
285
+
286
+ ${chalk.green('rev sync reviewed.docx')}
287
+ ${chalk.dim('# Or just: rev sync (auto-detects most recent .docx)')}
288
+
289
+ Your markdown files now contain their feedback as annotations.
290
+
291
+ ${chalk.bold('STEP 4: WORK THROUGH COMMENTS')}
292
+
293
+ ${chalk.green('rev todo')} ${chalk.dim('# See all pending comments')}
294
+ ${chalk.green('rev next')} ${chalk.dim('# Show next pending comment')}
295
+ ${chalk.green('rev reply file.md -n 1 -m "Done"')}
296
+ ${chalk.green('rev resolve file.md -n 1')}
297
+
298
+ ${chalk.bold('STEP 5: ACCEPT/REJECT CHANGES')}
299
+
300
+ ${chalk.green('rev accept file.md -a')} ${chalk.dim('# Accept all changes')}
301
+ ${chalk.green('rev reject file.md -n 2')} ${chalk.dim('# Reject specific change')}
302
+ ${chalk.dim('# Or use interactive mode:')}
303
+ ${chalk.green('rev review file.md')}
304
+
305
+ ${chalk.bold('STEP 6: REBUILD')}
306
+
307
+ ${chalk.green('rev build docx')}
308
+ ${chalk.green('rev build docx --dual')} ${chalk.dim('# Clean + comments version')}
309
+
310
+ ${chalk.bold('STEP 7: ARCHIVE & REPEAT')}
311
+
312
+ ${chalk.green('rev archive')} ${chalk.dim('# Move reviewer files to archive/')}
313
+ ${chalk.dim('# Send new .docx, repeat cycle')}
314
314
  `);
315
315
  }
316
316
  function showSyntaxHelp() {
317
- console.log(`
318
- ${chalk.bold.cyan('rev')} ${chalk.dim('- Annotation Syntax (CriticMarkup)')}
319
-
320
- ${chalk.bold('INSERTIONS')}
321
-
322
- Syntax: ${chalk.green('{++inserted text++}')}
323
- Meaning: This text was added by the reviewer
324
-
325
- Example:
326
- We ${chalk.green('{++specifically++}')} focused on neophytes.
327
- → Reviewer added the word "specifically"
328
-
329
- ${chalk.bold('DELETIONS')}
330
-
331
- Syntax: ${chalk.red('{--deleted text--}')}
332
- Meaning: This text was removed by the reviewer
333
-
334
- Example:
335
- We focused on ${chalk.red('{--recent--}')} neophytes.
336
- → Reviewer removed the word "recent"
337
-
338
- ${chalk.bold('SUBSTITUTIONS')}
339
-
340
- Syntax: ${chalk.yellow('{~~old text~>new text~~}')}
341
- Meaning: Text was changed from old to new
342
-
343
- Example:
344
- The effect was ${chalk.yellow('{~~significant~>substantial~~}')}.
345
- → Reviewer changed "significant" to "substantial"
346
-
347
- ${chalk.bold('COMMENTS')}
348
-
349
- Syntax: ${chalk.blue('{>>Author: comment text<<}')}
350
- Meaning: Reviewer left a comment at this location
351
-
352
- Example:
353
- The results were significant. ${chalk.blue('{>>Dr. Smith: Add p-value<<}')}
354
- → Dr. Smith commented asking for a p-value
355
-
356
- Comments are placed ${chalk.bold('after')} the text they reference.
317
+ console.log(`
318
+ ${chalk.bold.cyan('rev')} ${chalk.dim('- Annotation Syntax (CriticMarkup)')}
319
+
320
+ ${chalk.bold('INSERTIONS')}
321
+
322
+ Syntax: ${chalk.green('{++inserted text++}')}
323
+ Meaning: This text was added by the reviewer
324
+
325
+ Example:
326
+ We ${chalk.green('{++specifically++}')} focused on neophytes.
327
+ → Reviewer added the word "specifically"
328
+
329
+ ${chalk.bold('DELETIONS')}
330
+
331
+ Syntax: ${chalk.red('{--deleted text--}')}
332
+ Meaning: This text was removed by the reviewer
333
+
334
+ Example:
335
+ We focused on ${chalk.red('{--recent--}')} neophytes.
336
+ → Reviewer removed the word "recent"
337
+
338
+ ${chalk.bold('SUBSTITUTIONS')}
339
+
340
+ Syntax: ${chalk.yellow('{~~old text~>new text~~}')}
341
+ Meaning: Text was changed from old to new
342
+
343
+ Example:
344
+ The effect was ${chalk.yellow('{~~significant~>substantial~~}')}.
345
+ → Reviewer changed "significant" to "substantial"
346
+
347
+ ${chalk.bold('COMMENTS')}
348
+
349
+ Syntax: ${chalk.blue('{>>Author: comment text<<}')}
350
+ Meaning: Reviewer left a comment at this location
351
+
352
+ Example:
353
+ The results were significant. ${chalk.blue('{>>Dr. Smith: Add p-value<<}')}
354
+ → Dr. Smith commented asking for a p-value
355
+
356
+ Comments are placed ${chalk.bold('after')} the text they reference.
357
357
  `);
358
358
  }
359
359
  function showCommandsHelp() {
360
- console.log(`
361
- ${chalk.bold.cyan('rev')} ${chalk.dim('- Command Reference')}
362
-
363
- ${chalk.bold('rev import')} <docx> <original-md>
364
-
365
- Import changes from a Word document by comparing against your
366
- original Markdown source.
367
-
368
- ${chalk.bold('Arguments:')}
369
- docx Word document from reviewer
370
- original-md Your original Markdown file
371
-
372
- ${chalk.bold('Options:')}
373
- -o, --output <file> Write to different file (default: overwrites original)
374
- -a, --author <name> Author name for changes (default: "Reviewer")
375
- --dry-run Preview changes without saving
376
-
377
- ${chalk.bold('rev review')} <file>
378
-
379
- Interactively review and accept/reject track changes.
380
- Comments are preserved; only track changes are processed.
381
-
382
- ${chalk.bold('Keys:')}
383
- a Accept this change
384
- r Reject this change
385
- s Skip (decide later)
386
- A Accept all remaining changes
387
- L Reject all remaining changes
388
- q Quit without saving
389
-
390
- ${chalk.bold('rev strip')} <file>
391
-
392
- Remove annotations, outputting clean Markdown.
393
- Track changes are applied (insertions kept, deletions removed).
394
-
395
- ${chalk.bold('Options:')}
396
- -o, --output <file> Write to file (default: stdout)
397
- -c, --keep-comments Keep comment annotations
398
-
399
- ${chalk.bold('rev help')} [topic]
400
-
401
- Show help. Optional topics:
402
- workflow Step-by-step workflow guide
403
- syntax Annotation syntax reference
404
- commands This command reference
360
+ console.log(`
361
+ ${chalk.bold.cyan('rev')} ${chalk.dim('- Command Reference')}
362
+
363
+ ${chalk.bold('rev import')} <docx> <original-md>
364
+
365
+ Import changes from a Word document by comparing against your
366
+ original Markdown source.
367
+
368
+ ${chalk.bold('Arguments:')}
369
+ docx Word document from reviewer
370
+ original-md Your original Markdown file
371
+
372
+ ${chalk.bold('Options:')}
373
+ -o, --output <file> Write to different file (default: overwrites original)
374
+ -a, --author <name> Author name for changes (default: "Reviewer")
375
+ --dry-run Preview changes without saving
376
+
377
+ ${chalk.bold('rev review')} <file>
378
+
379
+ Interactively review and accept/reject track changes.
380
+ Comments are preserved; only track changes are processed.
381
+
382
+ ${chalk.bold('Keys:')}
383
+ a Accept this change
384
+ r Reject this change
385
+ s Skip (decide later)
386
+ A Accept all remaining changes
387
+ L Reject all remaining changes
388
+ q Quit without saving
389
+
390
+ ${chalk.bold('rev strip')} <file>
391
+
392
+ Remove annotations, outputting clean Markdown.
393
+ Track changes are applied (insertions kept, deletions removed).
394
+
395
+ ${chalk.bold('Options:')}
396
+ -o, --output <file> Write to file (default: stdout)
397
+ -c, --keep-comments Keep comment annotations
398
+
399
+ ${chalk.bold('rev help')} [topic]
400
+
401
+ Show help. Optional topics:
402
+ workflow Step-by-step workflow guide
403
+ syntax Annotation syntax reference
404
+ commands This command reference
405
405
  `);
406
406
  }
407
407
  //# sourceMappingURL=utilities.js.map
@@ -50,16 +50,16 @@ export function register(program) {
50
50
  }
51
51
  }
52
52
  else {
53
- commentsXml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
54
- <w:comments xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
53
+ commentsXml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
54
+ <w:comments xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
55
55
  </w:comments>`;
56
56
  }
57
57
  const author = options.author || getUserName() || 'Claude';
58
58
  const date = new Date().toISOString();
59
59
  const commentId = nextCommentId;
60
60
  // Add comment to comments.xml
61
- const newComment = `<w:comment w:id="${commentId}" w:author="${author}" w:date="${date}">
62
- <w:p><w:r><w:t>${options.message}</w:t></w:r></w:p>
61
+ const newComment = `<w:comment w:id="${commentId}" w:author="${author}" w:date="${date}">
62
+ <w:p><w:r><w:t>${options.message}</w:t></w:r></w:p>
63
63
  </w:comment>`;
64
64
  commentsXml = commentsXml.replace('</w:comments>', `${newComment}\n</w:comments>`);
65
65
  // Find text and add comment markers
@@ -200,15 +200,15 @@ export function register(program) {
200
200
  }
201
201
  }
202
202
  else {
203
- commentsXml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
204
- <w:comments xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
203
+ commentsXml = `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
204
+ <w:comments xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
205
205
  </w:comments>`;
206
206
  }
207
207
  const date = new Date().toISOString();
208
208
  const commentId = nextCommentId;
209
209
  // Add comment to comments.xml
210
- const newComment = `<w:comment w:id="${commentId}" w:author="${author}" w:date="${date}">
211
- <w:p><w:r><w:t>${message}</w:t></w:r></w:p>
210
+ const newComment = `<w:comment w:id="${commentId}" w:author="${author}" w:date="${date}">
211
+ <w:p><w:r><w:t>${message}</w:t></w:r></w:p>
212
212
  </w:comment>`;
213
213
  commentsXml = commentsXml.replace('</w:comments>', `${newComment}\n</w:comments>`);
214
214
  // Find text and add comment markers
@@ -125,9 +125,9 @@ export function loadDictionary(directory = '.') {
125
125
  */
126
126
  export function saveDictionary(words, directory = '.') {
127
127
  const dictPath = path.join(directory, DEFAULT_DICT_NAME);
128
- const header = `# Custom dictionary for docrev
129
- # Add one word per line
130
- # Lines starting with # are comments
128
+ const header = `# Custom dictionary for docrev
129
+ # Add one word per line
130
+ # Lines starting with # are comments
131
131
  `;
132
132
  const content = header + [...words].sort().join('\n') + '\n';
133
133
  fs.writeFileSync(dictPath, content, 'utf-8');
@@ -8,42 +8,42 @@ import { escapeLatex } from './utils.js';
8
8
  * LaTeX preamble for margin comments
9
9
  * Uses todonotes package with custom styling
10
10
  */
11
- export const MARGIN_NOTES_PREAMBLE = `
12
- % Margin notes for comments
13
- \\usepackage[colorinlistoftodos,textsize=scriptsize]{todonotes}
14
- \\usepackage{xcolor}
15
-
16
- % Define comment colors by author
17
- \\definecolor{commentblue}{RGB}{59, 130, 246}
18
- \\definecolor{commentgreen}{RGB}{34, 197, 94}
19
- \\definecolor{commentorange}{RGB}{249, 115, 22}
20
- \\definecolor{commentpurple}{RGB}{168, 85, 247}
21
- \\definecolor{commentgray}{RGB}{107, 114, 128}
22
-
23
- % Custom margin note command
24
- \\newcommand{\\margincomment}[2][]{%
25
- \\todo[linecolor=commentblue,backgroundcolor=commentblue!10,bordercolor=commentblue,size=\\scriptsize,#1]{#2}%
26
- }
27
-
28
- % Author-specific commands
29
- \\newcommand{\\reviewercomment}[2]{%
30
- \\todo[linecolor=commentgreen,backgroundcolor=commentgreen!10,bordercolor=commentgreen,size=\\scriptsize]{\\textbf{#1:} #2}%
31
- }
32
-
33
- % Increase margin for notes (if needed)
34
- % \\setlength{\\marginparwidth}{2.5cm}
11
+ export const MARGIN_NOTES_PREAMBLE = `
12
+ % Margin notes for comments
13
+ \\usepackage[colorinlistoftodos,textsize=scriptsize]{todonotes}
14
+ \\usepackage{xcolor}
15
+
16
+ % Define comment colors by author
17
+ \\definecolor{commentblue}{RGB}{59, 130, 246}
18
+ \\definecolor{commentgreen}{RGB}{34, 197, 94}
19
+ \\definecolor{commentorange}{RGB}{249, 115, 22}
20
+ \\definecolor{commentpurple}{RGB}{168, 85, 247}
21
+ \\definecolor{commentgray}{RGB}{107, 114, 128}
22
+
23
+ % Custom margin note command
24
+ \\newcommand{\\margincomment}[2][]{%
25
+ \\todo[linecolor=commentblue,backgroundcolor=commentblue!10,bordercolor=commentblue,size=\\scriptsize,#1]{#2}%
26
+ }
27
+
28
+ % Author-specific commands
29
+ \\newcommand{\\reviewercomment}[2]{%
30
+ \\todo[linecolor=commentgreen,backgroundcolor=commentgreen!10,bordercolor=commentgreen,size=\\scriptsize]{\\textbf{#1:} #2}%
31
+ }
32
+
33
+ % Increase margin for notes (if needed)
34
+ % \\setlength{\\marginparwidth}{2.5cm}
35
35
  `;
36
36
  /**
37
37
  * Simpler preamble using marginpar (no extra packages needed)
38
38
  */
39
- export const SIMPLE_MARGIN_PREAMBLE = `
40
- % Simple margin notes for comments
41
- \\usepackage{xcolor}
42
- \\definecolor{commentcolor}{RGB}{59, 130, 246}
43
-
44
- \\newcommand{\\margincomment}[1]{%
45
- \\marginpar{\\raggedright\\scriptsize\\textcolor{commentcolor}{#1}}%
46
- }
39
+ export const SIMPLE_MARGIN_PREAMBLE = `
40
+ % Simple margin notes for comments
41
+ \\usepackage{xcolor}
42
+ \\definecolor{commentcolor}{RGB}{59, 130, 246}
43
+
44
+ \\newcommand{\\margincomment}[1]{%
45
+ \\marginpar{\\raggedright\\scriptsize\\textcolor{commentcolor}{#1}}%
46
+ }
47
47
  `;
48
48
  /**
49
49
  * Convert CriticMarkup comments to LaTeX margin notes
@@ -110,12 +110,12 @@ export function convertTrackChangesToLatex(markdown) {
110
110
  result = result.replace(/\{~~([^~]+)~>([^~]+)~~\}/g, (match, oldText, newText) => {
111
111
  return `\\textcolor{red}{\\sout{${escapeLatex(oldText)}}}\\textcolor{green}{${escapeLatex(newText)}}`;
112
112
  });
113
- const preamble = `
114
- % Track changes visualization
115
- \\usepackage{xcolor}
116
- \\usepackage[normalem]{ulem}
117
- \\definecolor{green}{RGB}{34, 197, 94}
118
- \\definecolor{red}{RGB}{239, 68, 68}
113
+ const preamble = `
114
+ % Track changes visualization
115
+ \\usepackage{xcolor}
116
+ \\usepackage[normalem]{ulem}
117
+ \\definecolor{green}{RGB}{34, 197, 94}
118
+ \\definecolor{red}{RGB}{239, 68, 68}
119
119
  `;
120
120
  return { markdown: result, preamble };
121
121
  }
@@ -131,16 +131,16 @@ export function getCombinedPreamble(options = {}) {
131
131
  preamble += useTodonotes ? MARGIN_NOTES_PREAMBLE : SIMPLE_MARGIN_PREAMBLE;
132
132
  }
133
133
  if (trackChanges) {
134
- preamble += `
135
- % Track changes visualization
136
- \\usepackage[normalem]{ulem}
134
+ preamble += `
135
+ % Track changes visualization
136
+ \\usepackage[normalem]{ulem}
137
137
  `;
138
138
  if (!comments) {
139
139
  preamble += `\\usepackage{xcolor}\n`;
140
140
  }
141
- preamble += `
142
- \\definecolor{insertgreen}{RGB}{34, 197, 94}
143
- \\definecolor{deletered}{RGB}{239, 68, 68}
141
+ preamble += `
142
+ \\definecolor{insertgreen}{RGB}{34, 197, 94}
143
+ \\definecolor{deletered}{RGB}{239, 68, 68}
144
144
  `;
145
145
  }
146
146
  return preamble;
@@ -128,63 +128,63 @@ export function getPluginDirs() {
128
128
  */
129
129
  export function createProfileTemplate(journalName) {
130
130
  const id = journalName.toLowerCase().replace(/\s+/g, '-');
131
- return `# Custom journal profile for ${journalName}
132
- # Save as: ~/.rev/profiles/${id}.yaml (user-wide)
133
- # Or: .rev/profiles/${id}.yaml (project-specific)
134
-
135
- id: ${id}
136
- name: "${journalName}"
137
- url: "https://journal-website.com/author-guidelines"
138
-
139
- # Word count limits
140
- wordLimit:
141
- main: 8000 # null for no limit
142
- abstract: 300
143
- title: null # characters
144
-
145
- # Reference requirements
146
- references:
147
- max: null # null for no limit
148
- doiRequired: true
149
-
150
- # Figure/table limits
151
- figures:
152
- max: 8
153
- combinedWithTables: false
154
-
155
- # Required sections
156
- sections:
157
- required:
158
- - Abstract
159
- - Introduction
160
- - Methods
161
- - Results
162
- - Discussion
163
- methodsPosition: null # 'end' or 'before-results'
164
-
165
- # Keywords
166
- keywords:
167
- min: 4
168
- max: 8
169
-
170
- # Other requirements
171
- dataAvailability: true
172
- highlights: false
173
- graphicalAbstract: false
174
-
175
- # Build formatting defaults (applied via rev build -j ${id})
176
- # formatting:
177
- # csl: "${id}" # CSL style name or path
178
- # pdf:
179
- # fontsize: 12pt
180
- # geometry: margin=1in
181
- # linestretch: 1.5
182
- # numbersections: false
183
- # docx:
184
- # reference: null # Path to reference .docx template
185
- # crossref:
186
- # figPrefix: [Fig., Figs.]
187
- # tblPrefix: [Table, Tables]
131
+ return `# Custom journal profile for ${journalName}
132
+ # Save as: ~/.rev/profiles/${id}.yaml (user-wide)
133
+ # Or: .rev/profiles/${id}.yaml (project-specific)
134
+
135
+ id: ${id}
136
+ name: "${journalName}"
137
+ url: "https://journal-website.com/author-guidelines"
138
+
139
+ # Word count limits
140
+ wordLimit:
141
+ main: 8000 # null for no limit
142
+ abstract: 300
143
+ title: null # characters
144
+
145
+ # Reference requirements
146
+ references:
147
+ max: null # null for no limit
148
+ doiRequired: true
149
+
150
+ # Figure/table limits
151
+ figures:
152
+ max: 8
153
+ combinedWithTables: false
154
+
155
+ # Required sections
156
+ sections:
157
+ required:
158
+ - Abstract
159
+ - Introduction
160
+ - Methods
161
+ - Results
162
+ - Discussion
163
+ methodsPosition: null # 'end' or 'before-results'
164
+
165
+ # Keywords
166
+ keywords:
167
+ min: 4
168
+ max: 8
169
+
170
+ # Other requirements
171
+ dataAvailability: true
172
+ highlights: false
173
+ graphicalAbstract: false
174
+
175
+ # Build formatting defaults (applied via rev build -j ${id})
176
+ # formatting:
177
+ # csl: "${id}" # CSL style name or path
178
+ # pdf:
179
+ # fontsize: 12pt
180
+ # geometry: margin=1in
181
+ # linestretch: 1.5
182
+ # numbersections: false
183
+ # docx:
184
+ # reference: null # Path to reference .docx template
185
+ # crossref:
186
+ # figPrefix: [Fig., Figs.]
187
+ # tblPrefix: [Table, Tables]
188
188
  `;
189
189
  }
190
190
  /**