Add font tag support and /rainbow command

This commit is contained in:
Tulir Asokan 2018-06-11 19:38:19 +03:00
parent d236560210
commit 5e3994ce2c
3 changed files with 78 additions and 0 deletions

View File

@ -78,6 +78,7 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
"part": {"leave"}, "part": {"leave"},
"send": {"sendevent"}, "send": {"sendevent"},
"state": {"setstate"}, "state": {"setstate"},
"rb": {"rainbow"},
}, },
commands: map[string]CommandHandler{ commands: map[string]CommandHandler{
"unknown-command": cmdUnknownCommand, "unknown-command": cmdUnknownCommand,
@ -91,6 +92,7 @@ func NewCommandProcessor(parent *MainView) *CommandProcessor {
"logout": cmdLogout, "logout": cmdLogout,
"sendevent": cmdSendEvent, "sendevent": cmdSendEvent,
"setstate": cmdSetState, "setstate": cmdSetState,
"rainbow": cmdRainbow,
}, },
} }
} }

View File

@ -20,6 +20,9 @@ import (
"encoding/json" "encoding/json"
"maunium.net/go/gomuks/debug" "maunium.net/go/gomuks/debug"
"strings" "strings"
"fmt"
"github.com/lucasb-eyer/go-colorful"
"unicode"
) )
func cmdMe(cmd *Command) { func cmdMe(cmd *Command) {
@ -29,6 +32,56 @@ func cmdMe(cmd *Command) {
cmd.UI.Render() cmd.UI.Render()
} }
// GradientTable from https://github.com/lucasb-eyer/go-colorful/blob/master/doc/gradientgen/gradientgen.go
type GradientTable []struct {
Col colorful.Color
Pos float64
}
func (gt GradientTable) GetInterpolatedColorFor(t float64) colorful.Color {
for i := 0; i < len(gt)-1; i++ {
c1 := gt[i]
c2 := gt[i+1]
if c1.Pos <= t && t <= c2.Pos {
t := (t - c1.Pos) / (c2.Pos - c1.Pos)
return c1.Col.BlendHcl(c2.Col, t).Clamped()
}
}
return gt[len(gt)-1].Col
}
var rainbow = GradientTable{
{colorful.LinearRgb(1, 0, 0), 0.0},
{colorful.LinearRgb(1, 0.5, 0), 0.1},
{colorful.LinearRgb(1, 1, 0), 0.2},
{colorful.LinearRgb(0.5, 1, 0), 0.3},
{colorful.LinearRgb(0, 1, 0), 0.4},
{colorful.LinearRgb(0, 1, 0.5), 0.5},
{colorful.LinearRgb(0, 1, 1), 0.6},
{colorful.LinearRgb(0, 0.5, 1), 0.7},
{colorful.LinearRgb(0.5, 0, 1), 0.8},
{colorful.LinearRgb(1, 0, 1), 0.9},
{colorful.LinearRgb(1, 0, 0.5), 1},
}
// TODO this command definitely belongs in a plugin once we have a plugin system.
func cmdRainbow(cmd *Command) {
text := strings.Join(cmd.Args, " ")
var html strings.Builder
fmt.Fprint(&html, "**🌈** ")
for i, char := range text {
if unicode.IsSpace(char) {
html.WriteRune(char)
continue
}
color := rainbow.GetInterpolatedColorFor(float64(i)/float64(len(text))).Hex()
fmt.Fprintf(&html, "<font color=\"%s\">%c</font>", color, char)
}
tempMessage := cmd.Room.NewTempMessage("m.text", html.String())
go cmd.MainView.sendTempMessage(cmd.Room, tempMessage, html.String())
cmd.UI.Render()
}
func cmdQuit(cmd *Command) { func cmdQuit(cmd *Command) {
cmd.Gomuks.Stop() cmd.Gomuks.Stop()
} }

View File

@ -29,6 +29,7 @@ import (
"maunium.net/go/gomuks/ui/widget" "maunium.net/go/gomuks/ui/widget"
"maunium.net/go/tcell" "maunium.net/go/tcell"
"strconv" "strconv"
"github.com/lucasb-eyer/go-colorful"
) )
var matrixToURL = regexp.MustCompile("^(?:https?://)?(?:www\\.)?matrix\\.to/#/([#@!].*)") var matrixToURL = regexp.MustCompile("^(?:https?://)?(?:www\\.)?matrix\\.to/#/([#@!].*)")
@ -125,6 +126,26 @@ func (parser *htmlParser) basicFormatToTString(node *html.Node, stripLinebreak b
return str return str
} }
func (parser *htmlParser) fontToTString(node *html.Node, stripLinebreak bool) tstring.TString {
str := parser.nodeToTagAwareTString(node.FirstChild, stripLinebreak)
hex := parser.getAttribute(node, "color")
if len(hex) == 0 {
return str
}
color, err := colorful.Hex(hex)
if err != nil {
return str
}
r, g, b := color.RGB255()
tcellColor := tcell.NewRGBColor(int32(r), int32(g), int32(b))
str.AdjustStyleFull(func(style tcell.Style) tcell.Style {
return style.Foreground(tcellColor)
})
return str
}
func (parser *htmlParser) headerToTString(node *html.Node, stripLinebreak bool) tstring.TString { func (parser *htmlParser) headerToTString(node *html.Node, stripLinebreak bool) tstring.TString {
children := parser.nodeToTStrings(node.FirstChild, stripLinebreak) children := parser.nodeToTStrings(node.FirstChild, stripLinebreak)
length := int(node.Data[1] - '0') length := int(node.Data[1] - '0')
@ -172,6 +193,8 @@ func (parser *htmlParser) tagToTString(node *html.Node, stripLinebreak bool) tst
return tstring.NewTString("\n") return tstring.NewTString("\n")
case "b", "strong", "i", "em", "s", "del", "u", "ins": case "b", "strong", "i", "em", "s", "del", "u", "ins":
return parser.basicFormatToTString(node, stripLinebreak) return parser.basicFormatToTString(node, stripLinebreak)
case "font":
return parser.fontToTString(node, stripLinebreak)
case "a": case "a":
return parser.linkToTString(node, stripLinebreak) return parser.linkToTString(node, stripLinebreak)
case "p": case "p":