revert for now, this is probably not the slow point for anything

This commit is contained in:
Ted Unangst 2019-12-02 02:48:12 -05:00
parent 95dfba8d14
commit 2668c04b8e
1 changed files with 65 additions and 112 deletions

View File

@ -16,11 +16,11 @@
package main package main
import ( import (
"bytes"
"fmt" "fmt"
"regexp" "regexp"
"strings" "strings"
"golang.org/x/net/html"
"humungus.tedunangst.com/r/webs/synlight" "humungus.tedunangst.com/r/webs/synlight"
) )
@ -37,8 +37,27 @@ var re_lister = regexp.MustCompile(`((^|\n)(\+|-).*)+\n?`)
var lighter = synlight.New(synlight.Options{Format: synlight.HTML}) var lighter = synlight.New(synlight.Options{Format: synlight.HTML})
// fewer side effects than html.EscapeString func markitzero(s string) string {
func fasterescaper(s []byte) []byte { // prepare the string
s = strings.TrimSpace(s)
s = strings.Replace(s, "\r", "", -1)
// save away the code blocks so we don't mess them up further
var bigcodes, lilcodes, images []string
s = re_bigcoder.ReplaceAllStringFunc(s, func(code string) string {
bigcodes = append(bigcodes, code)
return "``````"
})
s = re_coder.ReplaceAllStringFunc(s, func(code string) string {
lilcodes = append(lilcodes, code)
return "`x`"
})
s = re_imgfix.ReplaceAllStringFunc(s, func(img string) string {
images = append(images, img)
return "<img x>"
})
// fewer side effects than html.EscapeString
buf := make([]byte, 0, len(s)) buf := make([]byte, 0, len(s))
for _, c := range []byte(s) { for _, c := range []byte(s) {
switch c { switch c {
@ -52,130 +71,64 @@ func fasterescaper(s []byte) []byte {
buf = append(buf, c) buf = append(buf, c)
} }
} }
return buf s = string(buf)
}
func replaceifmatch(re *regexp.Regexp, input []byte, repl []byte) []byte {
if !re.Match(input) {
return input
}
return re.ReplaceAll(input, repl)
}
func replaceifmatchfn(re *regexp.Regexp, input []byte, repl func([]byte) []byte) []byte {
if !re.Match(input) {
return input
}
return re.ReplaceAllFunc(input, repl)
}
func replacenocopy(input []byte, pat []byte, repl []byte) []byte {
if !bytes.Contains(input, pat) {
return input
}
return bytes.Replace(input, pat, repl, -1)
}
func markitzero(ss string) string {
s := []byte(ss)
// prepare the string
s = bytes.TrimSpace(s)
s = replacenocopy(s, []byte("\r"), []byte(""))
hascode := bytes.Contains(s, []byte("`"))
// save away the code blocks so we don't mess them up further
var bigcodes, lilcodes, images [][]byte
if hascode {
s = replaceifmatchfn(re_bigcoder, s, func(code []byte) []byte {
bigcodes = append(bigcodes, code)
return []byte("``````")
})
s = replaceifmatchfn(re_coder, s, func(code []byte) []byte {
lilcodes = append(lilcodes, code)
return []byte("`x`")
})
}
s = replaceifmatchfn(re_imgfix, s, func(img []byte) []byte {
images = append(images, img)
return []byte("<img x>")
})
s = fasterescaper(s)
// mark it zero // mark it zero
if bytes.Contains(s, []byte("http")) { s = re_link.ReplaceAllStringFunc(s, linkreplacer)
s = replaceifmatchfn(re_link, s, linkreplacer) s = re_zerolink.ReplaceAllString(s, `<a href="$2">$1</a>`)
} s = re_bolder.ReplaceAllString(s, "$1<b>$2</b>$3")
s = replaceifmatch(re_zerolink, s, []byte(`<a href="$2">$1</a>`)) s = re_italicer.ReplaceAllString(s, "$1<i>$2</i>$3")
if bytes.Contains(s, []byte("**")) { s = re_quoter.ReplaceAllString(s, "<blockquote>$1<br><cite>$3</cite></blockquote><p>")
s = replaceifmatch(re_bolder, s, []byte("$1<b>$2</b>$3")) s = re_reciter.ReplaceAllString(s, "$1$2$3")
} s = strings.Replace(s, "\n---\n", "<hr><p>", -1)
if bytes.Contains(s, []byte("*")) {
s = replaceifmatch(re_italicer, s, []byte("$1<i>$2</i>$3"))
}
if bytes.Contains(s, []byte("&gt; ")) {
s = replaceifmatch(re_quoter, s, []byte("<blockquote>$1<br><cite>$3</cite></blockquote><p>"))
s = replaceifmatch(re_reciter, s, []byte("$1$2$3"))
}
s = replacenocopy(s, []byte("\n---\n"), []byte("<hr><p>"))
if bytes.Contains(s, []byte("\n+")) || bytes.Contains(s, []byte("\n-")) { s = re_lister.ReplaceAllStringFunc(s, func(m string) string {
s = replaceifmatchfn(re_lister, s, func(m []byte) []byte { m = strings.Trim(m, "\n")
m = bytes.Trim(m, "\n") items := strings.Split(m, "\n")
items := bytes.Split(m, []byte("\n")) r := "<ul>"
r := []byte("<ul>")
for _, item := range items { for _, item := range items {
r = append(r, []byte("<li>")...) r += "<li>" + strings.Trim(item[1:], " ")
r = append(r, bytes.Trim(item[1:], " ")...)
} }
r = append(r, []byte("</ul><p>")...) r += "</ul><p>"
return r return r
}) })
}
// restore images // restore images
s = replacenocopy(s, []byte("&lt;img x&gt;"), []byte("<img x>")) s = strings.Replace(s, "&lt;img x&gt;", "<img x>", -1)
s = replaceifmatchfn(re_imgfix, s, func([]byte) []byte { s = re_imgfix.ReplaceAllStringFunc(s, func(string) string {
img := images[0] img := images[0]
images = images[1:] images = images[1:]
return img return img
}) })
// now restore the code blocks // now restore the code blocks
if hascode { s = re_coder.ReplaceAllStringFunc(s, func(string) string {
s = replaceifmatchfn(re_coder, s, func([]byte) []byte {
code := lilcodes[0] code := lilcodes[0]
lilcodes = lilcodes[1:] lilcodes = lilcodes[1:]
return fasterescaper(code) code = html.EscapeString(code)
return code
}) })
s = replaceifmatchfn(re_bigcoder, s, func([]byte) []byte { s = re_bigcoder.ReplaceAllStringFunc(s, func(string) string {
code := bigcodes[0] code := bigcodes[0]
bigcodes = bigcodes[1:] bigcodes = bigcodes[1:]
m := re_bigcoder.FindSubmatch(code) m := re_bigcoder.FindStringSubmatch(code)
var buf bytes.Buffer return "<pre><code>" + lighter.HighlightString(m[2], m[1]) + "</code></pre><p>"
buf.WriteString("<pre><code>")
lighter.Highlight(m[2], string(m[1]), &buf)
buf.WriteString("</code></pre><p>")
return buf.Bytes()
}) })
s = replaceifmatch(re_coder, s, []byte("<code>$1</code>")) s = re_coder.ReplaceAllString(s, "<code>$1</code>")
}
// some final fixups // some final fixups
s = replacenocopy(s, []byte("\n"), []byte("<br>")) s = strings.Replace(s, "\n", "<br>", -1)
s = replacenocopy(s, []byte("<br><blockquote>"), []byte("<blockquote>")) s = strings.Replace(s, "<br><blockquote>", "<blockquote>", -1)
s = replacenocopy(s, []byte("<br><cite></cite>"), []byte("")) s = strings.Replace(s, "<br><cite></cite>", "", -1)
s = replacenocopy(s, []byte("<br><pre>"), []byte("<pre>")) s = strings.Replace(s, "<br><pre>", "<pre>", -1)
s = replacenocopy(s, []byte("<br><ul>"), []byte("<ul>")) s = strings.Replace(s, "<br><ul>", "<ul>", -1)
s = replacenocopy(s, []byte("<p><br>"), []byte("<p>")) s = strings.Replace(s, "<p><br>", "<p>", -1)
return string(s) return s
} }
func linkreplacer(burl []byte) []byte { func linkreplacer(url string) string {
url := string(burl)
if url[0:2] == "](" { if url[0:2] == "](" {
return burl return url
} }
prefix := "" prefix := ""
for !strings.HasPrefix(url, "http") { for !strings.HasPrefix(url, "http") {
@ -199,5 +152,5 @@ func linkreplacer(burl []byte) []byte {
if addparen { if addparen {
url += ")" url += ")"
} }
return []byte(prefix + url) return prefix + url
} }