- Fix parser not producing the correct results - Add tests for everything - Add readme with example Ready for v1
89 lines
2.3 KiB
Go
89 lines
2.3 KiB
Go
package treeificator
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"git.mstar.dev/mstar/goutils/other"
|
|
)
|
|
|
|
func Marshal(raw string, informers ...Informer) Node {
|
|
prefixToInformer := map[string]Informer{}
|
|
maxPrefixLen := 0
|
|
for _, informer := range informers {
|
|
prefixToInformer[informer.GetPrefix()] = informer
|
|
if l := len(informer.GetPrefix()); l > maxPrefixLen {
|
|
maxPrefixLen = l
|
|
}
|
|
}
|
|
defaultInformer := &DefaultInformer{}
|
|
delete(prefixToInformer, defaultInformer.GetPrefix())
|
|
elems, consumed := marshal(raw, prefixToInformer, nil)
|
|
_ = consumed
|
|
return Node{
|
|
NodeType: defaultInformer,
|
|
Elements: elems,
|
|
}
|
|
}
|
|
|
|
// Return the elements in the given string, using the given informers, in order of appearance.
|
|
func marshal(
|
|
raw string,
|
|
informers map[string]Informer,
|
|
activeInformer Informer,
|
|
) ([]NodeElement, uint64) {
|
|
elements := []NodeElement{}
|
|
buffer := make([]rune, 0)
|
|
var consumed uint64 = 0
|
|
var insideDiff uint64 = 0 // Nr of runes consumed by recursive calls
|
|
outer:
|
|
for i, char := range []rune(raw) {
|
|
i++
|
|
// Skip runes that have been consumed by recursive calls
|
|
if uint64(i) < consumed {
|
|
continue
|
|
}
|
|
buffer = append(buffer, char)
|
|
consumed = uint64(i)
|
|
for k, v := range informers {
|
|
if !strings.HasSuffix(string(buffer), k) {
|
|
continue
|
|
}
|
|
if len(buffer) > 0 {
|
|
// Cut informer prefix from buffer, append buffer as text element
|
|
elements = append(
|
|
elements,
|
|
NodeElement{Text: other.IntoPointer(strings.TrimSuffix(string(buffer), k))},
|
|
)
|
|
}
|
|
buffer = make([]rune, 0)
|
|
subElems, subConsumed := marshal(string([]rune(raw)[consumed:]), informers, v)
|
|
elements = append(elements, NodeElement{
|
|
Node: &Node{
|
|
NodeType: v,
|
|
Elements: subElems,
|
|
},
|
|
})
|
|
insideDiff += subConsumed
|
|
consumed += subConsumed
|
|
continue outer
|
|
}
|
|
if activeInformer != nil && strings.HasSuffix(string(buffer), activeInformer.GetSuffix()) {
|
|
if len(buffer) > 0 {
|
|
b := strings.TrimSuffix(string(buffer), activeInformer.GetSuffix())
|
|
elements = append(
|
|
elements,
|
|
NodeElement{
|
|
Text: other.IntoPointer(
|
|
b,
|
|
),
|
|
},
|
|
)
|
|
}
|
|
return elements, uint64(consumed) + 1
|
|
}
|
|
}
|
|
if len(buffer) > 0 {
|
|
elements = append(elements, NodeElement{Text: other.IntoPointer(string(buffer))})
|
|
}
|
|
return elements, uint64(consumed)
|
|
}
|