bbcode: separate string/func transformations into an interface

This commit is contained in:
mappu 2018-04-02 16:46:22 +12:00
parent 91887bcee5
commit ee4ed51530

View File

@ -32,46 +32,63 @@ func (this *BBCodeRenderer) Reset() {
this.CodePresent = false
}
//
type transformation interface {
MatchString(in string) bool
Apply(in string) string
}
type pregReplaceRule struct {
match *regexp.Regexp
*regexp.Regexp
replace string
}
func (this pregReplaceRule) Apply(in string) string {
return this.ReplaceAllString(in, this.replace)
}
type pregReplaceFunc struct {
*regexp.Regexp
replaceFunc func([]string) string
}
func (this pregReplaceFunc) Apply(in string) string {
return PregReplaceCallback(this.Regexp, this.replaceFunc, in)
}
// Internal part of BBCode rendering.
// It handles most leaf-level tags.
func (this *BBCodeRenderer) bbcode(data string) string {
s_to_r := []pregReplaceRule{
pregReplaceRule{regexp.MustCompile(`(?si)\[h\](.*?)\[/h\]`), `<h2>$1</h2>`, nil},
pregReplaceRule{regexp.MustCompile(`(?si)\[b\](.*?)\[/b\]`), `<b>$1</b>`, nil},
pregReplaceRule{regexp.MustCompile(`(?si)\[i\](.*?)\[/i\]`), `<i>$1</i>`, nil},
pregReplaceRule{regexp.MustCompile(`(?si)\[u\](.*?)\[/u\]`), `<u>$1</u>`, nil},
pregReplaceRule{regexp.MustCompile(`(?si)\[s\](.*?)\[/s\]`), `<span class="s">$1</span>`, nil},
pregReplaceRule{regexp.MustCompile(`(?si)\[spoiler\](.*?)\[/spoiler\]`), `<span class="spoiler">$1</span>`, nil},
pregReplaceRule{regexp.MustCompile(`(?si)\[img\](.*?)\[/img\]`), `<img alt="" src="$1">`, nil},
pregReplaceRule{regexp.MustCompile(`(?si)\[list\](.*?)\[/list\]`), `<ul><li>$1</li></ul>`, nil},
pregReplaceRule{regexp.MustCompile(`(?si)\[\*\]`), `</li><li>`, nil},
pregReplaceRule{regexp.MustCompile(`(?si)\[url=(.*?)\](.*?)\[/url\]`), `<a rel="noreferrer" href="$1">$2</a>`, nil},
pregReplaceRule{regexp.MustCompile(`(?si)\[article=(.*?)\](.*?)\[/article\]`), "", func(m []string) string {
s_to_r := []transformation{
pregReplaceRule{regexp.MustCompile(`(?si)\[h\](.*?)\[/h\]`), `<h2>$1</h2>`},
pregReplaceRule{regexp.MustCompile(`(?si)\[b\](.*?)\[/b\]`), `<b>$1</b>`},
pregReplaceRule{regexp.MustCompile(`(?si)\[i\](.*?)\[/i\]`), `<i>$1</i>`},
pregReplaceRule{regexp.MustCompile(`(?si)\[u\](.*?)\[/u\]`), `<u>$1</u>`},
pregReplaceRule{regexp.MustCompile(`(?si)\[s\](.*?)\[/s\]`), `<span class="s">$1</span>`},
pregReplaceRule{regexp.MustCompile(`(?si)\[spoiler\](.*?)\[/spoiler\]`), `<span class="spoiler">$1</span>`},
pregReplaceRule{regexp.MustCompile(`(?si)\[img\](.*?)\[/img\]`), `<img alt="" src="$1">`},
pregReplaceRule{regexp.MustCompile(`(?si)\[list\](.*?)\[/list\]`), `<ul><li>$1</li></ul>`},
pregReplaceRule{regexp.MustCompile(`(?si)\[\*\]`), `</li><li>`},
pregReplaceRule{regexp.MustCompile(`(?si)\[url=(.*?)\](.*?)\[/url\]`), `<a rel="noreferrer" href="$1">$2</a>`},
pregReplaceFunc{regexp.MustCompile(`(?si)\[article=(.*?)\](.*?)\[/article\]`), func(m []string) string {
return `<a href="` + template.HTMLEscapeString(this.baseUrl+`view/`+url.PathEscape(m[1])) + `">` + m[2] + `</a>`
}},
pregReplaceRule{regexp.MustCompile(`(?si)\[rev=(.*?)\](.*?)\[/rev\]`), "", func(m []string) string {
pregReplaceFunc{regexp.MustCompile(`(?si)\[rev=(.*?)\](.*?)\[/rev\]`), func(m []string) string {
return `<a href="` + template.HTMLEscapeString(this.baseUrl+`archive/`+url.PathEscape(m[1])) + `">` + m[2] + `</a>`
}},
pregReplaceRule{regexp.MustCompile(`(?si)\[imgur\](.*?)\.(...)\[/imgur\]`),
`<a href="https://i.imgur.com/${1}.${2}"><img class="imgur" alt="" src="https://i.imgur.com/${1}s.${2}" ></a>`,
nil,
},
pregReplaceRule{
regexp.MustCompile(`(?si)\[youtube](.*?)\[/youtube\]`),
`<iframe width="560" height="315" src="https://www.youtube-nocookie.com/embed/${1}" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>`,
nil,
},
pregReplaceRule{regexp.MustCompile(`(?si)\[section=(.*?)](.*?)\[/section\]`), "", func(m []string) string {
pregReplaceFunc{regexp.MustCompile(`(?si)\[section=(.*?)](.*?)\[/section\]`), func(m []string) string {
return `<div class="section"><a class="sectionheader" href="javascript:;" onclick="ts(this);">` + m[1] + `</a><span style="display:none;">` + strings.TrimSpace(m[2]) + `</span></div>`
}},
}
@ -80,20 +97,14 @@ func (this *BBCodeRenderer) bbcode(data string) string {
s_to_r = append(s_to_r,
pregReplaceRule{regexp.MustCompile(`(?si)\[` + regexp.QuoteMeta(this.ContentedTag) + `\](.*?)\[/` + regexp.QuoteMeta(this.ContentedTag) + `\]`),
`<a href="` + html.EscapeString(this.ContentedURL) + `p/${1}"><img class="imgur" alt="" src="` + html.EscapeString(this.ContentedURL) + `thumb/s/${1}" ></a>`,
nil,
},
)
}
for _, prr := range s_to_r {
for prr.match.MatchString(data) { // repeat until all recursive replacements are consumed
if len(prr.replace) > 0 {
data = prr.match.ReplaceAllString(data, prr.replace)
} else {
data = PregReplaceCallback(prr.match, prr.replaceFunc, data)
}
for prr.MatchString(data) { // repeat until all recursive replacements are consumed
data = prr.Apply(data)
}
}
return data