diff --git a/source/filesystem.go b/source/filesystem.go index 9d723685e..7bdcd702f 100644 --- a/source/filesystem.go +++ b/source/filesystem.go @@ -18,9 +18,11 @@ import ( "os" "path/filepath" "regexp" + "runtime" "strings" "github.com/spf13/hugo/hugofs" + "golang.org/x/text/unicode/norm" "github.com/spf13/viper" @@ -66,6 +68,11 @@ func (f *Filesystem) Files() []*File { func (f *Filesystem) add(name string, reader io.Reader) (err error) { var file *File + if runtime.GOOS == "darwin" { + // When a file system is HFS+, its filepath is in NFD form. + name = norm.NFC.String(name) + } + file, err = NewFileFromAbs(f.Base, name, reader) if err == nil { diff --git a/source/filesystem_test.go b/source/filesystem_test.go index 9a6b9fa88..d2101991b 100644 --- a/source/filesystem_test.go +++ b/source/filesystem_test.go @@ -16,6 +16,8 @@ package source import ( "bytes" "path/filepath" + "runtime" + "strings" "testing" ) @@ -82,3 +84,28 @@ func TestAddFile(t *testing.T) { } } } + +func TestUnicodeNorm(t *testing.T) { + if runtime.GOOS != "darwin" { + // Normalization code is only for Mac OS, since it is not necessary for other OSes. + return + } + + paths := []struct { + NFC string + NFD string + }{ + {NFC: "å", NFD: "\x61\xcc\x8a"}, + {NFC: "é", NFD: "\x65\xcc\x81"}, + } + + for _, path := range paths { + src := new(Filesystem) + _ = src.add(path.NFD, strings.NewReader("")) + f := src.Files()[0] + if f.BaseFileName() != path.NFC { + t.Fatalf("file name in NFD form should be normalized (%s)", path.NFC) + } + } + +}