wikitext-parser/list.go
2022-02-20 20:19:16 +01:00

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
}