Skip to content

fix(markup): recognize issue references next to CJK punctuation - #40097

Merged
silverwind merged 10 commits into
go-gitea:mainfrom
b84330808:fix-cjk-issue-refs
Nov 7, 2026
Merged

silverwind merged 10 commits into
go-gitea:mainfrom
b84330808:fix-cjk-issue-refs

Conversation

@b84330808

@b84330808 b84330808 commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Issue references next to non-ASCII characters, common in Chinese and Japanese text, are ignored: 修复#1, (#2) or Closes #3, create no link or cross reference.

Like on GitHub, any non-ASCII character may now precede #123, !123 or owner/repo#123, and anything but a word character may follow it. Dead trailing-space handling in the reference and mention search is removed.

I used Claude Code to write this change.

References like "修复 go-gitea#1。" or "(go-gitea#2)" were neither rendered as links nor
picked up as cross references or closing keywords, because the patterns
only accepted ASCII delimiters around the reference.

Assisted-by: Claude Code:claude-opus-5-5
@wxiaoguang

Copy link
Copy Markdown
Contributor
image

@github-actions github-actions Bot added topic/content-rendering Changes how certain filetypes are displayed type/bug labels Oct 30, 2026
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Oct 30, 2026
Build the delimiter class from all non-ASCII \p{P} characters, so quotes
like “go-gitea#4” and other full-width punctuation are covered too. ASCII
punctuation keeps its existing rules ("/home/gitea/go-gitea#1234" is still not
a reference).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@wxiaoguang

Copy link
Copy Markdown
Contributor

Why not simply use \p{P}?

@b84330808

Copy link
Copy Markdown
Contributor Author

Plain \p{P} also matches ASCII punctuation like /, #, & and ., so existing cases such as /home/gitea/#1234 start rendering as references (the current tests fail with it). So 03898af builds the class from the non-ASCII part of \p{P} plus U+3000: that covers 「」, “”, 。,、 and so on, and leaves the ASCII rules as they were.

@wxiaoguang

Copy link
Copy Markdown
Contributor

Plain \p{P} also matches ASCII punctuation like /, #, & and ., so existing cases such as /home/gitea/#1234 start rendering as references (the current tests fail with it). So 03898af builds the class from the non-ASCII part of \p{P} plus U+3000: that covers 「」, “”, 。,、 and so on, and leaves the ASCII rules as they were.

OK, but the current implement is too complicated.

I guess the best approach is like this: keep the regexp as simple as possible, then use our own code to check the surrounding bytes. This approach should be flexible enough and clear enough.

…code

The patterns now accept any non-ASCII character next to a reference, and
validReferenceBoundaries checks it: punctuation or a space is fine
("修复 go-gitea#1。", "(go-gitea#2)"), a letter is not ("修复go-gitea#1"). This replaces the
generated character class.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@b84330808

Copy link
Copy Markdown
Contributor Author

Makes sense, simplified it: the patterns now just accept any non-ASCII character next to the reference, and a small validReferenceBoundaries check in code allows it only if it's punctuation or a space. So 修复 #1。 and (#2) link, 修复#1 still doesn't, and the generated class is gone.

* origin/main: (92 commits)
  feat(release): allow setting a release as the latest (go-gitea#40214)
  fix(repo): reject unparsable required approvals in branch protection (go-gitea#40213)
  ci: update giteabot to v1.5.1, label conflict-free backports (go-gitea#40247)
  fix(pull): enforce user blocks on pull request reviews (go-gitea#40194)
  feat(auth)!: remove support for obsolete OpenID 2.0 draft (go-gitea#40231)
  enhance(codeowners): support section / glob / file view display / skip review request (go-gitea#40243)
  fix: upgrade Alpine base packages in Docker images (go-gitea#40252)
  fix(deps): update module github.com/andybalholm/brotli to v1.2.7 [security] (go-gitea#40246)
  fix(perm): keep read access for restricted collaborators on public repos (go-gitea#40234)
  fix(build): pass `#` test patterns to `go test -run` unchanged (go-gitea#39977)
  perf: reduce git processes and queries on pull request view (go-gitea#40224)
  fix(dump): --file extension is ignored when --type is not set (go-gitea#40235)
  enhance: enable `DEFAULT_DELETE_BRANCH_AFTER_MERGE` by default for new repos (go-gitea#39975)
  fix(packages): return empty Chef dependencies instead of null (go-gitea#40237)
  fix(migrations): Do not fail Bitbucket Server migration when pull request activities cannot be loaded (go-gitea#40205)
  chore(deps): update go.yaml.in/yaml/v4 to v4.0.0 (go-gitea#40222)
  [skip ci] Updated translations via Crowdin
  fix: fix missing accessible name on static Fomantic combobox dropdowns (go-gitea#40163)
  fix(web): build issue popup request from parsed link (go-gitea#40207)
  fix(web): inline the site manifest (go-gitea#40198)
  ...
…II characters

GitHub links a reference after any non-ASCII character and before
anything but a Unicode word character, so "修复go-gitea#1" and "go-gitea#1~go-gitea#5" are
references there too. The word character set is now shared with
heading anchors.

Assisted-by: Claude Code:claude-opus-5-5
The renderer and the cross reference finder repeated the same search,
including trailing-space handling that can never apply since the
reference itself contains no whitespace.

Assisted-by: Claude Code:claude-opus-5-5
…search

A mention never contains whitespace, so spaceTrimmedPattern never
matched and the search position always advanced to the mention's end.

Assisted-by: Claude Code:claude-opus-5-5
@GiteaBot GiteaBot added lgtm/need 1 This PR needs approval from one additional maintainer to be merged. and removed lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. labels Nov 6, 2026
@silverwind

Copy link
Copy Markdown
Member

Pushed these changes and merged main:

  1. Any non-ASCII character may precede a reference, so 修复#1 links, as it does on GitHub.
  2. Only a Unicode word character after a reference blocks it, so symbols and emoji like #1~#5 or #1🎉 link too.
  3. The word character set is shared with the heading anchors from fix(markup): make heading anchors match GitHub for whitespace and combining marks #40195 as util.IsWordRune.
  4. Rendering and cross reference detection share one search loop.
  5. Removed the dead trailing-space handling (spaceTrimmedPattern) from the reference and mention search.

Written by Claude (Opus 5.5).

@GiteaBot GiteaBot added lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. and removed lgtm/need 1 This PR needs approval from one additional maintainer to be merged. labels Nov 7, 2026
@silverwind
silverwind enabled auto-merge November 7, 2026 10:03
@silverwind
silverwind added this pull request to the merge queue Nov 7, 2026
Merged via the queue into go-gitea:main with commit 7efb5c0 Nov 7, 2026
24 checks passed
@GiteaBot GiteaBot added this to the 29.0.0 milestone Nov 7, 2026
silverwind added a commit to cocvn157/gitea that referenced this pull request Nov 7, 2026
* origin/main: (44 commits)
  fix(markup): recognize issue references next to CJK punctuation (go-gitea#40097)
  fix: add missing checks to several handlers and services (go-gitea#40120)
  fix(api): honor branch protection force push and allowlist options on create and edit (go-gitea#39990)
  fix(repo): mark repository as non-empty before git push returns (go-gitea#40102)
  [skip ci] Updated translations via Crowdin
  fix(web): handle TypeCastError when building form validation messages (go-gitea#40212)
  fix: stop discarding file close and test setup errors (go-gitea#39987)
  test(e2e): retry clipboard reads rejected by Firefox (go-gitea#40155)
  refactor: remove duplicated and dead Go code (go-gitea#40244)
  feat(release): allow setting a release as the latest (go-gitea#40214)
  fix(repo): reject unparsable required approvals in branch protection (go-gitea#40213)
  ci: update giteabot to v1.5.1, label conflict-free backports (go-gitea#40247)
  fix(pull): enforce user blocks on pull request reviews (go-gitea#40194)
  feat(auth)!: remove support for obsolete OpenID 2.0 draft (go-gitea#40231)
  enhance(codeowners): support section / glob / file view display / skip review request (go-gitea#40243)
  fix: upgrade Alpine base packages in Docker images (go-gitea#40252)
  fix(deps): update module github.com/andybalholm/brotli to v1.2.7 [security] (go-gitea#40246)
  fix(perm): keep read access for restricted collaborators on public repos (go-gitea#40234)
  fix(build): pass `#` test patterns to `go test -run` unchanged (go-gitea#39977)
  perf: reduce git processes and queries on pull request view (go-gitea#40224)
  ...
// issueNumericPattern matches string that references to a numeric issue, e.g. #1287
issueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[|\'|\")([#!][0-9]+)(?:\s|$|\)|\]|\'|\"|[:;,.?!]\s|[:;,.?!]$)`)
// TODO: REFERENCE-REGEXP-PATTERN: findValidReferenceIndex checks a non-ASCII trailing character
issueNumericPattern = regexp.MustCompile(`(?:\s|^|\(|\[|\'|\"|[^\x00-\x7f])([#!][0-9]+)(?:\s|$|\)|\]|\'|\"|[:;,.?!]\s|[:;,.?!]$|[^\x00-\x7f])`)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

refactor: lazy init global regexp variables - #40269

silverwind added a commit to silverwind/gitea that referenced this pull request Nov 7, 2026
* origin/main:
  fix(org): enforce unique team names in the database (go-gitea#40228)
  fix: truncate strings on character boundaries (go-gitea#40267)
  feat(packages): add private Terraform module registry (go-gitea#38040)
  fix(markup): recognize issue references next to CJK punctuation (go-gitea#40097)
  fix: add missing checks to several handlers and services (go-gitea#40120)
  fix(api): honor branch protection force push and allowlist options on create and edit (go-gitea#39990)
  fix(repo): mark repository as non-empty before git push returns (go-gitea#40102)
  [skip ci] Updated translations via Crowdin
  fix(web): handle TypeCastError when building form validation messages (go-gitea#40212)
  fix: stop discarding file close and test setup errors (go-gitea#39987)
  test(e2e): retry clipboard reads rejected by Firefox (go-gitea#40155)
  refactor: remove duplicated and dead Go code (go-gitea#40244)
  feat(release): allow setting a release as the latest (go-gitea#40214)
  fix(repo): reject unparsable required approvals in branch protection (go-gitea#40213)
  ci: update giteabot to v1.5.1, label conflict-free backports (go-gitea#40247)
  fix(pull): enforce user blocks on pull request reviews (go-gitea#40194)
  feat(auth)!: remove support for obsolete OpenID 2.0 draft (go-gitea#40231)
  enhance(codeowners): support section / glob / file view display / skip review request (go-gitea#40243)
  fix: upgrade Alpine base packages in Docker images (go-gitea#40252)
  fix(deps): update module github.com/andybalholm/brotli to v1.2.7 [security] (go-gitea#40246)

Assisted-by: Claude Code:claude-opus-5-5

# Conflicts:
#	services/release/release_test.go
silverwind added a commit to sandiyochristan/gitea that referenced this pull request Nov 7, 2026
* origin/main: (66 commits)
  chore: add report requirements (go-gitea#40262)
  refactor: lazy init global regexp variables (go-gitea#40269)
  fix(org): enforce unique team names in the database (go-gitea#40228)
  fix: truncate strings on character boundaries (go-gitea#40267)
  feat(packages): add private Terraform module registry (go-gitea#38040)
  fix(markup): recognize issue references next to CJK punctuation (go-gitea#40097)
  fix: add missing checks to several handlers and services (go-gitea#40120)
  fix(api): honor branch protection force push and allowlist options on create and edit (go-gitea#39990)
  fix(repo): mark repository as non-empty before git push returns (go-gitea#40102)
  [skip ci] Updated translations via Crowdin
  fix(web): handle TypeCastError when building form validation messages (go-gitea#40212)
  fix: stop discarding file close and test setup errors (go-gitea#39987)
  test(e2e): retry clipboard reads rejected by Firefox (go-gitea#40155)
  refactor: remove duplicated and dead Go code (go-gitea#40244)
  feat(release): allow setting a release as the latest (go-gitea#40214)
  fix(repo): reject unparsable required approvals in branch protection (go-gitea#40213)
  ci: update giteabot to v1.5.1, label conflict-free backports (go-gitea#40247)
  fix(pull): enforce user blocks on pull request reviews (go-gitea#40194)
  feat(auth)!: remove support for obsolete OpenID 2.0 draft (go-gitea#40231)
  enhance(codeowners): support section / glob / file view display / skip review request (go-gitea#40243)
  ...

# Conflicts:
#	tests/e2e/webauthn.test.ts
silverwind added a commit to silverwind/gitea that referenced this pull request Nov 7, 2026
* origin/main: (84 commits)
  fix(web): don't block README images with `REQUIRE_SIGNIN_VIEW = expensive` (go-gitea#40264)
  enhance(actions): create commit status for workflow_dispatch runs (go-gitea#39961)
  fix(repo): do not reuse pull mirror credentials for a new host (go-gitea#39991)
  chore: add report requirements (go-gitea#40262)
  refactor: lazy init global regexp variables (go-gitea#40269)
  fix(org): enforce unique team names in the database (go-gitea#40228)
  fix: truncate strings on character boundaries (go-gitea#40267)
  feat(packages): add private Terraform module registry (go-gitea#38040)
  fix(markup): recognize issue references next to CJK punctuation (go-gitea#40097)
  fix: add missing checks to several handlers and services (go-gitea#40120)
  fix(api): honor branch protection force push and allowlist options on create and edit (go-gitea#39990)
  fix(repo): mark repository as non-empty before git push returns (go-gitea#40102)
  [skip ci] Updated translations via Crowdin
  fix(web): handle TypeCastError when building form validation messages (go-gitea#40212)
  fix: stop discarding file close and test setup errors (go-gitea#39987)
  test(e2e): retry clipboard reads rejected by Firefox (go-gitea#40155)
  refactor: remove duplicated and dead Go code (go-gitea#40244)
  feat(release): allow setting a release as the latest (go-gitea#40214)
  fix(repo): reject unparsable required approvals in branch protection (go-gitea#40213)
  ci: update giteabot to v1.5.1, label conflict-free backports (go-gitea#40247)
  ...
wxiaoguang added a commit to SHIVANSHGARG07/gitea that referenced this pull request Nov 8, 2026
…itea#40097)

Issue references next to non-ASCII characters, common in Chinese and
Japanese text, are ignored: `修复go-gitea#1`, `(go-gitea#2)` or `Closes go-gitea#3,` create no
link or cross reference.

Like on GitHub, any non-ASCII character may now precede `go-gitea#123`, `!123`
or `owner/repo#123`, and anything but a word character may follow it.
Dead trailing-space handling in the reference and mention search is
removed.

I used Claude Code to write this change.

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
Co-authored-by: silverwind <[email protected]>
Co-authored-by: wxiaoguang <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/done This PR has enough approvals to get merged. There are no important open reservations anymore. topic/content-rendering Changes how certain filetypes are displayed type/bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants