Skip to content

fix: keep line ranges and titles out of the code block language - #1306

Open
raz-iacob wants to merge 1 commit into
dev-null-sh:productionfrom
raz-iacob:fix/code-block-fence-language
Open

raz-iacob wants to merge 1 commit into
dev-null-sh:productionfrom
raz-iacob:fix/code-block-fence-language

Conversation

@raz-iacob

@raz-iacob raz-iacob commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #1210. Some opening fences put the wrong thing in the code block's language, or lost their title:

  • A fence with no language that starts with a title, like ``` title="routes/web.php", used title="routes/web.php" as its label and had no filename.
  • A line range written right after the language, like ```js{2} (the VitePress and Gatsby style), kept js{2} as the language, so the block wasn't highlighted and the label showed js{2}.
  • A single-quoted title, like ```php title='app/Models/User.php', was ignored.

Now the first block shows routes/web.php, also in quoted commits and notifications, the second is highlighted as js, and the third shows app/Models/User.php.

Changes

  • CodeSpans reads the whole info string with the same tokens as before (key="value" pairs, {…} ranges, bare words), plus key='value' pairs, and { now ends a bare word. The language is the first token only when it's a bare word. lib/code.ts mirrors it, and both sides are tested with the same cases.
  • CodeBlock keeps its header for a block with a filename but no language in excerpts, where there's no copy button.

Validation

Local, on f6cd14b9 (based on a4670abe):

  • composer test:lint and composer test:types pass, type coverage is 100%.
  • composer test:unit passes: Pest 4,968 tests at 100% coverage, and every Node and .tsx unit test.
  • The new feature cases fail on production. The rows for an apostrophe inside double quotes and for an empty or unclosed single-quoted title are guards and pass on both.
  • Server and client parse 30,000 generated fences identically, including glued ranges, attribute-first fences, single and mixed quotes, NBSP and multibyte text.
  • Layout shift is 0 on first load and on client navigation from the log, at every viewport and theme below.

Visual evidence

Guest view of the same demo commit in Chrome (2x), production (a4670abe) vs this branch.

Before After
1440×900 light
1440×900 dark
390×844 light
390×844 dark

1366×650: light before · light after · dark before · dark after

Quoted excerpt of a block with only a title:

Before After
1440×900 light
390×844 dark

Its other viewports and themes are on the assets branch.

Device verification

No mobile interaction changes, only a label and highlighting. 390×844 was checked with viewport emulation in Chrome, not on hardware or a simulator.

Independent review

A separate, read-only reviewer agent (given the task, #1210, the repo guidelines, the diff and these captures) returned CODE: PASS and VISUAL: PASS for a4670abe..f6cd14b9, media b2c285a9, after parity runs of 120,134 fuzzed and real-world fences (c++, f#, js:line-numbers, ts twoslash, mixed quotes and more) with 0 mismatches. It confirmed the feature tests fail on production and the guard rows pass on both. Nested fences (#1227) were checked by reading the code, since only the opening line is parsed.

Limitations

  • Not checked in Safari or Firefox.
  • Quarto-style fences like ```{r} used to show {r} as the label and now show none. Neither was highlighted.
  • The composer preview and notifications weren't captured. The preview uses the client parser, which the shared cases and the parity run cover, and notifications render the same excerpt as quotes.

Summary by CodeRabbit

  • Bug Fixes
    • Improved code-fence parsing for language labels and filename attributes, including single- and double-quoted values and compact attribute formats.
    • Filenames now appear in code-block headers even when no language label is present.
    • Corrected filename display in both commit views and static excerpts, avoiding an unintended language label.
    • Improved handling of line ranges and unusual or incomplete attribute values.

@coderabbitai

coderabbitai Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c65d4cb9-2adb-4f35-b70c-3fe2de50128f
Commits

Reviewing files that changed from the base of the PR and between a4670ab and f6cd14b.

Files selected for processing: 5
  • app/Services/CodeSpans.php
  • resources/js/components/code-block.tsx
  • resources/js/lib/code.ts
  • tests/Unit/ComposerPreview.test.tsx
  • tests/Unit/Services/CodeSpansTest.php

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.

Walkthrough

Code fence parsing now supports quoted attributes and selects language and filename values in both PHP and JavaScript. Code block headers render when a filename is present, including when no language is set.

Changes: Fence metadata and filename labels

Layer / File(s) Summary
Parse fence languages and attributes
app/Services/CodeSpans.php, resources/js/lib/code.ts, tests/Unit/Services/CodeSpansTest.php, tests/Unit/ComposerPreview.test.tsx
Both parsers tokenize fence info strings and support single- and double-quoted attributes. The tests cover language and filename selection, including empty and unterminated values.
Render filename-only headers
resources/js/components/code-block.tsx, tests/Unit/ComposerPreview.test.tsx
The header renders when a filename is present, even without a language. Tests check filename labels in commit and static excerpt rendering.

Priority: Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: mnapoli, xheaven

Merge Risk: Minimal · up to f6cd1

No merge-blocking issue was identified in the fence-label changes.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: preventing line ranges and titles from being treated as the code block language.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 3 functions across 5 files.

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

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