Skip to content

Conversation

@bimakw
Copy link
Contributor

@bimakw bimakw commented Dec 23, 2025

Summary

This PR fixes #27383 where HTML headings like <h1>Title</h1> in markdown files would have empty permalink anchors (showing just # in the URL).

Before:

  • <h1>Heading without ID</h1> → permalink shows # (empty)

After:

  • <h1>Heading without ID</h1> → permalink shows #heading-without-id

Problem

When users write HTML headings in markdown without an id attribute, the frontend's anchors.ts generates permalink links using heading.id. If the heading has no id, the link becomes just #, which is not useful.

GitHub handles this by auto-generating IDs for HTML headings based on their text content, matching the behavior of Markdown headings.

Solution

Modified processNodeAttrID in modules/markup/html_node.go to:

  1. Detect heading tags (h1-h6) without an id attribute
  2. Extract the text content from the heading (including nested elements)
  3. Generate an ID using the same CleanValue function used for Markdown headings
  4. Apply the user-content- prefix as expected by the frontend

This ensures consistent behavior between:

  • Markdown headings: ## Titleid="user-content-title"
  • HTML headings: <h1>Title</h1>id="user-content-title"

Testing

Added test cases in modules/markup/html_node_test.go covering:

  • HTML headings without id (h1, h2, h3)
  • HTML headings with existing id (should preserve and prefix)
  • HTML headings with user-content prefix (should not double prefix)
  • Headings with special characters
  • Headings with nested elements (bold, italic)
  • Non-heading elements (should not get id)

All existing tests continue to pass.

Fixes #27383

@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Dec 23, 2025
@github-actions github-actions bot added the modifies/go Pull requests that update Go code label Dec 23, 2025
This fixes go-gitea#27383 where HTML headings like `<h1>Title</h1>` in markdown
files would have empty permalink anchors (showing just `#` in the URL).

The fix generates an ID from the heading's text content using the same
CleanValue function used for Markdown headings, ensuring consistent
behavior between:
- Markdown headings: `## Title` → `id="user-content-title"`
- HTML headings: `<h1>Title</h1>` → `id="user-content-title"`

Fixes go-gitea#27383
@bimakw bimakw force-pushed the fix/27383-html-heading-permalink branch from 65906c4 to 7cbe377 Compare December 23, 2025 12:22
@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 Dec 23, 2025
@silverwind
Copy link
Member

silverwind commented Dec 23, 2025

One difference from GitHub's implementation is that this id generation is not performed in issue comments, but is performed on Gitea.

I think the reason for this is because in issue comments you have multiple markdown documents on one page, so the generated IDs may not be unique any more. So ideally we should disable this generation mechanism on pages where there can be more than one markdown document.

@bimakw
Copy link
Contributor Author

bimakw commented Dec 24, 2025

good point! baru sadar juga kalo di issue comments bisa duplicate ID karena multiple markdown docs di satu page. mau saya tambahin logic buat skip generation di context issue comments? atau prefer bikin follow-up PR aja?

@wxiaoguang
Copy link
Contributor

See this

image

@bimakw
Copy link
Contributor Author

bimakw commented Dec 24, 2025

@wxiaoguang got it, jadi perlu skip ID generation untuk issue comments ya. mau saya fix di PR ini atau prefer follow-up PR terpisah?

@wxiaoguang
Copy link
Contributor

Please speak in English

@bimakw
Copy link
Contributor Author

bimakw commented Dec 24, 2025

@wxiaoguang got it, I need to skip ID generation for issue comments. Should I fix it in this PR or would you prefer a separate follow-up PR?

@wxiaoguang
Copy link
Contributor

It should be an easy fix in this PR, see #36233 (comment)

Skip auto-generating IDs for HTML headings in comment-like contexts
(issue comments, wiki pages) where multiple markdown documents exist
on one page, as this could create duplicate IDs.

This matches GitHub's behavior where heading IDs are only generated
for repository files (README, etc.) but not for issue comments.
@bimakw
Copy link
Contributor Author

bimakw commented Dec 24, 2025

@wxiaoguang Fixed. Now skipping heading ID generation for issue comments (when markupAllowShortIssuePattern is true). Added tests to verify the behavior.

@wxiaoguang
Copy link
Contributor

wxiaoguang commented Dec 24, 2025

Please don't use markupAllowShortIssuePattern, it is an abuse.

You need a clearly defined option to control the new behavior. (no need to add a configurable option, you can hard-code it for wiki and file)

Replace markupAllowShortIssuePattern check with a clearly defined
EnableHeadingIDGeneration option for controlling HTML heading ID
auto-generation.

- Add EnableHeadingIDGeneration field to RenderOptions
- Add WithEnableHeadingIDGeneration builder method
- Enable it explicitly in repo_file.go and repo_wiki.go
- Update tests to use the new explicit option
@bimakw
Copy link
Contributor Author

bimakw commented Dec 24, 2025

Thanks for the feedback! I've refactored the implementation to use a dedicated EnableHeadingIDGeneration option instead of abusing markupAllowShortIssuePattern.

Changes:

  • Added EnableHeadingIDGeneration field to RenderOptions
  • Added WithEnableHeadingIDGeneration() builder method to RenderContext
  • Enabled it explicitly in repo_file.go and repo_wiki.go
  • Updated tests to use the new explicit option

This makes the option clearly defined and hard-coded for file and wiki pages as requested.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/need 1 This PR needs approval from one additional maintainer to be merged. modifies/go Pull requests that update Go code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

wrong permalink to html heading in markdown file

4 participants