Source File
emoji.go
Belonging Package
github.com/yuin/goldmark-emoji
package emoji
import (
east
)
type Option interface {
emojiOption()
}
type ParserConfig struct {
Emojis definition.Emojis
}
const optEmojis parser.OptionName = "EmojiEmojis"
func ( *ParserConfig) ( parser.OptionName, interface{}) {
switch {
case optEmojis:
.Emojis = .(definition.Emojis)
}
}
type ParserOption interface {
Option
parser.Option
SetEmojiOption(*ParserConfig)
}
var _ ParserOption = &withEmojis{}
type withEmojis struct {
value definition.Emojis
}
func ( *withEmojis) () {}
func ( *withEmojis) ( *parser.Config) {
.Options[optEmojis] = .value
}
func ( *withEmojis) ( *ParserConfig) {
.Emojis = .value
}
func ( definition.Emojis) Option {
return &withEmojis{
value: ,
}
}
type RenderingMethod int
type RendererFunc func(w util.BufWriter, source []byte, n *east.Emoji, config *RendererConfig)
Func
)
type RendererConfig struct {
html.Config
const DefaultTwemojiTemplate = `<img class="emoji" draggable="false" alt="%[1]s" src="https://twemoji.maxcdn.com/v/latest/72x72/%[2]s.png"%[3]s>`
func ( *RendererConfig) ( renderer.OptionName, interface{}) {
switch {
case optRenderingMethod:
.Method = .(RenderingMethod)
case optTwemojiTemplate:
.TwemojiTemplate = .(string)
case optRendererFunc:
.RendererFunc = .(RendererFunc)
default:
.Config.SetOption(, )
}
}
type RendererOption interface {
Option
renderer.Option
SetEmojiOption(*RendererConfig)
}
var _ RendererOption = &withRenderingMethod{}
type withRenderingMethod struct {
value RenderingMethod
}
func ( *withRenderingMethod) () {
}
func ( *withRenderingMethod) ( *renderer.Config) {
.Options[optRenderingMethod] = .value
}
func ( *withRenderingMethod) ( *RendererConfig) {
.Method = .value
}
const optRenderingMethod renderer.OptionName = "EmojiRenderingMethod"
func ( RenderingMethod) Option {
return &withRenderingMethod{}
}
type withTwemojiTemplate struct {
value string
}
func ( *withTwemojiTemplate) () {
}
func ( *withTwemojiTemplate) ( *renderer.Config) {
.Options[optTwemojiTemplate] = .value
}
func ( *withTwemojiTemplate) ( *RendererConfig) {
.TwemojiTemplate = .value
}
const optTwemojiTemplate renderer.OptionName = "EmojiTwemojiTemplate"
func ( string) Option {
return &withTwemojiTemplate{}
}
var _ RendererOption = &withRendererFunc{}
type withRendererFunc struct {
value RendererFunc
}
func ( *withRendererFunc) () {
}
func ( *withRendererFunc) ( *renderer.Config) {
.Options[optRendererFunc] = .value
}
func ( *withRendererFunc) ( *RendererConfig) {
.RendererFunc = .value
}
const optRendererFunc renderer.OptionName = "EmojiRendererFunc"
func ( RendererFunc) Option {
return &withRendererFunc{}
}
type emojiParser struct {
ParserConfig
}
func ( ...ParserOption) parser.InlineParser {
:= &emojiParser{
ParserConfig: ParserConfig{
Emojis: definition.Github(),
},
}
for , := range {
.SetEmojiOption(&.ParserConfig)
}
return
}
func ( *emojiParser) () []byte {
return []byte{':'}
}
func ( *emojiParser) ( ast.Node, text.Reader, parser.Context) ast.Node {
, := .PeekLine()
if len() < 1 {
return nil
}
:= 1
for ; < len(); ++ {
:= []
if !(util.IsAlphaNumeric() || == '_' || == '-' || == '+') {
break
}
}
if >= len() || [] != ':' {
return nil
}
.Advance( + 1)
:= [1:]
, := .Emojis.Get(util.BytesToReadOnlyString())
if ! {
return nil
}
return east.NewEmoji(, )
}
type emojiHTMLRenderer struct {
RendererConfig
}
func ( ...RendererOption) renderer.NodeRenderer {
:= &emojiHTMLRenderer{
RendererConfig: RendererConfig{
Config: html.NewConfig(),
Method: Entity,
TwemojiTemplate: DefaultTwemojiTemplate,
RendererFunc: nil,
},
}
for , := range {
.SetEmojiOption(&.RendererConfig)
}
return
}
func ( *emojiHTMLRenderer) ( renderer.NodeRendererFuncRegisterer) {
.Register(east.KindEmoji, .renderEmoji)
}
const slash = " /"
const empty = ""
func ( *emojiHTMLRenderer) ( util.BufWriter, []byte, ast.Node, bool) (ast.WalkStatus, error) {
if ! {
return ast.WalkContinue, nil
}
:= .(*east.Emoji)
if !.Value.IsUnicode() && .Method != Func {
fmt.Fprintf(, `<span title="%s">:%s:</span>`, util.EscapeHTML(util.StringToReadOnlyBytes(.Value.Name)), .ShortName)
return ast.WalkContinue, nil
}
switch .Method {
case Entity:
for , := range .Value.Unicode {
if == 0x200D {
_, _ = .WriteString("‍")
continue
}
fmt.Fprintf(, "&#x%x;", )
}
case Unicode:
fmt.Fprintf(, "%s", string(.Value.Unicode))
case Twemoji:
:= slash
if !.XHTML {
= empty
}
:= []string{}
for , := range .Value.Unicode {
= append(, fmt.Sprintf("%x", ))
}
fmt.Fprintf(, .TwemojiTemplate, util.EscapeHTML(util.StringToReadOnlyBytes(.Value.Name)), strings.Join(, "-"), )
case Func:
.RendererFunc(, , , &.RendererConfig)
}
return ast.WalkContinue, nil
}
type emoji struct {
options []Option
}
func ( *emoji) ( goldmark.Markdown) {
:= []ParserOption{}
:= []RendererOption{}
for , := range .options {
if , := .(ParserOption); {
= append(, )
continue
}
if , := .(RendererOption); {
= append(, )
}
}
.Renderer().AddOptions(renderer.WithNodeRenderers(
util.Prioritized(NewHTMLRenderer(...), 200),
))
.Parser().AddOptions(parser.WithInlineParsers(
util.Prioritized(NewParser(...), 999),
))
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |