Skip to content

fix(markdown): preserve HTML in fenced code blocks#720

Open
risu729 wants to merge 2 commits into
jdx:mainfrom
risu729:agent/fix-markdown-fenced-code-escaping
Open

fix(markdown): preserve HTML in fenced code blocks#720
risu729 wants to merge 2 commits into
jdx:mainfrom
risu729:agent/fix-markdown-fenced-code-escaping

Conversation

@risu729

@risu729 risu729 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Preserve literal < characters inside conventional fenced code blocks while continuing to HTML-encode them in surrounding Markdown.

The escape filter previously processed each line independently, so it could protect inline and indented code but could not tell when a line belonged to a multiline fenced block.

This change deliberately supports the fence shape generated by replace_code_fences: column-zero fences beginning with exactly three backticks, optional info strings, and closing fences with optional trailing whitespace. It does not attempt to implement the full Markdown specification.

After rebasing, CI also exposed Rust 1.97 Clippy drift in three existing formatting expressions. The follow-up commit accepts exactly those no-behavior autofixes so the render cleanliness assertion remains stable.

Supersedes #386.
Addresses the escaping problem reported in jdx/mise#6949.

Validation

  • mise run render (clean worktree afterward)
  • mise run test
  • mise run lint

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@risu729, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 19 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: c422ee9f-e059-4716-bc55-cd271601b21d

📥 Commits

Reviewing files that changed from the base of the PR and between c48665e and fb0b4dd.

📒 Files selected for processing (3)
  • lib/src/docs/markdown/renderer.rs
  • lib/src/parse.rs
  • lib/src/spec/mount.rs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes HTML escaping inside fenced code blocks by lifting the per-line escape_md logic into a stateful function that tracks open/close fence boundaries. It also includes three Clippy autofix commits (removing redundant & borrows in format! calls) that were needed to keep the CI render-cleanliness assertion passing on Rust 1.97.

  • renderer.rs: The new escape_md function iterates lines while toggling in_fenced_code_block; it recognises column-zero triple-backtick fences (with optional info strings) as openers and backtick-only lines (optional trailing whitespace) as closers, leaving all content between them unescaped. Five targeted unit tests cover the main cases.
  • parse.rs / mount.rs: Mechanical Clippy lints — redundant & in format! arguments removed, no behaviour change.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to a well-tested escape filter, and the Clippy fixes are no-op reformats.

The stateful fence-tracking logic is straightforward and its edge cases (info strings, trailing whitespace on closing fences, indented lines, longer fences, unclosed fences) are each covered by a dedicated unit test. The opening/closing fence heuristics deliberately match only the shape emitted by replace_code_fences, which is documented in comments. The Clippy changes in parse.rs and mount.rs carry no behavioural risk.

No files require special attention.

Important Files Changed

Filename Overview
lib/src/docs/markdown/renderer.rs Extracts escape logic into escape_md function that now tracks fenced-code-block state across lines; adds five unit tests covering the main cases.
lib/src/parse.rs Clippy autofixes: removes redundant borrows in two format! argument positions.
lib/src/spec/mount.rs Clippy autofix: removes redundant borrow in format! argument.

Reviews (3): Last reviewed commit: "chore: apply clippy fixes" | Re-trigger Greptile

Comment thread lib/src/docs/markdown/renderer.rs Outdated
Comment thread lib/src/docs/markdown/renderer.rs
@risu729
risu729 force-pushed the agent/fix-markdown-fenced-code-escaping branch from 1bcee65 to faee02a Compare July 16, 2026 20:30
@risu729
risu729 marked this pull request as ready for review July 16, 2026 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant