92 lines
1.9 KiB
Go
92 lines
1.9 KiB
Go
|
|
package mdprint
|
||
|
|
|
||
|
|
func parseInline(text string) []Node {
|
||
|
|
var nodes []Node
|
||
|
|
runes := []rune(text)
|
||
|
|
i := 0
|
||
|
|
|
||
|
|
for i < len(runes) {
|
||
|
|
rem := string(runes[i:])
|
||
|
|
|
||
|
|
if len(rem) >= 2 && rem[:2] == "**" {
|
||
|
|
end := findDelim(runes, i+2, "**")
|
||
|
|
if end >= 0 {
|
||
|
|
inner := string(runes[i+2 : end])
|
||
|
|
nodes = append(nodes, Bold{Content: parseInline(inner)})
|
||
|
|
i = end + 2
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
nodes = append(nodes, Text{Text: "**"})
|
||
|
|
i += 2
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(rem) >= 1 && rem[:1] == "*" {
|
||
|
|
end := findDelim(runes, i+1, "*")
|
||
|
|
if end >= 0 {
|
||
|
|
inner := string(runes[i+1 : end])
|
||
|
|
nodes = append(nodes, Italic{Content: parseInline(inner)})
|
||
|
|
i = end + 1
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
nodes = append(nodes, Text{Text: "*"})
|
||
|
|
i++
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(rem) >= 1 && rem[:1] == "`" {
|
||
|
|
end := findDelim(runes, i+1, "`")
|
||
|
|
if end >= 0 {
|
||
|
|
nodes = append(nodes, Code{Text: string(runes[i+1 : end])})
|
||
|
|
i = end + 1
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
nodes = append(nodes, Text{Text: "`"})
|
||
|
|
i++
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
|
||
|
|
if len(rem) >= 1 && rem[:1] == "[" {
|
||
|
|
closeB := findDelim(runes, i+1, "]")
|
||
|
|
if closeB >= 0 && closeB+1 < len(runes) && runes[closeB+1] == '(' {
|
||
|
|
closeP := findDelim(runes, closeB+2, ")")
|
||
|
|
if closeP >= 0 {
|
||
|
|
linkText := string(runes[i+1 : closeB])
|
||
|
|
url := string(runes[closeB+2 : closeP])
|
||
|
|
nodes = append(nodes, Link{Content: parseInline(linkText), URL: url})
|
||
|
|
i = closeP + 1
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
textStart := i
|
||
|
|
for i < len(runes) {
|
||
|
|
ch := string(runes[i])
|
||
|
|
if ch == "*" || ch == "`" || ch == "[" {
|
||
|
|
break
|
||
|
|
}
|
||
|
|
if ch == "\\" && i+1 < len(runes) {
|
||
|
|
i += 2
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
i++
|
||
|
|
}
|
||
|
|
if i > textStart {
|
||
|
|
nodes = append(nodes, Text{Text: string(runes[textStart:i])})
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
return nodes
|
||
|
|
}
|
||
|
|
|
||
|
|
func findDelim(runes []rune, start int, delim string) int {
|
||
|
|
for j := start; j < len(runes); j++ {
|
||
|
|
rem := string(runes[j:])
|
||
|
|
if len(rem) >= len(delim) && rem[:len(delim)] == delim {
|
||
|
|
return j
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return -1
|
||
|
|
}
|