fix(sync): never rewrite inside inline code spans, and repair what it broke - #132
Merged
Conversation
… broke I shipped this in #130 and it corrupted five published pages. RewriteRelative skipped fenced code blocks but not inline code spans, and Go generic call syntax inside one — `AssertPureState[T](t)` — contains the exact ](...) shape a markdown link does. The rewriter resolved (t) as a relative path, so documented code rendered on the live site as: AssertPureState[T](https://github.com/livetemplate/livetemplate/blob/v0.22.0/docs/references/t) in reference/session.md (three places), reference/limitations.md and guides/ephemeral-components.md. My own plan for #130 flagged exactly this risk — "over-eager rewriting mangles code blocks" — and the guard I wrote covered only the fenced case. rewriteOutsideCodeSpans splits a line on backticks and rewrites only the even-indexed (prose) segments. A line with an ODD number of backticks cannot have its spans paired, and the parity is wrong from the stray one onward, so code would land on an "outside" index and be rewritten anyway — those lines are now left entirely alone. That costs a genuine link on a malformed line staying as upstream wrote it, which is recoverable; mangling documented code is not. The first version of that comment claimed the unbalanced case already erred toward safety. It did not — the test written to assert it failed, which is why the count check exists. Three regression tests: an inline span alongside a real link, multiple spans on one line, and the unbalanced case. Also re-syncs at v0.23.0, which repairs all five pages and brings down the release's own content — the Async/Pending guide rewrite, the Validate reference and the lvt-el overlay section. Verified: zero corrupted spans remain, zero relative links in content, tinkerdown validate 98/98. Supersedes the automated sync PR #131, which carries the same v0.23.0 content but through the unfixed rewriter. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QzC2djPjPHkNJgPzFpMX7v
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This fixes a bug I introduced in #130 that corrupted five published pages. Supersedes #131.
What broke
RewriteRelativeskipped fenced code blocks but not inline code spans. Go generic call syntax inside one —`AssertPureState[T](t)`— contains the exact](...)shape a markdown link does, so the rewriter resolved(t)as a relative path. Live on the site right now:Five places:
reference/session.md(×3),reference/limitations.md,guides/ephemeral-components.md.The #130 plan flagged this exact risk — "over-eager rewriting mangles code blocks" — and the guard I wrote covered only the fenced case. The inline case is the one that actually occurs in this corpus.
The fix
rewriteOutsideCodeSpanssplits a line on backticks and rewrites only even-indexed (prose) segments.A line with an odd number of backticks cannot have its spans paired, and the parity is wrong from the stray one onward — code would land on an "outside" index and be rewritten anyway. Those lines are now left entirely alone. That costs a genuine link on a malformed line staying as upstream wrote it, which is recoverable; mangling documented code is not.
Worth stating plainly: my first version of that comment claimed the unbalanced case already erred toward safety. It did not — the test I wrote to assert it failed, which is why the explicit count check exists rather than relying on parity.
Regression tests
Three, all of which fail against the previous implementation:
19
RewriteRelative/LinkRewritertests pass.Also carries the v0.23.0 sync
Re-syncing at
v0.23.0is what repairs the five pages, and it brings the release's own content with it — the Async/{{.lvt.Pending}}guide rewrite, theValidatereference section, and thelvt-eloverlay documentation from livetemplate#530.That makes this a strict superset of #131, which carries the same content through the unfixed rewriter. Close #131 in favour of this.
Verification
content/(the three the diff shows are fixture strings insync_test.go)source_refnowv0.23.0across mirrored pagestinkerdown validate content/: 98/98go build ./...,go vet ./cmd/...clean🤖 Generated with Claude Code
https://claude.ai/code/session_01QzC2djPjPHkNJgPzFpMX7v