diff --git a/internal/linkindex/linkindex.go b/internal/linkindex/linkindex.go index 93d94b6..c48acba 100644 --- a/internal/linkindex/linkindex.go +++ b/internal/linkindex/linkindex.go @@ -136,14 +136,18 @@ var ( whitespaceRunRE = regexp.MustCompile(`\s+`) ) -// GithubSlug replicates GitHub's heading-anchor slugger: lowercase; strip all -// but letters/digits/underscore/whitespace/hyphen; each whitespace char -// becomes one hyphen; trim leading/trailing hyphens. +// GithubSlug replicates GitHub's heading-anchor slugger (github-slugger, the +// package GitHub itself extracted from its rendering pipeline): lowercase; +// strip all but letters/digits/underscore/whitespace/hyphen; each whitespace +// char becomes one hyphen. Nothing is trimmed -- a leading/trailing hyphen +// survives whether it came from stripped punctuation ("`--json` output" +// becomes "--json-output", not "json-output") or from literal leading/ +// trailing whitespace in the heading text, matching the reference +// implementation, which calls no trim at all. func GithubSlug(heading string) string { s := strings.ToLower(heading) s = nonSlugRE.ReplaceAllString(s, "") - s = whitespaceRE.ReplaceAllString(s, "-") - return strings.Trim(s, "-") + return whitespaceRE.ReplaceAllString(s, "-") } // ConfluenceSlug replicates Confluence's scheme: preserve case and diff --git a/internal/linkindex/slug_test.go b/internal/linkindex/slug_test.go index b47fe77..fc5e78f 100644 --- a/internal/linkindex/slug_test.go +++ b/internal/linkindex/slug_test.go @@ -6,12 +6,13 @@ func TestGithubSlug(t *testing.T) { cases := map[string]string{ "Hello World": "hello-world", "Hello, World!": "hello-world", - " Leading/trailing": "leadingtrailing", - " Hello ": "hello", - "Café Menu": "café-menu", // Unicode letters are preserved, not stripped + " Leading/trailing": "--leadingtrailing", // leading whitespace is not trimmed + " Hello ": "-hello-", // nor is trailing + "Café Menu": "café-menu", // Unicode letters are preserved, not stripped "under_score": "under_score", "": "", - "---": "", // trims to nothing + "---": "---", // hyphens already in the heading are not trimmed either + "`--json` output": "--json-output", // punctuation-derived hyphens survive too (#120) } for in, want := range cases { if got := GithubSlug(in); got != want {