From 37b1461c7f7a9ee602d2c3973c6eb2f3ffdf8a94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dobros=C5=82aw=20=C5=BBybort?= Date: Wed, 6 Jul 2016 21:38:21 +0200 Subject: [PATCH] change: always apply Substitute map in alphabetic order fix #8 --- slug.go | 16 ++++++++++++---- slug_test.go | 8 +++++--- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/slug.go b/slug.go index b4d6b9f..4aead3e 100644 --- a/slug.go +++ b/slug.go @@ -8,6 +8,7 @@ package slug import ( "bytes" "regexp" + "sort" "strings" "github.com/rainycape/unidecode" @@ -80,17 +81,24 @@ func MakeLang(s string, lang string) (slug string) { } // Substitute returns string with superseded all substrings from -// provided substitution map. +// provided substitution map. Substitution map will be applied in alphabetic +// order. Many passes, on one substitution another one could apply. func Substitute(s string, sub map[string]string) (buf string) { buf = s - for key, val := range sub { - buf = strings.Replace(buf, key, val, -1) + var keys []string + for k := range sub { + keys = append(keys, k) + } + sort.Strings(keys) + + for _, key := range keys { + buf = strings.Replace(buf, key, sub[key], -1) } return } // SubstituteRune substitutes string chars with provided rune -// substitution map. +// substitution map. One pass. func SubstituteRune(s string, sub map[rune]string) string { var buf bytes.Buffer for _, c := range s { diff --git a/slug_test.go b/slug_test.go index 4a73b4f..4124154 100644 --- a/slug_test.go +++ b/slug_test.go @@ -90,8 +90,8 @@ func TestSlugMakeUserSubstituteLang(t *testing.T) { want string }{ {map[string]string{"'": " "}, "en", "That's great", "that-s-great"}, - {map[string]string{"&": "or"}, "en", "This & that", "this-or-that"}, // by default "&" => "and" - {map[string]string{"&": "or"}, "de", "This & that", "this-or-that"}, // by default "&" => "und" + {map[string]string{"&": "or"}, "en", "This & that", "this-or-that"}, // by default "&" => "and" + {map[string]string{"&": "or"}, "de", "This & that", "this-or-that"}, // by default "&" => "und" {map[string]string{"&": "or", "@": "the"}, "de", "@ This & that", "the-this-or-that"}, // by default "&" => "und", "@" => "an" } @@ -143,7 +143,8 @@ func TestSubstituteLang(t *testing.T) { want string }{ {map[string]string{"o": "no"}, "o o o", "no no no"}, - {map[string]string{"o": "no", "a": "or"}, "o a o", "no or no"}, + {map[string]string{"o": "no", "a": "or"}, "o a o", "no nor no"}, + {map[string]string{"a": "or", "o": "no"}, "o a o", "no nor no"}, {map[string]string{"'": " "}, "That's great", "That s great"}, } @@ -165,6 +166,7 @@ func TestSubstituteRuneLang(t *testing.T) { }{ {map[rune]string{'o': "no"}, "o o o", "no no no"}, {map[rune]string{'o': "no", 'a': "or"}, "o a o", "no or no"}, + {map[rune]string{'a': "or", 'o': "no"}, "o a o", "no or no"}, {map[rune]string{'\'': " "}, "That's great", "That s great"}, }