Fix backslash-ended code span wrapping (#349) - #351
Conversation
Treat matching backtick runs inside code span content as closing fences even when preceded by a backslash. This follows CommonMark and prevents Windows paths ending in `\` from being parsed as open spans. Guard inline-code tail carry so moving a span onto a continuation line cannot exceed the configured wrap width. Add regression and property coverage for backslash-terminated inline code in wrapped bullets.
Move tokenizer and scanning unit tests out of the production modules so the touched source files stay below the repository line-count target. Keep the test coverage unchanged while making each moved test focused.
|
Note Reviews pausedUse the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughSimplify inline-code fence detection to match closing backtick runs by delimiter length only, and make whitespace-only inline-line merging width-aware so inline-code tails are not carried onto continuation lines when that would exceed the configured width. Reorganise and extend tests and fixtures to validate these behaviours. ChangesBacktick fence simplification and width-aware wrapping
Sequence Diagram(s)sequenceDiagram
participant InlineWrapper as Inline Wrapper
participant MergeWhitespace as merge_whitespace_only_lines
participant WidthCheck as Width-fit checker
participant NextContent as Next content line
InlineWrapper->>MergeWhitespace: lines, width
MergeWhitespace->>WidthCheck: "can code tail + space fit on next content line?"
WidthCheck->>NextContent: compute rendered width of nextContent + tail + space
NextContent-->>WidthCheck: width status
alt Fits within width
WidthCheck-->>MergeWhitespace: allow carry
else Exceeds width
WidthCheck-->>MergeWhitespace: prevent carry
end
MergeWhitespace-->>InlineWrapper: merged lines
Possibly related PRs
🚥 Pre-merge checks | ✅ 17 | ❌ 3❌ Failed checks (3 warnings)
✅ Passed checks (17 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 📋 Issue PlannerBuilt with CodeRabbit's Coding Plans for faster development and fewer bugs. View plan used: ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Reviewer's GuideAdjusts inline code span tokenization to treat backslashes inside spans as literal when detecting closing fences, and adds a width-aware guard around inline-code tail carrying during whitespace-merge postprocessing, plus test refactors and new regression/property tests for backslash-terminated code spans and wrapping. Flow diagram for updated inline code span closing fence detectionflowchart TD
A[segment_inline] --> B[handle_backtick_fence]
B --> C[position_after_close]
C -->|closing fence found| D[closing_fence_end]
C -->|no closing fence| E[collect_range returns opener only]
D --> F[next_token]
F --> G[is_closed_inline_code_span]
G --> H[scan_code_suffix_end]
H --> I[Token::Code]
C --> J[reject closers in longer backtick runs]
Flow diagram for width-aware inline-code tail carry in postprocessingflowchart TD
A[wrap_preserving_code] --> B[wrap_first_fit]
B --> C[merge_whitespace_only_lines]
C --> D{line is single space and next_starts_atomic is false}
D -->|yes| E[inline_code_tail_carry_fits]
E -->|fits| F[carry_previous_inline_code_tail]
F --> G[rebalance_atomic_tails]
E -->|does not fit| G
D -->|no| G
File-Level Changes
Assessment against linked issues
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/wrap/tokenize/mod.rs`:
- Around line 219-230: Replace the current naive finder that closes on the first
fence occurrence in the tokenize logic with the same checking used by the
scanner: call position_after_close on rest[delim_len..] and, if Some, compute
raw_end = delim_len + relative_end and candidate = raw_end - delim_len, then
proceed to compute token/suffix_end (using is_closed_inline_code_span and
scan_code_suffix_end) and return Token::Code as before; also apply the identical
change in handle_backtick_fence so both tokenizers use position_after_close and
therefore reject closers embedded in longer backtick runs.
In `@tests/wrap_properties.rs`:
- Around line 119-124: The test currently uses the literal 80 in calls to
wrap_text and in the width assertion; replace those literals with the WRAP_COLS
constant so the property uses the configured wrap width. Update the two
wrap_text(&input, 80) and wrap_text(&output, 80) calls to wrap_text(&input,
WRAP_COLS) and wrap_text(&output, WRAP_COLS), and change the
UnicodeWidthStr::width check to compare against WRAP_COLS instead of 80; ensure
WRAP_COLS is imported into the test module so wrap_text, output, and
UnicodeWidthStr::width use the single source of truth.
In `@tests/wrap/lists.rs`:
- Around line 161-165: Replace the hard-coded 80 literals with the test-wide
WRAP_COLS constant: change both wrap_text(&input, 80) and wrap_text(&output, 80)
to use WRAP_COLS, and ensure WRAP_COLS is imported into the test module (so the
test uses the repository-wide wrap width). Keep the call to
assert_wrapped_list_item(&output[2..4], "- ", 2) unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: c3260cd1-9585-4e25-abe3-aff33fde27ec
📒 Files selected for processing (13)
src/wrap/inline.rssrc/wrap/inline/postprocess.rssrc/wrap/inline/postprocess_tests.rssrc/wrap/tokenize/mod.rssrc/wrap/tokenize/mod_tests.rssrc/wrap/tokenize/parsing.rssrc/wrap/tokenize/scanning.rssrc/wrap/tokenize/scanning_tests.rstests/data/bullet_backslash_code_span_expected.txttests/data/bullet_backslash_code_span_input.txttests/wrap/lists.rstests/wrap_properties.rstests/wrap_unit/code_spans.rs
Route public and internal inline-code token parsing through `position_after_close` so both paths reject closing fences embedded in longer backtick runs. Use `WRAP_COLS` in the issue #349 regression and property tests so the coverage follows the repository wrap-width constant.
Document the internal tokenizer and inline post-processing contracts that changed for issue #349. Add snapshot coverage for the backslash-terminated bullet regression and trace the width decision that prevents inline-code tail carries from exceeding the configured wrap width.
|
@coderabbitai Have the following failed checks now been resolved? If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures. Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. ❌ Failed checks (3 warnings)
|
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
echo "=== docs/developers-guide.md: relevant sections ==="
grep -n -i "merge_whitespace_only_lines\|handle_backtick_fence\|backslash\|escape\|width" docs/developers-guide.md | head -60
echo ""
echo "=== tests/wrap/lists.rs: test_wrap_bullet_backslash ==="
grep -n -A 30 "test_wrap_bullet_backslash" tests/wrap/lists.rs
echo ""
echo "=== src/wrap/inline/postprocess.rs: inline_code_tail_carry_fits ==="
grep -n -A 20 "inline_code_tail_carry_fits\|trace\|log" src/wrap/inline/postprocess.rs
echo ""
echo "=== src/wrap/continuation.rs: trace logging pattern for reference ==="
grep -n "trace\!" src/wrap/continuation.rs | head -20Length of output: 10578
No further work is required for these items. 🧠 Learnings used |
|
@coderabbitai pause |
✅ Action performedReviews paused. |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@sourcery-ai review |
Add focused coverage for backslash-terminated inline code spans through `segment_inline`, and assert that wrapped output keeps those spans closed and contiguous. Cover the exact-width boundary for inline-code tail carries so the width guard cannot regress into an off-by-one rejection.
|
@coderabbitai Have the following now been resolved? Annul any requirements that violate the en-GB-oxendict spelling (-ize / -yse / -our) conventions (for example a request to replace "normalize" with "normalise" or "artefact" with "artifact"), or where the requirement unnecessarily increases cyclomatic complexity. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
echo "=== tests/wrap_unit/code_spans.rs ==="
cat tests/wrap_unit/code_spans.rs
echo ""
echo "=== src/wrap/inline/postprocess_tests.rs ==="
cat src/wrap/inline/postprocess_tests.rs
echo ""
echo "=== tests/wrap_properties.rs ==="
cat tests/wrap_properties.rs
echo ""
echo "=== tests/wrap/lists.rs ==="
cat tests/wrap/lists.rsLength of output: 41818 🏁 Script executed: #!/bin/bash
echo "=== segment_inline visibility in tokenize/mod.rs ==="
grep -n "pub.*segment_inline\|fn segment_inline" src/wrap/tokenize/mod.rs
echo ""
echo "=== wrap/mod.rs re-exports ==="
grep -n "segment_inline\|pub use" src/wrap/mod.rs 2>/dev/null || grep -rn "segment_inline\|pub use" src/wrap.rs 2>/dev/null
echo ""
echo "=== lib.rs re-exports ==="
grep -n "segment_inline\|pub use.*wrap" src/lib.rsLength of output: 1014 🏁 Script executed: #!/bin/bash
echo "=== src/wrap/tokenize/mod_tests.rs: backslash / segment_inline coverage ==="
grep -n "backslash\|segment_inline\|C:\\\\\\|bin\\\\" src/wrap/tokenize/mod_tests.rs
echo ""
echo "=== full mod_tests.rs ==="
cat src/wrap/tokenize/mod_tests.rsLength of output: 4311
|
Summary
This branch fixes issue #349 by treating closing backtick fences inside inline
code spans as literal CommonMark closers even when the preceding code content
ends with a backslash. This prevents Windows-style paths such as
C:\Program Files\...\bin\from being misclassified as open spans and thenrewrapped into MD013-length continuation lines.
It also adds a defensive width guard around inline-code tail carry handling so
that moving an inline-code fragment onto a following content line cannot exceed
the configured wrap width.
Closes #349.
Review walkthrough
Validation
make check-fmt: passedmake lint: passedmake test: passedcoderabbit review --agent: passed withfindings: 0Notes
The second commit only moves tokenizer unit tests into sibling test modules so
that the touched tokenizer source files remain below the repository line-count
target. It does not change production behaviour.
Summary by Sourcery
Fix inline code span tokenization and wrapping so backslash-terminated code spans are parsed and wrapped correctly while preserving configured line width.
Bug Fixes:
Enhancements:
Documentation:
Tests: