Skip to content

Commit

Permalink
Add emoji support
Browse files Browse the repository at this point in the history
  • Loading branch information
prskr committed Mar 15, 2022
1 parent f18164d commit 21e41b0
Show file tree
Hide file tree
Showing 11 changed files with 195 additions and 338 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
*.so
*.dylib

emoji.json

# Test binary, build with `go test -c`
*.test

Expand All @@ -23,6 +25,7 @@ bin/

assets/reveal/
assets/mermaid/
assets/twemoji/

pkged.go

Expand Down
1 change: 1 addition & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ tasks:
- rm -f ./assets/reveal/plugin/menu/{bower.json,CONTRIBUTING.md,LICENSE,package.json,README.md,.gitignore,gulpfile.js,package-lock.json}
- curl -L https://github.com/highlightjs/highlight.js/archive/{{ .HIGHLIGHTJS_VERSION }}.tar.gz | tar -xvz --strip-components=3 -C ./assets/reveal/plugin/highlight --wildcards "*.css" highlight.js-{{ .HIGHLIGHTJS_VERSION }}/src/styles/
- curl -L https://registry.npmjs.org/mermaid/-/mermaid-{{ .MERMAID_VERSION }}.tgz | tar -xvz -C ./assets/mermaid/ package/dist --strip-components=2
- curl -L -o rendering/emoji/emoji.json https://raw.githubusercontent.com/muan/emojilib/main/dist/emoji-en-US.json

