diff options
author | Cameron Moore <[email protected]> | 2022-01-17 16:33:47 -0600 |
---|---|---|
committer | Bjørn Erik Pedersen <[email protected]> | 2022-02-23 21:21:46 +0100 |
commit | 6407b2cd016f23bc4a63748feebfc8ecaccecca7 (patch) | |
tree | d3ee4c066c12c83ab2a26e035ec081be6bd0d633 /helpers | |
parent | 6ff39fd908242e32942ddd7f239ffd06cc8e7dda (diff) | |
download | hugo-6407b2cd016f23bc4a63748feebfc8ecaccecca7.tar.gz hugo-6407b2cd016f23bc4a63748feebfc8ecaccecca7.zip |
helpers: Allow hyphens in UnicodeSanitize
Improve handling of existing hyphens in input to UnicodeSanitize.
This commit accomplishes three things:
1. Explicitly allow hyphens
2. Avoid appending a hyphen if a preceeding hyphen is found
3. Avoid prepending a hyphen if a trailing hyphen is found
Fixes #7288
Diffstat (limited to 'helpers')
-rw-r--r-- | helpers/path.go | 21 | ||||
-rw-r--r-- | helpers/path_test.go | 6 |
2 files changed, 21 insertions, 6 deletions
diff --git a/helpers/path.go b/helpers/path.go index a40e0f8ff..b302b1569 100644 --- a/helpers/path.go +++ b/helpers/path.go @@ -87,7 +87,8 @@ func ishex(c rune) bool { // a predefined set of special Unicode characters. // If RemovePathAccents configuration flag is enabled, Unicode accents // are also removed. -// Spaces will be replaced with a single hyphen, and sequential hyphens will be reduced to one. +// Hyphens in the original input are maintained. +// Spaces will be replaced with a single hyphen, and sequential replacement hyphens will be reduced to one. func (p *PathSpec) UnicodeSanitize(s string) string { if p.RemovePathAccents { s = text.RemoveAccentsString(s) @@ -95,20 +96,30 @@ func (p *PathSpec) UnicodeSanitize(s string) string { source := []rune(s) target := make([]rune, 0, len(source)) - var prependHyphen bool + var ( + prependHyphen bool + wasHyphen bool + ) for i, r := range source { - isAllowed := r == '.' || r == '/' || r == '\\' || r == '_' || r == '#' || r == '+' || r == '~' + isAllowed := r == '.' || r == '/' || r == '\\' || r == '_' || r == '#' || r == '+' || r == '~' || r == '-' isAllowed = isAllowed || unicode.IsLetter(r) || unicode.IsDigit(r) || unicode.IsMark(r) isAllowed = isAllowed || (r == '%' && i+2 < len(source) && ishex(source[i+1]) && ishex(source[i+2])) if isAllowed { + // track explicit hyphen in input; no need to add a new hyphen if + // we just saw one. + wasHyphen = r == '-' + if prependHyphen { - target = append(target, '-') + // if currently have a hyphen, don't prepend an extra one + if !wasHyphen { + target = append(target, '-') + } prependHyphen = false } target = append(target, r) - } else if len(target) > 0 && (r == '-' || unicode.IsSpace(r)) { + } else if len(target) > 0 && !wasHyphen && unicode.IsSpace(r) { prependHyphen = true } } diff --git a/helpers/path_test.go b/helpers/path_test.go index 1d2dc1184..6a119a741 100644 --- a/helpers/path_test.go +++ b/helpers/path_test.go @@ -40,6 +40,10 @@ func TestMakePath(t *testing.T) { expected string removeAccents bool }{ + {"dot.slash/backslash\\underscore_pound#plus+hyphen-", "dot.slash/backslash\\underscore_pound#plus+hyphen-", true}, + {"abcXYZ0123456789", "abcXYZ0123456789", true}, + {"%20 %2", "%20-2", true}, + {"foo- bar", "foo-bar", true}, {" Foo bar ", "Foo-bar", true}, {"Foo.Bar/foo_Bar-Foo", "Foo.Bar/foo_Bar-Foo", true}, {"fOO,bar:foobAR", "fOObarfoobAR", true}, @@ -52,7 +56,7 @@ func TestMakePath(t *testing.T) { {"a%C3%B1ame", "a%C3%B1ame", false}, // Issue #1292 {"this+is+a+test", "this+is+a+test", false}, // Issue #1290 {"~foo", "~foo", false}, // Issue #2177 - + {"foo--bar", "foo--bar", true}, // Issue #7288 } for _, test := range tests { |