220 lines
5.2 KiB
Go
220 lines
5.2 KiB
Go
package wikitext_parser
|
|
|
|
import "strings"
|
|
|
|
type DescriptionList struct {
|
|
Name []interface{}
|
|
Entries []interface{}
|
|
}
|
|
|
|
type UnorderedList struct {
|
|
Entries []interface{}
|
|
}
|
|
|
|
func ParseUnorderedList(text string, index int, depth int, indent int, startCharacter byte) (i int, list *UnorderedList) {
|
|
|
|
list = &UnorderedList{}
|
|
var c byte
|
|
lastToken := index
|
|
|
|
var currentValue []interface{}
|
|
|
|
addValue := func() int {
|
|
if lastToken < len(text) && i-lastToken > 0 {
|
|
t := strings.TrimSpace(text[lastToken:i])
|
|
if len(t) > 0 {
|
|
currentValue = append(currentValue, text[lastToken:i])
|
|
}
|
|
|
|
return len(t)
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
afterNewLine := true
|
|
processIndent := true
|
|
|
|
indentation := 0
|
|
|
|
for i = index; i < len(text); i++ {
|
|
c = text[i]
|
|
|
|
if c == ' ' || c == '\t' {
|
|
//keep the check for new line
|
|
if !afterNewLine {
|
|
processIndent = false
|
|
}
|
|
} else if processIndent && c == startCharacter {
|
|
indentation++
|
|
lastToken = i + 1
|
|
afterNewLine = false
|
|
} else if afterNewLine { //no new list values
|
|
if len(currentValue) > 0 {
|
|
list.Entries = append(list.Entries, currentValue)
|
|
currentValue = []interface{}{}
|
|
}
|
|
return lastToken, list
|
|
} else if indentation > indent {
|
|
if len(currentValue) > 0 {
|
|
list.Entries = append(list.Entries, currentValue)
|
|
currentValue = []interface{}{}
|
|
}
|
|
var level *UnorderedList
|
|
var scanIndex int
|
|
scanIndex, level = ParseUnorderedList(text, lastToken-indentation, depth+1, indentation, startCharacter)
|
|
if level != nil {
|
|
list.Entries = append(list.Entries, level)
|
|
}
|
|
lastToken = scanIndex
|
|
i = scanIndex - 1
|
|
indentation = 0
|
|
afterNewLine = true
|
|
processIndent = true
|
|
} else if indentation < indent {
|
|
if len(currentValue) > 0 {
|
|
list.Entries = append(list.Entries, currentValue)
|
|
currentValue = []interface{}{}
|
|
}
|
|
return lastToken - indentation, list
|
|
} else if c == '\n' {
|
|
addValue()
|
|
if len(currentValue) > 0 {
|
|
list.Entries = append(list.Entries, currentValue)
|
|
currentValue = []interface{}{}
|
|
}
|
|
indentation = 0
|
|
lastToken = i + 1
|
|
afterNewLine = true
|
|
processIndent = true
|
|
} else if (c == '{' && i < len(text)-1 && text[i+1] == '{') || (c == '[' && i < len(text)-1 && text[i+1] == '[') {
|
|
addValue()
|
|
var tpl *Template
|
|
var scanIndex int
|
|
scanIndex, tpl = ParseTemplate(text, i+2, depth+1, c)
|
|
if tpl != nil {
|
|
currentValue = append(currentValue, tpl)
|
|
}
|
|
lastToken = scanIndex
|
|
i = scanIndex - 1
|
|
} else if (c == '{' && i < len(text)-1 && text[i+1] != '{' && text[i+1] != '[') || (c == '[' && i < len(text)-1 && text[i+1] != '[' && text[i+1] != '{') {
|
|
addValue()
|
|
var link *Link
|
|
var scanIndex int
|
|
scanIndex, link = ParseLink(text, i+1, depth+1, c)
|
|
if link != nil {
|
|
currentValue = append(currentValue, link)
|
|
}
|
|
lastToken = scanIndex
|
|
i = scanIndex - 1
|
|
} else if c == '<' { //html trigger
|
|
addValue()
|
|
var html *HTML
|
|
var scanIndex int
|
|
scanIndex, html = ParseHTML(text, i, depth+1)
|
|
if html != nil {
|
|
currentValue = append(currentValue, html)
|
|
}
|
|
lastToken = scanIndex
|
|
i = scanIndex - 1
|
|
} else {
|
|
processIndent = false
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func ParseDescriptionList(text string, index int, depth int) (i int, list *DescriptionList) {
|
|
|
|
var c byte
|
|
lastToken := index
|
|
|
|
list = &DescriptionList{}
|
|
|
|
hasKey := false
|
|
|
|
addValue := func() int {
|
|
if lastToken < len(text) && i-lastToken > 0 {
|
|
t := strings.TrimSpace(text[lastToken:i])
|
|
if len(t) > 0 {
|
|
if !hasKey {
|
|
list.Name = append(list.Name, text[lastToken:i])
|
|
} else {
|
|
list.Entries = append(list.Entries, text[lastToken:i])
|
|
}
|
|
}
|
|
|
|
return len(t)
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
afterNewLine := false
|
|
|
|
for i = index; i < len(text); i++ {
|
|
c = text[i]
|
|
|
|
if c == ' ' || c == '\t' {
|
|
//keep the check for new line
|
|
} else if c == ':' {
|
|
addValue()
|
|
lastToken = i + 1
|
|
afterNewLine = false
|
|
hasKey = true
|
|
} else if afterNewLine { //no new list values
|
|
return lastToken, list
|
|
} else if c == '\n' {
|
|
addValue()
|
|
lastToken = i + 1
|
|
afterNewLine = true
|
|
hasKey = true
|
|
} else if (c == '{' && i < len(text)-1 && text[i+1] == '{') || (c == '[' && i < len(text)-1 && text[i+1] == '[') {
|
|
addValue()
|
|
var tpl *Template
|
|
var scanIndex int
|
|
scanIndex, tpl = ParseTemplate(text, i+2, depth+1, c)
|
|
if tpl != nil {
|
|
if !hasKey {
|
|
list.Name = append(list.Name, tpl)
|
|
} else {
|
|
list.Entries = append(list.Entries, tpl)
|
|
}
|
|
}
|
|
lastToken = scanIndex
|
|
i = scanIndex - 1
|
|
} else if (c == '{' && i < len(text)-1 && text[i+1] != '{' && text[i+1] != '[') || (c == '[' && i < len(text)-1 && text[i+1] != '[' && text[i+1] != '{') {
|
|
addValue()
|
|
var link *Link
|
|
var scanIndex int
|
|
scanIndex, link = ParseLink(text, i+1, depth+1, c)
|
|
if link != nil {
|
|
if !hasKey {
|
|
list.Name = append(list.Name, link)
|
|
} else {
|
|
list.Entries = append(list.Entries, link)
|
|
}
|
|
}
|
|
lastToken = scanIndex
|
|
i = scanIndex - 1
|
|
} else if c == '<' { //html trigger
|
|
addValue()
|
|
var html *HTML
|
|
var scanIndex int
|
|
scanIndex, html = ParseHTML(text, i, depth+1)
|
|
if html != nil {
|
|
if !hasKey {
|
|
list.Name = append(list.Name, html)
|
|
} else {
|
|
list.Entries = append(list.Entries, html)
|
|
}
|
|
}
|
|
lastToken = scanIndex
|
|
i = scanIndex - 1
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|