mirror of
https://github.com/danog/gojekyll.git
synced 2024-11-27 08:44:41 +01:00
70 lines
1.9 KiB
Go
70 lines
1.9 KiB
Go
package filters
|
||
|
||
// This file contains a very inefficient implementation, that scans the string multiple times.
|
||
// Replace it by a transducer if it shows up in hot spots.
|
||
|
||
import (
|
||
"fmt"
|
||
"regexp"
|
||
"strings"
|
||
)
|
||
|
||
var smartifyTransforms = []struct {
|
||
match *regexp.Regexp
|
||
repl string
|
||
}{
|
||
{regexp.MustCompile("(^|[^[:alnum:]])``(.+?)''"), "$1“$2”"},
|
||
{regexp.MustCompile(`(^|[^[:alnum:]])'`), "$1‘"},
|
||
{regexp.MustCompile(`'`), "’"},
|
||
{regexp.MustCompile(`(^|[^[:alnum:]])"`), "$1“"},
|
||
{regexp.MustCompile(`"($|[^[:alnum:]])`), "”$1"},
|
||
{regexp.MustCompile(`(^|\s)--($|\s)`), "$1–$2"},
|
||
{regexp.MustCompile(`(^|\s)---($|\s)`), "$1—$2"},
|
||
}
|
||
|
||
// replace these wherever they appear
|
||
var smartifyReplaceSpans = map[string]string{
|
||
"...": "…",
|
||
"(c)": "©",
|
||
"(r)": "®",
|
||
"(tm)": "™",
|
||
}
|
||
|
||
// replace these only if bounded by space or word boundaries
|
||
var smartifyReplaceWords = map[string]string{
|
||
// "---": "–",
|
||
// "--": "—",
|
||
}
|
||
|
||
var smartifyReplacements map[string]string
|
||
var smartifyReplacementPattern *regexp.Regexp
|
||
|
||
func init() {
|
||
smartifyReplacements = map[string]string{}
|
||
disjuncts := []string{}
|
||
regexQuoter := regexp.MustCompile(`[\(\)\.]`)
|
||
escape := func(s string) string {
|
||
return regexQuoter.ReplaceAllString(s, `\$0`)
|
||
}
|
||
for k, v := range smartifyReplaceSpans {
|
||
disjuncts = append(disjuncts, escape(k))
|
||
smartifyReplacements[k] = v
|
||
}
|
||
for k, v := range smartifyReplaceWords {
|
||
disjuncts = append(disjuncts, fmt.Sprintf(`(\b|\s|^)%s(\b|\s|$)`, escape(k)))
|
||
smartifyReplacements[k] = fmt.Sprintf("$1%s$2", v)
|
||
}
|
||
p := fmt.Sprintf(`(%s)`, strings.Join(disjuncts, `|`))
|
||
smartifyReplacementPattern = regexp.MustCompile(p)
|
||
}
|
||
|
||
func smartifyFilter(s string) string {
|
||
for _, rule := range smartifyTransforms {
|
||
s = rule.match.ReplaceAllString(s, rule.repl)
|
||
}
|
||
s = smartifyReplacementPattern.ReplaceAllStringFunc(s, func(w string) string {
|
||
return smartifyReplacements[w]
|
||
})
|
||
return s
|
||
}
|