From b37f694db4c3a5c53048d7fcb914ec60e3e10ab5 Mon Sep 17 00:00:00 2001 From: Sam Date: Sun, 6 Dec 2020 00:21:10 -0500 Subject: [PATCH] Add support for :emoji: (#92) --- ansi/elements.go | 9 +++++++++ ansi/renderer.go | 4 ++++ ansi/renderer_test.go | 3 +++ glamour.go | 9 +++++++++ glamour_test.go | 23 +++++++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ styles/examples/emoji.md | 1 + styles/examples/emoji.style | 1 + testdata/emoji.test | 1 + testdata/issues/48.md | 16 ++++++++++++++++ testdata/issues/48.test | 17 +++++++++++++++++ 12 files changed, 87 insertions(+) create mode 100644 styles/examples/emoji.md create mode 100644 styles/examples/emoji.style create mode 100644 testdata/emoji.test create mode 100644 testdata/issues/48.md create mode 100644 testdata/issues/48.test diff --git a/ansi/elements.go b/ansi/elements.go index f4403da..c09ed7f 100644 --- a/ansi/elements.go +++ b/ansi/elements.go @@ -7,6 +7,7 @@ import ( "io" "strings" + east "github.com/yuin/goldmark-emoji/ast" "github.com/yuin/goldmark/ast" astext "github.com/yuin/goldmark/extension/ast" ) @@ -375,6 +376,14 @@ func (tr *ANSIRenderer) NewElement(node ast.Node, source []byte) Element { case ast.KindTextBlock: return Element{} + case east.KindEmoji: + n := node.(*east.Emoji) + return Element{ + Renderer: &BaseElement{ + Token: string(n.Value.Unicode), + }, + } + // Unknown case default: fmt.Println("Warning: unhandled element", node.Kind().String()) diff --git a/ansi/renderer.go b/ansi/renderer.go index 3604914..65a9e80 100644 --- a/ansi/renderer.go +++ b/ansi/renderer.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/muesli/termenv" + east "github.com/yuin/goldmark-emoji/ast" "github.com/yuin/goldmark/ast" astext "github.com/yuin/goldmark/extension/ast" "github.com/yuin/goldmark/renderer" @@ -79,6 +80,9 @@ func (r *ANSIRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { // strikethrough reg.Register(astext.KindStrikethrough, r.renderNode) + + // emoji + reg.Register(east.KindEmoji, r.renderNode) } func (r *ANSIRenderer) renderNode(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { diff --git a/ansi/renderer_test.go b/ansi/renderer_test.go index 8cf8eab..dafb683 100644 --- a/ansi/renderer_test.go +++ b/ansi/renderer_test.go @@ -10,6 +10,7 @@ import ( "github.com/muesli/termenv" "github.com/yuin/goldmark" + emoji "github.com/yuin/goldmark-emoji" "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/renderer" @@ -56,6 +57,7 @@ func TestRenderer(t *testing.T) { goldmark.WithExtensions( extension.GFM, extension.DefinitionList, + emoji.Emoji, ), goldmark.WithParserOptions( parser.WithAutoHeadingID(), @@ -127,6 +129,7 @@ func TestRendererIssues(t *testing.T) { goldmark.WithExtensions( extension.GFM, extension.DefinitionList, + emoji.Emoji, ), goldmark.WithParserOptions( parser.WithAutoHeadingID(), diff --git a/glamour.go b/glamour.go index 3e69e7e..7b4a14c 100644 --- a/glamour.go +++ b/glamour.go @@ -9,6 +9,7 @@ import ( "github.com/muesli/termenv" "github.com/yuin/goldmark" + emoji "github.com/yuin/goldmark-emoji" "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/parser" "github.com/yuin/goldmark/renderer" @@ -184,6 +185,14 @@ func WithWordWrap(wordWrap int) TermRendererOption { } } +// WithEmoji sets a TermRenderer's emoji rendering. +func WithEmoji() TermRendererOption { + return func(tr *TermRenderer) error { + emoji.New().Extend(tr.md) + return nil + } +} + func (tr *TermRenderer) Read(b []byte) (int, error) { return tr.renderBuf.Read(b) } diff --git a/glamour_test.go b/glamour_test.go index 29296db..52f59a5 100644 --- a/glamour_test.go +++ b/glamour_test.go @@ -3,6 +3,7 @@ package glamour import ( "bytes" "io/ioutil" + "strings" "testing" ) @@ -90,6 +91,28 @@ func TestTermRenderer(t *testing.T) { } } +func TestWithEmoji(t *testing.T) { + r, err := NewTermRenderer( + WithEmoji(), + ) + if err != nil { + t.Fatal(err) + } + + b, err := r.Render(":+1:") + if err != nil { + t.Fatal(err) + } + b = strings.TrimSpace(b) + + // Thumbs up unicode character + td := "\U0001f44d" + + if td != b { + t.Errorf("Rendered output doesn't match!\nExpected: `\n%s`\nGot: `\n%s`\n", td, b) + } +} + func TestStyles(t *testing.T) { _, err := NewTermRenderer( WithAutoStyle(), diff --git a/go.mod b/go.mod index 65c33f6..51086aa 100644 --- a/go.mod +++ b/go.mod @@ -9,4 +9,5 @@ require ( github.com/muesli/termenv v0.7.4 github.com/olekukonko/tablewriter v0.0.4 github.com/yuin/goldmark v1.2.1 + github.com/yuin/goldmark-emoji v1.0.1 ) diff --git a/go.sum b/go.sum index f2b989f..94a1d3a 100644 --- a/go.sum +++ b/go.sum @@ -49,6 +49,8 @@ github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark-emoji v1.0.1 h1:ctuWEyzGBwiucEqxzwe0SOYDXPAucOrE9NQC18Wa1os= +github.com/yuin/goldmark-emoji v1.0.1/go.mod h1:2w1E6FEWLcDQkoTE+7HU6QF1F6SLlNGjRIBbIZQFqkQ= golang.org/x/net v0.0.0-20181220203305-927f97764cc3 h1:eH6Eip3UpmR+yM/qI9Ijluzb1bNv/cAU/n+6l8tRSis= golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/sys v0.0.0-20200116001909-b77594299b42 h1:vEOn+mP2zCOVzKckCZy6YsCtDblrpj/w7B9nxGNELpg= diff --git a/styles/examples/emoji.md b/styles/examples/emoji.md new file mode 100644 index 0000000..1bb7bee --- /dev/null +++ b/styles/examples/emoji.md @@ -0,0 +1 @@ +:octopus: :zap: :cat: = :heart: diff --git a/styles/examples/emoji.style b/styles/examples/emoji.style new file mode 100644 index 0000000..4433084 --- /dev/null +++ b/styles/examples/emoji.style @@ -0,0 +1 @@ +{ "emoji": {} } diff --git a/testdata/emoji.test b/testdata/emoji.test new file mode 100644 index 0000000..0d1abe4 --- /dev/null +++ b/testdata/emoji.test @@ -0,0 +1 @@ +🐙 ⚡ 🐱 = ❤️ diff --git a/testdata/issues/48.md b/testdata/issues/48.md new file mode 100644 index 0000000..f943aef --- /dev/null +++ b/testdata/issues/48.md @@ -0,0 +1,16 @@ +emoji in text + +:octopus: :zap: :cat: = :heart: + +emoji in header + +## :octopus: :zap: :cat: = :heart: + +no emoji in code blocks +``` +:octopus: :zap: :cat: = :heart: +``` + +no emoji in inline code + +`:octopus: :zap: :cat: = :heart:` diff --git a/testdata/issues/48.test b/testdata/issues/48.test new file mode 100644 index 0000000..9c22602 --- /dev/null +++ b/testdata/issues/48.test @@ -0,0 +1,17 @@ + + emoji in text                                                                +                                                                              + 🐙 ⚡ 🐱 = ❤️                                                                +                                                                              + emoji in header                                                              +                                                                              + ## 🐙 ⚡ 🐱 = ❤️                                                             +                                                                              + no emoji in code blocks                                                      +                                                                              +   :octopus: :zap: :cat: = :heart:                                            +                                                                              + no emoji in inline code                                                      +                                                                              +  :octopus: :zap: :cat: = :heart:                                             +