Skip to content

Follow-ups from PR #430: heading slug anchor IDs (polish, edge-case tests, dedup decisions) #471

Description

@schuyler

Tracking the non-blocking items surfaced while reviewing PR #430 (slug-based heading anchor IDs). None of these block that PR — capturing them here so we can handle them ourselves rather than asking the contributor to expand the scope of a focused fix.

Test coverage gaps

  • Empty-slug "section" fallback — no test exercises the branch where slugify() produces nothing (e.g. a punctuation-only ## !!! or dash-only ## --- heading).
  • Purely non-ASCII heading (e.g. ## 你好) — distinct from the mixed Introducción case; exercises the id as a raw UTF-8 byte sequence.
  • Repeated-dash collapse and trailing-dash trim (e.g. ## Foo --- Barfoo-bar, ## Foo foo) — each is its own code path with no current coverage.
  • Digit/underscore passthrough (e.g. ## Version 2_0version-2_0).
  • Harden the entity-skip tests with negative assertions (e.g. assert id="qampa" is absent, not just id="qa" present).
  • testDuplicateHeadingsCollapseToSameId: add XCTAssertGreaterThan(secondC, firstC) for rigor.
  • Quick Look anchor tests are a subset (3) of the preview suite (9); add the fallback and pure-UTF-8 parity cases (especially relevant given the duplicated implementation, below).

Code clarity

  • Remove the now-unused header_count++ in hoedown_patch_render_toc_header — the value is no longer read now that the TOC href is slug-based.
  • Fix the "encoding would break navigation" comment in both slug copies — modern browsers decode percent-encoded fragments before matching ids, so encoding would not break navigation; the raw-UTF-8 choice is fine, only the stated reason is inaccurate.
  • Note in a comment that ' / numeric character references are skipped (dropped), not decoded, to prevent a future "fix" that decodes them.
  • Comment the >= 0x80 well-formed-UTF-8 passthrough assumption and the trailing-hyphen-trim loop.
  • Reword the hoedown_patch_render_header comment: "independent of the TOC nesting level" → "independent of the Detect TOC token preference".

Structural / product decisions

  • Consolidate the duplicated slugify() / render_header logic shared byte-for-byte between MacDown/Code/Extension/hoedown_html_patch.c (MacDown target) and MacDownCore/MPQuickLookRenderer.m (MacDownCore target) — the two copies will drift if either is changed alone. Likely needs a shared C unit reachable from both targets.
  • Decide on GFM-style duplicate-id disambiguation (-1/-2 suffixes). Current behavior collapses identical headings to the same id (only the first is reachable by anchor); documented as intentional in a test. Common patterns like repeated ## API sections would be affected.
  • Confirm raw UTF-8 (vs percent-encoded) ids as the intended convention — currently valid HTML5 and works in WebKit.

Documentation

  • plans/test_coverage_improvement_plan.md:128 — stale rationale ("prevents unwanted header ID generation when table of contents is disabled"); heading IDs are now unconditional.
  • MacDown/Resources/help.md — document the new [link](#slug) anchor-navigation capability.
  • plans/quick-look-manual-testing.md — add a checklist item verifying heading id attributes / anchor navigation in Quick Look.

Related to #430, #429.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions