docrev 0.10.0 → 0.10.1

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/.gitattributes +1 -1
  2. package/CHANGELOG.md +173 -164
  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 +17 -47
  13. package/dist/lib/anchor-match.js.map +1 -1
  14. package/dist/lib/build.js +4 -4
  15. package/dist/lib/commands/context.d.ts +1 -1
  16. package/dist/lib/commands/context.d.ts.map +1 -1
  17. package/dist/lib/commands/context.js +1 -1
  18. package/dist/lib/commands/context.js.map +1 -1
  19. package/dist/lib/commands/sections.js +7 -7
  20. package/dist/lib/commands/sections.js.map +1 -1
  21. package/dist/lib/commands/sync.d.ts.map +1 -1
  22. package/dist/lib/commands/sync.js +15 -14
  23. package/dist/lib/commands/sync.js.map +1 -1
  24. package/dist/lib/commands/utilities.js +164 -164
  25. package/dist/lib/commands/verify-anchors.js +6 -6
  26. package/dist/lib/commands/verify-anchors.js.map +1 -1
  27. package/dist/lib/commands/word-tools.js +8 -8
  28. package/dist/lib/grammar.js +3 -3
  29. package/dist/lib/macro-filter.lua +201 -201
  30. package/dist/lib/pdf-comments.js +44 -44
  31. package/dist/lib/plugins.js +57 -57
  32. package/dist/lib/pptx-color-filter.lua +37 -37
  33. package/dist/lib/pptx-themes.js +115 -115
  34. package/dist/lib/sections.d.ts +35 -0
  35. package/dist/lib/sections.d.ts.map +1 -1
  36. package/dist/lib/sections.js +81 -0
  37. package/dist/lib/sections.js.map +1 -1
  38. package/dist/lib/spelling.js +2 -2
  39. package/dist/lib/templates.js +387 -387
  40. package/dist/lib/themes.js +51 -51
  41. package/docs-src/build.py +113 -113
  42. package/docs-src/extra.css +208 -208
  43. package/docs-src/md-to-html.lua +6 -6
  44. package/docs-src/template.html +116 -116
  45. package/eslint.config.js +27 -27
  46. package/lib/anchor-match.ts +276 -308
  47. package/lib/annotations.ts +644 -644
  48. package/lib/build.ts +1766 -1766
  49. package/lib/citations.ts +160 -160
  50. package/lib/commands/build.ts +855 -855
  51. package/lib/commands/citations.ts +515 -515
  52. package/lib/commands/comments.ts +1050 -1050
  53. package/lib/commands/context.ts +176 -174
  54. package/lib/commands/core.ts +309 -309
  55. package/lib/commands/doi.ts +435 -435
  56. package/lib/commands/file-ops.ts +372 -372
  57. package/lib/commands/history.ts +320 -320
  58. package/lib/commands/index.ts +87 -87
  59. package/lib/commands/init.ts +259 -259
  60. package/lib/commands/merge-resolve.ts +378 -378
  61. package/lib/commands/preview.ts +178 -178
  62. package/lib/commands/project-info.ts +244 -244
  63. package/lib/commands/quality.ts +517 -517
  64. package/lib/commands/response.ts +454 -454
  65. package/lib/commands/section-boundaries.ts +82 -82
  66. package/lib/commands/sections.ts +451 -451
  67. package/lib/commands/sync.ts +709 -706
  68. package/lib/commands/text-ops.ts +449 -449
  69. package/lib/commands/utilities.ts +448 -448
  70. package/lib/commands/verify-anchors.ts +272 -272
  71. package/lib/commands/word-tools.ts +340 -340
  72. package/lib/comment-realign.ts +517 -517
  73. package/lib/config.ts +84 -84
  74. package/lib/crossref.ts +781 -781
  75. package/lib/csl.ts +191 -191
  76. package/lib/dependencies.ts +98 -98
  77. package/lib/diff-engine.ts +465 -465
  78. package/lib/doi-cache.ts +115 -115
  79. package/lib/doi.ts +897 -897
  80. package/lib/equations.ts +506 -506
  81. package/lib/errors.ts +346 -346
  82. package/lib/format.ts +541 -541
  83. package/lib/git.ts +326 -326
  84. package/lib/grammar.ts +303 -303
  85. package/lib/image-registry.ts +180 -180
  86. package/lib/import.ts +911 -911
  87. package/lib/journals.ts +543 -543
  88. package/lib/macro-filter.lua +201 -201
  89. package/lib/macros.ts +273 -273
  90. package/lib/merge.ts +633 -633
  91. package/lib/orcid.ts +144 -144
  92. package/lib/pdf-comments.ts +263 -263
  93. package/lib/pdf-import.ts +524 -524
  94. package/lib/plugins.ts +362 -362
  95. package/lib/postprocess.ts +188 -188
  96. package/lib/pptx-color-filter.lua +37 -37
  97. package/lib/pptx-template.ts +469 -469
  98. package/lib/pptx-themes.ts +483 -483
  99. package/lib/protect-restore.ts +520 -520
  100. package/lib/rate-limiter.ts +94 -94
  101. package/lib/response.ts +197 -197
  102. package/lib/restore-references.ts +240 -240
  103. package/lib/review.ts +327 -327
  104. package/lib/schema.ts +488 -488
  105. package/lib/scientific-words.ts +73 -73
  106. package/lib/sections.ts +425 -335
  107. package/lib/slides.ts +756 -756
  108. package/lib/spelling.ts +334 -334
  109. package/lib/templates.ts +526 -526
  110. package/lib/themes.ts +742 -742
  111. package/lib/trackchanges.ts +247 -247
  112. package/lib/tui.ts +450 -450
  113. package/lib/types.ts +550 -550
  114. package/lib/undo.ts +250 -250
  115. package/lib/utils.ts +69 -69
  116. package/lib/variables.ts +179 -179
  117. package/lib/word-extraction.ts +806 -806
  118. package/lib/word.ts +643 -643
  119. package/lib/wordcomments.ts +840 -840
  120. package/mkdocs.yml +64 -64
  121. package/package.json +137 -137
  122. package/scripts/postbuild.js +47 -47
  123. package/skill/REFERENCE.md +539 -539
  124. package/skill/SKILL.md +295 -295
  125. package/tsconfig.json +26 -26
  126. package/types/index.d.ts +525 -525
