Improve newlines in HTML parser

This commit is contained in:
Tulir Asokan 2018-06-02 00:28:21 +03:00
parent 1da02e3a13
commit 7868bd90fa
2 changed files with 35 additions and 23 deletions

View File

@ -249,7 +249,7 @@ func (view *MessageView) replaceBuffer(original messages.UIMessage, new messages
} }
view.textBuffer = append(append(view.textBuffer[0:start], new.Buffer()...), view.textBuffer[end:]...) view.textBuffer = append(append(view.textBuffer[0:start], new.Buffer()...), view.textBuffer[end:]...)
if len(new.Buffer()) != end-start+1 { if len(new.Buffer()) != end-start {
metaBuffer := view.metaBuffer[0:start] metaBuffer := view.metaBuffer[0:start]
for range new.Buffer() { for range new.Buffer() {
metaBuffer = append(metaBuffer, new) metaBuffer = append(metaBuffer, new)
@ -504,6 +504,7 @@ func (view *MessageView) Draw(screen tcell.Screen) {
if len(view.textBuffer) != len(view.metaBuffer) { if len(view.textBuffer) != len(view.metaBuffer) {
debug.Printf("Unexpected text/meta buffer length mismatch: %d != %d.", len(view.textBuffer), len(view.metaBuffer)) debug.Printf("Unexpected text/meta buffer length mismatch: %d != %d.", len(view.textBuffer), len(view.metaBuffer))
view.prevMsgCount = 0
return return
} }

View File

@ -28,6 +28,7 @@ import (
"maunium.net/go/gomuks/ui/widget" "maunium.net/go/gomuks/ui/widget"
"maunium.net/go/tcell" "maunium.net/go/tcell"
"golang.org/x/net/html" "golang.org/x/net/html"
"strconv"
) )
var matrixToURL = regexp.MustCompile("^(?:https?://)?(?:www\\.)?matrix\\.to/#/([#@!].*)") var matrixToURL = regexp.MustCompile("^(?:https?://)?(?:www\\.)?matrix\\.to/#/([#@!].*)")
@ -57,23 +58,43 @@ var AdjustStyleStrikethrough = func(style tcell.Style) tcell.Style {
return style.Strikethrough(true) return style.Strikethrough(true)
} }
func (parser *htmlParser) getAttribute(node *html.Node, attribute string) string {
for _, attr := range node.Attr {
if attr.Key == attribute {
return attr.Val
}
}
return ""
}
func digits(num int) int {
return int(math.Floor(math.Log10(float64(num)))+1)
}
func (parser *htmlParser) listToTString(node *html.Node, stripLinebreak bool) tstring.TString { func (parser *htmlParser) listToTString(node *html.Node, stripLinebreak bool) tstring.TString {
ordered := node.Data == "ol" ordered := node.Data == "ol"
taggedChildren := parser.nodeToTaggedTStrings(node.FirstChild, stripLinebreak) taggedChildren := parser.nodeToTaggedTStrings(node.FirstChild, stripLinebreak)
paddingLength := 0
if ordered {
paddingLength = int(math.Floor(math.Log10(float64(len(taggedChildren)))) + 1)
}
padding := strings.Repeat(" ", paddingLength+2)
var children []tstring.TString
counter := 1 counter := 1
indentLength := 0
if ordered {
start := parser.getAttribute(node, "start")
if len(start) > 0 {
counter, _ = strconv.Atoi(start)
}
longestIndex := (counter - 1) + len(taggedChildren)
indentLength = digits(longestIndex)
}
indent := strings.Repeat(" ", indentLength+2)
var children []tstring.TString
for _, child := range taggedChildren { for _, child := range taggedChildren {
if child.tag != "li" { if child.tag != "li" {
continue continue
} }
var prefix string var prefix string
if ordered { if ordered {
prefix = fmt.Sprintf("%*d. ", paddingLength, counter) indexPadding := indentLength - digits(counter)
prefix = fmt.Sprintf("%d. %s", counter, strings.Repeat(" ", indexPadding))
} else { } else {
prefix = "● " prefix = "● "
} }
@ -81,7 +102,7 @@ func (parser *htmlParser) listToTString(node *html.Node, stripLinebreak bool) ts
counter++ counter++
parts := str.Split('\n') parts := str.Split('\n')
for i, part := range parts[1:] { for i, part := range parts[1:] {
parts[i+1] = part.Prepend(padding) parts[i+1] = part.Prepend(indent)
} }
str = tstring.Join(parts, "\n") str = tstring.Join(parts, "\n")
children = append(children, str) children = append(children, str)
@ -122,13 +143,7 @@ func (parser *htmlParser) blockquoteToTString(node *html.Node, stripLinebreak bo
func (parser *htmlParser) linkToTString(node *html.Node, stripLinebreak bool) tstring.TString { func (parser *htmlParser) linkToTString(node *html.Node, stripLinebreak bool) tstring.TString {
str := parser.nodeToTagAwareTString(node.FirstChild, stripLinebreak) str := parser.nodeToTagAwareTString(node.FirstChild, stripLinebreak)
var href string href := parser.getAttribute(node, "href")
for _, attr := range node.Attr {
if attr.Key == "href" {
href = attr.Val
break
}
}
if len(href) == 0 { if len(href) == 0 {
return str return str
} }
@ -205,14 +220,10 @@ func (parser *htmlParser) isBlockTag(tag string) bool {
func (parser *htmlParser) nodeToTagAwareTString(node *html.Node, stripLinebreak bool) tstring.TString { func (parser *htmlParser) nodeToTagAwareTString(node *html.Node, stripLinebreak bool) tstring.TString {
strs := parser.nodeToTaggedTStrings(node, stripLinebreak) strs := parser.nodeToTaggedTStrings(node, stripLinebreak)
output := tstring.NewBlankTString() output := tstring.NewBlankTString()
for i, str := range strs { for _, str := range strs {
tstr := str.TString tstr := str.TString
curIsBlock := parser.isBlockTag(str.tag) if parser.isBlockTag(str.tag) {
if i > 0 && curIsBlock { tstr = tstr.Prepend("\n").Append("\n")
tstr = tstr.Prepend("\n")
}
if curIsBlock && len(strs) < i+1 {
tstr = tstr.Append("\n")
} }
output = output.AppendTString(tstr) output = output.AppendTString(tstr)
} }