Changed code blocks lose their fence and get mangled (pandiff 0.8.0 fails its own test/diff.md)
Summary
When a code block differs between the two inputs, the rendered output is corrupted rather than
merely ugly: the fence is dropped, the block round-trips back as a paragraph, lines are
reflowed together, and Pandoc's smart punctuation rewrites the contents — so --config becomes
–config and "world." becomes “world.”. Copy-pasting a command out of a pandiff diff can
silently give you the wrong command.
This is a regression: the committed golden file test/diff.md still describes the correct
behaviour, so pandiff 0.8.0 fails its own test suite.
Reproducing with the repo's own fixtures
$ pandiff test/old.md test/new.md | sed -n '14,16p'
print(“Hello”) -print(“world.”) +print(“world!”) print(“Lorem ipsum
dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt”)
Expected, per test/diff.md lines 14-19:
``` diff
print("Hello")
-print("world.")
+print("world!")
print("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt")
Note the straight quotes in the golden vs. the curly quotes in the actual output.
Environment: pandiff 0.8.0 (npm), pandoc 3.10.2, node 24, macOS.
## Cause 1 — `pre.textContent` destroys the `<code>` child
`src/index.ts:145`:
```ts
pre.className = 'diff';
pre.textContent = diffu(pre.textContent || '', post.textContent || '');
Assigning to textContent replaces every child of the <pre>, including its <code>.
Pandoc's HTML reader only treats <pre> as a code block when it wraps a <code>; a bare
<pre> is read as a paragraph. That single character of markup is the difference:
$ printf '<pre class="diff">-a --config\n+b --config</pre>' | pandoc -f html -t markdown
-a --config +b --config # paragraph: reflowed, and -- -> en dash
$ printf '<pre class="diff"><code>-a --config\n+b --config</code></pre>' | pandoc -f html -t markdown
``` diff
-a --config
+b --config
## Cause 2 — highlighted blocks lose their line breaks
Separately, `convert()` builds the intermediate HTML with Pandoc's default syntax highlighting
enabled. Pandoc then emits one `<span id="cb1-N">` per line, with the newlines as text nodes
*between* the spans. `node-htmldiff` does not preserve those, so a changed block that has a
language tag collapses onto a single line even once cause 1 is fixed. Plain ``` blocks are
unaffected, which is why `test/old.md` (an indented block) only exposes cause 1.
## Proposed fix
Two small changes, both in `src/index.ts`:
1. Put the diff text in a `<code>` child instead of overwriting `pre.textContent`.
2. Pass `--no-highlight` to the **intermediate** conversion only. The final render is a separate
Pandoc call and keeps highlighting, so ``` diff output is still colourised. I used
`--no-highlight` rather than the modern `--syntax-highlighting=none` so the change still works
on older Pandoc, but note that Pandoc 3.10 deprecates it and warns; you may prefer the new
spelling, or to select it by version.
With both applied, `pandiff test/old.md test/new.md` matches `test/diff.md` apart from the image
paths, which the test harness supplies via its `extract-media` / `resource-path` options and the
bare CLI invocation does not.
## On the test suite
I could not use `npm test` as a gate: in my environment it reports 0 passing / 27 failing on
**unmodified** `master` as well (ENOENT on `test/*.md` and timeouts), identically before and after
the change, so the failures look environmental rather than related. The evidence above is the
direct `test/diff.md` comparison, which only the patched build matches. Your CI/devcontainer may
well behave differently.
Changed code blocks lose their fence and get mangled (pandiff 0.8.0 fails its own
test/diff.md)Summary
When a code block differs between the two inputs, the rendered output is corrupted rather than
merely ugly: the fence is dropped, the block round-trips back as a paragraph, lines are
reflowed together, and Pandoc's smart punctuation rewrites the contents — so
--configbecomes–configand"world."becomes“world.”. Copy-pasting a command out of a pandiff diff cansilently give you the wrong command.
This is a regression: the committed golden file
test/diff.mdstill describes the correctbehaviour, so pandiff 0.8.0 fails its own test suite.
Reproducing with the repo's own fixtures
Expected, per
test/diff.mdlines 14-19:Assigning to
textContentreplaces every child of the<pre>, including its<code>.Pandoc's HTML reader only treats
<pre>as a code block when it wraps a<code>; a bare<pre>is read as a paragraph. That single character of markup is the difference: