package emoji is a extension for the goldmark(http://github.com/yuin/goldmark).
package emoji

import (
	
	

	
	east 
	
	
	
	
	
	
	
)
Option interface sets options for this extension.
type Option interface {
	emojiOption()
}
ParserConfig struct is a data structure that holds configuration of the Emoji extension.
type ParserConfig struct {
	Emojis definition.Emojis
}

const optEmojis parser.OptionName = "EmojiEmojis"
SetOption implements parser.SetOptioner
func ( *ParserConfig) ( parser.OptionName,  interface{}) {
	switch  {
	case optEmojis:
		.Emojis = .(definition.Emojis)
	}
}
A ParserOption interface sets options for the emoji parser.
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
}
WithMaping is a functional option that defines links names to unicode emojis.
func ( definition.Emojis) Option {
	return &withEmojis{
		value: ,
	}
}
RenderingMethod indicates how emojis are rendered.
RendererFunc will be used for rendering emojis.
type RendererFunc func(w util.BufWriter, source []byte, n *east.Emoji, config *RendererConfig)

Entity renders an emoji as an html entity.
Unicode renders an emoji as unicode character.
Twemoji renders an emoji as an img tag with [twemoji](https://github.com/twitter/twemoji).
Func renders an emoji using RendererFunc.
	Func
)
RendererConfig struct holds options for the emoji renderer.
type RendererConfig struct {
	html.Config
Method indicates how emojis are rendered.
TwemojiTemplate is a printf template for twemoji. This value is valid only when Method is set to Twemoji. `printf` arguments are: 1: name (e.g. "face with tears of joy") 2: file name without an extension (e.g. 1f646-2642) 3: '/' if XHTML, otherwise ''
RendererFunc is a RendererFunc that renders emojis. This value is valid only when Method is set to Func.
DefaultTwemojiTemplate is a default value for RendererConfig.TwemojiTemplate.
const DefaultTwemojiTemplate = `<img class="emoji" draggable="false" alt="%[1]s" src="https://twemoji.maxcdn.com/v/latest/72x72/%[2]s.png"%[3]s>`
SetOption implements renderer.SetOptioner.
func ( *RendererConfig) ( renderer.OptionName,  interface{}) {
	switch  {
	case optRenderingMethod:
		.Method = .(RenderingMethod)
	case optTwemojiTemplate:
		.TwemojiTemplate = .(string)
	case optRendererFunc:
		.RendererFunc = .(RendererFunc)
	default:
		.Config.SetOption(, )
	}
}
A RendererOption interface sets options for the emoji renderer.
SetConfig implements renderer.Option#SetConfig.
SetEmojiOption implements RendererOption#SetEmojiOption
func ( *withRenderingMethod) ( *RendererConfig) {
	.Method = .value
}

const optRenderingMethod renderer.OptionName = "EmojiRenderingMethod"
WithRenderingMethod is a functional option that indicates how emojis are rendered.
SetConfig implements renderer.Option#SetConfig.
SetEmojiOption implements RendererOption#SetEmojiOption
WithTwemojiTemplate is a functional option that changes a twemoji img tag.
SetConfig implements renderer.Option#SetConfig.
SetEmojiOption implements RendererOption#SetEmojiOption
WithRendererFunc is a functional option that changes a renderer func.
NewParser returns a new parser.InlineParser that can parse emoji expressions.
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
}
NewHTMLRenderer returns a new HTMLRenderer.
RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs.
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("&zwj;")
				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
}
Emoji is a goldmark.Extender implementation.
var Emoji = &emoji{
	options: []Option{},
}
New returns a new extension with given options.
func ( ...Option) goldmark.Extender {
	return &emoji{
		options: ,
	}
}
Extend implements goldmark.Extender.
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),
	))