package/.gitattributes CHANGED
@@ -1 +1 @@
1
- dist/** linguist-generated
1
+ dist/** linguist-generated
package/CHANGELOG.md CHANGED
@@ -1,164 +1,173 @@
1
- # Changelog
2
-
3
- All notable changes to docrev will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [0.10.0] - 2026-05-20
9
-
10
- ### Added
11
- - **Placeholder macros.** Built-in `\tofill{X}` renders as bold orange `[X]` across DOCX, PDF/TeX/Beamer, and HTML drop the LaTeX-style command anywhere in a section file and the build expands it per format. No more copying a `tofill_filter.lua` + `\providecommand` boilerplate into each project. Users can add their own one-argument macros under `macros:` in `rev.yaml` (color, bold/italic, bracket wrap, prefix/suffix, per-format overrides). See `docs/configuration.md` for the schema.
12
- - **`lib/macros.ts` + `lib/macro-filter.lua`** registry-style implementation. Built-ins and user macros merge by name; user entries override built-ins. The lua filter loads its macro list from a JSON sidecar via the `DOCREV_MACROS_FILE` env var.
13
-
14
- ### Fixed
15
- - **Silent DOCX color drop.** Pandoc 3.x's docx writer does NOT honor `Span` with `style="color: #..."`, so a lua filter returning `pandoc.Span(pandoc.Strong(...), pandoc.Attr("", {}, {style="color: #C2410C"}))` produced zero `<w:color>` runs and the highlight vanished. The new filter emits raw OpenXML `<w:r>` nodes directly (the same pattern as the existing `pptx-color-filter.lua`), which produces real colored runs in Word.
16
- - **Silent DOCX paragraph drop.** Wrapping a `\tofill{X}` line in raw LaTeX like `\noindent \textit{\small ...}` made pandoc drop the entire paragraph from DOCX output, including the `\tofill` inside. The built-in `\providecommand` + lua-filter mechanism removes the need for any wrapper at all — placeholders survive every format.
17
- - **Filter path resolution on Windows paths with spaces.** `lib/build.ts` resolved `pptx-color-filter.lua` via `new URL(import.meta.url).pathname`, which returns URL-encoded `%20` for spaces, so `fs.existsSync` silently returned false on paths like `C:\Users\Gilles Colling\...`. Switched both pptx and macro filter resolution to `fileURLToPath`. PPTX color highlighting now actually works under default installs on user-named directories.
18
- - **Lua filter not shipped to runtime.** `scripts/postbuild.js` left `.lua` files in `lib/` only; the compiled `dist/lib/build.js` looked for them next to itself. PPTX colour filter (and now the macro filter) are now copied to `dist/lib/` during build.
19
-
20
- ### Notes for `\tofill` migration
21
- Projects that ship their own `tofill_filter.lua` and `\providecommand{\tofill}{...}` in a custom header keep working docrev's preamble uses `\providecommand`, so user `\renewcommand` (or pre-existing `\providecommand`) takes priority. To migrate, delete the local lua filter and any markdown wrappers like `\noindent \textit{\small ...}`; docrev's built-in covers all three formats. Override the color or style by adding the macro under `macros:` in `rev.yaml`.
22
-
23
- ## [0.9.11] - 2026-04-30
24
-
25
- ### Fixed
26
- - **Single-section comment placement.** `computeSectionBoundaries` left the last section's `end` at `Number.MAX_SAFE_INTEGER`, which collapsed the proportional-position math in `insertCommentsIntoMarkdown` to ~0. Every comment whose anchor wasn't in the first 200 chars of the markdown stacked at position 0. Now caps the last boundary's `end` at `fullDocText.length`, passed in from sync and verify-anchors.
27
- - **Re-sync duplicated comments.** `sync --comments-only` re-inserted every comment on each invocation, producing `{>>R1<<}{>>R1<<}{>>R1<<}…` over time. `insertCommentsIntoMarkdown` now scans ±200 chars around the target for an identical `{>>author: text<<}` block and skips insertion when found.
28
- - **Threading content destruction.** `prepareMarkdownWithMarkers`'s whitespace-consumption loops captured `charBefore` once outside the loop, so a single leading space caused `removeStart` to walk to position 0 and `slice()` to delete every preceding paragraph. Replaced with a one-char check.
29
- - **Multi-run anchor injection.** Pandoc splits a single anchor across multiple `<w:r>` blocks whenever it applies styling mid-anchor — smart-quote substitution, `*italic*`, `` `code` ``, `**bold**` all trigger this. The single-run scan in `injectCommentsAtMarkers` grabbed the start marker's `<w:t>`, looked for the end marker inside it, found nothing, and silently skipped the comment. New multi-run path splits the start run at the start marker, keeps middle runs verbatim, splits the end run at the end marker, and rebuilds with `commentRangeStart`/`commentRangeEnd` around the styled anchor portions.
30
- - **Nested-bracket anchors.** `prepareMarkdownWithMarkers` used `\[([^\]]+)\]\{\.mark\}` for the trailing anchor group, so any inner `]` (e.g. `[[0..9]]{.mark}`, `[*italic*]{.mark}`) terminated the match prematurely. Replaced with a manual balanced-bracket walker that handles arbitrary nesting depth and verifies a `{.mark}` suffix.
31
- - **Orphan-`[` over-stripping.** `stripAnnotations`'s orphan cleanup used `\[(?![^\[\]]*\])`, treating any inner `[` as a barrier and stripping the outer `[` of nested forms. Loosened to `\[(?![^\]\n]*\])`: an `[` is orphan only when no `]` follows before end of line.
32
-
33
- ### Changed
34
- - `sync --comments-only` summary distinguishes `placed` / `already present` / `unmatched` instead of subtracting before/after counts. Re-syncs now report "6 already present (skipped to avoid duplication)" instead of misreporting them as fully placed or fully unmatched. New `outStats` channel from `insertCommentsIntoMarkdown`.
35
-
36
- ## [0.9.10] - 2026-04-30
37
-
38
- ### Fixed
39
- - `stripAnnotations` stripped `[anchor]{.mark}` spans even when `keepComments=true`, leaving the dual-build marker generator with no anchor text and collapsing every multi-word anchor to a single fallback word in the rebuilt docx. Now preserves anchor spans that belong to retained `{>>...<<}` comments.
40
- - Comments authored at the very start of a Word section landed before the markdown file's `# Heading` line and rendered in the previous section. Added `pushPastSectionHeading` so position-0 comments advance to the first body paragraph of the section they were authored in.
41
- - Empty-anchor comments fell through to proportional placement even when before/after context uniquely identified the position, landing mid-word or splitting unrelated phrases. Context match now runs first; proportional placement is the fallback.
42
- - When an anchor appeared multiple times in the search window (repeated phrasing, formulaic prose), `insertCommentsIntoMarkdown` always picked the first occurrence. Now picks the occurrence closest to the docx-derived insert position.
43
-
44
- ## [0.9.7] - 2026-04-29
45
-
46
- ### Added
47
- - `rev sync --comments-only` — import only Word comments at fuzzy-matched anchors, leaving prose byte-identical. Use when the markdown was revised between sending the docx out for review and receiving it back; applying track changes from a stale draft would clobber newer edits.
48
- - `rev verify-anchors <docx>` drift report classifying every comment as `clean` / `drift` / `context-only` / `ambiguous` / `unmatched` against the current section markdown. Pair with `--comments-only` to plan placement before sync. Supports `--json` for scripting.
49
- - `extractHeadings()` in `word-extraction.ts` read heading paragraphs directly from `<w:pStyle>` styles, returning text + level + position in the same coordinate system as comment anchors.
50
- - Shared `lib/commands/section-boundaries.ts` single source of truth that maps `sections.yaml` to docx text positions, used by both sync and verify-anchors.
51
- - Shared `lib/anchor-match.ts` pure anchor-matching primitives (`findAnchorInText`, `stripCriticMarkup`, `classifyStrategy`) so sync (insertion) and verify-anchors (drift reporting) use the same fallback strategies.
52
- - New tests: `test/anchor-match.test.js` (11 cases covering each fallback strategy and the quality classifier).
53
-
54
- ### Fixed
55
- - **Section detection mistook prose for headings.** The old keyword finder scanned the concatenated body text and would match "results across countries" as the Results heading or skip the real Methods heading because the structured-abstract label `Methods:` lost its colon during text-run concatenation. Replaced with paragraph-style-based heading extraction, so boundaries now reflect actual heading paragraphs. Affects the new commands; the existing sync flow already used pandoc-derived headings and was unaffected.
56
- - `stripCriticMarkup` regex used `[^<]*` and silently failed on comments containing `<` characters (e.g. `pre-industrial trade (<1825)`). Switched to non-greedy `[\s\S]*?`.
57
- - `insertCommentsIntoMarkdown` always prepended a leading space when there was no anchor, accumulating multiple spaces when several comments shared a position 0 anchor. Removed the heuristic; comments insert at exact position so prose stays byte-identical except for the inserted blocks.
58
- - `verify-anchors` crashed with a stack trace when given a non-docx file (e.g. an `.md` path). Now reports a friendly error.
59
-
60
- ### Changed
61
- - New flag is `--comments-only` (positive form). The originally proposed `--no-overwrite` was dropped because Commander assigns `--no-X` to `options.x === false` rather than `options.noX === true`, which made the flag silently ignored.
62
- - `insertCommentsIntoMarkdown` now accepts `wrapAnchor?: boolean` (default `true`). When `false`, comment blocks are inserted next to the anchor without `[anchor]{.mark}` wrapping. `--comments-only` uses this so multiple comments sharing an anchor (e.g. 6 reviewers commenting on the same word) no longer produce nested broken CriticMarkup.
63
-
64
- ## [0.7.1] - 2025-01-02
65
-
66
- ### Added
67
- - Writing Markdown guide in docs (tables, equations, citations, cross-refs)
68
- - Grid table syntax documentation for merged cells
69
-
70
- ### Changed
71
- - README restructured for better scannability (490 290 lines)
72
- - Install section moved up for faster onboarding
73
- - Added Highlights section with quick feature overview
74
- - Condensed overlapping sections
75
-
76
- ## [0.7.0] - 2025-01-02
77
-
78
- ### Added
79
- - API rate limiting with exponential backoff for Crossref/DataCite/doi.org APIs
80
- - Windows support in CI matrix
81
- - Architecture documentation for contributors (`ARCHITECTURE.md`)
82
- - Exclusion patterns for cross-reference false positives (e.g., "Table of Contents")
83
- - Timeout support for PDF extraction (30s default)
84
-
85
- ### Changed
86
- - Consolidated YAML dependencies (removed `js-yaml`, using `yaml` package only)
87
- - Improved annotation false positive detection (code blocks, URLs, LaTeX patterns)
88
- - Enhanced error messages for Word import and PDF extraction
89
- - Updated User-Agent strings for API requests
90
- - Improved README with problem statement and quick example
91
-
92
- ### Fixed
93
- - CI lint step now checks all command files separately
94
- - Windows temp directory paths in tests
95
-
96
- ## [0.3.2] - 2024-12-29
97
-
98
- ### Added
99
- - Full TypeScript type definitions (`types/index.d.ts`)
100
- - GitHub Actions CI workflow (Node 18/20/22)
101
- - ESM subpath exports for all library modules
102
- - CLI integration tests (26 tests)
103
- - Comprehensive test coverage: 419 tests across 18 modules
104
-
105
- ### Fixed
106
- - DOI skip detection: `% no-doi` comments now correctly apply only to the next entry
107
-
108
- ### Changed
109
- - Added `engines` field requiring Node.js >=18.0.0
110
- - Updated README with badges (npm, CI, Node.js, License)
111
-
112
- ## [0.3.1] - 2024-12-28
113
-
114
- ### Fixed
115
- - Equation extraction test assertions
116
- - Minor bug fixes
117
-
118
- ## [0.3.0] - 2024-12-27
119
-
120
- ### Added
121
- - DOI validation via Crossref and DataCite APIs (`rev doi check`)
122
- - DOI lookup for missing entries (`rev doi lookup`)
123
- - DOI fetch and add commands (`rev doi fetch`, `rev doi add`)
124
- - Citation validation against bibliography (`rev citations`)
125
- - LaTeX equation extraction (`rev equations list`)
126
- - Word equation import OMML → LaTeX (`rev equations from-word`)
127
- - Response letter generation (`rev response`)
128
- - Journal validation profiles (`rev validate --journal`)
129
- - Advanced figure/table reference patterns (Figs. 1-3, Fig. 1a-c)
130
-
131
- ### Changed
132
- - Improved cross-reference pattern detection
133
- - Enhanced Word import with better section splitting
134
-
135
- ## [0.2.1] - 2024-12-26
136
-
137
- ### Added
138
- - Table of contents option (`rev build --toc`)
139
- - CSV export for comments (`rev comments --export`)
140
- - Anonymize command for blind review (`rev anonymize`)
141
- - Formatting utilities (tables, boxes, spinners)
142
-
143
- ## [0.2.0] - 2024-12-25
144
-
145
- ### Added
146
- - Integrated build system (`rev build pdf/docx/tex`)
147
- - Comment reply functionality (`rev reply`)
148
- - Word document bootstrap (`rev import` creates project from .docx)
149
- - Section-aware import (`rev sections`)
150
- - Cross-reference migration (`rev migrate`)
151
-
152
- ### Changed
153
- - Renamed project to docrev
154
- - Published to npm
155
-
156
- ## [0.1.0] - 2024-12-24
157
-
158
- ### Added
159
- - Initial release
160
- - CriticMarkup annotation parsing
161
- - Word ↔ Markdown round-trips
162
- - Interactive review TUI (`rev review`)
163
- - Comment management (`rev comments`, `rev resolve`)
164
- - Project templates (`rev new`)
1
+ # Changelog
2
+
3
+ All notable changes to docrev will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.10.1] - 2026-06-05
9
+
10
+ ### Fixed
11
+ - **`sync`/`verify-anchors`/`split` no longer require a separate `sections.yaml`.** `build` and `status` read the `sections:` list from `rev.yaml`, but the sync-side commands demanded a `sections.yaml` and aborted with `Config not found` on a perfectly valid `rev.yaml`-only project. They now resolve the section config from a single source of truth: an explicit `sections.yaml` is used when present (to override headers/aliases/order), otherwise the config is derived from `rev.yaml`'s `sections:` list. Running `rev init` first is no longer necessary.
12
+ - **Derived section headers honor the file's first heading at any level.** A section file that leads with a subsection (e.g. `02_objectives.md` starting with `## 1.2 Objectives`) now derives the header `1.2 Objectives` (via the new `extractFirstHeading`), so it matches the corresponding docx heading and routes to its own file instead of being folded into the preceding section. `extractHeader` keeps its H1-only contract for existing callers.
13
+
14
+ ### Added
15
+ - `resolveSectionsConfig(dir, configFile?)` and `deriveSectionsFromRev(dir)` in `lib/sections.ts`, with tests.
16
+
17
+ ## [0.10.0] - 2026-05-20
18
+
19
+ ### Added
20
+ - **Placeholder macros.** Built-in `\tofill{X}` renders as bold orange `[X]` across DOCX, PDF/TeX/Beamer, and HTML — drop the LaTeX-style command anywhere in a section file and the build expands it per format. No more copying a `tofill_filter.lua` + `\providecommand` boilerplate into each project. Users can add their own one-argument macros under `macros:` in `rev.yaml` (color, bold/italic, bracket wrap, prefix/suffix, per-format overrides). See `docs/configuration.md` for the schema.
21
+ - **`lib/macros.ts` + `lib/macro-filter.lua`** registry-style implementation. Built-ins and user macros merge by name; user entries override built-ins. The lua filter loads its macro list from a JSON sidecar via the `DOCREV_MACROS_FILE` env var.
22
+
23
+ ### Fixed
24
+ - **Silent DOCX color drop.** Pandoc 3.x's docx writer does NOT honor `Span` with `style="color: #..."`, so a lua filter returning `pandoc.Span(pandoc.Strong(...), pandoc.Attr("", {}, {style="color: #C2410C"}))` produced zero `<w:color>` runs and the highlight vanished. The new filter emits raw OpenXML `<w:r>` nodes directly (the same pattern as the existing `pptx-color-filter.lua`), which produces real colored runs in Word.
25
+ - **Silent DOCX paragraph drop.** Wrapping a `\tofill{X}` line in raw LaTeX like `\noindent \textit{\small ...}` made pandoc drop the entire paragraph from DOCX output, including the `\tofill` inside. The built-in `\providecommand` + lua-filter mechanism removes the need for any wrapper at all — placeholders survive every format.
26
+ - **Filter path resolution on Windows paths with spaces.** `lib/build.ts` resolved `pptx-color-filter.lua` via `new URL(import.meta.url).pathname`, which returns URL-encoded `%20` for spaces, so `fs.existsSync` silently returned false on paths like `C:\Users\Gilles Colling\...`. Switched both pptx and macro filter resolution to `fileURLToPath`. PPTX color highlighting now actually works under default installs on user-named directories.
27
+ - **Lua filter not shipped to runtime.** `scripts/postbuild.js` left `.lua` files in `lib/` only; the compiled `dist/lib/build.js` looked for them next to itself. PPTX colour filter (and now the macro filter) are now copied to `dist/lib/` during build.
28
+
29
+ ### Notes for `\tofill` migration
30
+ Projects that ship their own `tofill_filter.lua` and `\providecommand{\tofill}{...}` in a custom header keep working — docrev's preamble uses `\providecommand`, so user `\renewcommand` (or pre-existing `\providecommand`) takes priority. To migrate, delete the local lua filter and any markdown wrappers like `\noindent \textit{\small ...}`; docrev's built-in covers all three formats. Override the color or style by adding the macro under `macros:` in `rev.yaml`.
31
+
32
+ ## [0.9.11] - 2026-04-30
33
+
34
+ ### Fixed
35
+ - **Single-section comment placement.** `computeSectionBoundaries` left the last section's `end` at `Number.MAX_SAFE_INTEGER`, which collapsed the proportional-position math in `insertCommentsIntoMarkdown` to ~0. Every comment whose anchor wasn't in the first 200 chars of the markdown stacked at position 0. Now caps the last boundary's `end` at `fullDocText.length`, passed in from sync and verify-anchors.
36
+ - **Re-sync duplicated comments.** `sync --comments-only` re-inserted every comment on each invocation, producing `{>>R1<<}{>>R1<<}{>>R1<<}…` over time. `insertCommentsIntoMarkdown` now scans ±200 chars around the target for an identical `{>>author: text<<}` block and skips insertion when found.
37
+ - **Threading content destruction.** `prepareMarkdownWithMarkers`'s whitespace-consumption loops captured `charBefore` once outside the loop, so a single leading space caused `removeStart` to walk to position 0 and `slice()` to delete every preceding paragraph. Replaced with a one-char check.
38
+ - **Multi-run anchor injection.** Pandoc splits a single anchor across multiple `<w:r>` blocks whenever it applies styling mid-anchor — smart-quote substitution, `*italic*`, `` `code` ``, `**bold**` all trigger this. The single-run scan in `injectCommentsAtMarkers` grabbed the start marker's `<w:t>`, looked for the end marker inside it, found nothing, and silently skipped the comment. New multi-run path splits the start run at the start marker, keeps middle runs verbatim, splits the end run at the end marker, and rebuilds with `commentRangeStart`/`commentRangeEnd` around the styled anchor portions.
39
+ - **Nested-bracket anchors.** `prepareMarkdownWithMarkers` used `\[([^\]]+)\]\{\.mark\}` for the trailing anchor group, so any inner `]` (e.g. `[[0..9]]{.mark}`, `[*italic*]{.mark}`) terminated the match prematurely. Replaced with a manual balanced-bracket walker that handles arbitrary nesting depth and verifies a `{.mark}` suffix.
40
+ - **Orphan-`[` over-stripping.** `stripAnnotations`'s orphan cleanup used `\[(?![^\[\]]*\])`, treating any inner `[` as a barrier and stripping the outer `[` of nested forms. Loosened to `\[(?![^\]\n]*\])`: an `[` is orphan only when no `]` follows before end of line.
41
+
42
+ ### Changed
43
+ - `sync --comments-only` summary distinguishes `placed` / `already present` / `unmatched` instead of subtracting before/after counts. Re-syncs now report "6 already present (skipped to avoid duplication)" instead of misreporting them as fully placed or fully unmatched. New `outStats` channel from `insertCommentsIntoMarkdown`.
44
+
45
+ ## [0.9.10] - 2026-04-30
46
+
47
+ ### Fixed
48
+ - `stripAnnotations` stripped `[anchor]{.mark}` spans even when `keepComments=true`, leaving the dual-build marker generator with no anchor text and collapsing every multi-word anchor to a single fallback word in the rebuilt docx. Now preserves anchor spans that belong to retained `{>>...<<}` comments.
49
+ - Comments authored at the very start of a Word section landed before the markdown file's `# Heading` line and rendered in the previous section. Added `pushPastSectionHeading` so position-0 comments advance to the first body paragraph of the section they were authored in.
50
+ - Empty-anchor comments fell through to proportional placement even when before/after context uniquely identified the position, landing mid-word or splitting unrelated phrases. Context match now runs first; proportional placement is the fallback.
51
+ - When an anchor appeared multiple times in the search window (repeated phrasing, formulaic prose), `insertCommentsIntoMarkdown` always picked the first occurrence. Now picks the occurrence closest to the docx-derived insert position.
52
+
53
+ ## [0.9.7] - 2026-04-29
54
+
55
+ ### Added
56
+ - `rev sync --comments-only` import only Word comments at fuzzy-matched anchors, leaving prose byte-identical. Use when the markdown was revised between sending the docx out for review and receiving it back; applying track changes from a stale draft would clobber newer edits.
57
+ - `rev verify-anchors <docx>` drift report classifying every comment as `clean` / `drift` / `context-only` / `ambiguous` / `unmatched` against the current section markdown. Pair with `--comments-only` to plan placement before sync. Supports `--json` for scripting.
58
+ - `extractHeadings()` in `word-extraction.ts` read heading paragraphs directly from `<w:pStyle>` styles, returning text + level + position in the same coordinate system as comment anchors.
59
+ - Shared `lib/commands/section-boundaries.ts` — single source of truth that maps `sections.yaml` to docx text positions, used by both sync and verify-anchors.
60
+ - Shared `lib/anchor-match.ts` — pure anchor-matching primitives (`findAnchorInText`, `stripCriticMarkup`, `classifyStrategy`) so sync (insertion) and verify-anchors (drift reporting) use the same fallback strategies.
61
+ - New tests: `test/anchor-match.test.js` (11 cases covering each fallback strategy and the quality classifier).
62
+
63
+ ### Fixed
64
+ - **Section detection mistook prose for headings.** The old keyword finder scanned the concatenated body text and would match "results across countries" as the Results heading or skip the real Methods heading because the structured-abstract label `Methods:` lost its colon during text-run concatenation. Replaced with paragraph-style-based heading extraction, so boundaries now reflect actual heading paragraphs. Affects the new commands; the existing sync flow already used pandoc-derived headings and was unaffected.
65
+ - `stripCriticMarkup` regex used `[^<]*` and silently failed on comments containing `<` characters (e.g. `pre-industrial trade (<1825)`). Switched to non-greedy `[\s\S]*?`.
66
+ - `insertCommentsIntoMarkdown` always prepended a leading space when there was no anchor, accumulating multiple spaces when several comments shared a position 0 anchor. Removed the heuristic; comments insert at exact position so prose stays byte-identical except for the inserted blocks.
67
+ - `verify-anchors` crashed with a stack trace when given a non-docx file (e.g. an `.md` path). Now reports a friendly error.
68
+
69
+ ### Changed
70
+ - New flag is `--comments-only` (positive form). The originally proposed `--no-overwrite` was dropped because Commander assigns `--no-X` to `options.x === false` rather than `options.noX === true`, which made the flag silently ignored.
71
+ - `insertCommentsIntoMarkdown` now accepts `wrapAnchor?: boolean` (default `true`). When `false`, comment blocks are inserted next to the anchor without `[anchor]{.mark}` wrapping. `--comments-only` uses this so multiple comments sharing an anchor (e.g. 6 reviewers commenting on the same word) no longer produce nested broken CriticMarkup.
72
+
73
+ ## [0.7.1] - 2025-01-02
74
+
75
+ ### Added
76
+ - Writing Markdown guide in docs (tables, equations, citations, cross-refs)
77
+ - Grid table syntax documentation for merged cells
78
+
79
+ ### Changed
80
+ - README restructured for better scannability (490 → 290 lines)
81
+ - Install section moved up for faster onboarding
82
+ - Added Highlights section with quick feature overview
83
+ - Condensed overlapping sections
84
+
85
+ ## [0.7.0] - 2025-01-02
86
+
87
+ ### Added
88
+ - API rate limiting with exponential backoff for Crossref/DataCite/doi.org APIs
89
+ - Windows support in CI matrix
90
+ - Architecture documentation for contributors (`ARCHITECTURE.md`)
91
+ - Exclusion patterns for cross-reference false positives (e.g., "Table of Contents")
92
+ - Timeout support for PDF extraction (30s default)
93
+
94
+ ### Changed
95
+ - Consolidated YAML dependencies (removed `js-yaml`, using `yaml` package only)
96
+ - Improved annotation false positive detection (code blocks, URLs, LaTeX patterns)
97
+ - Enhanced error messages for Word import and PDF extraction
98
+ - Updated User-Agent strings for API requests
99
+ - Improved README with problem statement and quick example
100
+
101
+ ### Fixed
102
+ - CI lint step now checks all command files separately
103
+ - Windows temp directory paths in tests
104
+
105
+ ## [0.3.2] - 2024-12-29
106
+
107
+ ### Added
108
+ - Full TypeScript type definitions (`types/index.d.ts`)
109
+ - GitHub Actions CI workflow (Node 18/20/22)
110
+ - ESM subpath exports for all library modules
111
+ - CLI integration tests (26 tests)
112
+ - Comprehensive test coverage: 419 tests across 18 modules
113
+
114
+ ### Fixed
115
+ - DOI skip detection: `% no-doi` comments now correctly apply only to the next entry
116
+
117
+ ### Changed
118
+ - Added `engines` field requiring Node.js >=18.0.0
119
+ - Updated README with badges (npm, CI, Node.js, License)
120
+
121
+ ## [0.3.1] - 2024-12-28
122
+
123
+ ### Fixed
124
+ - Equation extraction test assertions
125
+ - Minor bug fixes
126
+
127
+ ## [0.3.0] - 2024-12-27
128
+
129
+ ### Added
130
+ - DOI validation via Crossref and DataCite APIs (`rev doi check`)
131
+ - DOI lookup for missing entries (`rev doi lookup`)
132
+ - DOI fetch and add commands (`rev doi fetch`, `rev doi add`)
133
+ - Citation validation against bibliography (`rev citations`)
134
+ - LaTeX equation extraction (`rev equations list`)
135
+ - Word equation import OMML → LaTeX (`rev equations from-word`)
136
+ - Response letter generation (`rev response`)
137
+ - Journal validation profiles (`rev validate --journal`)
138
+ - Advanced figure/table reference patterns (Figs. 1-3, Fig. 1a-c)
139
+
140
+ ### Changed
141
+ - Improved cross-reference pattern detection
142
+ - Enhanced Word import with better section splitting
143
+
144
+ ## [0.2.1] - 2024-12-26
145
+
146
+ ### Added
147
+ - Table of contents option (`rev build --toc`)
148
+ - CSV export for comments (`rev comments --export`)
149
+ - Anonymize command for blind review (`rev anonymize`)
150
+ - Formatting utilities (tables, boxes, spinners)
151
+
152
+ ## [0.2.0] - 2024-12-25
153
+
154
+ ### Added
155
+ - Integrated build system (`rev build pdf/docx/tex`)
156
+ - Comment reply functionality (`rev reply`)
157
+ - Word document bootstrap (`rev import` creates project from .docx)
158
+ - Section-aware import (`rev sections`)
159
+ - Cross-reference migration (`rev migrate`)
160
+
161
+ ### Changed
162
+ - Renamed project to docrev
163
+ - Published to npm
164
+
165
+ ## [0.1.0] - 2024-12-24
166
+
167
+ ### Added
168
+ - Initial release
169
+ - CriticMarkup annotation parsing
170
+ - Word ↔ Markdown round-trips
171
+ - Interactive review TUI (`rev review`)
172
+ - Comment management (`rev comments`, `rev resolve`)
173
+ - Project templates (`rev new`)