ca7c369e9e
Added #rid for linking to a specific post. Added a forum_exists function. Removed the null bytes from the posts The report system now uses #rid, #tid and numeric mentions instead of raw HTML. Improved the custom parser to take control characters into account. It also now parses items at the start of the post. Fixed the padding on the buttons on the profiles. #tid now takes into account whether the topic it links to exists.
371 lines
11 KiB
Go
371 lines
11 KiB
Go
package main
|
|
//import "log"
|
|
//import "fmt"
|
|
import "bytes"
|
|
//import "strings"
|
|
import "strconv"
|
|
import "regexp"
|
|
import "time"
|
|
import "math/rand"
|
|
|
|
var random *rand.Rand
|
|
var bbcode_invalid_number []byte
|
|
var bbcode_missing_tag []byte
|
|
|
|
var bbcode_bold *regexp.Regexp
|
|
var bbcode_italic *regexp.Regexp
|
|
var bbcode_underline *regexp.Regexp
|
|
var bbcode_strikethrough *regexp.Regexp
|
|
var bbcode_url *regexp.Regexp
|
|
var bbcode_url_label *regexp.Regexp
|
|
var bbcode_quotes *regexp.Regexp
|
|
|
|
func init() {
|
|
plugins["bbcode"] = NewPlugin("bbcode","BBCode","Azareal","http://github.com/Azareal","","","",init_bbcode,nil,deactivate_bbcode)
|
|
}
|
|
|
|
func init_bbcode() {
|
|
//plugins["bbcode"].AddHook("parse_assign", bbcode_parse_without_code)
|
|
plugins["bbcode"].AddHook("parse_assign", bbcode_full_parse)
|
|
|
|
bbcode_invalid_number = []byte("<span style='color: red;'>[Invalid Number]</span>")
|
|
bbcode_missing_tag = []byte("<span style='color: red;'>[Missing Tag]</span>")
|
|
|
|
bbcode_bold = regexp.MustCompile(`(?s)\[b\](.*)\[/b\]`)
|
|
bbcode_italic = regexp.MustCompile(`(?s)\[i\](.*)\[/i\]`)
|
|
bbcode_underline = regexp.MustCompile(`(?s)\[u\](.*)\[/u\]`)
|
|
bbcode_strikethrough = regexp.MustCompile(`(?s)\[s\](.*)\[/s\]`)
|
|
urlpattern := `(http|https|ftp|mailto*)(:??)\/\/([\.a-zA-Z\/]+)`
|
|
bbcode_url = regexp.MustCompile(`\[url\]` + urlpattern + `\[/url\]`)
|
|
bbcode_url_label = regexp.MustCompile(`(?s)\[url=` + urlpattern + `\](.*)\[/url\]`)
|
|
bbcode_quotes = regexp.MustCompile(`\[quote\](.*)\[/quote\]`)
|
|
|
|
random = rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
}
|
|
|
|
func deactivate_bbcode() {
|
|
//plugins["bbcode"].RemoveHook("parse_assign", bbcode_parse_without_code)
|
|
plugins["bbcode"].RemoveHook("parse_assign", bbcode_full_parse)
|
|
}
|
|
|
|
func bbcode_regex_parse(data interface{}) interface{} {
|
|
msg := data.(string)
|
|
msg = bbcode_bold.ReplaceAllString(msg,"<b>$1</b>")
|
|
msg = bbcode_italic.ReplaceAllString(msg,"<i>$1</i>")
|
|
msg = bbcode_underline.ReplaceAllString(msg,"<u>$1</u>")
|
|
msg = bbcode_strikethrough.ReplaceAllString(msg,"<s>$1</s>")
|
|
msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>")
|
|
msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>")
|
|
msg = bbcode_quotes.ReplaceAllString(msg,"<span class=\"postQuote\">$1</span>")
|
|
return msg
|
|
}
|
|
|
|
// Only does the simple BBCode like [u], [b], [i] and [s]
|
|
func bbcode_simple_parse(data interface{}) interface{} {
|
|
msg := data.(string)
|
|
msgbytes := []byte(msg)
|
|
has_u := false
|
|
has_b := false
|
|
has_i := false
|
|
has_s := false
|
|
for i := 0; (i + 2) < len(msgbytes); i++ {
|
|
if msgbytes[i] == '[' && msgbytes[i + 2] == ']' {
|
|
if msgbytes[i + 1] == 'b' && !has_b {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_b = true
|
|
} else if msgbytes[i + 1] == 'i' && !has_i {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_i = true
|
|
} else if msgbytes[i + 1] == 'u' && !has_u {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_u = true
|
|
} else if msgbytes[i + 1] == 's' && !has_s {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_s = true
|
|
}
|
|
i += 2
|
|
}
|
|
}
|
|
|
|
// There's an unclosed tag in there x.x
|
|
if has_i || has_u || has_b || has_s {
|
|
closer := []byte("</u></i></b></s>")
|
|
msgbytes = append(msgbytes, closer...)
|
|
}
|
|
return string(msgbytes)
|
|
}
|
|
|
|
// Here for benchmarking purposes. Might add a plugin setting for disabling [code] as it has it's paws everywhere
|
|
func bbcode_parse_without_code(data interface{}) interface{} {
|
|
msg := data.(string)
|
|
msgbytes := []byte(msg)
|
|
has_u := false
|
|
has_b := false
|
|
has_i := false
|
|
has_s := false
|
|
complex_bbc := false
|
|
for i := 0; (i + 3) < len(msgbytes); i++ {
|
|
if msgbytes[i] == '[' {
|
|
if msgbytes[i + 2] != ']' {
|
|
if msgbytes[i + 1] == '/' {
|
|
if msgbytes[i + 3] == ']' {
|
|
if msgbytes[i + 2] == 'b' {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 3] = '>'
|
|
has_b = false
|
|
} else if msgbytes[i + 2] == 'i' {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 3] = '>'
|
|
has_i = false
|
|
} else if msgbytes[i + 2] == 'u' {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 3] = '>'
|
|
has_u = false
|
|
} else if msgbytes[i + 2] == 's' {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 3] = '>'
|
|
has_s = false
|
|
}
|
|
i += 3
|
|
} else {
|
|
complex_bbc = true
|
|
}
|
|
} else {
|
|
complex_bbc = true
|
|
}
|
|
} else {
|
|
if msgbytes[i + 1] == 'b' && !has_b {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_b = true
|
|
} else if msgbytes[i + 1] == 'i' && !has_i {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_i = true
|
|
} else if msgbytes[i + 1] == 'u' && !has_u {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_u = true
|
|
} else if msgbytes[i + 1] == 's' && !has_s {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_s = true
|
|
}
|
|
i += 2
|
|
}
|
|
}
|
|
}
|
|
|
|
// There's an unclosed tag in there x.x
|
|
if has_i || has_u || has_b || has_s {
|
|
closer := []byte("</u></i></b></s>")
|
|
msgbytes = append(msgbytes, closer...)
|
|
}
|
|
|
|
// Copy the new complex parser over once the rough edges have been smoothed over
|
|
if complex_bbc {
|
|
msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>")
|
|
msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>")
|
|
msg = bbcode_quotes.ReplaceAllString(msg,"<span class=\"postQuote\">$1</span>")
|
|
}
|
|
return string(msgbytes)
|
|
}
|
|
|
|
// Does every type of BBCode
|
|
func bbcode_full_parse(data interface{}) interface{} {
|
|
msg := data.(string)
|
|
//fmt.Println("BBCode PrePre String:")
|
|
//fmt.Println("`"+msg+"`")
|
|
//fmt.Println("----")
|
|
msgbytes := []byte(msg)
|
|
has_u := false
|
|
has_b := false
|
|
has_i := false
|
|
has_s := false
|
|
has_c := false
|
|
complex_bbc := false
|
|
msgbytes = append(msgbytes,space_gap...)
|
|
//fmt.Println("BBCode Simple Pre:")
|
|
//fmt.Println("`"+string(msgbytes)+"`")
|
|
//fmt.Println("----")
|
|
for i := 0; i < len(msgbytes); i++ {
|
|
if msgbytes[i] == '[' {
|
|
if msgbytes[i + 2] != ']' {
|
|
if msgbytes[i + 1] == '/' {
|
|
if msgbytes[i + 3] == ']' {
|
|
if !has_c {
|
|
if msgbytes[i + 2] == 'b' {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 3] = '>'
|
|
has_b = false
|
|
} else if msgbytes[i + 2] == 'i' {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 3] = '>'
|
|
has_i = false
|
|
} else if msgbytes[i + 2] == 'u' {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 3] = '>'
|
|
has_u = false
|
|
} else if msgbytes[i + 2] == 's' {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 3] = '>'
|
|
has_s = false
|
|
}
|
|
i += 3
|
|
}
|
|
} else {
|
|
if msgbytes[i+2] == 'c' && msgbytes[i+3] == 'o' && msgbytes[i+4] == 'd' && msgbytes[i+5] == 'e' && msgbytes[i+6] == ']' {
|
|
has_c = false
|
|
i += 7
|
|
}
|
|
//if msglen >= (i+6) {
|
|
// fmt.Println("boo")
|
|
// fmt.Println(msglen)
|
|
// fmt.Println(i+6)
|
|
// fmt.Println(string(msgbytes[i:i+6]))
|
|
//}
|
|
complex_bbc = true
|
|
}
|
|
} else {
|
|
if msgbytes[i+1] == 'c' && msgbytes[i+2] == 'o' && msgbytes[i+3] == 'd' && msgbytes[i+4] == 'e' && msgbytes[i+5] == ']' {
|
|
has_c = true
|
|
i += 6
|
|
}
|
|
//if msglen >= (i+5) {
|
|
// fmt.Println("boo2")
|
|
// fmt.Println(string(msgbytes[i:i+5]))
|
|
//}
|
|
complex_bbc = true
|
|
}
|
|
} else if !has_c {
|
|
if msgbytes[i + 1] == 'b' && !has_b {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_b = true
|
|
} else if msgbytes[i + 1] == 'i' && !has_i {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_i = true
|
|
} else if msgbytes[i + 1] == 'u' && !has_u {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_u = true
|
|
} else if msgbytes[i + 1] == 's' && !has_s {
|
|
msgbytes[i] = '<'
|
|
msgbytes[i + 2] = '>'
|
|
has_s = true
|
|
}
|
|
i += 2
|
|
}
|
|
}
|
|
}
|
|
|
|
// There's an unclosed tag in there x.x
|
|
if has_i || has_u || has_b || has_s {
|
|
closer := []byte("</u></i></b></s>")
|
|
msgbytes = append(msgbytes, closer...)
|
|
}
|
|
|
|
if complex_bbc {
|
|
i := 0
|
|
var start int
|
|
var lastTag int
|
|
var outbytes []byte
|
|
//fmt.Println("BBCode Pre:")
|
|
//fmt.Println("`"+string(msgbytes)+"`")
|
|
//fmt.Println("----")
|
|
for ; i < len(msgbytes); i++ {
|
|
MainLoop:
|
|
if msgbytes[i] == '[' {
|
|
OuterComplex:
|
|
if msgbytes[i + 1] == 'u' {
|
|
if msgbytes[i+2] == 'r' && msgbytes[i+3] == 'l' && msgbytes[i+4] == ']' {
|
|
start = i + 5
|
|
outbytes = append(outbytes, msgbytes[lastTag:i]...)
|
|
i = start
|
|
i += partial_url_bytes_len(msgbytes[start:])
|
|
|
|
//fmt.Println("Partial Bytes:")
|
|
//fmt.Println(string(msgbytes[start:]))
|
|
//fmt.Println("-----")
|
|
if !bytes.Equal(msgbytes[i:i+6],[]byte("[/url]")) {
|
|
//fmt.Println("Invalid Bytes:")
|
|
//fmt.Println(string(msgbytes[i:i+6]))
|
|
//fmt.Println("-----")
|
|
outbytes = append(outbytes, invalid_url...)
|
|
goto MainLoop
|
|
}
|
|
|
|
outbytes = append(outbytes, url_open...)
|
|
outbytes = append(outbytes, msgbytes[start:i]...)
|
|
outbytes = append(outbytes, url_open2...)
|
|
outbytes = append(outbytes, msgbytes[start:i]...)
|
|
outbytes = append(outbytes, url_close...)
|
|
i += 6
|
|
lastTag = i
|
|
}
|
|
} else if msgbytes[i + 1] == 'r' {
|
|
if bytes.Equal(msgbytes[i+2:i+6],[]byte("and]")) {
|
|
outbytes = append(outbytes, msgbytes[lastTag:i]...)
|
|
start = i + 6
|
|
i = start
|
|
for ;; i++ {
|
|
if msgbytes[i] == '[' {
|
|
if !bytes.Equal(msgbytes[i+1:i+7],[]byte("/rand]")) {
|
|
outbytes = append(outbytes, bbcode_missing_tag...)
|
|
goto OuterComplex
|
|
}
|
|
break
|
|
} else if (len(msgbytes) - 1) < (i + 10) {
|
|
outbytes = append(outbytes, bbcode_missing_tag...)
|
|
goto OuterComplex
|
|
}
|
|
}
|
|
|
|
number, err := strconv.ParseInt(string(msgbytes[start:i]),10,64)
|
|
if err != nil {
|
|
outbytes = append(outbytes, bbcode_invalid_number...)
|
|
goto MainLoop
|
|
}
|
|
|
|
dat := []byte(strconv.FormatInt((random.Int63n(number)),10))
|
|
outbytes = append(outbytes, dat...)
|
|
//log.Print("Outputted the random number")
|
|
i += 7
|
|
lastTag = i
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//fmt.Println(string(outbytes))
|
|
if lastTag != i {
|
|
outbytes = append(outbytes, msgbytes[lastTag:]...)
|
|
//fmt.Println("Outbytes:")
|
|
//fmt.Println(`"`+string(outbytes)+`"`)
|
|
//fmt.Println("----")
|
|
}
|
|
|
|
if len(outbytes) != 0 {
|
|
//fmt.Println("BBCode Post:")
|
|
//fmt.Println(`"`+string(outbytes[0:len(outbytes) - 10])+`"`)
|
|
//fmt.Println("----")
|
|
msg = string(outbytes[0:len(outbytes) - 10])
|
|
} else {
|
|
msg = string(msgbytes[0:len(msgbytes) - 10])
|
|
}
|
|
|
|
//msg = bbcode_url.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$1$2//$3</i>")
|
|
msg = bbcode_url_label.ReplaceAllString(msg,"<a href=\"$1$2//$3\" rel=\"nofollow\">$4</i>")
|
|
msg = bbcode_quotes.ReplaceAllString(msg,"<span class=\"postQuote\">$1</span>")
|
|
// Convert [code] into class="codequotes"
|
|
//fmt.Println("guuuaaaa")
|
|
} else {
|
|
msg = string(msgbytes[0:len(msgbytes) - 10])
|
|
}
|
|
return msg
|
|
}
|