1
0
mirror of https://github.com/danog/gojekyll.git synced 2024-11-27 08:44:41 +01:00
gojekyll/filters/smartify.go
2017-07-09 13:00:25 -04:00

70 lines
1.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}