go-get-tool:
vars:
Expand Down
1 change: 0 additions & 1 deletion api/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ type Events struct {
func RegisterEventsAPI(router *httprouter.Router, hub *events.EventHub, logger *log.Logger) {
ev := &Events{hub: hub, logger: logger}
router.GET("/api/v1/events", ev.EventHandler)

}

func (e *Events) EventHandler(writer http.ResponseWriter, req *http.Request, _ httprouter.Params) {
Expand Down
14 changes: 7 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ go 1.17
require (
github.com/Masterminds/sprig/v3 v3.2.2
github.com/fsnotify/fsnotify v1.5.1
github.com/gomarkdown/markdown v0.0.0-20211203165214-0d698b49fbb4
github.com/gomarkdown/markdown v0.0.0-20220310201231-552c6011c0b8
github.com/google/uuid v1.3.0
github.com/julienschmidt/httprouter v1.3.0
github.com/mitchellh/go-homedir v1.1.0
github.com/sirupsen/logrus v1.8.1
github.com/spf13/cobra v1.3.0
github.com/spf13/cobra v1.4.0
github.com/spf13/viper v1.10.1
go.uber.org/multierr v1.7.0
go.uber.org/multierr v1.8.0
)

require (
Expand All @@ -23,23 +23,23 @@ require (
github.com/imdario/mergo v0.3.12 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/magiconair/properties v1.8.6 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/mapstructure v1.4.3 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
github.com/pelletier/go-toml v1.9.4 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spf13/afero v1.6.0 // indirect
github.com/spf13/afero v1.8.2 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.2.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
golang.org/x/crypto v0.0.0-20220314234724-5d542ad81a58 // indirect
golang.org/x/sys v0.0.0-20211214234402-4825e8c3871d // indirect
golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5 // indirect
golang.org/x/text v0.3.7 // indirect
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b // indirect
gopkg.in/ini.v1 v1.66.2 // indirect
gopkg.in/ini.v1 v1.66.4 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
358 changes: 29 additions & 329 deletions go.sum

Large diffs are not rendered by default.

32 changes: 32 additions & 0 deletions rendering/emoji/emoji.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package emoji

import (
_ "embed"
"encoding/json"
)

func isValidEmoji(input []byte) bool {
_, exists := emojiMap[string(input)]
return exists
}

var (
//go:embed emoji.json
emojiMapRaw []byte

emojiMap map[string]string
)

func init() {
rawMap := make(map[string][]string)
if err := json.Unmarshal(emojiMapRaw, &rawMap); err != nil {
panic(err)
}

emojiMap = make(map[string]string, len(rawMap))
for emoji, keywords := range rawMap {
for i := range keywords {
emojiMap[keywords[i]] = emoji
}
}
}
109 changes: 109 additions & 0 deletions rendering/emoji/emoji_parser.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package emoji

import (
"bytes"
"fmt"
"strconv"
"strings"
"unicode/utf8"

"github.com/gomarkdown/markdown/ast"
)

func NewEmojiParser() *EmojiParser {
return &EmojiParser{
seen: make(map[string]bool),
}
}

// Node is a node containing an emoji
type Node struct {
ast.Leaf
}

type EmojiParser struct {
seen map[string]bool
}

func (p *EmojiParser) EmojiParser(data []byte) (parsedNode ast.Node, result []byte, newLength int) {
if p.seen[string(data)] {
// Already processed
return nil, nil, 0
}
if bytes.Contains(data, []byte("class=\"emoji\"")) {
// Already processed
return nil, nil, 0
}
dataLen := len(data)
if dataLen <= 1 {
// Not long enough to be an emoji
return nil, nil, 0
}
if bytes.IndexByte(data, ':') == -1 {
// No emoji delimiters
return nil, nil, 0
}
// Translate emojis to HTML
resData := make([]byte, 0)
startIndex := bytes.IndexByte(data, ':')
resData = append(resData, data[0:startIndex]...)
for {
if startIndex >= len(data) {
// Done
break
}
endIndex := bytes.IndexByte(data[startIndex+1:], ':') + startIndex + 1
if endIndex > startIndex {
name := string(data[startIndex+1 : endIndex])
if isValidEmoji([]byte(name)) {
startIndex = endIndex + 1
url := fmt.Sprintf(`<img class="emoji" src=%q alt=":%s:"></img>`, GenerateEmojiURL(name), name)
resData = append(resData, []byte(url)...)
} else {
resData = append(resData, data[startIndex:endIndex]...)
startIndex = endIndex
}
if startIndex == dataLen {
break
}
} else {
break
}
}
if startIndex < dataLen {
resData = append(resData, data[startIndex:]...)
}

if !bytes.Contains(resData, []byte("class=\"emoji\"")) {
// Processed with no changes
p.seen[string(resData)] = true
}

return &ast.Softbreak{}, resData, dataLen
}

func GenerateEmojiURL(emoji string) string {
code, exists := emojiMap[emoji]
if !exists {
return ""
}
res := ""
chars := utf8.RuneCountInString(code)
curChar := 1
for _, c := range code {
tmp := strings.Trim(strings.ToLower(strconv.QuoteRuneToASCII(c)), "'")
if tmp != `\ufe0f` || (chars > 2 && curChar == chars) {
// Valid character to add
if curChar > 1 {
res += "-"
}
if len(tmp) == 1 {
res += fmt.Sprintf("%x", []byte(tmp))
} else {
res += strings.TrimLeft(tmp[2:], "0")
}
}
curChar++
}
return fmt.Sprintf("https://twemoji.maxcdn.com/2/svg/%s.svg", res)
}
5 changes: 5 additions & 0 deletions rendering/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"github.com/gomarkdown/markdown"
mdhtml "github.com/gomarkdown/markdown/html"
"github.com/gomarkdown/markdown/parser"

"github.com/baez90/goveal/rendering/emoji"
)

var (
Expand All @@ -32,7 +34,10 @@ func init() {
rr := &RevealRenderer{
Hash: fnv.New32a(),
}

emojis := emoji.NewEmojiParser()
mdParser := parser.NewWithExtensions(parserExtensions)
mdParser.Opts.ParserHook = emojis.EmojiParser
renderer := mdhtml.NewRenderer(mdhtml.RendererOptions{
Flags: mdhtml.CommonFlags | mdhtml.HrefTargetBlank,
RenderNodeHook: rr.RenderHook,
Expand Down
7 changes: 7 additions & 0 deletions web/css/site.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
img.emoji {
cursor: pointer;
height: 1em;
width: 1em;
margin: 0 .05em 0 .1em;
vertical-align: -0.1em;
}
1 change: 1 addition & 0 deletions web/index.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

<title>goveal</title>

<link rel="stylesheet" href="/css/site.css">
<link rel="stylesheet" href="/reveal/dist/reveal.css">
<link rel="stylesheet" href="/reveal/dist/reset.css">
<link rel="stylesheet" href="/reveal/dist/theme/{{ .Reveal.Theme }}.css" id="theme">
Expand Down
2 changes: 1 addition & 1 deletion web/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package web

import "embed"

//go:embed js/* index.gohtml
//go:embed js/* css/* index.gohtml
var WebFS embed.FS

0 comments on commit 21e41b0

Please sign in to comment.