From 887e2e232abec4e7cd9f8d19631f6ae5b14a0181 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Tue, 9 Apr 2019 00:59:56 +0300 Subject: Fix non-syntax-highlighted code block newline rendering --- ui/messages/htmlmessage.go | 47 ++++++++++++++++++++++++++++++++++++++-- ui/messages/parser/htmlparser.go | 37 +++++++++++-------------------- 2 files changed, 58 insertions(+), 26 deletions(-) (limited to 'ui/messages') diff --git a/ui/messages/htmlmessage.go b/ui/messages/htmlmessage.go index 8685442..eac0841 100644 --- a/ui/messages/htmlmessage.go +++ b/ui/messages/htmlmessage.go @@ -36,6 +36,10 @@ type HTMLMessage struct { BaseMessage Root HTMLEntity + + FocusedBackground tcell.Color + + focused bool } func NewHTMLMessage(id, sender, displayname string, msgtype mautrix.MessageType, root HTMLEntity, timestamp time.Time) UIMessage { @@ -45,9 +49,21 @@ func NewHTMLMessage(id, sender, displayname string, msgtype mautrix.MessageType, } } func (hw *HTMLMessage) Draw(screen mauview.Screen) { + if hw.focused { + screen.SetStyle(tcell.StyleDefault.Background(hw.FocusedBackground)) + } + screen.Clear() hw.Root.Draw(screen) } +func (hw *HTMLMessage) Focus() { + hw.focused = true +} + +func (hw *HTMLMessage) Blur() { + hw.focused = false +} + func (hw *HTMLMessage) OnKeyEvent(event mauview.KeyEvent) bool { return false } @@ -154,7 +170,7 @@ func NewListEntity(ordered bool, start int, children []HTMLEntity) *ListEntity { func (le *ListEntity) Draw(screen mauview.Screen) { width, _ := screen.Size() - proxyScreen := &mauview.ProxyScreen{Parent: screen, OffsetX: le.Indent, Width: width - le.Indent} + proxyScreen := &mauview.ProxyScreen{Parent: screen, OffsetX: le.Indent, Width: width - le.Indent, Style: le.Style} for i, entity := range le.Children { proxyScreen.Height = entity.Height() if le.Ordered { @@ -165,6 +181,7 @@ func (le *ListEntity) Draw(screen mauview.Screen) { screen.SetContent(0, proxyScreen.OffsetY, '●', nil, le.Style) } entity.Draw(proxyScreen) + proxyScreen.SetStyle(le.Style) proxyScreen.OffsetY += entity.Height() } } @@ -173,6 +190,31 @@ func (le *ListEntity) String() string { return fmt.Sprintf("&ListEntity{Ordered=%t, Start=%d, Base=%s},\n", le.Ordered, le.Start, le.BaseHTMLEntity) } +type CodeBlockEntity struct { + *BaseHTMLEntity + Background tcell.Style +} + +func NewCodeBlockEntity(children []HTMLEntity, background tcell.Style) *CodeBlockEntity { + return &CodeBlockEntity{ + BaseHTMLEntity: &BaseHTMLEntity{ + Tag: "pre", + Block: true, + Children: children, + }, + Background: background, + } +} + +func (ce *CodeBlockEntity) Draw(screen mauview.Screen) { + screen.Fill(' ', ce.Background) + ce.BaseHTMLEntity.Draw(screen) +} + +func (ce *CodeBlockEntity) AdjustStyle(fn AdjustStyleFunc) HTMLEntity { + return ce +} + type BreakEntity struct { *BaseHTMLEntity } @@ -297,13 +339,14 @@ func (he *BaseHTMLEntity) Draw(screen mauview.Screen) { } if len(he.Children) > 0 { prevBreak := false - proxyScreen := &mauview.ProxyScreen{Parent: screen, OffsetX: he.Indent, Width: width - he.Indent} + proxyScreen := &mauview.ProxyScreen{Parent: screen, OffsetX: he.Indent, Width: width - he.Indent, Style: he.Style} for i, entity := range he.Children { if i != 0 && entity.getStartX() == 0 { proxyScreen.OffsetY++ } proxyScreen.Height = entity.Height() entity.Draw(proxyScreen) + proxyScreen.SetStyle(he.Style) proxyScreen.OffsetY += entity.Height() - 1 _, isBreak := entity.(*BreakEntity) if prevBreak && isBreak { diff --git a/ui/messages/parser/htmlparser.go b/ui/messages/parser/htmlparser.go index e658c61..6e218df 100644 --- a/ui/messages/parser/htmlparser.go +++ b/ui/messages/parser/htmlparser.go @@ -221,7 +221,7 @@ func styleEntryToStyle(se chroma.StyleEntry) tcell.Style { } func (parser *htmlParser) syntaxHighlight(text, language string) messages.HTMLEntity { - lexer := lexers.Get(language) + lexer := lexers.Get(strings.ToLower(language)) if lexer == nil { return nil } @@ -229,7 +229,9 @@ func (parser *htmlParser) syntaxHighlight(text, language string) messages.HTMLEn if err != nil { return nil } + // TODO allow changing theme style := styles.SolarizedDark + tokens := iter.Tokens() children := make([]messages.HTMLEntity, len(tokens)) for i, token := range tokens { @@ -245,39 +247,26 @@ func (parser *htmlParser) syntaxHighlight(text, language string) messages.HTMLEn } } } - return &messages.BaseHTMLEntity{ - Tag: "pre", - Block: true, - Children: children, - } + return messages.NewCodeBlockEntity(children, styleEntryToStyle(style.Get(chroma.Background))) } func (parser *htmlParser) codeblockToEntity(node *html.Node) messages.HTMLEntity { - entity := &messages.BaseHTMLEntity{ - Tag: "pre", - Block: true, - } + lang := "plaintext" // TODO allow disabling syntax highlighting if node.FirstChild.Type == html.ElementNode && node.FirstChild.Data == "code" { - text := (&messages.BaseHTMLEntity{ - Children: parser.nodeToEntities(node.FirstChild.FirstChild, false), - }).PlainText() - attr := parser.getAttribute(node.FirstChild, "class") - var lang string + node = node.FirstChild + attr := parser.getAttribute(node, "class") for _, class := range strings.Split(attr, " ") { if strings.HasPrefix(class, "language-") { lang = class[len("language-"):] break } } - if len(lang) != 0 { - if parsed := parser.syntaxHighlight(text, lang); parsed != nil { - return parsed - } - } } - entity.Children = parser.nodeToEntities(node.FirstChild, false) - return entity + text := (&messages.BaseHTMLEntity{ + Children: parser.nodeToEntities(node.FirstChild, false), + }).PlainText() + return parser.syntaxHighlight(text, lang) } func (parser *htmlParser) tagNodeToEntity(node *html.Node, stripLinebreak bool) messages.HTMLEntity { @@ -311,7 +300,7 @@ func (parser *htmlParser) singleNodeToEntity(node *html.Node, stripLinebreak boo switch node.Type { case html.TextNode: if stripLinebreak { - node.Data = strings.Replace(node.Data, "\n", "", -1) + node.Data = strings.ReplaceAll(node.Data, "\n", "") } return &messages.BaseHTMLEntity{ Tag: "text", @@ -372,7 +361,7 @@ func ParseHTMLMessage(room *rooms.Room, evt *mautrix.Event, senderDisplayname st Tag: "emote", Children: []messages.HTMLEntity{ messages.NewHTMLTextEntity("* "), - messages.NewHTMLTextEntity("* ").AdjustStyle(AdjustStyleTextColor(widget.GetHashColor(evt.Sender))), + messages.NewHTMLTextEntity(senderDisplayname).AdjustStyle(AdjustStyleTextColor(widget.GetHashColor(evt.Sender))), messages.NewHTMLTextEntity(" "), root, }, -- cgit v1.2.3