Skip to content

text: Keep inline HTML mark highlights in Markdown - #3425

Merged
madcodelife merged 4 commits into
longbridge:mainfrom
henrikogaard:cursor/inline-html-mark-0bc0
Oct 10, 2026
Merged

madcodelife merged 4 commits into
longbridge:mainfrom
henrikogaard:cursor/inline-html-mark-0bc0

Conversation

@henrikogaard

@henrikogaard henrikogaard commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Closes #3423

Description

Inline <mark> tags inside a Markdown paragraph were dropped. CommonMark hands each raw tag over as its own HTML sibling, and inline_html_mark only knew strong/b/em/i/u/s/del/strike, so <mark> never paired and the text rendered without a highlight. color and style="background-color: …" were ignored.

This pairs <mark> like the other inline formatting tags, passes the opening tag's attributes through, and reuses the block HTML color rules (color first, then style="background-color", then the default #fef08a).

Screenshot

From Rísta, which uses TextView markdown preview. The left pane is the source editor; the right pane is the preview. The note has plain ==highlighted== (emitted as bare <mark>) and six colored highlights (emitted as <mark color="#rrggbbaa">).

Before After
Unpatched gpui-kit 0.7, dark theme This branch, dark theme

After, light theme:

This branch, light theme

How to Test

Unit tests:

cargo test -p gpui-base --lib -- text::format::markdown text::format::html
cargo fmt -p gpui-base -- --check
cargo clippy -p gpui-base --lib --tests -- --deny warnings

All three passed on this branch (73 format tests).

Rísta check: open a note with ==highlighted== and colored ==🔴text== highlights. The preview should show the default yellow mark and the colored washes, in both dark and light themes.

Checklist

  • I have read the CONTRIBUTING document and followed the guidelines.
  • Reviewed the changes in this PR and confirmed AI generated code (If any) is accurate.
  • Passed cargo run for story tests related to the changes.
  • Tested macOS, Windows and Linux platforms performance (if the change is platform-specific)

cursoragent and others added 2 commits October 9, 2026 18:13
Pair <mark> the same way as other inline HTML tags and reuse the
block-path color rules so default, color, and style highlights render.

