From 7868bd90fab77faa1e37674d543eefc1ff315fff Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Sat, 2 Jun 2018 00:28:21 +0300 Subject: [PATCH] Improve newlines in HTML parser --- ui/message-view.go | 3 +- ui/messages/parser/htmlparser.go | 55 +++++++++++++++++++------------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/ui/message-view.go b/ui/message-view.go index 9bd1795..9f3d811 100644 --- a/ui/message-view.go +++ b/ui/message-view.go @@ -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:]...) - if len(new.Buffer()) != end-start+1 { + if len(new.Buffer()) != end-start { metaBuffer := view.metaBuffer[0:start] for range new.Buffer() { metaBuffer = append(metaBuffer, new) @@ -504,6 +504,7 @@ func (view *MessageView) Draw(screen tcell.Screen) { if 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 } diff --git a/ui/messages/parser/htmlparser.go b/ui/messages/parser/htmlparser.go index b88f55e..9999c94 100644 --- a/ui/messages/parser/htmlparser.go +++ b/ui/messages/parser/htmlparser.go @@ -28,6 +28,7 @@ import ( "maunium.net/go/gomuks/ui/widget" "maunium.net/go/tcell" "golang.org/x/net/html" + "strconv" ) var matrixToURL = regexp.MustCompile("^(?:https?://)?(?:www\\.)?matrix\\.to/#/([#@!].*)") @@ -57,23 +58,43 @@ var AdjustStyleStrikethrough = func(style tcell.Style) tcell.Style { 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 { ordered := node.Data == "ol" 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 + 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 { if child.tag != "li" { continue } var prefix string if ordered { - prefix = fmt.Sprintf("%*d. ", paddingLength, counter) + indexPadding := indentLength - digits(counter) + prefix = fmt.Sprintf("%d. %s", counter, strings.Repeat(" ", indexPadding)) } else { prefix = "● " } @@ -81,7 +102,7 @@ func (parser *htmlParser) listToTString(node *html.Node, stripLinebreak bool) ts counter++ parts := str.Split('\n') for i, part := range parts[1:] { - parts[i+1] = part.Prepend(padding) + parts[i+1] = part.Prepend(indent) } str = tstring.Join(parts, "\n") 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 { str := parser.nodeToTagAwareTString(node.FirstChild, stripLinebreak) - var href string - for _, attr := range node.Attr { - if attr.Key == "href" { - href = attr.Val - break - } - } + href := parser.getAttribute(node, "href") if len(href) == 0 { return str } @@ -205,14 +220,10 @@ func (parser *htmlParser) isBlockTag(tag string) bool { func (parser *htmlParser) nodeToTagAwareTString(node *html.Node, stripLinebreak bool) tstring.TString { strs := parser.nodeToTaggedTStrings(node, stripLinebreak) output := tstring.NewBlankTString() - for i, str := range strs { + for _, str := range strs { tstr := str.TString - curIsBlock := parser.isBlockTag(str.tag) - if i > 0 && curIsBlock { - tstr = tstr.Prepend("\n") - } - if curIsBlock && len(strs) < i+1 { - tstr = tstr.Append("\n") + if parser.isBlockTag(str.tag) { + tstr = tstr.Prepend("\n").Append("\n") } output = output.AppendTString(tstr) }