This commit is contained in:
Dobrosław Żybort 2013-03-13 15:14:21 +01:00
commit e39a0b1334
7 changed files with 286 additions and 0 deletions

30
.hgignore Normal file
View File

@ -0,0 +1,30 @@
## Defaults
syntax: glob
## Special files
*~
[_]*
## Compiled Go source
[568vq].out
*.[568vq]
*.[ao]
*.exe
## Compiled Cgo source
*.cgo*
*.dll
*.so
## Data
*.bin
## Logs and databases
*.db
*.log
*.sql
*.sqlite
## OS generated files
Icon?
# * * *

43
README.md Normal file
View File

@ -0,0 +1,43 @@
slug
====
Package `slug` generate slug from unicode string. URL-friendly slugify with
multiple languages support.
[Documentation online](http://godoc.org/bitbucket.org/gosimple/slug)
## Example
package main
import(
"bitbucket.org/gosimple/slug"
"fmt"
)
text := slug.Make("Hellö Wörld хелло ворлд")
fmt.Println(text) // Will print: hello-world-khello-vorld
someText := slug.Make("影師")
fmt.Println(someText) // Will print: ying-shi
enText := slug.MakeLang("This & that", "en")
fmt.Println(enText) // Will print: this-and-that
deText := slug.MakeLang("Diese & Dass", "de")
fmt.Println(deText) // Will print: diese-und-dass
### Requests or bugs?
<https://bitbucket.org/gosimple/slug/issues>
## Installation
go get -u bitbucket.org/gosimple/slug
## License
The source files are distributed under the
[Mozilla Public License, version 2.0](http://mozilla.org/MPL/2.0/),
unless otherwise noted.
Please read the [FAQ](http://www.mozilla.org/MPL/2.0/FAQ.html)
if you have further questions regarding the license.

16
default_substitution.go Normal file
View File

@ -0,0 +1,16 @@
// Copyright 2013 by Dobrosław Żybort. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package slug
var defaultSub = map[rune]string{
'"': "",
'\'': "",
'': "",
'': "-", // figure dash
'': "-", // en dash
'—': "-", // em dash
'―': "-", // horizontal bar
}

35
doc.go Normal file
View File

@ -0,0 +1,35 @@
// Copyright 2013 by Dobrosław Żybort. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
/*
Package slug generate slug from unicode string. URL-friendly slugify with
multiple languages support.
Example:
package main
import(
"bitbucket.org/gosimple/slug"
"fmt"
)
text := slug.Make("Hellö Wörld хелло ворлд")
fmt.Println(text) // Will print hello-world-khello-vorld
someText := slug.Make("影師")
fmt.Println(someText) // Will print: ying-shi
enText := slug.MakeLang("This & that", "en")
fmt.Println(enText) // Will print 'this-and-that'
deText := slug.MakeLang("Diese & Dass", "de")
fmt.Println(deText) // Will print 'diese-und-dass'
Requests or bugs?
https://bitbucket.org/gosimple/slug/issues
*/
package slug

21
languages_substitution.go Normal file
View File

@ -0,0 +1,21 @@
// Copyright 2013 by Dobrosław Żybort. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package slug
var deSub = map[rune]string{
'&': "und",
'@': "an",
}
var enSub = map[rune]string{
'&': "and",
'@': "at",
}
var plSub = map[rune]string{
'&': "i",
'@': "na",
}

61
slug.go Normal file
View File

@ -0,0 +1,61 @@
// Copyright 2013 by Dobrosław Żybort. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package slug
import (
"github.com/fiam/gounidecode/unidecode"
"regexp"
"strings"
)
//=============================================================================
// Make returns slug generated from provided string. Will use "en" as language
// substitution.
func Make(s string) (slug string) {
return MakeLang(s, "en")
}
// MakeLang returns slug generated from provided string and will use provided
// language for chars substitution.
func MakeLang(s string, lang string) (slug string) {
slug = strings.TrimSpace(s)
// Select substitution language
switch lang {
case "de":
slug = substitute(slug, deSub)
case "en":
slug = substitute(slug, enSub)
case "pl":
slug = substitute(slug, plSub)
default: // fallback to "en" if lang not found
slug = substitute(slug, enSub)
}
slug = substitute(slug, defaultSub)
slug = unidecode.Unidecode(slug)
slug = strings.ToLower(slug)
slug = regexp.MustCompile("[^a-z0-9-_]").ReplaceAllString(slug, "-")
slug = regexp.MustCompile("-+").ReplaceAllString(slug, "-")
slug = strings.Trim(slug, "-")
return slug
}
// Substitute string chars with provided substitution map.
func substitute(s string, sub map[rune]string) (buf string) {
for _, c := range s {
if d, ok := sub[c]; ok {
buf += d
} else {
buf += string(c)
}
}
return
}

80
slug_test.go Normal file
View File

@ -0,0 +1,80 @@
// Copyright 2013 by Dobrosław Żybort. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
package slug
import (
"testing"
)
//=============================================================================
var SlugMakeTests = []struct {
in string
out string
}{
{"DOBROSLAWZYBORT", "dobroslawzybort"},
{"Dobroslaw Zybort", "dobroslaw-zybort"},
{" Dobroslaw Zybort ?", "dobroslaw-zybort"},
{"Dobrosław Żybort", "dobroslaw-zybort"},
{"Ala ma 6 kotów.", "ala-ma-6-kotow"},
{"áÁàÀãÃâÂäÄąĄą̊Ą̊", "aaaaaaaaaaaaaa"},
{"ćĆĉĈçÇ", "cccccc"},
{"éÉèÈẽẼêÊëËęĘ", "eeeeeeeeeeee"},
{"íÍìÌĩĨîÎïÏįĮ", "iiiiiiiiiiii"},
{"łŁ", "ll"},
{"ńŃ", "nn"},
{"óÓòÒõÕôÔöÖǫǪǭǬø", "ooooooooooooooo"},
{"śŚ", "ss"},
{"úÚùÙũŨûÛüÜųŲ", "uuuuuuuuuuuu"},
{"y̨Y̨", "yy"},
{"źŹżŹ", "zzzz"},
{"·/,:;`˜'\"", ""},
{"20002013", "2000-2013"},
{"style—not", "style-not"},
{"test_slug", "test_slug"},
{"Æ", "ae"},
{"Ich heiße", "ich-heisse"},
{"This & that", "this-and-that"},
{"fácil €", "facil-eu"},
{"smile ☺", "smile"},
{"Hellö Wörld хелло ворлд", "hello-world-khello-vorld"},
{"\"C'est déjà lété.\"", "cest-deja-lete"},
{"jaja---lol-méméméoo--a", "jaja-lol-mememeoo-a"},
{"影師", "ying-shi"},
}
func TestSlugMake(t *testing.T) {
for index, st := range SlugMakeTests {
slug := Make(st.in)
if st.out != slug {
t.Errorf(
"%d. Make(%v) => out = %v, want %v",
index, st.in, slug, st.out)
}
}
}
var SlugMakeLangTests = []struct {
lang string
in string
out string
}{
{"en", "This & that", "this-and-that"},
{"de", "This & that", "this-und-that"},
}
func TestSlugMakeLang(t *testing.T) {
for index, smlt := range SlugMakeLangTests {
slug := MakeLang(smlt.in, smlt.lang)
if smlt.out != slug {
t.Errorf(
"%d. MakeLang(%v, \"%v\") => out = %v, want %v",
index, smlt.in, smlt.lang, slug, smlt.out)
}
}
}