Co-authored-by: Henrik Øgård <henrikogaard@users.noreply.github.com>
Co-authored-by: Henrik Øgård <henrikogaard@users.noreply.github.com>
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-09T18:49:49.922047Z d04acc2 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d04acc26c4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/base/src/text/format/html.rs Outdated
if let (Some(key), Some(value)) = (parts.next(), parts.next())
&& key.trim().eq_ignore_ascii_case("background-color")
{
return parse_mark_color(value.trim());

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the last background-color declaration

When an existing HTML <mark> has repeated declarations, such as style="background-color:red;background-color:blue", this early return selects red. Before this refactor, style_attrs inserted every declaration into a HashMap, so the later declaration overwrote the earlier one, matching inline-style cascade; this therefore changes existing block-HTML rendering, and an invalid first declaration also prevents a later valid fallback. Scan the full declaration list and retain the last applicable color instead.

AGENTS.md reference: AGENTS.md:L124-L125

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — the old HashMap path kept the last background-color string and then parsed it. style_background_color now scans the full list the same way, so a later valid declaration wins and an invalid last value still fails instead of falling back to an earlier one.

Scan the full style list and parse the last background-color, matching
the old HashMap cascade so an earlier declaration no longer wins.

Co-authored-by: Henrik Øgård <henrikogaard@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@madcodelife

Copy link
Copy Markdown
Member

Thanks for the PR!

I pushed a small follow-up commit:

  1. Attribute names: inline_html_attr now reads a key up to whitespace, =, / or >. Before, a key like data_id or xml:lang stopped the scan, so in <mark data_id="1" color="blue"> the color was never reached and the highlight fell back to yellow. The test now covers this case.
  2. One style parser: style_attrs now takes the CSS string, and both the block and inline paths go through it, so style_background_color is gone. The last background-color still wins, the same as before this PR, so the dedicated test for it was dropped too.
  3. Test scope: inline_html_mark_applies_highlight_colors now only asserts the <mark> runs. The <strong>/<em>/<u>/<del> checks are already covered by the existing inline tag tests.

@madcodelife
madcodelife enabled auto-merge (squash) October 10, 2026 09:59
@madcodelife
madcodelife merged commit ed27c62 into longbridge:main Oct 10, 2026
16 checks passed
@huacnlee huacnlee mentioned this pull request Oct 12, 2026
huacnlee added a commit that referenced this pull request Oct 12, 2026
## Description

Prepare v0.7.2 on `stable` from the PRs merged into `main` since v0.7.1,
leaving out every change that breaks existing consumers. `stable`
already carries #3371 and #3373; this adds the remaining compatible PRs
with `git cherry-pick -x` and bumps the workspace to 0.7.2.

### Included

- kit: Add optional gpui-fast backend (#3375)
- tooltip: Make show delay and grace period configurable with
`TooltipDefaults` (#3376)
- docs: Explain recovering focus when the focused element stops
rendering (#3386)
- diff: Add readonly patch viewer (#3378)
- kit: Use one Windows manifest with GPUI Fast (#3380)
- test: Make Progress and TitleBar findable in UI tests (#3383)
- input: Preserve selection, focus ring and context menu actions (#3382)
- diff: Add a Git history example and complete review APIs (#3388)
- text_view: Ignore gestures that stay inside one block plugin (#3390)
- text_view: Round the first and last table rows to the frame radius
(#3309)
- menu: Open a context menu with a long press on touch (#3393)
- text_view: Keep narrow table columns on one line (#3399)
- settings: Keep focus rings inside the list viewport (#3394)
- scrollable_mask: Keep rounded scroll-table corners clean at any scroll
offset (#3400)
- dialog: Add margin_top to AlertDialog (#3404)
- input: Add InputState::add_selection for programmatic multi-cursor
(#3403)
- text_selection: Stop writing selection state on every frame (#3407)
- table: Make the sort icon a labelled button (#3396)
- table: Report visible row ranges of one row or none (#3397)
- dialog: Support configurable entrance animations (#3405)
- docs: Explain the open_dialog builder and footer contracts (#3406)
- dock: Hand the focus to the tab that replaces a closed one (#3409)
- dropdown_button: Add A11y names for the menu trigger (#3410)
- text, resizable: Stop notifying state that did not change (#3418)
- editor: Add on-demand completion commands (#3411)
- table: Clear a right-clicked cell's outline on the next click (#3413)
- tab: Scroll a clicked tab into view with the next one peeking (#3419)
- table: Allow a header row height separate from the body (#3420)
- menu: Focus a context menu before its first frame (#3422)
- text: Preserve logical selection across presentation changes (#3421)
- text: Keep inline HTML mark highlights in Markdown (#3425)
- input: Anchor completion/code-action popups to the current frame's
caret (#3412)
- input: Run custom context menu builders after releasing the input
(#3433)
- input: Keep auto-grow rows fitted when the limits change (#3430)
- text: Paint TextView selection under the glyphs (#3439)

Already on `stable`: #3371, #3373.

### Excluded (Breaking Changes)

- #3432 motion: `Easing::sample` now returns values outside `[0, 1]` for
overshooting curves.
- #3415 tab: new `TabVariant::Folder` breaks exhaustive matches.
- #3402 kit: pointer helpers now keep held modifiers; nested
context-menu behavior changes in tests.
- #3384 test: `TestWindowExt` gains required methods.
- #3302 resizable: `ResizeHandle::on_drag` takes `&T` instead of
`Rc<T>`.
- #3389, #3395, #3398 webview: wrapper API changes, `gpui-wry` →
`gpui-webview` rename, and the GPUI Fast requirement.

#3411, #3405 and #3396 have a Breaking Changes section that reads "None"
and are included. #3376 only deprecates `TooltipRequest::placement`, and
#3397 / #3382 change behavior compatibly, so they are included too.

### Adaptations

- `crates/kit/tests/collections.rs` and `crates/kit/tests/rendering.rs`:
conflict resolutions drop the tests that belong to #3402 and keep each
backported PR's own test.
- `test: Keep backported tests on the v0.7.1 test API`: the menu and
completion tests from #3422 and #3412 used `find_all` and
`pointer_down`/`pointer_up` from #3384/#3402. They now query
`gpui_kit::base::test_support::snapshots` and dispatch mouse events
directly.
- `kit: Prepare v0.7.2`: workspace version bump; `Cargo.lock` only
updates workspace members.

## Public API

No new public API beyond what the included PRs add; each lists its items
in its own `## Public API` section (notably #3375, #3376, #3378, #3388,
#3403, #3404, #3405, #3411, #3420).

## How to Test

- `cargo clippy --workspace --all-targets -- --deny warnings` passes on
Linux.
- `cargo test -p gpui-kit --features "test-support component assets"
--test collections --test menu --test input` passes on Linux.
- The macOS-only `rendering` test (#3439 adds one case, the count is
updated to 11) was not run.

AI-assisted: the backport, conflict resolution and test adaptations were
done with Claude Code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Floyd Wang <codelife721@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: Gustave <gustavel@gmail.com>
Co-authored-by: luren <84951845+lurenjia534@users.noreply.github.com>
Co-authored-by: Ylin <ylinwind@gmail.com>
Co-authored-by: ihavecoke <mixboip@gmail.com>
Co-authored-by: Lorenzo <150276837+Bombatomica64@users.noreply.github.com>
Co-authored-by: MR. XIE <113512030+xxww0098@users.noreply.github.com>
Co-authored-by: xxww0098 <shefkie1957@gmail.com>
Co-authored-by: Sola 🌙🤖 <266175376+sola-ryu@users.noreply.github.com>
Co-authored-by: Sola <sola-ryu@users.noreply.github.com>
Co-authored-by: Andy Hsu <i@nn.ci>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Floyd Wang <gassnake999@gmail.com>
Co-authored-by: Daiki Tomioka <20753105+TomiXRM@users.noreply.github.com>
Co-authored-by: Henrik Øgård <henrik@ogard.no>
Co-authored-by: Henrik Øgård <henrikogaard@users.noreply.github.com>
Co-authored-by: Endless <endless@longbridge.com>
Co-authored-by: John Costa <costajohnt@gmail.com>
Co-authored-by: Alexander <87220898+sneffets@users.noreply.github.com>
Co-authored-by: Cesar Talén <154442565+cesartalen@users.noreply.github.com>
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.

TextView markdown: inline <mark> tags are dropped (no highlight, color ignored)

3 participants