Skip to content

fix(markdown): align heading slugs with GitHub anchors - #197

Open
sean0407 wants to merge 1 commit into
firecrawl:mainfrom
sean0407:codex/anydoc-190-github-anchor-slugs
Open

sean0407 wants to merge 1 commit into
firecrawl:mainfrom
sean0407:codex/anydoc-190-github-anchor-slugs

Conversation

@sean0407

@sean0407 sean0407 commented Oct 18, 2026 •

Copy link
Copy Markdown

Summary

GitHub heading slug behavior
+ keep variation selectors used in emoji presentation
- omit Unicode Other_Number characters such as ² and ½

Closes #190. This keeps generated internal links aligned with GitHub's heading anchors for the reported Unicode cases.

Evidence

  • Before: ❤️ Love produced #-love instead of GitHub's #️-love; x² formula retained ² although GitHub removes it.
  • After: regression assertions cover ❤️ Love, 2️⃣ Second, and x² formula ½.
  • cargo test -p anydoc --locked --offline: 286 unit tests passed; integration tests 2 + 1 passed; 9 snapshot tests passed, 1 ignored; doc tests 0.
  • cargo fmt --all -- --check: passed.

Merge Danger

Door: Two-way; the change can be reverted in one commit.

Blast Radius: Narrow; only GitHub-compatible heading fragment generation changes.


Summary by cubic

Aligns markdown heading slug generation with GitHub's anchor behavior so internal links to headings with Unicode edge cases resolve correctly. Fixes #190.

  • Keeps variation selectors used in emoji presentation, so ❤️ Love now slugs to #️-love.
  • Removes Unicode Other_Number characters, so x² formula ½ now slugs to #x-formula-.
  • Adds the unicode-properties dependency to detect the character category.

Written for commit a06f283. Summary will update on new commits.

View guided diff

@cubic-dev-ai cubic-dev-ai 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.

1 issue found across 3 files

Confidence score: 5/5

  • The gfm_slug docs in src/render/markdown/anchors.rs still say all numbers are retained, but the predicate drops Other_Number characters. Update the comment to name the numeric categories that are retained.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/render/markdown/anchors.rs">

<violation number="1" location="src/render/markdown/anchors.rs:189">
P3: The slug predicate now drops `Other_Number` characters, but the `gfm_slug` documentation still says that numbers are retained. Update the comment to describe the retained numeric categories so the documented contract matches the GitHub-compatible behavior.</violation>
</file>

Reply with feedback, questions, or to request a fix.

View guided diff | Re-trigger cubic

' ' => Some('-'),
'-' => Some(c),
c if c.is_alphanumeric() || is_combining_mark(c) || is_connector_punctuation(c) => {
c if (c.is_alphanumeric() && c.general_category() != GeneralCategory::OtherNumber)

@cubic-dev-ai cubic-dev-ai Bot Oct 18, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P3: The slug predicate now drops Other_Number characters, but the gfm_slug documentation still says that numbers are retained. Update the comment to describe the retained numeric categories so the documented contract matches the GitHub-compatible behavior.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At src/render/markdown/anchors.rs, line 189:

<comment>The slug predicate now drops `Other_Number` characters, but the `gfm_slug` documentation still says that numbers are retained. Update the comment to describe the retained numeric categories so the documented contract matches the GitHub-compatible behavior.</comment>

<file context>
@@ -185,7 +186,10 @@ fn gfm_slug(text: &str) -> String {
             ' ' => Some('-'),
             '-' => Some(c),
-            c if c.is_alphanumeric() || is_combining_mark(c) || is_connector_punctuation(c) => {
+            c if (c.is_alphanumeric() && c.general_category() != GeneralCategory::OtherNumber)
+                || is_combining_mark(c)
+                || is_connector_punctuation(c) =>
</file context>
Fix with cubic

@rahul05ranjan rahul05ranjan 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.

The two-pronged fix checks out: excluding OtherNumber while keeping the rest of is_alphanumeric drops ²/½ but keeps ordinary digits, which matches the github-slugger behavior these anchors need to agree with (letters + marks + Nd kept, No dropped). And the extension of the combining-mark ranges to 0xFE00..=0xFE0F and 0xE0100..=0xE01EF is correct — those variation selectors are Mn marks, so emoji-presentation sequences like 2️⃣ survive with their keycap digit instead of getting mangled. I verified the category claims against Unicode data and the test table covers the three failure modes from the issue. The only thing I couldn't independently re-verify is GitHub's live anchor output for those exact headings, but the expected values are consistent with the issue report.

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

2 participants