镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

chore(mobile): upgrade gpt_markdown to 1.3.4 and migrate to new APIs - #8184

Open
saminsohag wants to merge 5 commits into
block:mainfrom
Infinitix-LLC:chore/mobile-gpt-markdown-1.3.4
Open

saminsohag wants to merge 5 commits into
block:mainfrom
Infinitix-LLC:chore/mobile-gpt-markdown-1.3.4

Conversation

@saminsohag

@saminsohag saminsohag commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Upgrades mobile's gpt_markdown from 1.2.1 to 1.3.4 and moves off the APIs that 1.3 deprecates, so mobile renders through the package's default parser instead of the legacy regex pipeline.

API migration

  • @mention, #channel and custom emoji move from InlineMd + inlineComponents to InlinePattern + inlinePatterns. Passing inlineComponents forced the whole widget onto the legacy parser.
  • InlinePattern's default scopes already exclude link labels, so the explicit allScopesExceptLinkLabel overrides from fix(mobile): keep token labels visible in authored Markdown links #7545 are no longer needed; the [#channel](url) / [@mention](url) / [:emoji:](url) regression tests still pass.
  • linkBuilder → inlineLinkBuilder. Links stay widgets via asWidgetSpan, so mobile: long-press a message link for open, copy and share #9135's long-press (the Open/Copy/Share link sheet and the press tint) keeps working; gpt_markdown's text-span links support neither. Tap handling moved into _openLink, unchanged in behavior.
  • The parser now decodes [/] itself, so _markdownLabelEntityPattern is removed.

Autolinking

Buzz's own normalizeBareLinks pre-processor is removed in favor of gpt_markdown's autolink with autolinkSchemes: {'buzz'}, as the package docs recommend. Visible differences:

  • Trailing punctuation now stays outside HTTP(S) links too (GFM rules), not only Buzz links.
  • URLs with a port, a single-label host or an @ (http://localhost:3000, https://example.com:8443, https://mastodon.social/@alice) still link: gpt_markdown's bare autolink rejects them, so they are wrapped in <...>, which it links.
  • www. hosts and email addresses become links. Email links open the mail app.
  • A bare buzz:// URL of an unknown shape stays plain text, as before.

Inbox and search previews (MessagePreview) used normalizeBareLinks too. They now recognize bare and <angle> URLs themselves, so media URLs still show as "Image"/"Video", channel links as chips, and message/repo links get their short label.

Other 1.3.x parser changes

These come with the package's default parser and are visible in messages:

  • A line followed by a --- line becomes a (setext) heading, as it already does on desktop (react-markdown + remark-gfm).
  • __x__ renders as bold.
  • HTML entities such as &amp; are decoded.
  • <!-- comments --> are hidden.

Backslash escapes (rebased onto #8925)

#8925 landed while this was open. It replaces each backslash escape with an invisible stand-in before parsing, then restores the character when rendering. This PR keeps that, because 1.3.4's own escape handling reads \[x\] and \(x\) as math, while #8925 (like CommonMark and desktop) shows them literally.

  • fix(mobile): render Markdown backslash escapes #8925's InlineMd that restores escapes is now an InlinePattern in all scopes, so it does not force the legacy parser.
  • Inside link destinations and bare URLs, escapes are resolved to their characters instead ([x](https://e.com/a\_b) links to https://e.com/a_b): gpt_markdown swaps inline-pattern matches for placeholders even inside URLs, so a stand-in there could not be restored. inlineLinkBuilder restores stand-ins in autolink labels.
  • Angle autolinks such as <https://e.com/a\> are left alone when escapes are swapped out. A backslash inside them is literal, and swapping it out broke the closing >.
  • MessagePreview uses the shared helpers in markdown_escapes.dart for its bare and angle URL detection.
  • fix(mobile): render Markdown backslash escapes #8925's multi-line strikethrough limitation (the stand-in showing as #) no longer happens with 1.3.4; its test row now expects #.

Known limitation: gpt_markdown 1.3.4 drops the backslash before > in an angle autolink (<https://e.com/a\> links to https://e.com/a). CommonMark keeps it.

Fixes the new rendering exposed

  • Stray backtick in links. The mention rewrite in MessageContent re-added backticks around every odd segment, which adds one extra backtick when the count is odd (e.g. a 4-backtick fence closer). Previously hidden; with autolink the link swallowed it.
  • Tokens inside URLs. Inline patterns are also matched inside link URLs, so [x](https://e.com/?u=@alice) or a bare https://e.com/?q=#general had the token cut out of the URL. Mention and channel patterns now also skip a token right after =, &, ? or %.
  • Screen readers. A Buzz link chip's placeholder merged its whole paragraph — mention and channel pills included — into a single semantics node with one label and one tap. Each chip now gets its own node, so every pill is its own stop with its own action. Repo/PR/issue chips no longer advertise a tap they cannot perform. Ordinary links keep their own link stop with a tap action.
  • Height-bounded forum preview. The forum post card squeezed MessageContent into a max height; the new block layout reported a RenderFlex overflow. It now lays the content out at its natural height and clips it.

Related issue

Closes #8179.

Related:

Testing

  • just mobile-check — format and analyze clean, no deprecation warnings.
  • just mobile-test — 4561 passed, 67 skipped, 0 failed.
  • just file-size-check — passes.
  • message_content_autolink_test.dart ports the deleted normalizer's cases (code-span boundaries, delimiters, punctuation, entity permalinks) to assertions on what MessageContent actually renders, and checks that email links open.
  • preview_text_test.dart covers bare and angle URLs in previews.
  • link_normalizer_test.dart runs the code-boundary table (backtick and tilde fences, quotes, escaped backticks) against mapMarkdownProse.
  • New tests for tokens inside link URLs and for each inline pill getting its own screen-reader stop; each fails without its fix.
  • Each ordinary link is keyed message-link:<url> (chips keep buzz-link-chip:<url>), and link tests find links by that key.
  • Ran the app on iOS Simulator (just mobile-dev): bare links and emails render as links, trailing punctuation stays outside, [x](https://e.com/?u=@alice) and https://e.com/?q=#general stay single links with no pills, #channel pills still render, links open in Safari, and text followed by --- renders as a heading. The simulator has no Mail app, so the email tap is covered by opens email links instead.
  • After the rebase, ran the app on iOS Simulator again: [\#buzz](url) shows #buzz, \[x\] \(y\) show as text (not math), \*x\* \_y\_ are not emphasized, a \\ b shows one backslash, code keeps a\#b, an escaped backtick stays literal, and <https://example.com/a> opens in Safari. Search previews show the same message without backslashes or stand-ins, with no @alice pill from a link URL.

buzz-review-completed

@saminsohag
saminsohag requested a review from a team as a code owner October 8, 2026 18:40
@github-actions

github-actions Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

🔐 Codex Security Review

Status: review required for the current range.

The current range is 22d96d94ef043292803b6d5c929652abd69612dd...2ea33d2b19be166b222c98a682f8e2c6bc5e5c01.
A new review must complete for this exact range. When manual authorization
is required, a user with write access must comment exactly
@buzz-security-review 2ea33d2b19be166b222c98a682f8e2c6bc5e5c01 to authorize a new review.
Any previous review applies only to its recorded range.

@saminsohag
saminsohag force-pushed the chore/mobile-gpt-markdown-1.3.4 branch from 02df67f to 2265793 Compare October 8, 2026 19:12

@loganj loganj left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🤖 Larry and Auto: an independent adversarial review of af14d87ba491. Source review, plus a local run at this head: just mobile-check found no issues, and just mobile-test passed (3733 passed, 16 skipped; unconfigured-push suite 4 passed). Mobile CI has not run on this fork PR.

The migration matches the real gpt_markdown 1.3.4 API (inlineLinkBuilder, LinkBuildDetails.labelSpans, LinkTextSpan.wrapping, InlinePattern.prefixed, autolinkSchemes, default scopes), and pubspec.lock is consistent. The stray-backtick fix is exact.

Why we are not approving yet: merged with current main (158b3bf56), this does not compile (inline at link_normalizer.dart:11). The fix needs a design choice for message previews, so the rebased result should get another look.

Other items:

  • Question: screen-reader access to ordinary links (inline, message_content.dart:681).
  • Error (small): email autolinks look tappable but do nothing (inline, :713).
  • Advice: mention and channel patterns inside URLs (inline, :402); the forum preview overflow stripe (inline).
  • Convention: the PR body is stale. #7545 is merged (Oct 21), so the "Depends on #7545" note no longer applies. The "pulse reply preview" it mentions is not in this diff. "Visible differences" also leaves out some 1.3.x parser changes users will see: Text followed by a --- line becomes a setext heading, __x__ becomes bold, \* loses its backslash, HTML entities are decoded, and <!-- --> is hidden. The setext heading may surprise chat users.
  • Preference: gpt_markdown's parser now decodes &#91;, &#92; and &#93; itself, so _markdownLabelEntityPattern may be redundant, and with it the labelSpans workaround at :594. _useMessageInlineComponents and inline_components.dart now hold InlinePatterns, so those names are stale.

@saminsohag
saminsohag force-pushed the chore/mobile-gpt-markdown-1.3.4 branch from af14d87 to f518ab7 Compare October 31, 2026 09:46
@saminsohag

Copy link
Copy Markdown
Contributor Author

Rebased onto main and addressed the review in f518ab7.

  • Updated the PR description. I kept the --- heading change, since desktop already renders it the same way.
  • Removed _markdownLabelEntityPattern, since the parser handles those entities now. I kept the labelSpans text, because link.label still includes the parser's placeholders for mentions and channels.
  • Renamed inline_components.dart to inline_patterns.dart.

@saminsohag
saminsohag force-pushed the chore/mobile-gpt-markdown-1.3.4 branch from f518ab7 to 40a71d1 Compare October 31, 2026 18:51
@saminsohag

Copy link
Copy Markdown
Contributor Author

Rebased onto main to resolve conflicts with #8860 and #8862. The channel pattern now uses the shared channelTokenPattern, and the =&?% URL guard is in that shared pattern so messages and previews stay in sync.

@saminsohag
saminsohag force-pushed the chore/mobile-gpt-markdown-1.3.4 branch from 40a71d1 to 4dab1cc Compare November 4, 2026 17:01
Move mentions, channels and custom emoji from InlineMd/inlineComponents
to InlinePattern/inlinePatterns, and linkBuilder to inlineLinkBuilder.
This puts mobile on gpt_markdown's default parser.

Replace normalizeBareLinks with gpt_markdown's autolink
(autolinkSchemes: {'buzz'}), as the package docs recommend.

Fix what the new rendering exposed:
- the mention rewrite added a stray backtick when the count was odd
- a Buzz link chip merged its paragraph into one screen-reader stop
- height-bounded previews overflowed instead of clipping

Signed-off-by: Samin Yeasar Sohag <sssohag172@gmail.com>
Signed-off-by: Samin Yeasar Sohag <sssohag172@gmail.com>
A backslash inside an angle autolink is literal in CommonMark, but
shielding turned `\>` into a stand-in, so <https://e.com/a\> lost its
closing bracket. Leave angle autolinks untouched (doubling only authored
markers).

gpt_markdown 1.3.4 now restores escapes in multi-line strikethrough, so

Signed-off-by: Samin Yeasar Sohag <sssohag172@gmail.com>
block#8925's known-limitation row expects # instead of its fullwidth form.
Links render as widgets again so a hold can open the link sheet and tint
the link; gpt_markdown text spans support neither. Each ordinary link is
keyed message-link:<url>, and link tests find links by that key instead
of as LinkTextSpans, restoring upstream assertions where they existed.

A Buzz URL of an unknown shape stays plain text instead of becoming a
link whose tap and Open action do nothing, as it was before the
migration.

Signed-off-by: Samin Yeasar Sohag <sssohag172@gmail.com>
@saminsohag
saminsohag force-pushed the chore/mobile-gpt-markdown-1.3.4 branch from 4dab1cc to bfaf4dd Compare November 9, 2026 09:22
- Resolve escapes inside link destinations and bare URLs instead of
  shielding them: gpt_markdown swaps inline-pattern matches for
  placeholders even inside URLs, so a stand-in there could not be
  restored and the link opened a broken address.
- Wrap bare HTTP(S) URLs that gpt_markdown's autolink rejects (a port,
  a host without a dot, an @) in <...>, so localhost, :8443 and
  mastodon-style URLs link again.
- Give autolink labels the themed link style, so bare URLs match
  authored links instead of drawing near body-text grey.
- Offer Open for mailto links in the long-press sheet, matching the tap.
- Render an authored [label](buzz://unknown) as plain text, not a
  link-styled run that does nothing.

Signed-off-by: Samin Yeasar Sohag <sssohag172@gmail.com>

This branch has not been deployed

No deployments
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.

Mobile markdown still renders through gpt_markdown's deprecated legacy parser

2 participants