Skip to content

fix(parser): link scheme URLs whose fragment is a hash route - #9

Closed
Dananz wants to merge 1 commit into
pingdotgg:feat/t3chat-markdown-parity-v2from
Dananz:fix/autolink-hash-route-fragments
Closed

Dananz wants to merge 1 commit into
pingdotgg:feat/t3chat-markdown-parity-v2from
Dananz:fix/autolink-hash-route-fragments

Conversation

@Dananz

@Dananz Dananz commented Oct 23, 2026 •

Copy link
Copy Markdown

What/Why?

In T3 Code's mobile chat, a bare URL with a hash route isn't tappable. https://studio.example.ts.net:9501/#/chat and https://example.com/#!/inbox render as plain text, while https://example.com/page#section links fine. Single-page apps (dev servers, dashboards behind Tailscale) commonly print URLs like this.

Cause: in md_analyze_permissive_autolink, the fragment segment for scheme links allows only .-+_:%~ beside letters and digits, and the segment scan stops at the first character outside that set. For #/chat that is the very first character, so the fragment is empty, end stays on the #, and the trailing-boundary check then rejects the whole autolink.

Fix: for scheme links (opener->ch == ':'), also allow /!?=&@,; in the fragment. All of these are valid fragment characters in RFC 3986. www. and e-mail autolinks are unchanged. Trailing sentence punctuation still stays outside the link, because the existing ?!.,:* trim runs after the fragment scan.

Testing

  • scripts/test-core-parser.sh passes. I added a line to tests/fixtures/gfm.md and re-recorded the golden dump. The only golden changes are that line: both URLs link in the four variants with permissive autolinks on, stay plain text in extensions-off-gfm, and the final . stays outside the link.
  • I also checked a local build of the parser with See https://example.com/#/chat., **https://example.com/#/chat**, https://example.com/docs#intro, next, http://localhost:3000/x and https://example.com:8080/chat. Each links with the expected bounds.
  • Ran the native iOS example app in the simulator with a sample message, before and after (screenshots below). Not run on Android.

Screenshots

iOS example app (apps/ios-example, Text screen with a sample message), iPhone 17 Pro simulator, iOS 27.0. The same build with and without the one-line change.

Before After

PR Checklist

  • Code compiles and runs on iOS
  • Code compiles and runs on Android
  • Updated documentation/README if applicable
  • Ran example app to verify changes
  • Core parser golden tests are passing

Bare URLs such as https://host:9501/#/chat or https://example.com/#!/inbox
were left as plain text: the permissive autolink fragment scan only accepted
a fragment starting with a letter or digit and had no '/' or '!'.
Allow the RFC 3986 fragment characters /!?=&@,; for scheme links.
@coderabbitai

coderabbitai Bot commented Oct 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b5e00761-e8d4-4cbf-b7c9-04c8d9be947f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@juliusmarminge

Copy link
Copy Markdown
Member

Thanks! This landed on fork/t3-mobile as a cherry-pick (this PR targets the old parity branch), together with a follow-up that keeps a trailing ; out of the link: with ; now allowed in fragments, https://example.com/page#section; then had started linking the ;. It ships in T3 Code's 1.2.0-t3.18 archive (pingdotgg/t3code#32180).

There's no separate upstream PR because md4c master already links these URLs (mity/md4c#454). That reaches enriched-markdown through software-mansion-labs/md4c#7, and we'll drop this patch when it lands.

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.

2 participants