Skip to content

fix: invalid inline-span attribute block stays literal#237

Merged
dereuromark merged 1 commit into
masterfrom
fix/invalid-span-attr-literal
Jun 9, 2026
Merged

fix: invalid inline-span attribute block stays literal#237
dereuromark merged 1 commit into
masterfrom
fix/invalid-span-attr-literal

Conversation

@dereuromark

Copy link
Copy Markdown
Contributor

What

A bracketed run directly abutting an attribute block always materialized a <span> and then silently dropped any block that was not valid attribute syntax. The payload vanished:

input before after
[x]{???} <span>x</span> [x]{???}
[*x*]{???} <span><strong>x</strong></span> [<strong>x</strong>]{???}
[x]{.a}{???} <span class="a">x</span> <span class="a">x</span>{???}

Fix

A new isValidAttrPayload() gates both span formation and applyConsecutiveAttributes(): a {...} block forms or extends attributes only when it yields an attribute, or is empty/whitespace/comment-only. A block carrying unrecognized content is not an attribute block, so the brackets and the block render literally (the bracket text is still inline-parsed). The change applies to spans, links, and code spans through the shared helper.

Empty and whitespace-only blocks ([x]{}, [x]{ }) still form a bare <span>, kept so DefaultAttributesExtension can target it. Note djot keeps {=...=} highlight, so [x]{=y=} now correctly renders [x]<mark>y</mark> (the highlight was previously swallowed as a span attribute).

Backport of markup-carve/carve-php#43, adapted to djot (which retains {=...=} highlight and the empty-block span).

Known limitation

An exotic [x]{.a}{???}{.b} leaves the trailing {.b} to attach to the now-literal {???} via djot's standalone-attribute feature (text{.b} -> <span class="b">text</span>), yielding <span class="a">x</span><span class="b">{???}</span> rather than fully-literal {???}{.b}. Suppressing that would mean conditionally disabling a separate, legitimate djot feature; out of scope for this fix.

Tests

Added cases for the invalid-block-literal behavior and the preserved empty-block span. Full suite and official corpus green.

A bracketed run abutting an attribute block always materialized a
<span> and then silently dropped any block that was not valid attribute
syntax. `[x]{???}` rendered as `<span>x</span>` with the `{???}` payload
lost.

Gate span formation (and consecutive attribute application) on a new
isValidAttrPayload(): a block forms/extends attributes only when it
yields an attribute or is empty/whitespace/comment-only. An invalid
block leaves the brackets and the block literal, with the bracket text
still inline-parsed, e.g. `[*x*]{???}` -> `[<strong>x</strong>]{???}`.

Empty/whitespace blocks ([x]{} / [x]{ }) still form a bare <span> so a
default-attribute extension can target it. Applies to spans, links, and
code spans via the shared applyConsecutiveAttributes().
@codecov

codecov Bot commented Jun 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 93.75000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 91.89%. Comparing base (32c0d50) to head (e3a8cbe).
⚠️ Report is 3 commits behind head on master.

Files with missing lines Patch % Lines
src/Parser/InlineParser.php 93.75% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master     #237      +/-   ##
============================================
- Coverage     91.89%   91.89%   -0.01%     
- Complexity     3523     3527       +4     
============================================
  Files           106      106              
  Lines          9958     9970      +12     
============================================
+ Hits           9151     9162      +11     
- Misses          807      808       +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dereuromark dereuromark merged commit 720e301 into master Jun 9, 2026
6 checks passed
@dereuromark dereuromark deleted the fix/invalid-span-attr-literal branch June 9, 2026 14:25
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