From 907dae0359ee71af6fd8e8ae9c6dd8845a16aee1 Mon Sep 17 00:00:00 2001 From: Maxim Lebedev Date: Fri, 10 Nov 2023 02:15:18 +0600 Subject: [PATCH] :pushpin: Vendored imported go modules --- .../github.com/yuin/goldmark-emoji/.gitignore | 15 + vendor/github.com/yuin/goldmark-emoji/LICENSE | 21 + .../github.com/yuin/goldmark-emoji/README.md | 71 + .../yuin/goldmark-emoji/ast/emoji.go | 42 + .../goldmark-emoji/definition/definition.go | 106 + .../yuin/goldmark-emoji/definition/github.go | 1831 ++++++++++++++ .../github.com/yuin/goldmark-emoji/emoji.go | 360 +++ vendor/github.com/yuin/goldmark/.gitignore | 19 + vendor/github.com/yuin/goldmark/.golangci.yml | 105 + vendor/github.com/yuin/goldmark/LICENSE | 21 + vendor/github.com/yuin/goldmark/Makefile | 13 + vendor/github.com/yuin/goldmark/README.md | 557 +++++ vendor/github.com/yuin/goldmark/ast/ast.go | 508 ++++ vendor/github.com/yuin/goldmark/ast/block.go | 508 ++++ vendor/github.com/yuin/goldmark/ast/inline.go | 549 +++++ .../goldmark/extension/ast/definition_list.go | 83 + .../yuin/goldmark/extension/ast/footnote.go | 138 ++ .../goldmark/extension/ast/strikethrough.go | 29 + .../yuin/goldmark/extension/ast/table.go | 158 ++ .../yuin/goldmark/extension/ast/tasklist.go | 35 + .../github.com/yuin/goldmark/extension/cjk.go | 72 + .../goldmark/extension/definition_list.go | 274 +++ .../yuin/goldmark/extension/footnote.go | 691 ++++++ .../github.com/yuin/goldmark/extension/gfm.go | 18 + .../yuin/goldmark/extension/linkify.go | 320 +++ .../yuin/goldmark/extension/package.go | 2 + .../yuin/goldmark/extension/strikethrough.go | 117 + .../yuin/goldmark/extension/table.go | 564 +++++ .../yuin/goldmark/extension/tasklist.go | 120 + .../yuin/goldmark/extension/typographer.go | 348 +++ vendor/github.com/yuin/goldmark/markdown.go | 140 ++ .../yuin/goldmark/parser/attribute.go | 329 +++ .../yuin/goldmark/parser/atx_heading.go | 248 ++ .../yuin/goldmark/parser/auto_link.go | 42 + .../yuin/goldmark/parser/blockquote.go | 69 + .../yuin/goldmark/parser/code_block.go | 100 + .../yuin/goldmark/parser/code_span.go | 84 + .../yuin/goldmark/parser/delimiter.go | 238 ++ .../yuin/goldmark/parser/emphasis.go | 50 + .../yuin/goldmark/parser/fcode_block.go | 121 + .../yuin/goldmark/parser/html_block.go | 229 ++ .../github.com/yuin/goldmark/parser/link.go | 410 ++++ .../yuin/goldmark/parser/link_ref.go | 152 ++ .../github.com/yuin/goldmark/parser/list.go | 287 +++ .../yuin/goldmark/parser/list_item.go | 90 + .../yuin/goldmark/parser/paragraph.go | 72 + .../github.com/yuin/goldmark/parser/parser.go | 1259 ++++++++++ .../yuin/goldmark/parser/raw_html.go | 162 ++ .../yuin/goldmark/parser/setext_headings.go | 126 + .../yuin/goldmark/parser/thematic_break.go | 75 + .../yuin/goldmark/renderer/html/html.go | 1019 ++++++++ .../yuin/goldmark/renderer/renderer.go | 174 ++ .../github.com/yuin/goldmark/text/package.go | 2 + .../github.com/yuin/goldmark/text/reader.go | 660 +++++ .../github.com/yuin/goldmark/text/segment.go | 209 ++ .../yuin/goldmark/util/html5entities.go | 2143 +++++++++++++++++ .../goldmark/util/unicode_case_folding.go | 1535 ++++++++++++ vendor/github.com/yuin/goldmark/util/util.go | 982 ++++++++ .../github.com/yuin/goldmark/util/util_cjk.go | 469 ++++ .../yuin/goldmark/util/util_safe.go | 14 + .../yuin/goldmark/util/util_unsafe.go | 24 + vendor/modules.txt | 16 + 62 files changed, 19225 insertions(+) create mode 100644 vendor/github.com/yuin/goldmark-emoji/.gitignore create mode 100644 vendor/github.com/yuin/goldmark-emoji/LICENSE create mode 100644 vendor/github.com/yuin/goldmark-emoji/README.md create mode 100644 vendor/github.com/yuin/goldmark-emoji/ast/emoji.go create mode 100644 vendor/github.com/yuin/goldmark-emoji/definition/definition.go create mode 100644 vendor/github.com/yuin/goldmark-emoji/definition/github.go create mode 100644 vendor/github.com/yuin/goldmark-emoji/emoji.go create mode 100644 vendor/github.com/yuin/goldmark/.gitignore create mode 100644 vendor/github.com/yuin/goldmark/.golangci.yml create mode 100644 vendor/github.com/yuin/goldmark/LICENSE create mode 100644 vendor/github.com/yuin/goldmark/Makefile create mode 100644 vendor/github.com/yuin/goldmark/README.md create mode 100644 vendor/github.com/yuin/goldmark/ast/ast.go create mode 100644 vendor/github.com/yuin/goldmark/ast/block.go create mode 100644 vendor/github.com/yuin/goldmark/ast/inline.go create mode 100644 vendor/github.com/yuin/goldmark/extension/ast/definition_list.go create mode 100644 vendor/github.com/yuin/goldmark/extension/ast/footnote.go create mode 100644 vendor/github.com/yuin/goldmark/extension/ast/strikethrough.go create mode 100644 vendor/github.com/yuin/goldmark/extension/ast/table.go create mode 100644 vendor/github.com/yuin/goldmark/extension/ast/tasklist.go create mode 100644 vendor/github.com/yuin/goldmark/extension/cjk.go create mode 100644 vendor/github.com/yuin/goldmark/extension/definition_list.go create mode 100644 vendor/github.com/yuin/goldmark/extension/footnote.go create mode 100644 vendor/github.com/yuin/goldmark/extension/gfm.go create mode 100644 vendor/github.com/yuin/goldmark/extension/linkify.go create mode 100644 vendor/github.com/yuin/goldmark/extension/package.go create mode 100644 vendor/github.com/yuin/goldmark/extension/strikethrough.go create mode 100644 vendor/github.com/yuin/goldmark/extension/table.go create mode 100644 vendor/github.com/yuin/goldmark/extension/tasklist.go create mode 100644 vendor/github.com/yuin/goldmark/extension/typographer.go create mode 100644 vendor/github.com/yuin/goldmark/markdown.go create mode 100644 vendor/github.com/yuin/goldmark/parser/attribute.go create mode 100644 vendor/github.com/yuin/goldmark/parser/atx_heading.go create mode 100644 vendor/github.com/yuin/goldmark/parser/auto_link.go create mode 100644 vendor/github.com/yuin/goldmark/parser/blockquote.go create mode 100644 vendor/github.com/yuin/goldmark/parser/code_block.go create mode 100644 vendor/github.com/yuin/goldmark/parser/code_span.go create mode 100644 vendor/github.com/yuin/goldmark/parser/delimiter.go create mode 100644 vendor/github.com/yuin/goldmark/parser/emphasis.go create mode 100644 vendor/github.com/yuin/goldmark/parser/fcode_block.go create mode 100644 vendor/github.com/yuin/goldmark/parser/html_block.go create mode 100644 vendor/github.com/yuin/goldmark/parser/link.go create mode 100644 vendor/github.com/yuin/goldmark/parser/link_ref.go create mode 100644 vendor/github.com/yuin/goldmark/parser/list.go create mode 100644 vendor/github.com/yuin/goldmark/parser/list_item.go create mode 100644 vendor/github.com/yuin/goldmark/parser/paragraph.go create mode 100644 vendor/github.com/yuin/goldmark/parser/parser.go create mode 100644 vendor/github.com/yuin/goldmark/parser/raw_html.go create mode 100644 vendor/github.com/yuin/goldmark/parser/setext_headings.go create mode 100644 vendor/github.com/yuin/goldmark/parser/thematic_break.go create mode 100644 vendor/github.com/yuin/goldmark/renderer/html/html.go create mode 100644 vendor/github.com/yuin/goldmark/renderer/renderer.go create mode 100644 vendor/github.com/yuin/goldmark/text/package.go create mode 100644 vendor/github.com/yuin/goldmark/text/reader.go create mode 100644 vendor/github.com/yuin/goldmark/text/segment.go create mode 100644 vendor/github.com/yuin/goldmark/util/html5entities.go create mode 100644 vendor/github.com/yuin/goldmark/util/unicode_case_folding.go create mode 100644 vendor/github.com/yuin/goldmark/util/util.go create mode 100644 vendor/github.com/yuin/goldmark/util/util_cjk.go create mode 100644 vendor/github.com/yuin/goldmark/util/util_safe.go create mode 100644 vendor/github.com/yuin/goldmark/util/util_unsafe.go diff --git a/vendor/github.com/yuin/goldmark-emoji/.gitignore b/vendor/github.com/yuin/goldmark-emoji/.gitignore new file mode 100644 index 0000000..4a70bf1 --- /dev/null +++ b/vendor/github.com/yuin/goldmark-emoji/.gitignore @@ -0,0 +1,15 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test +*.pprof + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +.DS_Store diff --git a/vendor/github.com/yuin/goldmark-emoji/LICENSE b/vendor/github.com/yuin/goldmark-emoji/LICENSE new file mode 100644 index 0000000..829d181 --- /dev/null +++ b/vendor/github.com/yuin/goldmark-emoji/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Yusuke Inuzuka + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/yuin/goldmark-emoji/README.md b/vendor/github.com/yuin/goldmark-emoji/README.md new file mode 100644 index 0000000..1ac4748 --- /dev/null +++ b/vendor/github.com/yuin/goldmark-emoji/README.md @@ -0,0 +1,71 @@ +goldmark-emoji +========================= + +[![GoDev][godev-image]][godev-url] + +[godev-image]: https://pkg.go.dev/badge/github.com/yuin/goldmark-emoji +[godev-url]: https://pkg.go.dev/github.com/yuin/goldmark-emoji + +goldmark-emoji is an extension for the [goldmark](http://github.com/yuin/goldmark) +that parses `:joy:` style emojis. + +Installation +-------------------- + +``` +go get github.com/yuin/goldmark-emoji +``` + +Usage +-------------------- + +```go +import ( + "bytes" + "fmt" + + "github.com/yuin/goldmark" + "github.com/yuin/goldmark-emoji" + "github.com/yuin/goldmark-emoji/definition" +) + +func main() { + markdown := goldmark.New( + goldmark.WithExtensions( + emoji.Emoji, + ), + ) + source := ` + Joy :joy: + ` + var buf bytes.Buffer + if err := markdown.Convert([]byte(source), &buf); err != nil { + panic(err) + } + fmt.Print(buf.String()) +} +``` + +See `emoji_test.go` for detailed usage. + +### Options + +Options for the extension + +| Option | Description | +| ------ | ----------- | +| `WithEmojis` | Definition of emojis. This defaults to github emoji set | +| `WithRenderingMethod` | `Entity` : renders as HTML entities, `Twemoji` : renders as an img tag that uses [twemoji](https://github.com/twitter/twemoji), `Func` : renders using a go function | +| `WithTwemojiTemplate` | Twemoji img tag printf template | +| `WithRendererFunc` | renders by a go function | + + + +License +-------------------- +MIT + +Author +-------------------- +Yusuke Inuzuka + diff --git a/vendor/github.com/yuin/goldmark-emoji/ast/emoji.go b/vendor/github.com/yuin/goldmark-emoji/ast/emoji.go new file mode 100644 index 0000000..4f8e783 --- /dev/null +++ b/vendor/github.com/yuin/goldmark-emoji/ast/emoji.go @@ -0,0 +1,42 @@ +// Package ast defines AST nodes that represetns emoji extension's elements. +package ast + +import ( + "fmt" + + "github.com/yuin/goldmark-emoji/definition" + gast "github.com/yuin/goldmark/ast" +) + +// Emoji represents an inline emoji. +type Emoji struct { + gast.BaseInline + + ShortName []byte + Value *definition.Emoji +} + +// Dump implements Node.Dump. +func (n *Emoji) Dump(source []byte, level int) { + m := map[string]string{ + "ShortName": string(n.ShortName), + "Value": fmt.Sprintf("%#v", n.Value), + } + gast.DumpHelper(n, source, level, m, nil) +} + +// KindEmoji is a NodeKind of the emoji node. +var KindEmoji = gast.NewNodeKind("Emoji") + +// Kind implements Node.Kind. +func (n *Emoji) Kind() gast.NodeKind { + return KindEmoji +} + +// NewEmoji returns a new Emoji node. +func NewEmoji(shortName []byte, value *definition.Emoji) *Emoji { + return &Emoji{ + ShortName: shortName, + Value: value, + } +} diff --git a/vendor/github.com/yuin/goldmark-emoji/definition/definition.go b/vendor/github.com/yuin/goldmark-emoji/definition/definition.go new file mode 100644 index 0000000..f5d6298 --- /dev/null +++ b/vendor/github.com/yuin/goldmark-emoji/definition/definition.go @@ -0,0 +1,106 @@ +package definition + +// Emoji is a data structure that holds a single emoji. +type Emoji struct { + // Name is a name of this emoji. + Name string + + // ShortNames is a shorter representation of this emoji. + ShortNames []string + + // Unicode is an unicode representation of this emoji. + Unicode []rune +} + +// NewEmoji returns a new Emoji. +func NewEmoji(name string, unicode []rune, shortNames ...string) Emoji { + if len(shortNames) == 0 { + panic("Emoji must have at least 1 short name.") + } + if len(unicode) == 0 { + unicode = []rune{0xFFFD} + } + return Emoji{ + Name: name, + ShortNames: shortNames, + Unicode: unicode, + } +} + +// IsUnicode returns true if this emoji is defined in unicode, otherwise false. +func (em *Emoji) IsUnicode() bool { + return !(len(em.Unicode) == 1 && em.Unicode[0] == 0xFFFD) +} + +// Emojis is a collection of emojis. +type Emojis interface { + // Get returns (*Emoji, true) if found mapping associated with given short name, otherwise (nil, false). + Get(shortName string) (*Emoji, bool) + + // Add adds new emojis to this collection. + Add(Emojis) + + // Clone clones this collection. + Clone() Emojis +} + +type emojis struct { + list []Emoji + m map[string]*Emoji + children []Emojis +} + +// NewEmojis returns a new Emojis. +func NewEmojis(es ...Emoji) Emojis { + m := &emojis{ + list: es, + m: map[string]*Emoji{}, + children: []Emojis{}, + } + for i := range es { + emoji := &m.list[i] + for _, s := range emoji.ShortNames { + m.m[s] = emoji + } + } + return m +} + +func (m *emojis) Add(emojis Emojis) { + m.children = append(m.children, emojis) +} + +func (m *emojis) Clone() Emojis { + es := &emojis{ + list: m.list, + m: m.m, + children: make([]Emojis, len(m.children)), + } + copy(es.children, m.children) + return es +} + +func (m *emojis) Get(shortName string) (*Emoji, bool) { + v, ok := m.m[shortName] + if ok { + return v, ok + } + + for _, es := range m.children { + v, ok := es.Get(shortName) + if ok { + return v, ok + } + } + return nil, false +} + +// EmojisOption sets options for Emojis. +type EmojisOption func(Emojis) + +// WithEmojis is an EmojisOption that adds emojis to the Emojis. +func WithEmojis(emojis ...Emoji) EmojisOption { + return func(m Emojis) { + m.Add(NewEmojis(emojis...)) + } +} diff --git a/vendor/github.com/yuin/goldmark-emoji/definition/github.go b/vendor/github.com/yuin/goldmark-emoji/definition/github.go new file mode 100644 index 0000000..923dd26 --- /dev/null +++ b/vendor/github.com/yuin/goldmark-emoji/definition/github.go @@ -0,0 +1,1831 @@ +// This file was generated by _tools/gen-definitions.go. DO NOT EDIT. + +package definition +import "sync" + +var github Emojis +var githubOnce sync.Once + +func Github(opts ...EmojisOption) Emojis { + githubOnce.Do(func() { + github = NewEmojis( + NewEmoji("grinning face", []int32{128512}, "grinning"), + NewEmoji("grinning face with big eyes", []int32{128515}, "smiley"), + NewEmoji("grinning face with smiling eyes", []int32{128516}, "smile"), + NewEmoji("beaming face with smiling eyes", []int32{128513}, "grin"), + NewEmoji("grinning squinting face", []int32{128518}, "laughing", "satisfied"), + NewEmoji("grinning face with sweat", []int32{128517}, "sweat_smile"), + NewEmoji("rolling on the floor laughing", []int32{129315}, "rofl"), + NewEmoji("face with tears of joy", []int32{128514}, "joy"), + NewEmoji("slightly smiling face", []int32{128578}, "slightly_smiling_face"), + NewEmoji("upside-down face", []int32{128579}, "upside_down_face"), + NewEmoji("winking face", []int32{128521}, "wink"), + NewEmoji("smiling face with smiling eyes", []int32{128522}, "blush"), + NewEmoji("smiling face with halo", []int32{128519}, "innocent"), + NewEmoji("smiling face with hearts", []int32{129392}, "smiling_face_with_three_hearts"), + NewEmoji("smiling face with heart-eyes", []int32{128525}, "heart_eyes"), + NewEmoji("star-struck", []int32{129321}, "star_struck"), + NewEmoji("face blowing a kiss", []int32{128536}, "kissing_heart"), + NewEmoji("kissing face", []int32{128535}, "kissing"), + NewEmoji("smiling face", []int32{9786, 65039}, "relaxed"), + NewEmoji("kissing face with closed eyes", []int32{128538}, "kissing_closed_eyes"), + NewEmoji("kissing face with smiling eyes", []int32{128537}, "kissing_smiling_eyes"), + NewEmoji("smiling face with tear", []int32{129394}, "smiling_face_with_tear"), + NewEmoji("face savoring food", []int32{128523}, "yum"), + NewEmoji("face with tongue", []int32{128539}, "stuck_out_tongue"), + NewEmoji("winking face with tongue", []int32{128540}, "stuck_out_tongue_winking_eye"), + NewEmoji("zany face", []int32{129322}, "zany_face"), + NewEmoji("squinting face with tongue", []int32{128541}, "stuck_out_tongue_closed_eyes"), + NewEmoji("money-mouth face", []int32{129297}, "money_mouth_face"), + NewEmoji("smiling face with open hands", []int32{129303}, "hugs"), + NewEmoji("face with hand over mouth", []int32{129325}, "hand_over_mouth"), + NewEmoji("shushing face", []int32{129323}, "shushing_face"), + NewEmoji("thinking face", []int32{129300}, "thinking"), + NewEmoji("zipper-mouth face", []int32{129296}, "zipper_mouth_face"), + NewEmoji("face with raised eyebrow", []int32{129320}, "raised_eyebrow"), + NewEmoji("neutral face", []int32{128528}, "neutral_face"), + NewEmoji("expressionless face", []int32{128529}, "expressionless"), + NewEmoji("face without mouth", []int32{128566}, "no_mouth"), + NewEmoji("face in clouds", []int32{128566, 8205, 127787, 65039}, "face_in_clouds"), + NewEmoji("smirking face", []int32{128527}, "smirk"), + NewEmoji("unamused face", []int32{128530}, "unamused"), + NewEmoji("face with rolling eyes", []int32{128580}, "roll_eyes"), + NewEmoji("grimacing face", []int32{128556}, "grimacing"), + NewEmoji("face exhaling", []int32{128558, 8205, 128168}, "face_exhaling"), + NewEmoji("lying face", []int32{129317}, "lying_face"), + NewEmoji("relieved face", []int32{128524}, "relieved"), + NewEmoji("pensive face", []int32{128532}, "pensive"), + NewEmoji("sleepy face", []int32{128554}, "sleepy"), + NewEmoji("drooling face", []int32{129316}, "drooling_face"), + NewEmoji("sleeping face", []int32{128564}, "sleeping"), + NewEmoji("face with medical mask", []int32{128567}, "mask"), + NewEmoji("face with thermometer", []int32{129298}, "face_with_thermometer"), + NewEmoji("face with head-bandage", []int32{129301}, "face_with_head_bandage"), + NewEmoji("nauseated face", []int32{129314}, "nauseated_face"), + NewEmoji("face vomiting", []int32{129326}, "vomiting_face"), + NewEmoji("sneezing face", []int32{129319}, "sneezing_face"), + NewEmoji("hot face", []int32{129397}, "hot_face"), + NewEmoji("cold face", []int32{129398}, "cold_face"), + NewEmoji("woozy face", []int32{129396}, "woozy_face"), + NewEmoji("face with crossed-out eyes", []int32{128565}, "dizzy_face"), + NewEmoji("face with spiral eyes", []int32{128565, 8205, 128171}, "face_with_spiral_eyes"), + NewEmoji("exploding head", []int32{129327}, "exploding_head"), + NewEmoji("cowboy hat face", []int32{129312}, "cowboy_hat_face"), + NewEmoji("partying face", []int32{129395}, "partying_face"), + NewEmoji("disguised face", []int32{129400}, "disguised_face"), + NewEmoji("smiling face with sunglasses", []int32{128526}, "sunglasses"), + NewEmoji("nerd face", []int32{129299}, "nerd_face"), + NewEmoji("face with monocle", []int32{129488}, "monocle_face"), + NewEmoji("confused face", []int32{128533}, "confused"), + NewEmoji("worried face", []int32{128543}, "worried"), + NewEmoji("slightly frowning face", []int32{128577}, "slightly_frowning_face"), + NewEmoji("frowning face", []int32{9785, 65039}, "frowning_face"), + NewEmoji("face with open mouth", []int32{128558}, "open_mouth"), + NewEmoji("hushed face", []int32{128559}, "hushed"), + NewEmoji("astonished face", []int32{128562}, "astonished"), + NewEmoji("flushed face", []int32{128563}, "flushed"), + NewEmoji("pleading face", []int32{129402}, "pleading_face"), + NewEmoji("frowning face with open mouth", []int32{128550}, "frowning"), + NewEmoji("anguished face", []int32{128551}, "anguished"), + NewEmoji("fearful face", []int32{128552}, "fearful"), + NewEmoji("anxious face with sweat", []int32{128560}, "cold_sweat"), + NewEmoji("sad but relieved face", []int32{128549}, "disappointed_relieved"), + NewEmoji("crying face", []int32{128546}, "cry"), + NewEmoji("loudly crying face", []int32{128557}, "sob"), + NewEmoji("face screaming in fear", []int32{128561}, "scream"), + NewEmoji("confounded face", []int32{128534}, "confounded"), + NewEmoji("persevering face", []int32{128547}, "persevere"), + NewEmoji("disappointed face", []int32{128542}, "disappointed"), + NewEmoji("downcast face with sweat", []int32{128531}, "sweat"), + NewEmoji("weary face", []int32{128553}, "weary"), + NewEmoji("tired face", []int32{128555}, "tired_face"), + NewEmoji("yawning face", []int32{129393}, "yawning_face"), + NewEmoji("face with steam from nose", []int32{128548}, "triumph"), + NewEmoji("pouting face", []int32{128545}, "rage", "pout"), + NewEmoji("angry face", []int32{128544}, "angry"), + NewEmoji("face with symbols on mouth", []int32{129324}, "cursing_face"), + NewEmoji("smiling face with horns", []int32{128520}, "smiling_imp"), + NewEmoji("angry face with horns", []int32{128127}, "imp"), + NewEmoji("skull", []int32{128128}, "skull"), + NewEmoji("skull and crossbones", []int32{9760, 65039}, "skull_and_crossbones"), + NewEmoji("pile of poo", []int32{128169}, "hankey", "poop", "shit"), + NewEmoji("clown face", []int32{129313}, "clown_face"), + NewEmoji("ogre", []int32{128121}, "japanese_ogre"), + NewEmoji("goblin", []int32{128122}, "japanese_goblin"), + NewEmoji("ghost", []int32{128123}, "ghost"), + NewEmoji("alien", []int32{128125}, "alien"), + NewEmoji("alien monster", []int32{128126}, "space_invader"), + NewEmoji("robot", []int32{129302}, "robot"), + NewEmoji("grinning cat", []int32{128570}, "smiley_cat"), + NewEmoji("grinning cat with smiling eyes", []int32{128568}, "smile_cat"), + NewEmoji("cat with tears of joy", []int32{128569}, "joy_cat"), + NewEmoji("smiling cat with heart-eyes", []int32{128571}, "heart_eyes_cat"), + NewEmoji("cat with wry smile", []int32{128572}, "smirk_cat"), + NewEmoji("kissing cat", []int32{128573}, "kissing_cat"), + NewEmoji("weary cat", []int32{128576}, "scream_cat"), + NewEmoji("crying cat", []int32{128575}, "crying_cat_face"), + NewEmoji("pouting cat", []int32{128574}, "pouting_cat"), + NewEmoji("see-no-evil monkey", []int32{128584}, "see_no_evil"), + NewEmoji("hear-no-evil monkey", []int32{128585}, "hear_no_evil"), + NewEmoji("speak-no-evil monkey", []int32{128586}, "speak_no_evil"), + NewEmoji("kiss mark", []int32{128139}, "kiss"), + NewEmoji("love letter", []int32{128140}, "love_letter"), + NewEmoji("heart with arrow", []int32{128152}, "cupid"), + NewEmoji("heart with ribbon", []int32{128157}, "gift_heart"), + NewEmoji("sparkling heart", []int32{128150}, "sparkling_heart"), + NewEmoji("growing heart", []int32{128151}, "heartpulse"), + NewEmoji("beating heart", []int32{128147}, "heartbeat"), + NewEmoji("revolving hearts", []int32{128158}, "revolving_hearts"), + NewEmoji("two hearts", []int32{128149}, "two_hearts"), + NewEmoji("heart decoration", []int32{128159}, "heart_decoration"), + NewEmoji("heart exclamation", []int32{10083, 65039}, "heavy_heart_exclamation"), + NewEmoji("broken heart", []int32{128148}, "broken_heart"), + NewEmoji("heart on fire", []int32{10084, 65039, 8205, 128293}, "heart_on_fire"), + NewEmoji("mending heart", []int32{10084, 65039, 8205, 129657}, "mending_heart"), + NewEmoji("red heart", []int32{10084, 65039}, "heart"), + NewEmoji("orange heart", []int32{129505}, "orange_heart"), + NewEmoji("yellow heart", []int32{128155}, "yellow_heart"), + NewEmoji("green heart", []int32{128154}, "green_heart"), + NewEmoji("blue heart", []int32{128153}, "blue_heart"), + NewEmoji("purple heart", []int32{128156}, "purple_heart"), + NewEmoji("brown heart", []int32{129294}, "brown_heart"), + NewEmoji("black heart", []int32{128420}, "black_heart"), + NewEmoji("white heart", []int32{129293}, "white_heart"), + NewEmoji("hundred points", []int32{128175}, "100"), + NewEmoji("anger symbol", []int32{128162}, "anger"), + NewEmoji("collision", []int32{128165}, "boom", "collision"), + NewEmoji("dizzy", []int32{128171}, "dizzy"), + NewEmoji("sweat droplets", []int32{128166}, "sweat_drops"), + NewEmoji("dashing away", []int32{128168}, "dash"), + NewEmoji("hole", []int32{128371, 65039}, "hole"), + NewEmoji("bomb", []int32{128163}, "bomb"), + NewEmoji("speech balloon", []int32{128172}, "speech_balloon"), + NewEmoji("eye in speech bubble", []int32{128065, 65039, 8205, 128488, 65039}, "eye_speech_bubble"), + NewEmoji("left speech bubble", []int32{128488, 65039}, "left_speech_bubble"), + NewEmoji("right anger bubble", []int32{128495, 65039}, "right_anger_bubble"), + NewEmoji("thought balloon", []int32{128173}, "thought_balloon"), + NewEmoji("zzz", []int32{128164}, "zzz"), + NewEmoji("waving hand", []int32{128075}, "wave"), + NewEmoji("raised back of hand", []int32{129306}, "raised_back_of_hand"), + NewEmoji("hand with fingers splayed", []int32{128400, 65039}, "raised_hand_with_fingers_splayed"), + NewEmoji("raised hand", []int32{9995}, "hand", "raised_hand"), + NewEmoji("vulcan salute", []int32{128406}, "vulcan_salute"), + NewEmoji("OK hand", []int32{128076}, "ok_hand"), + NewEmoji("pinched fingers", []int32{129292}, "pinched_fingers"), + NewEmoji("pinching hand", []int32{129295}, "pinching_hand"), + NewEmoji("victory hand", []int32{9996, 65039}, "v"), + NewEmoji("crossed fingers", []int32{129310}, "crossed_fingers"), + NewEmoji("love-you gesture", []int32{129311}, "love_you_gesture"), + NewEmoji("sign of the horns", []int32{129304}, "metal"), + NewEmoji("call me hand", []int32{129305}, "call_me_hand"), + NewEmoji("backhand index pointing left", []int32{128072}, "point_left"), + NewEmoji("backhand index pointing right", []int32{128073}, "point_right"), + NewEmoji("backhand index pointing up", []int32{128070}, "point_up_2"), + NewEmoji("middle finger", []int32{128405}, "middle_finger", "fu"), + NewEmoji("backhand index pointing down", []int32{128071}, "point_down"), + NewEmoji("index pointing up", []int32{9757, 65039}, "point_up"), + NewEmoji("thumbs up", []int32{128077}, "+1", "thumbsup"), + NewEmoji("thumbs down", []int32{128078}, "-1", "thumbsdown"), + NewEmoji("raised fist", []int32{9994}, "fist_raised", "fist"), + NewEmoji("oncoming fist", []int32{128074}, "fist_oncoming", "facepunch", "punch"), + NewEmoji("left-facing fist", []int32{129307}, "fist_left"), + NewEmoji("right-facing fist", []int32{129308}, "fist_right"), + NewEmoji("clapping hands", []int32{128079}, "clap"), + NewEmoji("raising hands", []int32{128588}, "raised_hands"), + NewEmoji("open hands", []int32{128080}, "open_hands"), + NewEmoji("palms up together", []int32{129330}, "palms_up_together"), + NewEmoji("handshake", []int32{129309}, "handshake"), + NewEmoji("folded hands", []int32{128591}, "pray"), + NewEmoji("writing hand", []int32{9997, 65039}, "writing_hand"), + NewEmoji("nail polish", []int32{128133}, "nail_care"), + NewEmoji("selfie", []int32{129331}, "selfie"), + NewEmoji("flexed biceps", []int32{128170}, "muscle"), + NewEmoji("mechanical arm", []int32{129470}, "mechanical_arm"), + NewEmoji("mechanical leg", []int32{129471}, "mechanical_leg"), + NewEmoji("leg", []int32{129461}, "leg"), + NewEmoji("foot", []int32{129462}, "foot"), + NewEmoji("ear", []int32{128066}, "ear"), + NewEmoji("ear with hearing aid", []int32{129467}, "ear_with_hearing_aid"), + NewEmoji("nose", []int32{128067}, "nose"), + NewEmoji("brain", []int32{129504}, "brain"), + NewEmoji("anatomical heart", []int32{129728}, "anatomical_heart"), + NewEmoji("lungs", []int32{129729}, "lungs"), + NewEmoji("tooth", []int32{129463}, "tooth"), + NewEmoji("bone", []int32{129460}, "bone"), + NewEmoji("eyes", []int32{128064}, "eyes"), + NewEmoji("eye", []int32{128065, 65039}, "eye"), + NewEmoji("tongue", []int32{128069}, "tongue"), + NewEmoji("mouth", []int32{128068}, "lips"), + NewEmoji("baby", []int32{128118}, "baby"), + NewEmoji("child", []int32{129490}, "child"), + NewEmoji("boy", []int32{128102}, "boy"), + NewEmoji("girl", []int32{128103}, "girl"), + NewEmoji("person", []int32{129489}, "adult"), + NewEmoji("person: blond hair", []int32{128113}, "blond_haired_person"), + NewEmoji("man", []int32{128104}, "man"), + NewEmoji("person: beard", []int32{129492}, "bearded_person"), + NewEmoji("man: beard", []int32{129492, 8205, 9794, 65039}, "man_beard"), + NewEmoji("woman: beard", []int32{129492, 8205, 9792, 65039}, "woman_beard"), + NewEmoji("man: red hair", []int32{128104, 8205, 129456}, "red_haired_man"), + NewEmoji("man: curly hair", []int32{128104, 8205, 129457}, "curly_haired_man"), + NewEmoji("man: white hair", []int32{128104, 8205, 129459}, "white_haired_man"), + NewEmoji("man: bald", []int32{128104, 8205, 129458}, "bald_man"), + NewEmoji("woman", []int32{128105}, "woman"), + NewEmoji("woman: red hair", []int32{128105, 8205, 129456}, "red_haired_woman"), + NewEmoji("person: red hair", []int32{129489, 8205, 129456}, "person_red_hair"), + NewEmoji("woman: curly hair", []int32{128105, 8205, 129457}, "curly_haired_woman"), + NewEmoji("person: curly hair", []int32{129489, 8205, 129457}, "person_curly_hair"), + NewEmoji("woman: white hair", []int32{128105, 8205, 129459}, "white_haired_woman"), + NewEmoji("person: white hair", []int32{129489, 8205, 129459}, "person_white_hair"), + NewEmoji("woman: bald", []int32{128105, 8205, 129458}, "bald_woman"), + NewEmoji("person: bald", []int32{129489, 8205, 129458}, "person_bald"), + NewEmoji("woman: blond hair", []int32{128113, 8205, 9792, 65039}, "blond_haired_woman", "blonde_woman"), + NewEmoji("man: blond hair", []int32{128113, 8205, 9794, 65039}, "blond_haired_man"), + NewEmoji("older person", []int32{129491}, "older_adult"), + NewEmoji("old man", []int32{128116}, "older_man"), + NewEmoji("old woman", []int32{128117}, "older_woman"), + NewEmoji("person frowning", []int32{128589}, "frowning_person"), + NewEmoji("man frowning", []int32{128589, 8205, 9794, 65039}, "frowning_man"), + NewEmoji("woman frowning", []int32{128589, 8205, 9792, 65039}, "frowning_woman"), + NewEmoji("person pouting", []int32{128590}, "pouting_face"), + NewEmoji("man pouting", []int32{128590, 8205, 9794, 65039}, "pouting_man"), + NewEmoji("woman pouting", []int32{128590, 8205, 9792, 65039}, "pouting_woman"), + NewEmoji("person gesturing NO", []int32{128581}, "no_good"), + NewEmoji("man gesturing NO", []int32{128581, 8205, 9794, 65039}, "no_good_man", "ng_man"), + NewEmoji("woman gesturing NO", []int32{128581, 8205, 9792, 65039}, "no_good_woman", "ng_woman"), + NewEmoji("person gesturing OK", []int32{128582}, "ok_person"), + NewEmoji("man gesturing OK", []int32{128582, 8205, 9794, 65039}, "ok_man"), + NewEmoji("woman gesturing OK", []int32{128582, 8205, 9792, 65039}, "ok_woman"), + NewEmoji("person tipping hand", []int32{128129}, "tipping_hand_person", "information_desk_person"), + NewEmoji("man tipping hand", []int32{128129, 8205, 9794, 65039}, "tipping_hand_man", "sassy_man"), + NewEmoji("woman tipping hand", []int32{128129, 8205, 9792, 65039}, "tipping_hand_woman", "sassy_woman"), + NewEmoji("person raising hand", []int32{128587}, "raising_hand"), + NewEmoji("man raising hand", []int32{128587, 8205, 9794, 65039}, "raising_hand_man"), + NewEmoji("woman raising hand", []int32{128587, 8205, 9792, 65039}, "raising_hand_woman"), + NewEmoji("deaf person", []int32{129487}, "deaf_person"), + NewEmoji("deaf man", []int32{129487, 8205, 9794, 65039}, "deaf_man"), + NewEmoji("deaf woman", []int32{129487, 8205, 9792, 65039}, "deaf_woman"), + NewEmoji("person bowing", []int32{128583}, "bow"), + NewEmoji("man bowing", []int32{128583, 8205, 9794, 65039}, "bowing_man"), + NewEmoji("woman bowing", []int32{128583, 8205, 9792, 65039}, "bowing_woman"), + NewEmoji("person facepalming", []int32{129318}, "facepalm"), + NewEmoji("man facepalming", []int32{129318, 8205, 9794, 65039}, "man_facepalming"), + NewEmoji("woman facepalming", []int32{129318, 8205, 9792, 65039}, "woman_facepalming"), + NewEmoji("person shrugging", []int32{129335}, "shrug"), + NewEmoji("man shrugging", []int32{129335, 8205, 9794, 65039}, "man_shrugging"), + NewEmoji("woman shrugging", []int32{129335, 8205, 9792, 65039}, "woman_shrugging"), + NewEmoji("health worker", []int32{129489, 8205, 9877, 65039}, "health_worker"), + NewEmoji("man health worker", []int32{128104, 8205, 9877, 65039}, "man_health_worker"), + NewEmoji("woman health worker", []int32{128105, 8205, 9877, 65039}, "woman_health_worker"), + NewEmoji("student", []int32{129489, 8205, 127891}, "student"), + NewEmoji("man student", []int32{128104, 8205, 127891}, "man_student"), + NewEmoji("woman student", []int32{128105, 8205, 127891}, "woman_student"), + NewEmoji("teacher", []int32{129489, 8205, 127979}, "teacher"), + NewEmoji("man teacher", []int32{128104, 8205, 127979}, "man_teacher"), + NewEmoji("woman teacher", []int32{128105, 8205, 127979}, "woman_teacher"), + NewEmoji("judge", []int32{129489, 8205, 9878, 65039}, "judge"), + NewEmoji("man judge", []int32{128104, 8205, 9878, 65039}, "man_judge"), + NewEmoji("woman judge", []int32{128105, 8205, 9878, 65039}, "woman_judge"), + NewEmoji("farmer", []int32{129489, 8205, 127806}, "farmer"), + NewEmoji("man farmer", []int32{128104, 8205, 127806}, "man_farmer"), + NewEmoji("woman farmer", []int32{128105, 8205, 127806}, "woman_farmer"), + NewEmoji("cook", []int32{129489, 8205, 127859}, "cook"), + NewEmoji("man cook", []int32{128104, 8205, 127859}, "man_cook"), + NewEmoji("woman cook", []int32{128105, 8205, 127859}, "woman_cook"), + NewEmoji("mechanic", []int32{129489, 8205, 128295}, "mechanic"), + NewEmoji("man mechanic", []int32{128104, 8205, 128295}, "man_mechanic"), + NewEmoji("woman mechanic", []int32{128105, 8205, 128295}, "woman_mechanic"), + NewEmoji("factory worker", []int32{129489, 8205, 127981}, "factory_worker"), + NewEmoji("man factory worker", []int32{128104, 8205, 127981}, "man_factory_worker"), + NewEmoji("woman factory worker", []int32{128105, 8205, 127981}, "woman_factory_worker"), + NewEmoji("office worker", []int32{129489, 8205, 128188}, "office_worker"), + NewEmoji("man office worker", []int32{128104, 8205, 128188}, "man_office_worker"), + NewEmoji("woman office worker", []int32{128105, 8205, 128188}, "woman_office_worker"), + NewEmoji("scientist", []int32{129489, 8205, 128300}, "scientist"), + NewEmoji("man scientist", []int32{128104, 8205, 128300}, "man_scientist"), + NewEmoji("woman scientist", []int32{128105, 8205, 128300}, "woman_scientist"), + NewEmoji("technologist", []int32{129489, 8205, 128187}, "technologist"), + NewEmoji("man technologist", []int32{128104, 8205, 128187}, "man_technologist"), + NewEmoji("woman technologist", []int32{128105, 8205, 128187}, "woman_technologist"), + NewEmoji("singer", []int32{129489, 8205, 127908}, "singer"), + NewEmoji("man singer", []int32{128104, 8205, 127908}, "man_singer"), + NewEmoji("woman singer", []int32{128105, 8205, 127908}, "woman_singer"), + NewEmoji("artist", []int32{129489, 8205, 127912}, "artist"), + NewEmoji("man artist", []int32{128104, 8205, 127912}, "man_artist"), + NewEmoji("woman artist", []int32{128105, 8205, 127912}, "woman_artist"), + NewEmoji("pilot", []int32{129489, 8205, 9992, 65039}, "pilot"), + NewEmoji("man pilot", []int32{128104, 8205, 9992, 65039}, "man_pilot"), + NewEmoji("woman pilot", []int32{128105, 8205, 9992, 65039}, "woman_pilot"), + NewEmoji("astronaut", []int32{129489, 8205, 128640}, "astronaut"), + NewEmoji("man astronaut", []int32{128104, 8205, 128640}, "man_astronaut"), + NewEmoji("woman astronaut", []int32{128105, 8205, 128640}, "woman_astronaut"), + NewEmoji("firefighter", []int32{129489, 8205, 128658}, "firefighter"), + NewEmoji("man firefighter", []int32{128104, 8205, 128658}, "man_firefighter"), + NewEmoji("woman firefighter", []int32{128105, 8205, 128658}, "woman_firefighter"), + NewEmoji("police officer", []int32{128110}, "police_officer", "cop"), + NewEmoji("man police officer", []int32{128110, 8205, 9794, 65039}, "policeman"), + NewEmoji("woman police officer", []int32{128110, 8205, 9792, 65039}, "policewoman"), + NewEmoji("detective", []int32{128373, 65039}, "detective"), + NewEmoji("man detective", []int32{128373, 65039, 8205, 9794, 65039}, "male_detective"), + NewEmoji("woman detective", []int32{128373, 65039, 8205, 9792, 65039}, "female_detective"), + NewEmoji("guard", []int32{128130}, "guard"), + NewEmoji("man guard", []int32{128130, 8205, 9794, 65039}, "guardsman"), + NewEmoji("woman guard", []int32{128130, 8205, 9792, 65039}, "guardswoman"), + NewEmoji("ninja", []int32{129399}, "ninja"), + NewEmoji("construction worker", []int32{128119}, "construction_worker"), + NewEmoji("man construction worker", []int32{128119, 8205, 9794, 65039}, "construction_worker_man"), + NewEmoji("woman construction worker", []int32{128119, 8205, 9792, 65039}, "construction_worker_woman"), + NewEmoji("prince", []int32{129332}, "prince"), + NewEmoji("princess", []int32{128120}, "princess"), + NewEmoji("person wearing turban", []int32{128115}, "person_with_turban"), + NewEmoji("man wearing turban", []int32{128115, 8205, 9794, 65039}, "man_with_turban"), + NewEmoji("woman wearing turban", []int32{128115, 8205, 9792, 65039}, "woman_with_turban"), + NewEmoji("person with skullcap", []int32{128114}, "man_with_gua_pi_mao"), + NewEmoji("woman with headscarf", []int32{129493}, "woman_with_headscarf"), + NewEmoji("person in tuxedo", []int32{129333}, "person_in_tuxedo"), + NewEmoji("man in tuxedo", []int32{129333, 8205, 9794, 65039}, "man_in_tuxedo"), + NewEmoji("woman in tuxedo", []int32{129333, 8205, 9792, 65039}, "woman_in_tuxedo"), + NewEmoji("person with veil", []int32{128112}, "person_with_veil"), + NewEmoji("man with veil", []int32{128112, 8205, 9794, 65039}, "man_with_veil"), + NewEmoji("woman with veil", []int32{128112, 8205, 9792, 65039}, "woman_with_veil", "bride_with_veil"), + NewEmoji("pregnant woman", []int32{129328}, "pregnant_woman"), + NewEmoji("breast-feeding", []int32{129329}, "breast_feeding"), + NewEmoji("woman feeding baby", []int32{128105, 8205, 127868}, "woman_feeding_baby"), + NewEmoji("man feeding baby", []int32{128104, 8205, 127868}, "man_feeding_baby"), + NewEmoji("person feeding baby", []int32{129489, 8205, 127868}, "person_feeding_baby"), + NewEmoji("baby angel", []int32{128124}, "angel"), + NewEmoji("Santa Claus", []int32{127877}, "santa"), + NewEmoji("Mrs. Claus", []int32{129334}, "mrs_claus"), + NewEmoji("mx claus", []int32{129489, 8205, 127876}, "mx_claus"), + NewEmoji("superhero", []int32{129464}, "superhero"), + NewEmoji("man superhero", []int32{129464, 8205, 9794, 65039}, "superhero_man"), + NewEmoji("woman superhero", []int32{129464, 8205, 9792, 65039}, "superhero_woman"), + NewEmoji("supervillain", []int32{129465}, "supervillain"), + NewEmoji("man supervillain", []int32{129465, 8205, 9794, 65039}, "supervillain_man"), + NewEmoji("woman supervillain", []int32{129465, 8205, 9792, 65039}, "supervillain_woman"), + NewEmoji("mage", []int32{129497}, "mage"), + NewEmoji("man mage", []int32{129497, 8205, 9794, 65039}, "mage_man"), + NewEmoji("woman mage", []int32{129497, 8205, 9792, 65039}, "mage_woman"), + NewEmoji("fairy", []int32{129498}, "fairy"), + NewEmoji("man fairy", []int32{129498, 8205, 9794, 65039}, "fairy_man"), + NewEmoji("woman fairy", []int32{129498, 8205, 9792, 65039}, "fairy_woman"), + NewEmoji("vampire", []int32{129499}, "vampire"), + NewEmoji("man vampire", []int32{129499, 8205, 9794, 65039}, "vampire_man"), + NewEmoji("woman vampire", []int32{129499, 8205, 9792, 65039}, "vampire_woman"), + NewEmoji("merperson", []int32{129500}, "merperson"), + NewEmoji("merman", []int32{129500, 8205, 9794, 65039}, "merman"), + NewEmoji("mermaid", []int32{129500, 8205, 9792, 65039}, "mermaid"), + NewEmoji("elf", []int32{129501}, "elf"), + NewEmoji("man elf", []int32{129501, 8205, 9794, 65039}, "elf_man"), + NewEmoji("woman elf", []int32{129501, 8205, 9792, 65039}, "elf_woman"), + NewEmoji("genie", []int32{129502}, "genie"), + NewEmoji("man genie", []int32{129502, 8205, 9794, 65039}, "genie_man"), + NewEmoji("woman genie", []int32{129502, 8205, 9792, 65039}, "genie_woman"), + NewEmoji("zombie", []int32{129503}, "zombie"), + NewEmoji("man zombie", []int32{129503, 8205, 9794, 65039}, "zombie_man"), + NewEmoji("woman zombie", []int32{129503, 8205, 9792, 65039}, "zombie_woman"), + NewEmoji("person getting massage", []int32{128134}, "massage"), + NewEmoji("man getting massage", []int32{128134, 8205, 9794, 65039}, "massage_man"), + NewEmoji("woman getting massage", []int32{128134, 8205, 9792, 65039}, "massage_woman"), + NewEmoji("person getting haircut", []int32{128135}, "haircut"), + NewEmoji("man getting haircut", []int32{128135, 8205, 9794, 65039}, "haircut_man"), + NewEmoji("woman getting haircut", []int32{128135, 8205, 9792, 65039}, "haircut_woman"), + NewEmoji("person walking", []int32{128694}, "walking"), + NewEmoji("man walking", []int32{128694, 8205, 9794, 65039}, "walking_man"), + NewEmoji("woman walking", []int32{128694, 8205, 9792, 65039}, "walking_woman"), + NewEmoji("person standing", []int32{129485}, "standing_person"), + NewEmoji("man standing", []int32{129485, 8205, 9794, 65039}, "standing_man"), + NewEmoji("woman standing", []int32{129485, 8205, 9792, 65039}, "standing_woman"), + NewEmoji("person kneeling", []int32{129486}, "kneeling_person"), + NewEmoji("man kneeling", []int32{129486, 8205, 9794, 65039}, "kneeling_man"), + NewEmoji("woman kneeling", []int32{129486, 8205, 9792, 65039}, "kneeling_woman"), + NewEmoji("person with white cane", []int32{129489, 8205, 129455}, "person_with_probing_cane"), + NewEmoji("man with white cane", []int32{128104, 8205, 129455}, "man_with_probing_cane"), + NewEmoji("woman with white cane", []int32{128105, 8205, 129455}, "woman_with_probing_cane"), + NewEmoji("person in motorized wheelchair", []int32{129489, 8205, 129468}, "person_in_motorized_wheelchair"), + NewEmoji("man in motorized wheelchair", []int32{128104, 8205, 129468}, "man_in_motorized_wheelchair"), + NewEmoji("woman in motorized wheelchair", []int32{128105, 8205, 129468}, "woman_in_motorized_wheelchair"), + NewEmoji("person in manual wheelchair", []int32{129489, 8205, 129469}, "person_in_manual_wheelchair"), + NewEmoji("man in manual wheelchair", []int32{128104, 8205, 129469}, "man_in_manual_wheelchair"), + NewEmoji("woman in manual wheelchair", []int32{128105, 8205, 129469}, "woman_in_manual_wheelchair"), + NewEmoji("person running", []int32{127939}, "runner", "running"), + NewEmoji("man running", []int32{127939, 8205, 9794, 65039}, "running_man"), + NewEmoji("woman running", []int32{127939, 8205, 9792, 65039}, "running_woman"), + NewEmoji("woman dancing", []int32{128131}, "woman_dancing", "dancer"), + NewEmoji("man dancing", []int32{128378}, "man_dancing"), + NewEmoji("person in suit levitating", []int32{128372, 65039}, "business_suit_levitating"), + NewEmoji("people with bunny ears", []int32{128111}, "dancers"), + NewEmoji("men with bunny ears", []int32{128111, 8205, 9794, 65039}, "dancing_men"), + NewEmoji("women with bunny ears", []int32{128111, 8205, 9792, 65039}, "dancing_women"), + NewEmoji("person in steamy room", []int32{129494}, "sauna_person"), + NewEmoji("man in steamy room", []int32{129494, 8205, 9794, 65039}, "sauna_man"), + NewEmoji("woman in steamy room", []int32{129494, 8205, 9792, 65039}, "sauna_woman"), + NewEmoji("person climbing", []int32{129495}, "climbing"), + NewEmoji("man climbing", []int32{129495, 8205, 9794, 65039}, "climbing_man"), + NewEmoji("woman climbing", []int32{129495, 8205, 9792, 65039}, "climbing_woman"), + NewEmoji("person fencing", []int32{129338}, "person_fencing"), + NewEmoji("horse racing", []int32{127943}, "horse_racing"), + NewEmoji("skier", []int32{9975, 65039}, "skier"), + NewEmoji("snowboarder", []int32{127938}, "snowboarder"), + NewEmoji("person golfing", []int32{127948, 65039}, "golfing"), + NewEmoji("man golfing", []int32{127948, 65039, 8205, 9794, 65039}, "golfing_man"), + NewEmoji("woman golfing", []int32{127948, 65039, 8205, 9792, 65039}, "golfing_woman"), + NewEmoji("person surfing", []int32{127940}, "surfer"), + NewEmoji("man surfing", []int32{127940, 8205, 9794, 65039}, "surfing_man"), + NewEmoji("woman surfing", []int32{127940, 8205, 9792, 65039}, "surfing_woman"), + NewEmoji("person rowing boat", []int32{128675}, "rowboat"), + NewEmoji("man rowing boat", []int32{128675, 8205, 9794, 65039}, "rowing_man"), + NewEmoji("woman rowing boat", []int32{128675, 8205, 9792, 65039}, "rowing_woman"), + NewEmoji("person swimming", []int32{127946}, "swimmer"), + NewEmoji("man swimming", []int32{127946, 8205, 9794, 65039}, "swimming_man"), + NewEmoji("woman swimming", []int32{127946, 8205, 9792, 65039}, "swimming_woman"), + NewEmoji("person bouncing ball", []int32{9977, 65039}, "bouncing_ball_person"), + NewEmoji("man bouncing ball", []int32{9977, 65039, 8205, 9794, 65039}, "bouncing_ball_man", "basketball_man"), + NewEmoji("woman bouncing ball", []int32{9977, 65039, 8205, 9792, 65039}, "bouncing_ball_woman", "basketball_woman"), + NewEmoji("person lifting weights", []int32{127947, 65039}, "weight_lifting"), + NewEmoji("man lifting weights", []int32{127947, 65039, 8205, 9794, 65039}, "weight_lifting_man"), + NewEmoji("woman lifting weights", []int32{127947, 65039, 8205, 9792, 65039}, "weight_lifting_woman"), + NewEmoji("person biking", []int32{128692}, "bicyclist"), + NewEmoji("man biking", []int32{128692, 8205, 9794, 65039}, "biking_man"), + NewEmoji("woman biking", []int32{128692, 8205, 9792, 65039}, "biking_woman"), + NewEmoji("person mountain biking", []int32{128693}, "mountain_bicyclist"), + NewEmoji("man mountain biking", []int32{128693, 8205, 9794, 65039}, "mountain_biking_man"), + NewEmoji("woman mountain biking", []int32{128693, 8205, 9792, 65039}, "mountain_biking_woman"), + NewEmoji("person cartwheeling", []int32{129336}, "cartwheeling"), + NewEmoji("man cartwheeling", []int32{129336, 8205, 9794, 65039}, "man_cartwheeling"), + NewEmoji("woman cartwheeling", []int32{129336, 8205, 9792, 65039}, "woman_cartwheeling"), + NewEmoji("people wrestling", []int32{129340}, "wrestling"), + NewEmoji("men wrestling", []int32{129340, 8205, 9794, 65039}, "men_wrestling"), + NewEmoji("women wrestling", []int32{129340, 8205, 9792, 65039}, "women_wrestling"), + NewEmoji("person playing water polo", []int32{129341}, "water_polo"), + NewEmoji("man playing water polo", []int32{129341, 8205, 9794, 65039}, "man_playing_water_polo"), + NewEmoji("woman playing water polo", []int32{129341, 8205, 9792, 65039}, "woman_playing_water_polo"), + NewEmoji("person playing handball", []int32{129342}, "handball_person"), + NewEmoji("man playing handball", []int32{129342, 8205, 9794, 65039}, "man_playing_handball"), + NewEmoji("woman playing handball", []int32{129342, 8205, 9792, 65039}, "woman_playing_handball"), + NewEmoji("person juggling", []int32{129337}, "juggling_person"), + NewEmoji("man juggling", []int32{129337, 8205, 9794, 65039}, "man_juggling"), + NewEmoji("woman juggling", []int32{129337, 8205, 9792, 65039}, "woman_juggling"), + NewEmoji("person in lotus position", []int32{129496}, "lotus_position"), + NewEmoji("man in lotus position", []int32{129496, 8205, 9794, 65039}, "lotus_position_man"), + NewEmoji("woman in lotus position", []int32{129496, 8205, 9792, 65039}, "lotus_position_woman"), + NewEmoji("person taking bath", []int32{128704}, "bath"), + NewEmoji("person in bed", []int32{128716}, "sleeping_bed"), + NewEmoji("people holding hands", []int32{129489, 8205, 129309, 8205, 129489}, "people_holding_hands"), + NewEmoji("women holding hands", []int32{128109}, "two_women_holding_hands"), + NewEmoji("woman and man holding hands", []int32{128107}, "couple"), + NewEmoji("men holding hands", []int32{128108}, "two_men_holding_hands"), + NewEmoji("kiss", []int32{128143}, "couplekiss"), + NewEmoji("kiss: woman, man", []int32{128105, 8205, 10084, 65039, 8205, 128139, 8205, 128104}, "couplekiss_man_woman"), + NewEmoji("kiss: man, man", []int32{128104, 8205, 10084, 65039, 8205, 128139, 8205, 128104}, "couplekiss_man_man"), + NewEmoji("kiss: woman, woman", []int32{128105, 8205, 10084, 65039, 8205, 128139, 8205, 128105}, "couplekiss_woman_woman"), + NewEmoji("couple with heart", []int32{128145}, "couple_with_heart"), + NewEmoji("couple with heart: woman, man", []int32{128105, 8205, 10084, 65039, 8205, 128104}, "couple_with_heart_woman_man"), + NewEmoji("couple with heart: man, man", []int32{128104, 8205, 10084, 65039, 8205, 128104}, "couple_with_heart_man_man"), + NewEmoji("couple with heart: woman, woman", []int32{128105, 8205, 10084, 65039, 8205, 128105}, "couple_with_heart_woman_woman"), + NewEmoji("family", []int32{128106}, "family"), + NewEmoji("family: man, woman, boy", []int32{128104, 8205, 128105, 8205, 128102}, "family_man_woman_boy"), + NewEmoji("family: man, woman, girl", []int32{128104, 8205, 128105, 8205, 128103}, "family_man_woman_girl"), + NewEmoji("family: man, woman, girl, boy", []int32{128104, 8205, 128105, 8205, 128103, 8205, 128102}, "family_man_woman_girl_boy"), + NewEmoji("family: man, woman, boy, boy", []int32{128104, 8205, 128105, 8205, 128102, 8205, 128102}, "family_man_woman_boy_boy"), + NewEmoji("family: man, woman, girl, girl", []int32{128104, 8205, 128105, 8205, 128103, 8205, 128103}, "family_man_woman_girl_girl"), + NewEmoji("family: man, man, boy", []int32{128104, 8205, 128104, 8205, 128102}, "family_man_man_boy"), + NewEmoji("family: man, man, girl", []int32{128104, 8205, 128104, 8205, 128103}, "family_man_man_girl"), + NewEmoji("family: man, man, girl, boy", []int32{128104, 8205, 128104, 8205, 128103, 8205, 128102}, "family_man_man_girl_boy"), + NewEmoji("family: man, man, boy, boy", []int32{128104, 8205, 128104, 8205, 128102, 8205, 128102}, "family_man_man_boy_boy"), + NewEmoji("family: man, man, girl, girl", []int32{128104, 8205, 128104, 8205, 128103, 8205, 128103}, "family_man_man_girl_girl"), + NewEmoji("family: woman, woman, boy", []int32{128105, 8205, 128105, 8205, 128102}, "family_woman_woman_boy"), + NewEmoji("family: woman, woman, girl", []int32{128105, 8205, 128105, 8205, 128103}, "family_woman_woman_girl"), + NewEmoji("family: woman, woman, girl, boy", []int32{128105, 8205, 128105, 8205, 128103, 8205, 128102}, "family_woman_woman_girl_boy"), + NewEmoji("family: woman, woman, boy, boy", []int32{128105, 8205, 128105, 8205, 128102, 8205, 128102}, "family_woman_woman_boy_boy"), + NewEmoji("family: woman, woman, girl, girl", []int32{128105, 8205, 128105, 8205, 128103, 8205, 128103}, "family_woman_woman_girl_girl"), + NewEmoji("family: man, boy", []int32{128104, 8205, 128102}, "family_man_boy"), + NewEmoji("family: man, boy, boy", []int32{128104, 8205, 128102, 8205, 128102}, "family_man_boy_boy"), + NewEmoji("family: man, girl", []int32{128104, 8205, 128103}, "family_man_girl"), + NewEmoji("family: man, girl, boy", []int32{128104, 8205, 128103, 8205, 128102}, "family_man_girl_boy"), + NewEmoji("family: man, girl, girl", []int32{128104, 8205, 128103, 8205, 128103}, "family_man_girl_girl"), + NewEmoji("family: woman, boy", []int32{128105, 8205, 128102}, "family_woman_boy"), + NewEmoji("family: woman, boy, boy", []int32{128105, 8205, 128102, 8205, 128102}, "family_woman_boy_boy"), + NewEmoji("family: woman, girl", []int32{128105, 8205, 128103}, "family_woman_girl"), + NewEmoji("family: woman, girl, boy", []int32{128105, 8205, 128103, 8205, 128102}, "family_woman_girl_boy"), + NewEmoji("family: woman, girl, girl", []int32{128105, 8205, 128103, 8205, 128103}, "family_woman_girl_girl"), + NewEmoji("speaking head", []int32{128483, 65039}, "speaking_head"), + NewEmoji("bust in silhouette", []int32{128100}, "bust_in_silhouette"), + NewEmoji("busts in silhouette", []int32{128101}, "busts_in_silhouette"), + NewEmoji("people hugging", []int32{129730}, "people_hugging"), + NewEmoji("footprints", []int32{128099}, "footprints"), + NewEmoji("monkey face", []int32{128053}, "monkey_face"), + NewEmoji("monkey", []int32{128018}, "monkey"), + NewEmoji("gorilla", []int32{129421}, "gorilla"), + NewEmoji("orangutan", []int32{129447}, "orangutan"), + NewEmoji("dog face", []int32{128054}, "dog"), + NewEmoji("dog", []int32{128021}, "dog2"), + NewEmoji("guide dog", []int32{129454}, "guide_dog"), + NewEmoji("service dog", []int32{128021, 8205, 129466}, "service_dog"), + NewEmoji("poodle", []int32{128041}, "poodle"), + NewEmoji("wolf", []int32{128058}, "wolf"), + NewEmoji("fox", []int32{129418}, "fox_face"), + NewEmoji("raccoon", []int32{129437}, "raccoon"), + NewEmoji("cat face", []int32{128049}, "cat"), + NewEmoji("cat", []int32{128008}, "cat2"), + NewEmoji("black cat", []int32{128008, 8205, 11035}, "black_cat"), + NewEmoji("lion", []int32{129409}, "lion"), + NewEmoji("tiger face", []int32{128047}, "tiger"), + NewEmoji("tiger", []int32{128005}, "tiger2"), + NewEmoji("leopard", []int32{128006}, "leopard"), + NewEmoji("horse face", []int32{128052}, "horse"), + NewEmoji("horse", []int32{128014}, "racehorse"), + NewEmoji("unicorn", []int32{129412}, "unicorn"), + NewEmoji("zebra", []int32{129427}, "zebra"), + NewEmoji("deer", []int32{129420}, "deer"), + NewEmoji("bison", []int32{129452}, "bison"), + NewEmoji("cow face", []int32{128046}, "cow"), + NewEmoji("ox", []int32{128002}, "ox"), + NewEmoji("water buffalo", []int32{128003}, "water_buffalo"), + NewEmoji("cow", []int32{128004}, "cow2"), + NewEmoji("pig face", []int32{128055}, "pig"), + NewEmoji("pig", []int32{128022}, "pig2"), + NewEmoji("boar", []int32{128023}, "boar"), + NewEmoji("pig nose", []int32{128061}, "pig_nose"), + NewEmoji("ram", []int32{128015}, "ram"), + NewEmoji("ewe", []int32{128017}, "sheep"), + NewEmoji("goat", []int32{128016}, "goat"), + NewEmoji("camel", []int32{128042}, "dromedary_camel"), + NewEmoji("two-hump camel", []int32{128043}, "camel"), + NewEmoji("llama", []int32{129433}, "llama"), + NewEmoji("giraffe", []int32{129426}, "giraffe"), + NewEmoji("elephant", []int32{128024}, "elephant"), + NewEmoji("mammoth", []int32{129443}, "mammoth"), + NewEmoji("rhinoceros", []int32{129423}, "rhinoceros"), + NewEmoji("hippopotamus", []int32{129435}, "hippopotamus"), + NewEmoji("mouse face", []int32{128045}, "mouse"), + NewEmoji("mouse", []int32{128001}, "mouse2"), + NewEmoji("rat", []int32{128000}, "rat"), + NewEmoji("hamster", []int32{128057}, "hamster"), + NewEmoji("rabbit face", []int32{128048}, "rabbit"), + NewEmoji("rabbit", []int32{128007}, "rabbit2"), + NewEmoji("chipmunk", []int32{128063, 65039}, "chipmunk"), + NewEmoji("beaver", []int32{129451}, "beaver"), + NewEmoji("hedgehog", []int32{129428}, "hedgehog"), + NewEmoji("bat", []int32{129415}, "bat"), + NewEmoji("bear", []int32{128059}, "bear"), + NewEmoji("polar bear", []int32{128059, 8205, 10052, 65039}, "polar_bear"), + NewEmoji("koala", []int32{128040}, "koala"), + NewEmoji("panda", []int32{128060}, "panda_face"), + NewEmoji("sloth", []int32{129445}, "sloth"), + NewEmoji("otter", []int32{129446}, "otter"), + NewEmoji("skunk", []int32{129448}, "skunk"), + NewEmoji("kangaroo", []int32{129432}, "kangaroo"), + NewEmoji("badger", []int32{129441}, "badger"), + NewEmoji("paw prints", []int32{128062}, "feet", "paw_prints"), + NewEmoji("turkey", []int32{129411}, "turkey"), + NewEmoji("chicken", []int32{128020}, "chicken"), + NewEmoji("rooster", []int32{128019}, "rooster"), + NewEmoji("hatching chick", []int32{128035}, "hatching_chick"), + NewEmoji("baby chick", []int32{128036}, "baby_chick"), + NewEmoji("front-facing baby chick", []int32{128037}, "hatched_chick"), + NewEmoji("bird", []int32{128038}, "bird"), + NewEmoji("penguin", []int32{128039}, "penguin"), + NewEmoji("dove", []int32{128330, 65039}, "dove"), + NewEmoji("eagle", []int32{129413}, "eagle"), + NewEmoji("duck", []int32{129414}, "duck"), + NewEmoji("swan", []int32{129442}, "swan"), + NewEmoji("owl", []int32{129417}, "owl"), + NewEmoji("dodo", []int32{129444}, "dodo"), + NewEmoji("feather", []int32{129718}, "feather"), + NewEmoji("flamingo", []int32{129449}, "flamingo"), + NewEmoji("peacock", []int32{129434}, "peacock"), + NewEmoji("parrot", []int32{129436}, "parrot"), + NewEmoji("frog", []int32{128056}, "frog"), + NewEmoji("crocodile", []int32{128010}, "crocodile"), + NewEmoji("turtle", []int32{128034}, "turtle"), + NewEmoji("lizard", []int32{129422}, "lizard"), + NewEmoji("snake", []int32{128013}, "snake"), + NewEmoji("dragon face", []int32{128050}, "dragon_face"), + NewEmoji("dragon", []int32{128009}, "dragon"), + NewEmoji("sauropod", []int32{129429}, "sauropod"), + NewEmoji("T-Rex", []int32{129430}, "t-rex"), + NewEmoji("spouting whale", []int32{128051}, "whale"), + NewEmoji("whale", []int32{128011}, "whale2"), + NewEmoji("dolphin", []int32{128044}, "dolphin", "flipper"), + NewEmoji("seal", []int32{129453}, "seal"), + NewEmoji("fish", []int32{128031}, "fish"), + NewEmoji("tropical fish", []int32{128032}, "tropical_fish"), + NewEmoji("blowfish", []int32{128033}, "blowfish"), + NewEmoji("shark", []int32{129416}, "shark"), + NewEmoji("octopus", []int32{128025}, "octopus"), + NewEmoji("spiral shell", []int32{128026}, "shell"), + NewEmoji("snail", []int32{128012}, "snail"), + NewEmoji("butterfly", []int32{129419}, "butterfly"), + NewEmoji("bug", []int32{128027}, "bug"), + NewEmoji("ant", []int32{128028}, "ant"), + NewEmoji("honeybee", []int32{128029}, "bee", "honeybee"), + NewEmoji("beetle", []int32{129714}, "beetle"), + NewEmoji("lady beetle", []int32{128030}, "lady_beetle"), + NewEmoji("cricket", []int32{129431}, "cricket"), + NewEmoji("cockroach", []int32{129715}, "cockroach"), + NewEmoji("spider", []int32{128375, 65039}, "spider"), + NewEmoji("spider web", []int32{128376, 65039}, "spider_web"), + NewEmoji("scorpion", []int32{129410}, "scorpion"), + NewEmoji("mosquito", []int32{129439}, "mosquito"), + NewEmoji("fly", []int32{129712}, "fly"), + NewEmoji("worm", []int32{129713}, "worm"), + NewEmoji("microbe", []int32{129440}, "microbe"), + NewEmoji("bouquet", []int32{128144}, "bouquet"), + NewEmoji("cherry blossom", []int32{127800}, "cherry_blossom"), + NewEmoji("white flower", []int32{128174}, "white_flower"), + NewEmoji("rosette", []int32{127989, 65039}, "rosette"), + NewEmoji("rose", []int32{127801}, "rose"), + NewEmoji("wilted flower", []int32{129344}, "wilted_flower"), + NewEmoji("hibiscus", []int32{127802}, "hibiscus"), + NewEmoji("sunflower", []int32{127803}, "sunflower"), + NewEmoji("blossom", []int32{127804}, "blossom"), + NewEmoji("tulip", []int32{127799}, "tulip"), + NewEmoji("seedling", []int32{127793}, "seedling"), + NewEmoji("potted plant", []int32{129716}, "potted_plant"), + NewEmoji("evergreen tree", []int32{127794}, "evergreen_tree"), + NewEmoji("deciduous tree", []int32{127795}, "deciduous_tree"), + NewEmoji("palm tree", []int32{127796}, "palm_tree"), + NewEmoji("cactus", []int32{127797}, "cactus"), + NewEmoji("sheaf of rice", []int32{127806}, "ear_of_rice"), + NewEmoji("herb", []int32{127807}, "herb"), + NewEmoji("shamrock", []int32{9752, 65039}, "shamrock"), + NewEmoji("four leaf clover", []int32{127808}, "four_leaf_clover"), + NewEmoji("maple leaf", []int32{127809}, "maple_leaf"), + NewEmoji("fallen leaf", []int32{127810}, "fallen_leaf"), + NewEmoji("leaf fluttering in wind", []int32{127811}, "leaves"), + NewEmoji("grapes", []int32{127815}, "grapes"), + NewEmoji("melon", []int32{127816}, "melon"), + NewEmoji("watermelon", []int32{127817}, "watermelon"), + NewEmoji("tangerine", []int32{127818}, "tangerine", "orange", "mandarin"), + NewEmoji("lemon", []int32{127819}, "lemon"), + NewEmoji("banana", []int32{127820}, "banana"), + NewEmoji("pineapple", []int32{127821}, "pineapple"), + NewEmoji("mango", []int32{129389}, "mango"), + NewEmoji("red apple", []int32{127822}, "apple"), + NewEmoji("green apple", []int32{127823}, "green_apple"), + NewEmoji("pear", []int32{127824}, "pear"), + NewEmoji("peach", []int32{127825}, "peach"), + NewEmoji("cherries", []int32{127826}, "cherries"), + NewEmoji("strawberry", []int32{127827}, "strawberry"), + NewEmoji("blueberries", []int32{129744}, "blueberries"), + NewEmoji("kiwi fruit", []int32{129373}, "kiwi_fruit"), + NewEmoji("tomato", []int32{127813}, "tomato"), + NewEmoji("olive", []int32{129746}, "olive"), + NewEmoji("coconut", []int32{129381}, "coconut"), + NewEmoji("avocado", []int32{129361}, "avocado"), + NewEmoji("eggplant", []int32{127814}, "eggplant"), + NewEmoji("potato", []int32{129364}, "potato"), + NewEmoji("carrot", []int32{129365}, "carrot"), + NewEmoji("ear of corn", []int32{127805}, "corn"), + NewEmoji("hot pepper", []int32{127798, 65039}, "hot_pepper"), + NewEmoji("bell pepper", []int32{129745}, "bell_pepper"), + NewEmoji("cucumber", []int32{129362}, "cucumber"), + NewEmoji("leafy green", []int32{129388}, "leafy_green"), + NewEmoji("broccoli", []int32{129382}, "broccoli"), + NewEmoji("garlic", []int32{129476}, "garlic"), + NewEmoji("onion", []int32{129477}, "onion"), + NewEmoji("mushroom", []int32{127812}, "mushroom"), + NewEmoji("peanuts", []int32{129372}, "peanuts"), + NewEmoji("chestnut", []int32{127792}, "chestnut"), + NewEmoji("bread", []int32{127838}, "bread"), + NewEmoji("croissant", []int32{129360}, "croissant"), + NewEmoji("baguette bread", []int32{129366}, "baguette_bread"), + NewEmoji("flatbread", []int32{129747}, "flatbread"), + NewEmoji("pretzel", []int32{129384}, "pretzel"), + NewEmoji("bagel", []int32{129391}, "bagel"), + NewEmoji("pancakes", []int32{129374}, "pancakes"), + NewEmoji("waffle", []int32{129479}, "waffle"), + NewEmoji("cheese wedge", []int32{129472}, "cheese"), + NewEmoji("meat on bone", []int32{127830}, "meat_on_bone"), + NewEmoji("poultry leg", []int32{127831}, "poultry_leg"), + NewEmoji("cut of meat", []int32{129385}, "cut_of_meat"), + NewEmoji("bacon", []int32{129363}, "bacon"), + NewEmoji("hamburger", []int32{127828}, "hamburger"), + NewEmoji("french fries", []int32{127839}, "fries"), + NewEmoji("pizza", []int32{127829}, "pizza"), + NewEmoji("hot dog", []int32{127789}, "hotdog"), + NewEmoji("sandwich", []int32{129386}, "sandwich"), + NewEmoji("taco", []int32{127790}, "taco"), + NewEmoji("burrito", []int32{127791}, "burrito"), + NewEmoji("tamale", []int32{129748}, "tamale"), + NewEmoji("stuffed flatbread", []int32{129369}, "stuffed_flatbread"), + NewEmoji("falafel", []int32{129478}, "falafel"), + NewEmoji("egg", []int32{129370}, "egg"), + NewEmoji("cooking", []int32{127859}, "fried_egg"), + NewEmoji("shallow pan of food", []int32{129368}, "shallow_pan_of_food"), + NewEmoji("pot of food", []int32{127858}, "stew"), + NewEmoji("fondue", []int32{129749}, "fondue"), + NewEmoji("bowl with spoon", []int32{129379}, "bowl_with_spoon"), + NewEmoji("green salad", []int32{129367}, "green_salad"), + NewEmoji("popcorn", []int32{127871}, "popcorn"), + NewEmoji("butter", []int32{129480}, "butter"), + NewEmoji("salt", []int32{129474}, "salt"), + NewEmoji("canned food", []int32{129387}, "canned_food"), + NewEmoji("bento box", []int32{127857}, "bento"), + NewEmoji("rice cracker", []int32{127832}, "rice_cracker"), + NewEmoji("rice ball", []int32{127833}, "rice_ball"), + NewEmoji("cooked rice", []int32{127834}, "rice"), + NewEmoji("curry rice", []int32{127835}, "curry"), + NewEmoji("steaming bowl", []int32{127836}, "ramen"), + NewEmoji("spaghetti", []int32{127837}, "spaghetti"), + NewEmoji("roasted sweet potato", []int32{127840}, "sweet_potato"), + NewEmoji("oden", []int32{127842}, "oden"), + NewEmoji("sushi", []int32{127843}, "sushi"), + NewEmoji("fried shrimp", []int32{127844}, "fried_shrimp"), + NewEmoji("fish cake with swirl", []int32{127845}, "fish_cake"), + NewEmoji("moon cake", []int32{129390}, "moon_cake"), + NewEmoji("dango", []int32{127841}, "dango"), + NewEmoji("dumpling", []int32{129375}, "dumpling"), + NewEmoji("fortune cookie", []int32{129376}, "fortune_cookie"), + NewEmoji("takeout box", []int32{129377}, "takeout_box"), + NewEmoji("crab", []int32{129408}, "crab"), + NewEmoji("lobster", []int32{129438}, "lobster"), + NewEmoji("shrimp", []int32{129424}, "shrimp"), + NewEmoji("squid", []int32{129425}, "squid"), + NewEmoji("oyster", []int32{129450}, "oyster"), + NewEmoji("soft ice cream", []int32{127846}, "icecream"), + NewEmoji("shaved ice", []int32{127847}, "shaved_ice"), + NewEmoji("ice cream", []int32{127848}, "ice_cream"), + NewEmoji("doughnut", []int32{127849}, "doughnut"), + NewEmoji("cookie", []int32{127850}, "cookie"), + NewEmoji("birthday cake", []int32{127874}, "birthday"), + NewEmoji("shortcake", []int32{127856}, "cake"), + NewEmoji("cupcake", []int32{129473}, "cupcake"), + NewEmoji("pie", []int32{129383}, "pie"), + NewEmoji("chocolate bar", []int32{127851}, "chocolate_bar"), + NewEmoji("candy", []int32{127852}, "candy"), + NewEmoji("lollipop", []int32{127853}, "lollipop"), + NewEmoji("custard", []int32{127854}, "custard"), + NewEmoji("honey pot", []int32{127855}, "honey_pot"), + NewEmoji("baby bottle", []int32{127868}, "baby_bottle"), + NewEmoji("glass of milk", []int32{129371}, "milk_glass"), + NewEmoji("hot beverage", []int32{9749}, "coffee"), + NewEmoji("teapot", []int32{129750}, "teapot"), + NewEmoji("teacup without handle", []int32{127861}, "tea"), + NewEmoji("sake", []int32{127862}, "sake"), + NewEmoji("bottle with popping cork", []int32{127870}, "champagne"), + NewEmoji("wine glass", []int32{127863}, "wine_glass"), + NewEmoji("cocktail glass", []int32{127864}, "cocktail"), + NewEmoji("tropical drink", []int32{127865}, "tropical_drink"), + NewEmoji("beer mug", []int32{127866}, "beer"), + NewEmoji("clinking beer mugs", []int32{127867}, "beers"), + NewEmoji("clinking glasses", []int32{129346}, "clinking_glasses"), + NewEmoji("tumbler glass", []int32{129347}, "tumbler_glass"), + NewEmoji("cup with straw", []int32{129380}, "cup_with_straw"), + NewEmoji("bubble tea", []int32{129483}, "bubble_tea"), + NewEmoji("beverage box", []int32{129475}, "beverage_box"), + NewEmoji("mate", []int32{129481}, "mate"), + NewEmoji("ice", []int32{129482}, "ice_cube"), + NewEmoji("chopsticks", []int32{129378}, "chopsticks"), + NewEmoji("fork and knife with plate", []int32{127869, 65039}, "plate_with_cutlery"), + NewEmoji("fork and knife", []int32{127860}, "fork_and_knife"), + NewEmoji("spoon", []int32{129348}, "spoon"), + NewEmoji("kitchen knife", []int32{128298}, "hocho", "knife"), + NewEmoji("amphora", []int32{127994}, "amphora"), + NewEmoji("globe showing Europe-Africa", []int32{127757}, "earth_africa"), + NewEmoji("globe showing Americas", []int32{127758}, "earth_americas"), + NewEmoji("globe showing Asia-Australia", []int32{127759}, "earth_asia"), + NewEmoji("globe with meridians", []int32{127760}, "globe_with_meridians"), + NewEmoji("world map", []int32{128506, 65039}, "world_map"), + NewEmoji("map of Japan", []int32{128510}, "japan"), + NewEmoji("compass", []int32{129517}, "compass"), + NewEmoji("snow-capped mountain", []int32{127956, 65039}, "mountain_snow"), + NewEmoji("mountain", []int32{9968, 65039}, "mountain"), + NewEmoji("volcano", []int32{127755}, "volcano"), + NewEmoji("mount fuji", []int32{128507}, "mount_fuji"), + NewEmoji("camping", []int32{127957, 65039}, "camping"), + NewEmoji("beach with umbrella", []int32{127958, 65039}, "beach_umbrella"), + NewEmoji("desert", []int32{127964, 65039}, "desert"), + NewEmoji("desert island", []int32{127965, 65039}, "desert_island"), + NewEmoji("national park", []int32{127966, 65039}, "national_park"), + NewEmoji("stadium", []int32{127967, 65039}, "stadium"), + NewEmoji("classical building", []int32{127963, 65039}, "classical_building"), + NewEmoji("building construction", []int32{127959, 65039}, "building_construction"), + NewEmoji("brick", []int32{129521}, "bricks"), + NewEmoji("rock", []int32{129704}, "rock"), + NewEmoji("wood", []int32{129717}, "wood"), + NewEmoji("hut", []int32{128726}, "hut"), + NewEmoji("houses", []int32{127960, 65039}, "houses"), + NewEmoji("derelict house", []int32{127962, 65039}, "derelict_house"), + NewEmoji("house", []int32{127968}, "house"), + NewEmoji("house with garden", []int32{127969}, "house_with_garden"), + NewEmoji("office building", []int32{127970}, "office"), + NewEmoji("Japanese post office", []int32{127971}, "post_office"), + NewEmoji("post office", []int32{127972}, "european_post_office"), + NewEmoji("hospital", []int32{127973}, "hospital"), + NewEmoji("bank", []int32{127974}, "bank"), + NewEmoji("hotel", []int32{127976}, "hotel"), + NewEmoji("love hotel", []int32{127977}, "love_hotel"), + NewEmoji("convenience store", []int32{127978}, "convenience_store"), + NewEmoji("school", []int32{127979}, "school"), + NewEmoji("department store", []int32{127980}, "department_store"), + NewEmoji("factory", []int32{127981}, "factory"), + NewEmoji("Japanese castle", []int32{127983}, "japanese_castle"), + NewEmoji("castle", []int32{127984}, "european_castle"), + NewEmoji("wedding", []int32{128146}, "wedding"), + NewEmoji("Tokyo tower", []int32{128508}, "tokyo_tower"), + NewEmoji("Statue of Liberty", []int32{128509}, "statue_of_liberty"), + NewEmoji("church", []int32{9962}, "church"), + NewEmoji("mosque", []int32{128332}, "mosque"), + NewEmoji("hindu temple", []int32{128725}, "hindu_temple"), + NewEmoji("synagogue", []int32{128333}, "synagogue"), + NewEmoji("shinto shrine", []int32{9961, 65039}, "shinto_shrine"), + NewEmoji("kaaba", []int32{128331}, "kaaba"), + NewEmoji("fountain", []int32{9970}, "fountain"), + NewEmoji("tent", []int32{9978}, "tent"), + NewEmoji("foggy", []int32{127745}, "foggy"), + NewEmoji("night with stars", []int32{127747}, "night_with_stars"), + NewEmoji("cityscape", []int32{127961, 65039}, "cityscape"), + NewEmoji("sunrise over mountains", []int32{127748}, "sunrise_over_mountains"), + NewEmoji("sunrise", []int32{127749}, "sunrise"), + NewEmoji("cityscape at dusk", []int32{127750}, "city_sunset"), + NewEmoji("sunset", []int32{127751}, "city_sunrise"), + NewEmoji("bridge at night", []int32{127753}, "bridge_at_night"), + NewEmoji("hot springs", []int32{9832, 65039}, "hotsprings"), + NewEmoji("carousel horse", []int32{127904}, "carousel_horse"), + NewEmoji("ferris wheel", []int32{127905}, "ferris_wheel"), + NewEmoji("roller coaster", []int32{127906}, "roller_coaster"), + NewEmoji("barber pole", []int32{128136}, "barber"), + NewEmoji("circus tent", []int32{127914}, "circus_tent"), + NewEmoji("locomotive", []int32{128642}, "steam_locomotive"), + NewEmoji("railway car", []int32{128643}, "railway_car"), + NewEmoji("high-speed train", []int32{128644}, "bullettrain_side"), + NewEmoji("bullet train", []int32{128645}, "bullettrain_front"), + NewEmoji("train", []int32{128646}, "train2"), + NewEmoji("metro", []int32{128647}, "metro"), + NewEmoji("light rail", []int32{128648}, "light_rail"), + NewEmoji("station", []int32{128649}, "station"), + NewEmoji("tram", []int32{128650}, "tram"), + NewEmoji("monorail", []int32{128669}, "monorail"), + NewEmoji("mountain railway", []int32{128670}, "mountain_railway"), + NewEmoji("tram car", []int32{128651}, "train"), + NewEmoji("bus", []int32{128652}, "bus"), + NewEmoji("oncoming bus", []int32{128653}, "oncoming_bus"), + NewEmoji("trolleybus", []int32{128654}, "trolleybus"), + NewEmoji("minibus", []int32{128656}, "minibus"), + NewEmoji("ambulance", []int32{128657}, "ambulance"), + NewEmoji("fire engine", []int32{128658}, "fire_engine"), + NewEmoji("police car", []int32{128659}, "police_car"), + NewEmoji("oncoming police car", []int32{128660}, "oncoming_police_car"), + NewEmoji("taxi", []int32{128661}, "taxi"), + NewEmoji("oncoming taxi", []int32{128662}, "oncoming_taxi"), + NewEmoji("automobile", []int32{128663}, "car", "red_car"), + NewEmoji("oncoming automobile", []int32{128664}, "oncoming_automobile"), + NewEmoji("sport utility vehicle", []int32{128665}, "blue_car"), + NewEmoji("pickup truck", []int32{128763}, "pickup_truck"), + NewEmoji("delivery truck", []int32{128666}, "truck"), + NewEmoji("articulated lorry", []int32{128667}, "articulated_lorry"), + NewEmoji("tractor", []int32{128668}, "tractor"), + NewEmoji("racing car", []int32{127950, 65039}, "racing_car"), + NewEmoji("motorcycle", []int32{127949, 65039}, "motorcycle"), + NewEmoji("motor scooter", []int32{128757}, "motor_scooter"), + NewEmoji("manual wheelchair", []int32{129469}, "manual_wheelchair"), + NewEmoji("motorized wheelchair", []int32{129468}, "motorized_wheelchair"), + NewEmoji("auto rickshaw", []int32{128762}, "auto_rickshaw"), + NewEmoji("bicycle", []int32{128690}, "bike"), + NewEmoji("kick scooter", []int32{128756}, "kick_scooter"), + NewEmoji("skateboard", []int32{128761}, "skateboard"), + NewEmoji("roller skate", []int32{128764}, "roller_skate"), + NewEmoji("bus stop", []int32{128655}, "busstop"), + NewEmoji("motorway", []int32{128739, 65039}, "motorway"), + NewEmoji("railway track", []int32{128740, 65039}, "railway_track"), + NewEmoji("oil drum", []int32{128738, 65039}, "oil_drum"), + NewEmoji("fuel pump", []int32{9981}, "fuelpump"), + NewEmoji("police car light", []int32{128680}, "rotating_light"), + NewEmoji("horizontal traffic light", []int32{128677}, "traffic_light"), + NewEmoji("vertical traffic light", []int32{128678}, "vertical_traffic_light"), + NewEmoji("stop sign", []int32{128721}, "stop_sign"), + NewEmoji("construction", []int32{128679}, "construction"), + NewEmoji("anchor", []int32{9875}, "anchor"), + NewEmoji("sailboat", []int32{9973}, "boat", "sailboat"), + NewEmoji("canoe", []int32{128758}, "canoe"), + NewEmoji("speedboat", []int32{128676}, "speedboat"), + NewEmoji("passenger ship", []int32{128755, 65039}, "passenger_ship"), + NewEmoji("ferry", []int32{9972, 65039}, "ferry"), + NewEmoji("motor boat", []int32{128741, 65039}, "motor_boat"), + NewEmoji("ship", []int32{128674}, "ship"), + NewEmoji("airplane", []int32{9992, 65039}, "airplane"), + NewEmoji("small airplane", []int32{128745, 65039}, "small_airplane"), + NewEmoji("airplane departure", []int32{128747}, "flight_departure"), + NewEmoji("airplane arrival", []int32{128748}, "flight_arrival"), + NewEmoji("parachute", []int32{129666}, "parachute"), + NewEmoji("seat", []int32{128186}, "seat"), + NewEmoji("helicopter", []int32{128641}, "helicopter"), + NewEmoji("suspension railway", []int32{128671}, "suspension_railway"), + NewEmoji("mountain cableway", []int32{128672}, "mountain_cableway"), + NewEmoji("aerial tramway", []int32{128673}, "aerial_tramway"), + NewEmoji("satellite", []int32{128752, 65039}, "artificial_satellite"), + NewEmoji("rocket", []int32{128640}, "rocket"), + NewEmoji("flying saucer", []int32{128760}, "flying_saucer"), + NewEmoji("bellhop bell", []int32{128718, 65039}, "bellhop_bell"), + NewEmoji("luggage", []int32{129523}, "luggage"), + NewEmoji("hourglass done", []int32{8987}, "hourglass"), + NewEmoji("hourglass not done", []int32{9203}, "hourglass_flowing_sand"), + NewEmoji("watch", []int32{8986}, "watch"), + NewEmoji("alarm clock", []int32{9200}, "alarm_clock"), + NewEmoji("stopwatch", []int32{9201, 65039}, "stopwatch"), + NewEmoji("timer clock", []int32{9202, 65039}, "timer_clock"), + NewEmoji("mantelpiece clock", []int32{128368, 65039}, "mantelpiece_clock"), + NewEmoji("twelve o’clock", []int32{128347}, "clock12"), + NewEmoji("twelve-thirty", []int32{128359}, "clock1230"), + NewEmoji("one o’clock", []int32{128336}, "clock1"), + NewEmoji("one-thirty", []int32{128348}, "clock130"), + NewEmoji("two o’clock", []int32{128337}, "clock2"), + NewEmoji("two-thirty", []int32{128349}, "clock230"), + NewEmoji("three o’clock", []int32{128338}, "clock3"), + NewEmoji("three-thirty", []int32{128350}, "clock330"), + NewEmoji("four o’clock", []int32{128339}, "clock4"), + NewEmoji("four-thirty", []int32{128351}, "clock430"), + NewEmoji("five o’clock", []int32{128340}, "clock5"), + NewEmoji("five-thirty", []int32{128352}, "clock530"), + NewEmoji("six o’clock", []int32{128341}, "clock6"), + NewEmoji("six-thirty", []int32{128353}, "clock630"), + NewEmoji("seven o’clock", []int32{128342}, "clock7"), + NewEmoji("seven-thirty", []int32{128354}, "clock730"), + NewEmoji("eight o’clock", []int32{128343}, "clock8"), + NewEmoji("eight-thirty", []int32{128355}, "clock830"), + NewEmoji("nine o’clock", []int32{128344}, "clock9"), + NewEmoji("nine-thirty", []int32{128356}, "clock930"), + NewEmoji("ten o’clock", []int32{128345}, "clock10"), + NewEmoji("ten-thirty", []int32{128357}, "clock1030"), + NewEmoji("eleven o’clock", []int32{128346}, "clock11"), + NewEmoji("eleven-thirty", []int32{128358}, "clock1130"), + NewEmoji("new moon", []int32{127761}, "new_moon"), + NewEmoji("waxing crescent moon", []int32{127762}, "waxing_crescent_moon"), + NewEmoji("first quarter moon", []int32{127763}, "first_quarter_moon"), + NewEmoji("waxing gibbous moon", []int32{127764}, "moon", "waxing_gibbous_moon"), + NewEmoji("full moon", []int32{127765}, "full_moon"), + NewEmoji("waning gibbous moon", []int32{127766}, "waning_gibbous_moon"), + NewEmoji("last quarter moon", []int32{127767}, "last_quarter_moon"), + NewEmoji("waning crescent moon", []int32{127768}, "waning_crescent_moon"), + NewEmoji("crescent moon", []int32{127769}, "crescent_moon"), + NewEmoji("new moon face", []int32{127770}, "new_moon_with_face"), + NewEmoji("first quarter moon face", []int32{127771}, "first_quarter_moon_with_face"), + NewEmoji("last quarter moon face", []int32{127772}, "last_quarter_moon_with_face"), + NewEmoji("thermometer", []int32{127777, 65039}, "thermometer"), + NewEmoji("sun", []int32{9728, 65039}, "sunny"), + NewEmoji("full moon face", []int32{127773}, "full_moon_with_face"), + NewEmoji("sun with face", []int32{127774}, "sun_with_face"), + NewEmoji("ringed planet", []int32{129680}, "ringed_planet"), + NewEmoji("star", []int32{11088}, "star"), + NewEmoji("glowing star", []int32{127775}, "star2"), + NewEmoji("shooting star", []int32{127776}, "stars"), + NewEmoji("milky way", []int32{127756}, "milky_way"), + NewEmoji("cloud", []int32{9729, 65039}, "cloud"), + NewEmoji("sun behind cloud", []int32{9925}, "partly_sunny"), + NewEmoji("cloud with lightning and rain", []int32{9928, 65039}, "cloud_with_lightning_and_rain"), + NewEmoji("sun behind small cloud", []int32{127780, 65039}, "sun_behind_small_cloud"), + NewEmoji("sun behind large cloud", []int32{127781, 65039}, "sun_behind_large_cloud"), + NewEmoji("sun behind rain cloud", []int32{127782, 65039}, "sun_behind_rain_cloud"), + NewEmoji("cloud with rain", []int32{127783, 65039}, "cloud_with_rain"), + NewEmoji("cloud with snow", []int32{127784, 65039}, "cloud_with_snow"), + NewEmoji("cloud with lightning", []int32{127785, 65039}, "cloud_with_lightning"), + NewEmoji("tornado", []int32{127786, 65039}, "tornado"), + NewEmoji("fog", []int32{127787, 65039}, "fog"), + NewEmoji("wind face", []int32{127788, 65039}, "wind_face"), + NewEmoji("cyclone", []int32{127744}, "cyclone"), + NewEmoji("rainbow", []int32{127752}, "rainbow"), + NewEmoji("closed umbrella", []int32{127746}, "closed_umbrella"), + NewEmoji("umbrella", []int32{9730, 65039}, "open_umbrella"), + NewEmoji("umbrella with rain drops", []int32{9748}, "umbrella"), + NewEmoji("umbrella on ground", []int32{9969, 65039}, "parasol_on_ground"), + NewEmoji("high voltage", []int32{9889}, "zap"), + NewEmoji("snowflake", []int32{10052, 65039}, "snowflake"), + NewEmoji("snowman", []int32{9731, 65039}, "snowman_with_snow"), + NewEmoji("snowman without snow", []int32{9924}, "snowman"), + NewEmoji("comet", []int32{9732, 65039}, "comet"), + NewEmoji("fire", []int32{128293}, "fire"), + NewEmoji("droplet", []int32{128167}, "droplet"), + NewEmoji("water wave", []int32{127754}, "ocean"), + NewEmoji("jack-o-lantern", []int32{127875}, "jack_o_lantern"), + NewEmoji("Christmas tree", []int32{127876}, "christmas_tree"), + NewEmoji("fireworks", []int32{127878}, "fireworks"), + NewEmoji("sparkler", []int32{127879}, "sparkler"), + NewEmoji("firecracker", []int32{129512}, "firecracker"), + NewEmoji("sparkles", []int32{10024}, "sparkles"), + NewEmoji("balloon", []int32{127880}, "balloon"), + NewEmoji("party popper", []int32{127881}, "tada"), + NewEmoji("confetti ball", []int32{127882}, "confetti_ball"), + NewEmoji("tanabata tree", []int32{127883}, "tanabata_tree"), + NewEmoji("pine decoration", []int32{127885}, "bamboo"), + NewEmoji("Japanese dolls", []int32{127886}, "dolls"), + NewEmoji("carp streamer", []int32{127887}, "flags"), + NewEmoji("wind chime", []int32{127888}, "wind_chime"), + NewEmoji("moon viewing ceremony", []int32{127889}, "rice_scene"), + NewEmoji("red envelope", []int32{129511}, "red_envelope"), + NewEmoji("ribbon", []int32{127872}, "ribbon"), + NewEmoji("wrapped gift", []int32{127873}, "gift"), + NewEmoji("reminder ribbon", []int32{127895, 65039}, "reminder_ribbon"), + NewEmoji("admission tickets", []int32{127903, 65039}, "tickets"), + NewEmoji("ticket", []int32{127915}, "ticket"), + NewEmoji("military medal", []int32{127894, 65039}, "medal_military"), + NewEmoji("trophy", []int32{127942}, "trophy"), + NewEmoji("sports medal", []int32{127941}, "medal_sports"), + NewEmoji("1st place medal", []int32{129351}, "1st_place_medal"), + NewEmoji("2nd place medal", []int32{129352}, "2nd_place_medal"), + NewEmoji("3rd place medal", []int32{129353}, "3rd_place_medal"), + NewEmoji("soccer ball", []int32{9917}, "soccer"), + NewEmoji("baseball", []int32{9918}, "baseball"), + NewEmoji("softball", []int32{129358}, "softball"), + NewEmoji("basketball", []int32{127936}, "basketball"), + NewEmoji("volleyball", []int32{127952}, "volleyball"), + NewEmoji("american football", []int32{127944}, "football"), + NewEmoji("rugby football", []int32{127945}, "rugby_football"), + NewEmoji("tennis", []int32{127934}, "tennis"), + NewEmoji("flying disc", []int32{129359}, "flying_disc"), + NewEmoji("bowling", []int32{127923}, "bowling"), + NewEmoji("cricket game", []int32{127951}, "cricket_game"), + NewEmoji("field hockey", []int32{127953}, "field_hockey"), + NewEmoji("ice hockey", []int32{127954}, "ice_hockey"), + NewEmoji("lacrosse", []int32{129357}, "lacrosse"), + NewEmoji("ping pong", []int32{127955}, "ping_pong"), + NewEmoji("badminton", []int32{127992}, "badminton"), + NewEmoji("boxing glove", []int32{129354}, "boxing_glove"), + NewEmoji("martial arts uniform", []int32{129355}, "martial_arts_uniform"), + NewEmoji("goal net", []int32{129349}, "goal_net"), + NewEmoji("flag in hole", []int32{9971}, "golf"), + NewEmoji("ice skate", []int32{9976, 65039}, "ice_skate"), + NewEmoji("fishing pole", []int32{127907}, "fishing_pole_and_fish"), + NewEmoji("diving mask", []int32{129343}, "diving_mask"), + NewEmoji("running shirt", []int32{127933}, "running_shirt_with_sash"), + NewEmoji("skis", []int32{127935}, "ski"), + NewEmoji("sled", []int32{128759}, "sled"), + NewEmoji("curling stone", []int32{129356}, "curling_stone"), + NewEmoji("bullseye", []int32{127919}, "dart"), + NewEmoji("yo-yo", []int32{129664}, "yo_yo"), + NewEmoji("kite", []int32{129665}, "kite"), + NewEmoji("pool 8 ball", []int32{127921}, "8ball"), + NewEmoji("crystal ball", []int32{128302}, "crystal_ball"), + NewEmoji("magic wand", []int32{129668}, "magic_wand"), + NewEmoji("nazar amulet", []int32{129535}, "nazar_amulet"), + NewEmoji("video game", []int32{127918}, "video_game"), + NewEmoji("joystick", []int32{128377, 65039}, "joystick"), + NewEmoji("slot machine", []int32{127920}, "slot_machine"), + NewEmoji("game die", []int32{127922}, "game_die"), + NewEmoji("puzzle piece", []int32{129513}, "jigsaw"), + NewEmoji("teddy bear", []int32{129528}, "teddy_bear"), + NewEmoji("piñata", []int32{129669}, "pinata"), + NewEmoji("nesting dolls", []int32{129670}, "nesting_dolls"), + NewEmoji("spade suit", []int32{9824, 65039}, "spades"), + NewEmoji("heart suit", []int32{9829, 65039}, "hearts"), + NewEmoji("diamond suit", []int32{9830, 65039}, "diamonds"), + NewEmoji("club suit", []int32{9827, 65039}, "clubs"), + NewEmoji("chess pawn", []int32{9823, 65039}, "chess_pawn"), + NewEmoji("joker", []int32{127183}, "black_joker"), + NewEmoji("mahjong red dragon", []int32{126980}, "mahjong"), + NewEmoji("flower playing cards", []int32{127924}, "flower_playing_cards"), + NewEmoji("performing arts", []int32{127917}, "performing_arts"), + NewEmoji("framed picture", []int32{128444, 65039}, "framed_picture"), + NewEmoji("artist palette", []int32{127912}, "art"), + NewEmoji("thread", []int32{129525}, "thread"), + NewEmoji("sewing needle", []int32{129697}, "sewing_needle"), + NewEmoji("yarn", []int32{129526}, "yarn"), + NewEmoji("knot", []int32{129698}, "knot"), + NewEmoji("glasses", []int32{128083}, "eyeglasses"), + NewEmoji("sunglasses", []int32{128374, 65039}, "dark_sunglasses"), + NewEmoji("goggles", []int32{129405}, "goggles"), + NewEmoji("lab coat", []int32{129404}, "lab_coat"), + NewEmoji("safety vest", []int32{129466}, "safety_vest"), + NewEmoji("necktie", []int32{128084}, "necktie"), + NewEmoji("t-shirt", []int32{128085}, "shirt", "tshirt"), + NewEmoji("jeans", []int32{128086}, "jeans"), + NewEmoji("scarf", []int32{129507}, "scarf"), + NewEmoji("gloves", []int32{129508}, "gloves"), + NewEmoji("coat", []int32{129509}, "coat"), + NewEmoji("socks", []int32{129510}, "socks"), + NewEmoji("dress", []int32{128087}, "dress"), + NewEmoji("kimono", []int32{128088}, "kimono"), + NewEmoji("sari", []int32{129403}, "sari"), + NewEmoji("one-piece swimsuit", []int32{129649}, "one_piece_swimsuit"), + NewEmoji("briefs", []int32{129650}, "swim_brief"), + NewEmoji("shorts", []int32{129651}, "shorts"), + NewEmoji("bikini", []int32{128089}, "bikini"), + NewEmoji("woman’s clothes", []int32{128090}, "womans_clothes"), + NewEmoji("purse", []int32{128091}, "purse"), + NewEmoji("handbag", []int32{128092}, "handbag"), + NewEmoji("clutch bag", []int32{128093}, "pouch"), + NewEmoji("shopping bags", []int32{128717, 65039}, "shopping"), + NewEmoji("backpack", []int32{127890}, "school_satchel"), + NewEmoji("thong sandal", []int32{129652}, "thong_sandal"), + NewEmoji("man’s shoe", []int32{128094}, "mans_shoe", "shoe"), + NewEmoji("running shoe", []int32{128095}, "athletic_shoe"), + NewEmoji("hiking boot", []int32{129406}, "hiking_boot"), + NewEmoji("flat shoe", []int32{129407}, "flat_shoe"), + NewEmoji("high-heeled shoe", []int32{128096}, "high_heel"), + NewEmoji("woman’s sandal", []int32{128097}, "sandal"), + NewEmoji("ballet shoes", []int32{129648}, "ballet_shoes"), + NewEmoji("woman’s boot", []int32{128098}, "boot"), + NewEmoji("crown", []int32{128081}, "crown"), + NewEmoji("woman’s hat", []int32{128082}, "womans_hat"), + NewEmoji("top hat", []int32{127913}, "tophat"), + NewEmoji("graduation cap", []int32{127891}, "mortar_board"), + NewEmoji("billed cap", []int32{129506}, "billed_cap"), + NewEmoji("military helmet", []int32{129686}, "military_helmet"), + NewEmoji("rescue worker’s helmet", []int32{9937, 65039}, "rescue_worker_helmet"), + NewEmoji("prayer beads", []int32{128255}, "prayer_beads"), + NewEmoji("lipstick", []int32{128132}, "lipstick"), + NewEmoji("ring", []int32{128141}, "ring"), + NewEmoji("gem stone", []int32{128142}, "gem"), + NewEmoji("muted speaker", []int32{128263}, "mute"), + NewEmoji("speaker low volume", []int32{128264}, "speaker"), + NewEmoji("speaker medium volume", []int32{128265}, "sound"), + NewEmoji("speaker high volume", []int32{128266}, "loud_sound"), + NewEmoji("loudspeaker", []int32{128226}, "loudspeaker"), + NewEmoji("megaphone", []int32{128227}, "mega"), + NewEmoji("postal horn", []int32{128239}, "postal_horn"), + NewEmoji("bell", []int32{128276}, "bell"), + NewEmoji("bell with slash", []int32{128277}, "no_bell"), + NewEmoji("musical score", []int32{127932}, "musical_score"), + NewEmoji("musical note", []int32{127925}, "musical_note"), + NewEmoji("musical notes", []int32{127926}, "notes"), + NewEmoji("studio microphone", []int32{127897, 65039}, "studio_microphone"), + NewEmoji("level slider", []int32{127898, 65039}, "level_slider"), + NewEmoji("control knobs", []int32{127899, 65039}, "control_knobs"), + NewEmoji("microphone", []int32{127908}, "microphone"), + NewEmoji("headphone", []int32{127911}, "headphones"), + NewEmoji("radio", []int32{128251}, "radio"), + NewEmoji("saxophone", []int32{127927}, "saxophone"), + NewEmoji("accordion", []int32{129687}, "accordion"), + NewEmoji("guitar", []int32{127928}, "guitar"), + NewEmoji("musical keyboard", []int32{127929}, "musical_keyboard"), + NewEmoji("trumpet", []int32{127930}, "trumpet"), + NewEmoji("violin", []int32{127931}, "violin"), + NewEmoji("banjo", []int32{129685}, "banjo"), + NewEmoji("drum", []int32{129345}, "drum"), + NewEmoji("long drum", []int32{129688}, "long_drum"), + NewEmoji("mobile phone", []int32{128241}, "iphone"), + NewEmoji("mobile phone with arrow", []int32{128242}, "calling"), + NewEmoji("telephone", []int32{9742, 65039}, "phone", "telephone"), + NewEmoji("telephone receiver", []int32{128222}, "telephone_receiver"), + NewEmoji("pager", []int32{128223}, "pager"), + NewEmoji("fax machine", []int32{128224}, "fax"), + NewEmoji("battery", []int32{128267}, "battery"), + NewEmoji("electric plug", []int32{128268}, "electric_plug"), + NewEmoji("laptop", []int32{128187}, "computer"), + NewEmoji("desktop computer", []int32{128421, 65039}, "desktop_computer"), + NewEmoji("printer", []int32{128424, 65039}, "printer"), + NewEmoji("keyboard", []int32{9000, 65039}, "keyboard"), + NewEmoji("computer mouse", []int32{128433, 65039}, "computer_mouse"), + NewEmoji("trackball", []int32{128434, 65039}, "trackball"), + NewEmoji("computer disk", []int32{128189}, "minidisc"), + NewEmoji("floppy disk", []int32{128190}, "floppy_disk"), + NewEmoji("optical disk", []int32{128191}, "cd"), + NewEmoji("dvd", []int32{128192}, "dvd"), + NewEmoji("abacus", []int32{129518}, "abacus"), + NewEmoji("movie camera", []int32{127909}, "movie_camera"), + NewEmoji("film frames", []int32{127902, 65039}, "film_strip"), + NewEmoji("film projector", []int32{128253, 65039}, "film_projector"), + NewEmoji("clapper board", []int32{127916}, "clapper"), + NewEmoji("television", []int32{128250}, "tv"), + NewEmoji("camera", []int32{128247}, "camera"), + NewEmoji("camera with flash", []int32{128248}, "camera_flash"), + NewEmoji("video camera", []int32{128249}, "video_camera"), + NewEmoji("videocassette", []int32{128252}, "vhs"), + NewEmoji("magnifying glass tilted left", []int32{128269}, "mag"), + NewEmoji("magnifying glass tilted right", []int32{128270}, "mag_right"), + NewEmoji("candle", []int32{128367, 65039}, "candle"), + NewEmoji("light bulb", []int32{128161}, "bulb"), + NewEmoji("flashlight", []int32{128294}, "flashlight"), + NewEmoji("red paper lantern", []int32{127982}, "izakaya_lantern", "lantern"), + NewEmoji("diya lamp", []int32{129684}, "diya_lamp"), + NewEmoji("notebook with decorative cover", []int32{128212}, "notebook_with_decorative_cover"), + NewEmoji("closed book", []int32{128213}, "closed_book"), + NewEmoji("open book", []int32{128214}, "book", "open_book"), + NewEmoji("green book", []int32{128215}, "green_book"), + NewEmoji("blue book", []int32{128216}, "blue_book"), + NewEmoji("orange book", []int32{128217}, "orange_book"), + NewEmoji("books", []int32{128218}, "books"), + NewEmoji("notebook", []int32{128211}, "notebook"), + NewEmoji("ledger", []int32{128210}, "ledger"), + NewEmoji("page with curl", []int32{128195}, "page_with_curl"), + NewEmoji("scroll", []int32{128220}, "scroll"), + NewEmoji("page facing up", []int32{128196}, "page_facing_up"), + NewEmoji("newspaper", []int32{128240}, "newspaper"), + NewEmoji("rolled-up newspaper", []int32{128478, 65039}, "newspaper_roll"), + NewEmoji("bookmark tabs", []int32{128209}, "bookmark_tabs"), + NewEmoji("bookmark", []int32{128278}, "bookmark"), + NewEmoji("label", []int32{127991, 65039}, "label"), + NewEmoji("money bag", []int32{128176}, "moneybag"), + NewEmoji("coin", []int32{129689}, "coin"), + NewEmoji("yen banknote", []int32{128180}, "yen"), + NewEmoji("dollar banknote", []int32{128181}, "dollar"), + NewEmoji("euro banknote", []int32{128182}, "euro"), + NewEmoji("pound banknote", []int32{128183}, "pound"), + NewEmoji("money with wings", []int32{128184}, "money_with_wings"), + NewEmoji("credit card", []int32{128179}, "credit_card"), + NewEmoji("receipt", []int32{129534}, "receipt"), + NewEmoji("chart increasing with yen", []int32{128185}, "chart"), + NewEmoji("envelope", []int32{9993, 65039}, "envelope"), + NewEmoji("e-mail", []int32{128231}, "email", "e-mail"), + NewEmoji("incoming envelope", []int32{128232}, "incoming_envelope"), + NewEmoji("envelope with arrow", []int32{128233}, "envelope_with_arrow"), + NewEmoji("outbox tray", []int32{128228}, "outbox_tray"), + NewEmoji("inbox tray", []int32{128229}, "inbox_tray"), + NewEmoji("package", []int32{128230}, "package"), + NewEmoji("closed mailbox with raised flag", []int32{128235}, "mailbox"), + NewEmoji("closed mailbox with lowered flag", []int32{128234}, "mailbox_closed"), + NewEmoji("open mailbox with raised flag", []int32{128236}, "mailbox_with_mail"), + NewEmoji("open mailbox with lowered flag", []int32{128237}, "mailbox_with_no_mail"), + NewEmoji("postbox", []int32{128238}, "postbox"), + NewEmoji("ballot box with ballot", []int32{128499, 65039}, "ballot_box"), + NewEmoji("pencil", []int32{9999, 65039}, "pencil2"), + NewEmoji("black nib", []int32{10002, 65039}, "black_nib"), + NewEmoji("fountain pen", []int32{128395, 65039}, "fountain_pen"), + NewEmoji("pen", []int32{128394, 65039}, "pen"), + NewEmoji("paintbrush", []int32{128396, 65039}, "paintbrush"), + NewEmoji("crayon", []int32{128397, 65039}, "crayon"), + NewEmoji("memo", []int32{128221}, "memo", "pencil"), + NewEmoji("briefcase", []int32{128188}, "briefcase"), + NewEmoji("file folder", []int32{128193}, "file_folder"), + NewEmoji("open file folder", []int32{128194}, "open_file_folder"), + NewEmoji("card index dividers", []int32{128450, 65039}, "card_index_dividers"), + NewEmoji("calendar", []int32{128197}, "date"), + NewEmoji("tear-off calendar", []int32{128198}, "calendar"), + NewEmoji("spiral notepad", []int32{128466, 65039}, "spiral_notepad"), + NewEmoji("spiral calendar", []int32{128467, 65039}, "spiral_calendar"), + NewEmoji("card index", []int32{128199}, "card_index"), + NewEmoji("chart increasing", []int32{128200}, "chart_with_upwards_trend"), + NewEmoji("chart decreasing", []int32{128201}, "chart_with_downwards_trend"), + NewEmoji("bar chart", []int32{128202}, "bar_chart"), + NewEmoji("clipboard", []int32{128203}, "clipboard"), + NewEmoji("pushpin", []int32{128204}, "pushpin"), + NewEmoji("round pushpin", []int32{128205}, "round_pushpin"), + NewEmoji("paperclip", []int32{128206}, "paperclip"), + NewEmoji("linked paperclips", []int32{128391, 65039}, "paperclips"), + NewEmoji("straight ruler", []int32{128207}, "straight_ruler"), + NewEmoji("triangular ruler", []int32{128208}, "triangular_ruler"), + NewEmoji("scissors", []int32{9986, 65039}, "scissors"), + NewEmoji("card file box", []int32{128451, 65039}, "card_file_box"), + NewEmoji("file cabinet", []int32{128452, 65039}, "file_cabinet"), + NewEmoji("wastebasket", []int32{128465, 65039}, "wastebasket"), + NewEmoji("locked", []int32{128274}, "lock"), + NewEmoji("unlocked", []int32{128275}, "unlock"), + NewEmoji("locked with pen", []int32{128271}, "lock_with_ink_pen"), + NewEmoji("locked with key", []int32{128272}, "closed_lock_with_key"), + NewEmoji("key", []int32{128273}, "key"), + NewEmoji("old key", []int32{128477, 65039}, "old_key"), + NewEmoji("hammer", []int32{128296}, "hammer"), + NewEmoji("axe", []int32{129683}, "axe"), + NewEmoji("pick", []int32{9935, 65039}, "pick"), + NewEmoji("hammer and pick", []int32{9874, 65039}, "hammer_and_pick"), + NewEmoji("hammer and wrench", []int32{128736, 65039}, "hammer_and_wrench"), + NewEmoji("dagger", []int32{128481, 65039}, "dagger"), + NewEmoji("crossed swords", []int32{9876, 65039}, "crossed_swords"), + NewEmoji("water pistol", []int32{128299}, "gun"), + NewEmoji("boomerang", []int32{129667}, "boomerang"), + NewEmoji("bow and arrow", []int32{127993}, "bow_and_arrow"), + NewEmoji("shield", []int32{128737, 65039}, "shield"), + NewEmoji("carpentry saw", []int32{129690}, "carpentry_saw"), + NewEmoji("wrench", []int32{128295}, "wrench"), + NewEmoji("screwdriver", []int32{129691}, "screwdriver"), + NewEmoji("nut and bolt", []int32{128297}, "nut_and_bolt"), + NewEmoji("gear", []int32{9881, 65039}, "gear"), + NewEmoji("clamp", []int32{128476, 65039}, "clamp"), + NewEmoji("balance scale", []int32{9878, 65039}, "balance_scale"), + NewEmoji("white cane", []int32{129455}, "probing_cane"), + NewEmoji("link", []int32{128279}, "link"), + NewEmoji("chains", []int32{9939, 65039}, "chains"), + NewEmoji("hook", []int32{129693}, "hook"), + NewEmoji("toolbox", []int32{129520}, "toolbox"), + NewEmoji("magnet", []int32{129522}, "magnet"), + NewEmoji("ladder", []int32{129692}, "ladder"), + NewEmoji("alembic", []int32{9879, 65039}, "alembic"), + NewEmoji("test tube", []int32{129514}, "test_tube"), + NewEmoji("petri dish", []int32{129515}, "petri_dish"), + NewEmoji("dna", []int32{129516}, "dna"), + NewEmoji("microscope", []int32{128300}, "microscope"), + NewEmoji("telescope", []int32{128301}, "telescope"), + NewEmoji("satellite antenna", []int32{128225}, "satellite"), + NewEmoji("syringe", []int32{128137}, "syringe"), + NewEmoji("drop of blood", []int32{129656}, "drop_of_blood"), + NewEmoji("pill", []int32{128138}, "pill"), + NewEmoji("adhesive bandage", []int32{129657}, "adhesive_bandage"), + NewEmoji("stethoscope", []int32{129658}, "stethoscope"), + NewEmoji("door", []int32{128682}, "door"), + NewEmoji("elevator", []int32{128727}, "elevator"), + NewEmoji("mirror", []int32{129694}, "mirror"), + NewEmoji("window", []int32{129695}, "window"), + NewEmoji("bed", []int32{128719, 65039}, "bed"), + NewEmoji("couch and lamp", []int32{128715, 65039}, "couch_and_lamp"), + NewEmoji("chair", []int32{129681}, "chair"), + NewEmoji("toilet", []int32{128701}, "toilet"), + NewEmoji("plunger", []int32{129696}, "plunger"), + NewEmoji("shower", []int32{128703}, "shower"), + NewEmoji("bathtub", []int32{128705}, "bathtub"), + NewEmoji("mouse trap", []int32{129700}, "mouse_trap"), + NewEmoji("razor", []int32{129682}, "razor"), + NewEmoji("lotion bottle", []int32{129524}, "lotion_bottle"), + NewEmoji("safety pin", []int32{129527}, "safety_pin"), + NewEmoji("broom", []int32{129529}, "broom"), + NewEmoji("basket", []int32{129530}, "basket"), + NewEmoji("roll of paper", []int32{129531}, "roll_of_paper"), + NewEmoji("bucket", []int32{129699}, "bucket"), + NewEmoji("soap", []int32{129532}, "soap"), + NewEmoji("toothbrush", []int32{129701}, "toothbrush"), + NewEmoji("sponge", []int32{129533}, "sponge"), + NewEmoji("fire extinguisher", []int32{129519}, "fire_extinguisher"), + NewEmoji("shopping cart", []int32{128722}, "shopping_cart"), + NewEmoji("cigarette", []int32{128684}, "smoking"), + NewEmoji("coffin", []int32{9904, 65039}, "coffin"), + NewEmoji("headstone", []int32{129702}, "headstone"), + NewEmoji("funeral urn", []int32{9905, 65039}, "funeral_urn"), + NewEmoji("moai", []int32{128511}, "moyai"), + NewEmoji("placard", []int32{129703}, "placard"), + NewEmoji("ATM sign", []int32{127975}, "atm"), + NewEmoji("litter in bin sign", []int32{128686}, "put_litter_in_its_place"), + NewEmoji("potable water", []int32{128688}, "potable_water"), + NewEmoji("wheelchair symbol", []int32{9855}, "wheelchair"), + NewEmoji("men’s room", []int32{128697}, "mens"), + NewEmoji("women’s room", []int32{128698}, "womens"), + NewEmoji("restroom", []int32{128699}, "restroom"), + NewEmoji("baby symbol", []int32{128700}, "baby_symbol"), + NewEmoji("water closet", []int32{128702}, "wc"), + NewEmoji("passport control", []int32{128706}, "passport_control"), + NewEmoji("customs", []int32{128707}, "customs"), + NewEmoji("baggage claim", []int32{128708}, "baggage_claim"), + NewEmoji("left luggage", []int32{128709}, "left_luggage"), + NewEmoji("warning", []int32{9888, 65039}, "warning"), + NewEmoji("children crossing", []int32{128696}, "children_crossing"), + NewEmoji("no entry", []int32{9940}, "no_entry"), + NewEmoji("prohibited", []int32{128683}, "no_entry_sign"), + NewEmoji("no bicycles", []int32{128691}, "no_bicycles"), + NewEmoji("no smoking", []int32{128685}, "no_smoking"), + NewEmoji("no littering", []int32{128687}, "do_not_litter"), + NewEmoji("non-potable water", []int32{128689}, "non-potable_water"), + NewEmoji("no pedestrians", []int32{128695}, "no_pedestrians"), + NewEmoji("no mobile phones", []int32{128245}, "no_mobile_phones"), + NewEmoji("no one under eighteen", []int32{128286}, "underage"), + NewEmoji("radioactive", []int32{9762, 65039}, "radioactive"), + NewEmoji("biohazard", []int32{9763, 65039}, "biohazard"), + NewEmoji("up arrow", []int32{11014, 65039}, "arrow_up"), + NewEmoji("up-right arrow", []int32{8599, 65039}, "arrow_upper_right"), + NewEmoji("right arrow", []int32{10145, 65039}, "arrow_right"), + NewEmoji("down-right arrow", []int32{8600, 65039}, "arrow_lower_right"), + NewEmoji("down arrow", []int32{11015, 65039}, "arrow_down"), + NewEmoji("down-left arrow", []int32{8601, 65039}, "arrow_lower_left"), + NewEmoji("left arrow", []int32{11013, 65039}, "arrow_left"), + NewEmoji("up-left arrow", []int32{8598, 65039}, "arrow_upper_left"), + NewEmoji("up-down arrow", []int32{8597, 65039}, "arrow_up_down"), + NewEmoji("left-right arrow", []int32{8596, 65039}, "left_right_arrow"), + NewEmoji("right arrow curving left", []int32{8617, 65039}, "leftwards_arrow_with_hook"), + NewEmoji("left arrow curving right", []int32{8618, 65039}, "arrow_right_hook"), + NewEmoji("right arrow curving up", []int32{10548, 65039}, "arrow_heading_up"), + NewEmoji("right arrow curving down", []int32{10549, 65039}, "arrow_heading_down"), + NewEmoji("clockwise vertical arrows", []int32{128259}, "arrows_clockwise"), + NewEmoji("counterclockwise arrows button", []int32{128260}, "arrows_counterclockwise"), + NewEmoji("BACK arrow", []int32{128281}, "back"), + NewEmoji("END arrow", []int32{128282}, "end"), + NewEmoji("ON! arrow", []int32{128283}, "on"), + NewEmoji("SOON arrow", []int32{128284}, "soon"), + NewEmoji("TOP arrow", []int32{128285}, "top"), + NewEmoji("place of worship", []int32{128720}, "place_of_worship"), + NewEmoji("atom symbol", []int32{9883, 65039}, "atom_symbol"), + NewEmoji("om", []int32{128329, 65039}, "om"), + NewEmoji("star of David", []int32{10017, 65039}, "star_of_david"), + NewEmoji("wheel of dharma", []int32{9784, 65039}, "wheel_of_dharma"), + NewEmoji("yin yang", []int32{9775, 65039}, "yin_yang"), + NewEmoji("latin cross", []int32{10013, 65039}, "latin_cross"), + NewEmoji("orthodox cross", []int32{9766, 65039}, "orthodox_cross"), + NewEmoji("star and crescent", []int32{9770, 65039}, "star_and_crescent"), + NewEmoji("peace symbol", []int32{9774, 65039}, "peace_symbol"), + NewEmoji("menorah", []int32{128334}, "menorah"), + NewEmoji("dotted six-pointed star", []int32{128303}, "six_pointed_star"), + NewEmoji("Aries", []int32{9800}, "aries"), + NewEmoji("Taurus", []int32{9801}, "taurus"), + NewEmoji("Gemini", []int32{9802}, "gemini"), + NewEmoji("Cancer", []int32{9803}, "cancer"), + NewEmoji("Leo", []int32{9804}, "leo"), + NewEmoji("Virgo", []int32{9805}, "virgo"), + NewEmoji("Libra", []int32{9806}, "libra"), + NewEmoji("Scorpio", []int32{9807}, "scorpius"), + NewEmoji("Sagittarius", []int32{9808}, "sagittarius"), + NewEmoji("Capricorn", []int32{9809}, "capricorn"), + NewEmoji("Aquarius", []int32{9810}, "aquarius"), + NewEmoji("Pisces", []int32{9811}, "pisces"), + NewEmoji("Ophiuchus", []int32{9934}, "ophiuchus"), + NewEmoji("shuffle tracks button", []int32{128256}, "twisted_rightwards_arrows"), + NewEmoji("repeat button", []int32{128257}, "repeat"), + NewEmoji("repeat single button", []int32{128258}, "repeat_one"), + NewEmoji("play button", []int32{9654, 65039}, "arrow_forward"), + NewEmoji("fast-forward button", []int32{9193}, "fast_forward"), + NewEmoji("next track button", []int32{9197, 65039}, "next_track_button"), + NewEmoji("play or pause button", []int32{9199, 65039}, "play_or_pause_button"), + NewEmoji("reverse button", []int32{9664, 65039}, "arrow_backward"), + NewEmoji("fast reverse button", []int32{9194}, "rewind"), + NewEmoji("last track button", []int32{9198, 65039}, "previous_track_button"), + NewEmoji("upwards button", []int32{128316}, "arrow_up_small"), + NewEmoji("fast up button", []int32{9195}, "arrow_double_up"), + NewEmoji("downwards button", []int32{128317}, "arrow_down_small"), + NewEmoji("fast down button", []int32{9196}, "arrow_double_down"), + NewEmoji("pause button", []int32{9208, 65039}, "pause_button"), + NewEmoji("stop button", []int32{9209, 65039}, "stop_button"), + NewEmoji("record button", []int32{9210, 65039}, "record_button"), + NewEmoji("eject button", []int32{9167, 65039}, "eject_button"), + NewEmoji("cinema", []int32{127910}, "cinema"), + NewEmoji("dim button", []int32{128261}, "low_brightness"), + NewEmoji("bright button", []int32{128262}, "high_brightness"), + NewEmoji("antenna bars", []int32{128246}, "signal_strength"), + NewEmoji("vibration mode", []int32{128243}, "vibration_mode"), + NewEmoji("mobile phone off", []int32{128244}, "mobile_phone_off"), + NewEmoji("female sign", []int32{9792, 65039}, "female_sign"), + NewEmoji("male sign", []int32{9794, 65039}, "male_sign"), + NewEmoji("transgender symbol", []int32{9895, 65039}, "transgender_symbol"), + NewEmoji("multiply", []int32{10006, 65039}, "heavy_multiplication_x"), + NewEmoji("plus", []int32{10133}, "heavy_plus_sign"), + NewEmoji("minus", []int32{10134}, "heavy_minus_sign"), + NewEmoji("divide", []int32{10135}, "heavy_division_sign"), + NewEmoji("infinity", []int32{9854, 65039}, "infinity"), + NewEmoji("double exclamation mark", []int32{8252, 65039}, "bangbang"), + NewEmoji("exclamation question mark", []int32{8265, 65039}, "interrobang"), + NewEmoji("red question mark", []int32{10067}, "question"), + NewEmoji("white question mark", []int32{10068}, "grey_question"), + NewEmoji("white exclamation mark", []int32{10069}, "grey_exclamation"), + NewEmoji("red exclamation mark", []int32{10071}, "exclamation", "heavy_exclamation_mark"), + NewEmoji("wavy dash", []int32{12336, 65039}, "wavy_dash"), + NewEmoji("currency exchange", []int32{128177}, "currency_exchange"), + NewEmoji("heavy dollar sign", []int32{128178}, "heavy_dollar_sign"), + NewEmoji("medical symbol", []int32{9877, 65039}, "medical_symbol"), + NewEmoji("recycling symbol", []int32{9851, 65039}, "recycle"), + NewEmoji("fleur-de-lis", []int32{9884, 65039}, "fleur_de_lis"), + NewEmoji("trident emblem", []int32{128305}, "trident"), + NewEmoji("name badge", []int32{128219}, "name_badge"), + NewEmoji("Japanese symbol for beginner", []int32{128304}, "beginner"), + NewEmoji("hollow red circle", []int32{11093}, "o"), + NewEmoji("check mark button", []int32{9989}, "white_check_mark"), + NewEmoji("check box with check", []int32{9745, 65039}, "ballot_box_with_check"), + NewEmoji("check mark", []int32{10004, 65039}, "heavy_check_mark"), + NewEmoji("cross mark", []int32{10060}, "x"), + NewEmoji("cross mark button", []int32{10062}, "negative_squared_cross_mark"), + NewEmoji("curly loop", []int32{10160}, "curly_loop"), + NewEmoji("double curly loop", []int32{10175}, "loop"), + NewEmoji("part alternation mark", []int32{12349, 65039}, "part_alternation_mark"), + NewEmoji("eight-spoked asterisk", []int32{10035, 65039}, "eight_spoked_asterisk"), + NewEmoji("eight-pointed star", []int32{10036, 65039}, "eight_pointed_black_star"), + NewEmoji("sparkle", []int32{10055, 65039}, "sparkle"), + NewEmoji("copyright", []int32{169, 65039}, "copyright"), + NewEmoji("registered", []int32{174, 65039}, "registered"), + NewEmoji("trade mark", []int32{8482, 65039}, "tm"), + NewEmoji("keycap: #", []int32{35, 65039, 8419}, "hash"), + NewEmoji("keycap: *", []int32{42, 65039, 8419}, "asterisk"), + NewEmoji("keycap: 0", []int32{48, 65039, 8419}, "zero"), + NewEmoji("keycap: 1", []int32{49, 65039, 8419}, "one"), + NewEmoji("keycap: 2", []int32{50, 65039, 8419}, "two"), + NewEmoji("keycap: 3", []int32{51, 65039, 8419}, "three"), + NewEmoji("keycap: 4", []int32{52, 65039, 8419}, "four"), + NewEmoji("keycap: 5", []int32{53, 65039, 8419}, "five"), + NewEmoji("keycap: 6", []int32{54, 65039, 8419}, "six"), + NewEmoji("keycap: 7", []int32{55, 65039, 8419}, "seven"), + NewEmoji("keycap: 8", []int32{56, 65039, 8419}, "eight"), + NewEmoji("keycap: 9", []int32{57, 65039, 8419}, "nine"), + NewEmoji("keycap: 10", []int32{128287}, "keycap_ten"), + NewEmoji("input latin uppercase", []int32{128288}, "capital_abcd"), + NewEmoji("input latin lowercase", []int32{128289}, "abcd"), + NewEmoji("input numbers", []int32{128290}, "1234"), + NewEmoji("input symbols", []int32{128291}, "symbols"), + NewEmoji("input latin letters", []int32{128292}, "abc"), + NewEmoji("A button (blood type)", []int32{127344, 65039}, "a"), + NewEmoji("AB button (blood type)", []int32{127374}, "ab"), + NewEmoji("B button (blood type)", []int32{127345, 65039}, "b"), + NewEmoji("CL button", []int32{127377}, "cl"), + NewEmoji("COOL button", []int32{127378}, "cool"), + NewEmoji("FREE button", []int32{127379}, "free"), + NewEmoji("information", []int32{8505, 65039}, "information_source"), + NewEmoji("ID button", []int32{127380}, "id"), + NewEmoji("circled M", []int32{9410, 65039}, "m"), + NewEmoji("NEW button", []int32{127381}, "new"), + NewEmoji("NG button", []int32{127382}, "ng"), + NewEmoji("O button (blood type)", []int32{127358, 65039}, "o2"), + NewEmoji("OK button", []int32{127383}, "ok"), + NewEmoji("P button", []int32{127359, 65039}, "parking"), + NewEmoji("SOS button", []int32{127384}, "sos"), + NewEmoji("UP! button", []int32{127385}, "up"), + NewEmoji("VS button", []int32{127386}, "vs"), + NewEmoji("Japanese “here” button", []int32{127489}, "koko"), + NewEmoji("Japanese “service charge” button", []int32{127490, 65039}, "sa"), + NewEmoji("Japanese “monthly amount” button", []int32{127543, 65039}, "u6708"), + NewEmoji("Japanese “not free of charge” button", []int32{127542}, "u6709"), + NewEmoji("Japanese “reserved” button", []int32{127535}, "u6307"), + NewEmoji("Japanese “bargain” button", []int32{127568}, "ideograph_advantage"), + NewEmoji("Japanese “discount” button", []int32{127545}, "u5272"), + NewEmoji("Japanese “free of charge” button", []int32{127514}, "u7121"), + NewEmoji("Japanese “prohibited” button", []int32{127538}, "u7981"), + NewEmoji("Japanese “acceptable” button", []int32{127569}, "accept"), + NewEmoji("Japanese “application” button", []int32{127544}, "u7533"), + NewEmoji("Japanese “passing grade” button", []int32{127540}, "u5408"), + NewEmoji("Japanese “vacancy” button", []int32{127539}, "u7a7a"), + NewEmoji("Japanese “congratulations” button", []int32{12951, 65039}, "congratulations"), + NewEmoji("Japanese “secret” button", []int32{12953, 65039}, "secret"), + NewEmoji("Japanese “open for business” button", []int32{127546}, "u55b6"), + NewEmoji("Japanese “no vacancy” button", []int32{127541}, "u6e80"), + NewEmoji("red circle", []int32{128308}, "red_circle"), + NewEmoji("orange circle", []int32{128992}, "orange_circle"), + NewEmoji("yellow circle", []int32{128993}, "yellow_circle"), + NewEmoji("green circle", []int32{128994}, "green_circle"), + NewEmoji("blue circle", []int32{128309}, "large_blue_circle"), + NewEmoji("purple circle", []int32{128995}, "purple_circle"), + NewEmoji("brown circle", []int32{128996}, "brown_circle"), + NewEmoji("black circle", []int32{9899}, "black_circle"), + NewEmoji("white circle", []int32{9898}, "white_circle"), + NewEmoji("red square", []int32{128997}, "red_square"), + NewEmoji("orange square", []int32{128999}, "orange_square"), + NewEmoji("yellow square", []int32{129000}, "yellow_square"), + NewEmoji("green square", []int32{129001}, "green_square"), + NewEmoji("blue square", []int32{128998}, "blue_square"), + NewEmoji("purple square", []int32{129002}, "purple_square"), + NewEmoji("brown square", []int32{129003}, "brown_square"), + NewEmoji("black large square", []int32{11035}, "black_large_square"), + NewEmoji("white large square", []int32{11036}, "white_large_square"), + NewEmoji("black medium square", []int32{9724, 65039}, "black_medium_square"), + NewEmoji("white medium square", []int32{9723, 65039}, "white_medium_square"), + NewEmoji("black medium-small square", []int32{9726}, "black_medium_small_square"), + NewEmoji("white medium-small square", []int32{9725}, "white_medium_small_square"), + NewEmoji("black small square", []int32{9642, 65039}, "black_small_square"), + NewEmoji("white small square", []int32{9643, 65039}, "white_small_square"), + NewEmoji("large orange diamond", []int32{128310}, "large_orange_diamond"), + NewEmoji("large blue diamond", []int32{128311}, "large_blue_diamond"), + NewEmoji("small orange diamond", []int32{128312}, "small_orange_diamond"), + NewEmoji("small blue diamond", []int32{128313}, "small_blue_diamond"), + NewEmoji("red triangle pointed up", []int32{128314}, "small_red_triangle"), + NewEmoji("red triangle pointed down", []int32{128315}, "small_red_triangle_down"), + NewEmoji("diamond with a dot", []int32{128160}, "diamond_shape_with_a_dot_inside"), + NewEmoji("radio button", []int32{128280}, "radio_button"), + NewEmoji("white square button", []int32{128307}, "white_square_button"), + NewEmoji("black square button", []int32{128306}, "black_square_button"), + NewEmoji("chequered flag", []int32{127937}, "checkered_flag"), + NewEmoji("triangular flag", []int32{128681}, "triangular_flag_on_post"), + NewEmoji("crossed flags", []int32{127884}, "crossed_flags"), + NewEmoji("black flag", []int32{127988}, "black_flag"), + NewEmoji("white flag", []int32{127987, 65039}, "white_flag"), + NewEmoji("rainbow flag", []int32{127987, 65039, 8205, 127752}, "rainbow_flag"), + NewEmoji("transgender flag", []int32{127987, 65039, 8205, 9895, 65039}, "transgender_flag"), + NewEmoji("pirate flag", []int32{127988, 8205, 9760, 65039}, "pirate_flag"), + NewEmoji("flag: Ascension Island", []int32{127462, 127464}, "ascension_island"), + NewEmoji("flag: Andorra", []int32{127462, 127465}, "andorra"), + NewEmoji("flag: United Arab Emirates", []int32{127462, 127466}, "united_arab_emirates"), + NewEmoji("flag: Afghanistan", []int32{127462, 127467}, "afghanistan"), + NewEmoji("flag: Antigua & Barbuda", []int32{127462, 127468}, "antigua_barbuda"), + NewEmoji("flag: Anguilla", []int32{127462, 127470}, "anguilla"), + NewEmoji("flag: Albania", []int32{127462, 127473}, "albania"), + NewEmoji("flag: Armenia", []int32{127462, 127474}, "armenia"), + NewEmoji("flag: Angola", []int32{127462, 127476}, "angola"), + NewEmoji("flag: Antarctica", []int32{127462, 127478}, "antarctica"), + NewEmoji("flag: Argentina", []int32{127462, 127479}, "argentina"), + NewEmoji("flag: American Samoa", []int32{127462, 127480}, "american_samoa"), + NewEmoji("flag: Austria", []int32{127462, 127481}, "austria"), + NewEmoji("flag: Australia", []int32{127462, 127482}, "australia"), + NewEmoji("flag: Aruba", []int32{127462, 127484}, "aruba"), + NewEmoji("flag: Åland Islands", []int32{127462, 127485}, "aland_islands"), + NewEmoji("flag: Azerbaijan", []int32{127462, 127487}, "azerbaijan"), + NewEmoji("flag: Bosnia & Herzegovina", []int32{127463, 127462}, "bosnia_herzegovina"), + NewEmoji("flag: Barbados", []int32{127463, 127463}, "barbados"), + NewEmoji("flag: Bangladesh", []int32{127463, 127465}, "bangladesh"), + NewEmoji("flag: Belgium", []int32{127463, 127466}, "belgium"), + NewEmoji("flag: Burkina Faso", []int32{127463, 127467}, "burkina_faso"), + NewEmoji("flag: Bulgaria", []int32{127463, 127468}, "bulgaria"), + NewEmoji("flag: Bahrain", []int32{127463, 127469}, "bahrain"), + NewEmoji("flag: Burundi", []int32{127463, 127470}, "burundi"), + NewEmoji("flag: Benin", []int32{127463, 127471}, "benin"), + NewEmoji("flag: St. Barthélemy", []int32{127463, 127473}, "st_barthelemy"), + NewEmoji("flag: Bermuda", []int32{127463, 127474}, "bermuda"), + NewEmoji("flag: Brunei", []int32{127463, 127475}, "brunei"), + NewEmoji("flag: Bolivia", []int32{127463, 127476}, "bolivia"), + NewEmoji("flag: Caribbean Netherlands", []int32{127463, 127478}, "caribbean_netherlands"), + NewEmoji("flag: Brazil", []int32{127463, 127479}, "brazil"), + NewEmoji("flag: Bahamas", []int32{127463, 127480}, "bahamas"), + NewEmoji("flag: Bhutan", []int32{127463, 127481}, "bhutan"), + NewEmoji("flag: Bouvet Island", []int32{127463, 127483}, "bouvet_island"), + NewEmoji("flag: Botswana", []int32{127463, 127484}, "botswana"), + NewEmoji("flag: Belarus", []int32{127463, 127486}, "belarus"), + NewEmoji("flag: Belize", []int32{127463, 127487}, "belize"), + NewEmoji("flag: Canada", []int32{127464, 127462}, "canada"), + NewEmoji("flag: Cocos (Keeling) Islands", []int32{127464, 127464}, "cocos_islands"), + NewEmoji("flag: Congo - Kinshasa", []int32{127464, 127465}, "congo_kinshasa"), + NewEmoji("flag: Central African Republic", []int32{127464, 127467}, "central_african_republic"), + NewEmoji("flag: Congo - Brazzaville", []int32{127464, 127468}, "congo_brazzaville"), + NewEmoji("flag: Switzerland", []int32{127464, 127469}, "switzerland"), + NewEmoji("flag: Côte d’Ivoire", []int32{127464, 127470}, "cote_divoire"), + NewEmoji("flag: Cook Islands", []int32{127464, 127472}, "cook_islands"), + NewEmoji("flag: Chile", []int32{127464, 127473}, "chile"), + NewEmoji("flag: Cameroon", []int32{127464, 127474}, "cameroon"), + NewEmoji("flag: China", []int32{127464, 127475}, "cn"), + NewEmoji("flag: Colombia", []int32{127464, 127476}, "colombia"), + NewEmoji("flag: Clipperton Island", []int32{127464, 127477}, "clipperton_island"), + NewEmoji("flag: Costa Rica", []int32{127464, 127479}, "costa_rica"), + NewEmoji("flag: Cuba", []int32{127464, 127482}, "cuba"), + NewEmoji("flag: Cape Verde", []int32{127464, 127483}, "cape_verde"), + NewEmoji("flag: Curaçao", []int32{127464, 127484}, "curacao"), + NewEmoji("flag: Christmas Island", []int32{127464, 127485}, "christmas_island"), + NewEmoji("flag: Cyprus", []int32{127464, 127486}, "cyprus"), + NewEmoji("flag: Czechia", []int32{127464, 127487}, "czech_republic"), + NewEmoji("flag: Germany", []int32{127465, 127466}, "de"), + NewEmoji("flag: Diego Garcia", []int32{127465, 127468}, "diego_garcia"), + NewEmoji("flag: Djibouti", []int32{127465, 127471}, "djibouti"), + NewEmoji("flag: Denmark", []int32{127465, 127472}, "denmark"), + NewEmoji("flag: Dominica", []int32{127465, 127474}, "dominica"), + NewEmoji("flag: Dominican Republic", []int32{127465, 127476}, "dominican_republic"), + NewEmoji("flag: Algeria", []int32{127465, 127487}, "algeria"), + NewEmoji("flag: Ceuta & Melilla", []int32{127466, 127462}, "ceuta_melilla"), + NewEmoji("flag: Ecuador", []int32{127466, 127464}, "ecuador"), + NewEmoji("flag: Estonia", []int32{127466, 127466}, "estonia"), + NewEmoji("flag: Egypt", []int32{127466, 127468}, "egypt"), + NewEmoji("flag: Western Sahara", []int32{127466, 127469}, "western_sahara"), + NewEmoji("flag: Eritrea", []int32{127466, 127479}, "eritrea"), + NewEmoji("flag: Spain", []int32{127466, 127480}, "es"), + NewEmoji("flag: Ethiopia", []int32{127466, 127481}, "ethiopia"), + NewEmoji("flag: European Union", []int32{127466, 127482}, "eu", "european_union"), + NewEmoji("flag: Finland", []int32{127467, 127470}, "finland"), + NewEmoji("flag: Fiji", []int32{127467, 127471}, "fiji"), + NewEmoji("flag: Falkland Islands", []int32{127467, 127472}, "falkland_islands"), + NewEmoji("flag: Micronesia", []int32{127467, 127474}, "micronesia"), + NewEmoji("flag: Faroe Islands", []int32{127467, 127476}, "faroe_islands"), + NewEmoji("flag: France", []int32{127467, 127479}, "fr"), + NewEmoji("flag: Gabon", []int32{127468, 127462}, "gabon"), + NewEmoji("flag: United Kingdom", []int32{127468, 127463}, "gb", "uk"), + NewEmoji("flag: Grenada", []int32{127468, 127465}, "grenada"), + NewEmoji("flag: Georgia", []int32{127468, 127466}, "georgia"), + NewEmoji("flag: French Guiana", []int32{127468, 127467}, "french_guiana"), + NewEmoji("flag: Guernsey", []int32{127468, 127468}, "guernsey"), + NewEmoji("flag: Ghana", []int32{127468, 127469}, "ghana"), + NewEmoji("flag: Gibraltar", []int32{127468, 127470}, "gibraltar"), + NewEmoji("flag: Greenland", []int32{127468, 127473}, "greenland"), + NewEmoji("flag: Gambia", []int32{127468, 127474}, "gambia"), + NewEmoji("flag: Guinea", []int32{127468, 127475}, "guinea"), + NewEmoji("flag: Guadeloupe", []int32{127468, 127477}, "guadeloupe"), + NewEmoji("flag: Equatorial Guinea", []int32{127468, 127478}, "equatorial_guinea"), + NewEmoji("flag: Greece", []int32{127468, 127479}, "greece"), + NewEmoji("flag: South Georgia & South Sandwich Islands", []int32{127468, 127480}, "south_georgia_south_sandwich_islands"), + NewEmoji("flag: Guatemala", []int32{127468, 127481}, "guatemala"), + NewEmoji("flag: Guam", []int32{127468, 127482}, "guam"), + NewEmoji("flag: Guinea-Bissau", []int32{127468, 127484}, "guinea_bissau"), + NewEmoji("flag: Guyana", []int32{127468, 127486}, "guyana"), + NewEmoji("flag: Hong Kong SAR China", []int32{127469, 127472}, "hong_kong"), + NewEmoji("flag: Heard & McDonald Islands", []int32{127469, 127474}, "heard_mcdonald_islands"), + NewEmoji("flag: Honduras", []int32{127469, 127475}, "honduras"), + NewEmoji("flag: Croatia", []int32{127469, 127479}, "croatia"), + NewEmoji("flag: Haiti", []int32{127469, 127481}, "haiti"), + NewEmoji("flag: Hungary", []int32{127469, 127482}, "hungary"), + NewEmoji("flag: Canary Islands", []int32{127470, 127464}, "canary_islands"), + NewEmoji("flag: Indonesia", []int32{127470, 127465}, "indonesia"), + NewEmoji("flag: Ireland", []int32{127470, 127466}, "ireland"), + NewEmoji("flag: Israel", []int32{127470, 127473}, "israel"), + NewEmoji("flag: Isle of Man", []int32{127470, 127474}, "isle_of_man"), + NewEmoji("flag: India", []int32{127470, 127475}, "india"), + NewEmoji("flag: British Indian Ocean Territory", []int32{127470, 127476}, "british_indian_ocean_territory"), + NewEmoji("flag: Iraq", []int32{127470, 127478}, "iraq"), + NewEmoji("flag: Iran", []int32{127470, 127479}, "iran"), + NewEmoji("flag: Iceland", []int32{127470, 127480}, "iceland"), + NewEmoji("flag: Italy", []int32{127470, 127481}, "it"), + NewEmoji("flag: Jersey", []int32{127471, 127466}, "jersey"), + NewEmoji("flag: Jamaica", []int32{127471, 127474}, "jamaica"), + NewEmoji("flag: Jordan", []int32{127471, 127476}, "jordan"), + NewEmoji("flag: Japan", []int32{127471, 127477}, "jp"), + NewEmoji("flag: Kenya", []int32{127472, 127466}, "kenya"), + NewEmoji("flag: Kyrgyzstan", []int32{127472, 127468}, "kyrgyzstan"), + NewEmoji("flag: Cambodia", []int32{127472, 127469}, "cambodia"), + NewEmoji("flag: Kiribati", []int32{127472, 127470}, "kiribati"), + NewEmoji("flag: Comoros", []int32{127472, 127474}, "comoros"), + NewEmoji("flag: St. Kitts & Nevis", []int32{127472, 127475}, "st_kitts_nevis"), + NewEmoji("flag: North Korea", []int32{127472, 127477}, "north_korea"), + NewEmoji("flag: South Korea", []int32{127472, 127479}, "kr"), + NewEmoji("flag: Kuwait", []int32{127472, 127484}, "kuwait"), + NewEmoji("flag: Cayman Islands", []int32{127472, 127486}, "cayman_islands"), + NewEmoji("flag: Kazakhstan", []int32{127472, 127487}, "kazakhstan"), + NewEmoji("flag: Laos", []int32{127473, 127462}, "laos"), + NewEmoji("flag: Lebanon", []int32{127473, 127463}, "lebanon"), + NewEmoji("flag: St. Lucia", []int32{127473, 127464}, "st_lucia"), + NewEmoji("flag: Liechtenstein", []int32{127473, 127470}, "liechtenstein"), + NewEmoji("flag: Sri Lanka", []int32{127473, 127472}, "sri_lanka"), + NewEmoji("flag: Liberia", []int32{127473, 127479}, "liberia"), + NewEmoji("flag: Lesotho", []int32{127473, 127480}, "lesotho"), + NewEmoji("flag: Lithuania", []int32{127473, 127481}, "lithuania"), + NewEmoji("flag: Luxembourg", []int32{127473, 127482}, "luxembourg"), + NewEmoji("flag: Latvia", []int32{127473, 127483}, "latvia"), + NewEmoji("flag: Libya", []int32{127473, 127486}, "libya"), + NewEmoji("flag: Morocco", []int32{127474, 127462}, "morocco"), + NewEmoji("flag: Monaco", []int32{127474, 127464}, "monaco"), + NewEmoji("flag: Moldova", []int32{127474, 127465}, "moldova"), + NewEmoji("flag: Montenegro", []int32{127474, 127466}, "montenegro"), + NewEmoji("flag: St. Martin", []int32{127474, 127467}, "st_martin"), + NewEmoji("flag: Madagascar", []int32{127474, 127468}, "madagascar"), + NewEmoji("flag: Marshall Islands", []int32{127474, 127469}, "marshall_islands"), + NewEmoji("flag: North Macedonia", []int32{127474, 127472}, "macedonia"), + NewEmoji("flag: Mali", []int32{127474, 127473}, "mali"), + NewEmoji("flag: Myanmar (Burma)", []int32{127474, 127474}, "myanmar"), + NewEmoji("flag: Mongolia", []int32{127474, 127475}, "mongolia"), + NewEmoji("flag: Macao SAR China", []int32{127474, 127476}, "macau"), + NewEmoji("flag: Northern Mariana Islands", []int32{127474, 127477}, "northern_mariana_islands"), + NewEmoji("flag: Martinique", []int32{127474, 127478}, "martinique"), + NewEmoji("flag: Mauritania", []int32{127474, 127479}, "mauritania"), + NewEmoji("flag: Montserrat", []int32{127474, 127480}, "montserrat"), + NewEmoji("flag: Malta", []int32{127474, 127481}, "malta"), + NewEmoji("flag: Mauritius", []int32{127474, 127482}, "mauritius"), + NewEmoji("flag: Maldives", []int32{127474, 127483}, "maldives"), + NewEmoji("flag: Malawi", []int32{127474, 127484}, "malawi"), + NewEmoji("flag: Mexico", []int32{127474, 127485}, "mexico"), + NewEmoji("flag: Malaysia", []int32{127474, 127486}, "malaysia"), + NewEmoji("flag: Mozambique", []int32{127474, 127487}, "mozambique"), + NewEmoji("flag: Namibia", []int32{127475, 127462}, "namibia"), + NewEmoji("flag: New Caledonia", []int32{127475, 127464}, "new_caledonia"), + NewEmoji("flag: Niger", []int32{127475, 127466}, "niger"), + NewEmoji("flag: Norfolk Island", []int32{127475, 127467}, "norfolk_island"), + NewEmoji("flag: Nigeria", []int32{127475, 127468}, "nigeria"), + NewEmoji("flag: Nicaragua", []int32{127475, 127470}, "nicaragua"), + NewEmoji("flag: Netherlands", []int32{127475, 127473}, "netherlands"), + NewEmoji("flag: Norway", []int32{127475, 127476}, "norway"), + NewEmoji("flag: Nepal", []int32{127475, 127477}, "nepal"), + NewEmoji("flag: Nauru", []int32{127475, 127479}, "nauru"), + NewEmoji("flag: Niue", []int32{127475, 127482}, "niue"), + NewEmoji("flag: New Zealand", []int32{127475, 127487}, "new_zealand"), + NewEmoji("flag: Oman", []int32{127476, 127474}, "oman"), + NewEmoji("flag: Panama", []int32{127477, 127462}, "panama"), + NewEmoji("flag: Peru", []int32{127477, 127466}, "peru"), + NewEmoji("flag: French Polynesia", []int32{127477, 127467}, "french_polynesia"), + NewEmoji("flag: Papua New Guinea", []int32{127477, 127468}, "papua_new_guinea"), + NewEmoji("flag: Philippines", []int32{127477, 127469}, "philippines"), + NewEmoji("flag: Pakistan", []int32{127477, 127472}, "pakistan"), + NewEmoji("flag: Poland", []int32{127477, 127473}, "poland"), + NewEmoji("flag: St. Pierre & Miquelon", []int32{127477, 127474}, "st_pierre_miquelon"), + NewEmoji("flag: Pitcairn Islands", []int32{127477, 127475}, "pitcairn_islands"), + NewEmoji("flag: Puerto Rico", []int32{127477, 127479}, "puerto_rico"), + NewEmoji("flag: Palestinian Territories", []int32{127477, 127480}, "palestinian_territories"), + NewEmoji("flag: Portugal", []int32{127477, 127481}, "portugal"), + NewEmoji("flag: Palau", []int32{127477, 127484}, "palau"), + NewEmoji("flag: Paraguay", []int32{127477, 127486}, "paraguay"), + NewEmoji("flag: Qatar", []int32{127478, 127462}, "qatar"), + NewEmoji("flag: Réunion", []int32{127479, 127466}, "reunion"), + NewEmoji("flag: Romania", []int32{127479, 127476}, "romania"), + NewEmoji("flag: Serbia", []int32{127479, 127480}, "serbia"), + NewEmoji("flag: Russia", []int32{127479, 127482}, "ru"), + NewEmoji("flag: Rwanda", []int32{127479, 127484}, "rwanda"), + NewEmoji("flag: Saudi Arabia", []int32{127480, 127462}, "saudi_arabia"), + NewEmoji("flag: Solomon Islands", []int32{127480, 127463}, "solomon_islands"), + NewEmoji("flag: Seychelles", []int32{127480, 127464}, "seychelles"), + NewEmoji("flag: Sudan", []int32{127480, 127465}, "sudan"), + NewEmoji("flag: Sweden", []int32{127480, 127466}, "sweden"), + NewEmoji("flag: Singapore", []int32{127480, 127468}, "singapore"), + NewEmoji("flag: St. Helena", []int32{127480, 127469}, "st_helena"), + NewEmoji("flag: Slovenia", []int32{127480, 127470}, "slovenia"), + NewEmoji("flag: Svalbard & Jan Mayen", []int32{127480, 127471}, "svalbard_jan_mayen"), + NewEmoji("flag: Slovakia", []int32{127480, 127472}, "slovakia"), + NewEmoji("flag: Sierra Leone", []int32{127480, 127473}, "sierra_leone"), + NewEmoji("flag: San Marino", []int32{127480, 127474}, "san_marino"), + NewEmoji("flag: Senegal", []int32{127480, 127475}, "senegal"), + NewEmoji("flag: Somalia", []int32{127480, 127476}, "somalia"), + NewEmoji("flag: Suriname", []int32{127480, 127479}, "suriname"), + NewEmoji("flag: South Sudan", []int32{127480, 127480}, "south_sudan"), + NewEmoji("flag: São Tomé & Príncipe", []int32{127480, 127481}, "sao_tome_principe"), + NewEmoji("flag: El Salvador", []int32{127480, 127483}, "el_salvador"), + NewEmoji("flag: Sint Maarten", []int32{127480, 127485}, "sint_maarten"), + NewEmoji("flag: Syria", []int32{127480, 127486}, "syria"), + NewEmoji("flag: Eswatini", []int32{127480, 127487}, "swaziland"), + NewEmoji("flag: Tristan da Cunha", []int32{127481, 127462}, "tristan_da_cunha"), + NewEmoji("flag: Turks & Caicos Islands", []int32{127481, 127464}, "turks_caicos_islands"), + NewEmoji("flag: Chad", []int32{127481, 127465}, "chad"), + NewEmoji("flag: French Southern Territories", []int32{127481, 127467}, "french_southern_territories"), + NewEmoji("flag: Togo", []int32{127481, 127468}, "togo"), + NewEmoji("flag: Thailand", []int32{127481, 127469}, "thailand"), + NewEmoji("flag: Tajikistan", []int32{127481, 127471}, "tajikistan"), + NewEmoji("flag: Tokelau", []int32{127481, 127472}, "tokelau"), + NewEmoji("flag: Timor-Leste", []int32{127481, 127473}, "timor_leste"), + NewEmoji("flag: Turkmenistan", []int32{127481, 127474}, "turkmenistan"), + NewEmoji("flag: Tunisia", []int32{127481, 127475}, "tunisia"), + NewEmoji("flag: Tonga", []int32{127481, 127476}, "tonga"), + NewEmoji("flag: Turkey", []int32{127481, 127479}, "tr"), + NewEmoji("flag: Trinidad & Tobago", []int32{127481, 127481}, "trinidad_tobago"), + NewEmoji("flag: Tuvalu", []int32{127481, 127483}, "tuvalu"), + NewEmoji("flag: Taiwan", []int32{127481, 127484}, "taiwan"), + NewEmoji("flag: Tanzania", []int32{127481, 127487}, "tanzania"), + NewEmoji("flag: Ukraine", []int32{127482, 127462}, "ukraine"), + NewEmoji("flag: Uganda", []int32{127482, 127468}, "uganda"), + NewEmoji("flag: U.S. Outlying Islands", []int32{127482, 127474}, "us_outlying_islands"), + NewEmoji("flag: United Nations", []int32{127482, 127475}, "united_nations"), + NewEmoji("flag: United States", []int32{127482, 127480}, "us"), + NewEmoji("flag: Uruguay", []int32{127482, 127486}, "uruguay"), + NewEmoji("flag: Uzbekistan", []int32{127482, 127487}, "uzbekistan"), + NewEmoji("flag: Vatican City", []int32{127483, 127462}, "vatican_city"), + NewEmoji("flag: St. Vincent & Grenadines", []int32{127483, 127464}, "st_vincent_grenadines"), + NewEmoji("flag: Venezuela", []int32{127483, 127466}, "venezuela"), + NewEmoji("flag: British Virgin Islands", []int32{127483, 127468}, "british_virgin_islands"), + NewEmoji("flag: U.S. Virgin Islands", []int32{127483, 127470}, "us_virgin_islands"), + NewEmoji("flag: Vietnam", []int32{127483, 127475}, "vietnam"), + NewEmoji("flag: Vanuatu", []int32{127483, 127482}, "vanuatu"), + NewEmoji("flag: Wallis & Futuna", []int32{127484, 127467}, "wallis_futuna"), + NewEmoji("flag: Samoa", []int32{127484, 127480}, "samoa"), + NewEmoji("flag: Kosovo", []int32{127485, 127472}, "kosovo"), + NewEmoji("flag: Yemen", []int32{127486, 127466}, "yemen"), + NewEmoji("flag: Mayotte", []int32{127486, 127481}, "mayotte"), + NewEmoji("flag: South Africa", []int32{127487, 127462}, "south_africa"), + NewEmoji("flag: Zambia", []int32{127487, 127474}, "zambia"), + NewEmoji("flag: Zimbabwe", []int32{127487, 127484}, "zimbabwe"), + NewEmoji("flag: England", []int32{127988, 917607, 917602, 917605, 917614, 917607, 917631}, "england"), + NewEmoji("flag: Scotland", []int32{127988, 917607, 917602, 917619, 917603, 917620, 917631}, "scotland"), + NewEmoji("flag: Wales", []int32{127988, 917607, 917602, 917623, 917612, 917619, 917631}, "wales"), + ) + }) + m := github.Clone() + for _, opt := range opts { + opt(m) + } + return m +} diff --git a/vendor/github.com/yuin/goldmark-emoji/emoji.go b/vendor/github.com/yuin/goldmark-emoji/emoji.go new file mode 100644 index 0000000..46f1ec3 --- /dev/null +++ b/vendor/github.com/yuin/goldmark-emoji/emoji.go @@ -0,0 +1,360 @@ +// package emoji is a extension for the goldmark(http://github.com/yuin/goldmark). +package emoji + +import ( + "fmt" + "strings" + + "github.com/yuin/goldmark" + east "github.com/yuin/goldmark-emoji/ast" + "github.com/yuin/goldmark-emoji/definition" + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/renderer/html" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +// 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 (c *ParserConfig) SetOption(name parser.OptionName, value interface{}) { + switch name { + case optEmojis: + c.Emojis = value.(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 (o *withEmojis) emojiOption() {} + +func (o *withEmojis) SetParserOption(c *parser.Config) { + c.Options[optEmojis] = o.value +} + +func (o *withEmojis) SetEmojiOption(c *ParserConfig) { + c.Emojis = o.value +} + +// WithMaping is a functional option that defines links names to unicode emojis. +func WithEmojis(value definition.Emojis) Option { + return &withEmojis{ + value: value, + } +} + +// RenderingMethod indicates how emojis are rendered. +type RenderingMethod int + +// RendererFunc will be used for rendering emojis. +type RendererFunc func(w util.BufWriter, source []byte, n *east.Emoji, config *RendererConfig) + +const ( + // Entity renders an emoji as an html entity. + Entity RenderingMethod = iota + + // Unicode renders an emoji as unicode character. + Unicode + + // Twemoji renders an emoji as an img tag with [twemoji](https://github.com/twitter/twemoji). + 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. + Method RenderingMethod + + // 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 '' + // + TwemojiTemplate string + + // RendererFunc is a RendererFunc that renders emojis. This value is valid only when Method is set to Func. + RendererFunc RendererFunc +} + +// DefaultTwemojiTemplate is a default value for RendererConfig.TwemojiTemplate. +const DefaultTwemojiTemplate = `%[1]s` + +// SetOption implements renderer.SetOptioner. +func (c *RendererConfig) SetOption(name renderer.OptionName, value interface{}) { + switch name { + case optRenderingMethod: + c.Method = value.(RenderingMethod) + case optTwemojiTemplate: + c.TwemojiTemplate = value.(string) + case optRendererFunc: + c.RendererFunc = value.(RendererFunc) + default: + c.Config.SetOption(name, value) + } +} + +// A RendererOption interface sets options for the emoji renderer. +type RendererOption interface { + Option + renderer.Option + + SetEmojiOption(*RendererConfig) +} + +var _ RendererOption = &withRenderingMethod{} + +type withRenderingMethod struct { + value RenderingMethod +} + +func (o *withRenderingMethod) emojiOption() { +} + +// SetConfig implements renderer.Option#SetConfig. +func (o *withRenderingMethod) SetConfig(c *renderer.Config) { + c.Options[optRenderingMethod] = o.value +} + +// SetEmojiOption implements RendererOption#SetEmojiOption +func (o *withRenderingMethod) SetEmojiOption(c *RendererConfig) { + c.Method = o.value +} + +const optRenderingMethod renderer.OptionName = "EmojiRenderingMethod" + +// WithRenderingMethod is a functional option that indicates how emojis are rendered. +func WithRenderingMethod(a RenderingMethod) Option { + return &withRenderingMethod{a} +} + +type withTwemojiTemplate struct { + value string +} + +func (o *withTwemojiTemplate) emojiOption() { +} + +// SetConfig implements renderer.Option#SetConfig. +func (o *withTwemojiTemplate) SetConfig(c *renderer.Config) { + c.Options[optTwemojiTemplate] = o.value +} + +// SetEmojiOption implements RendererOption#SetEmojiOption +func (o *withTwemojiTemplate) SetEmojiOption(c *RendererConfig) { + c.TwemojiTemplate = o.value +} + +const optTwemojiTemplate renderer.OptionName = "EmojiTwemojiTemplate" + +// WithTwemojiTemplate is a functional option that changes a twemoji img tag. +func WithTwemojiTemplate(s string) Option { + return &withTwemojiTemplate{s} +} + +var _ RendererOption = &withRendererFunc{} + +type withRendererFunc struct { + value RendererFunc +} + +func (o *withRendererFunc) emojiOption() { +} + +// SetConfig implements renderer.Option#SetConfig. +func (o *withRendererFunc) SetConfig(c *renderer.Config) { + c.Options[optRendererFunc] = o.value +} + +// SetEmojiOption implements RendererOption#SetEmojiOption +func (o *withRendererFunc) SetEmojiOption(c *RendererConfig) { + c.RendererFunc = o.value +} + +const optRendererFunc renderer.OptionName = "EmojiRendererFunc" + +// WithRendererFunc is a functional option that changes a renderer func. +func WithRendererFunc(f RendererFunc) Option { + return &withRendererFunc{f} +} + +type emojiParser struct { + ParserConfig +} + +// NewParser returns a new parser.InlineParser that can parse emoji expressions. +func NewParser(opts ...ParserOption) parser.InlineParser { + p := &emojiParser{ + ParserConfig: ParserConfig{ + Emojis: definition.Github(), + }, + } + for _, o := range opts { + o.SetEmojiOption(&p.ParserConfig) + } + return p +} + +func (s *emojiParser) Trigger() []byte { + return []byte{':'} +} + +func (s *emojiParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node { + line, _ := block.PeekLine() + if len(line) < 1 { + return nil + } + i := 1 + for ; i < len(line); i++ { + c := line[i] + if !(util.IsAlphaNumeric(c) || c == '_' || c == '-' || c == '+') { + break + } + } + if i >= len(line) || line[i] != ':' { + return nil + } + block.Advance(i + 1) + shortName := line[1:i] + emoji, ok := s.Emojis.Get(util.BytesToReadOnlyString(shortName)) + if !ok { + return nil + } + return east.NewEmoji(shortName, emoji) +} + +type emojiHTMLRenderer struct { + RendererConfig +} + +// NewHTMLRenderer returns a new HTMLRenderer. +func NewHTMLRenderer(opts ...RendererOption) renderer.NodeRenderer { + r := &emojiHTMLRenderer{ + RendererConfig: RendererConfig{ + Config: html.NewConfig(), + Method: Entity, + TwemojiTemplate: DefaultTwemojiTemplate, + RendererFunc: nil, + }, + } + for _, opt := range opts { + opt.SetEmojiOption(&r.RendererConfig) + } + return r +} + +// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs. +func (r *emojiHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { + reg.Register(east.KindEmoji, r.renderEmoji) +} + +const slash = " /" +const empty = "" + +func (r *emojiHTMLRenderer) renderEmoji(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { + if !entering { + return ast.WalkContinue, nil + } + node := n.(*east.Emoji) + if !node.Value.IsUnicode() && r.Method != Func { + fmt.Fprintf(w, `:%s:`, util.EscapeHTML(util.StringToReadOnlyBytes(node.Value.Name)), node.ShortName) + return ast.WalkContinue, nil + } + + switch r.Method { + case Entity: + for _, r := range node.Value.Unicode { + if r == 0x200D { + _, _ = w.WriteString("‍") + continue + } + fmt.Fprintf(w, "&#x%x;", r) + } + case Unicode: + fmt.Fprintf(w, "%s", string(node.Value.Unicode)) + case Twemoji: + s := slash + if !r.XHTML { + s = empty + } + values := []string{} + for _, r := range node.Value.Unicode { + values = append(values, fmt.Sprintf("%x", r)) + } + fmt.Fprintf(w, r.TwemojiTemplate, util.EscapeHTML(util.StringToReadOnlyBytes(node.Value.Name)), strings.Join(values, "-"), s) + case Func: + r.RendererFunc(w, source, node, &r.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 New(opts ...Option) goldmark.Extender { + return &emoji{ + options: opts, + } +} + +// Extend implements goldmark.Extender. +func (e *emoji) Extend(m goldmark.Markdown) { + pOpts := []ParserOption{} + rOpts := []RendererOption{} + for _, o := range e.options { + if po, ok := o.(ParserOption); ok { + pOpts = append(pOpts, po) + continue + } + if ro, ok := o.(RendererOption); ok { + rOpts = append(rOpts, ro) + } + } + + m.Renderer().AddOptions(renderer.WithNodeRenderers( + util.Prioritized(NewHTMLRenderer(rOpts...), 200), + )) + + m.Parser().AddOptions(parser.WithInlineParsers( + util.Prioritized(NewParser(pOpts...), 999), + )) + +} diff --git a/vendor/github.com/yuin/goldmark/.gitignore b/vendor/github.com/yuin/goldmark/.gitignore new file mode 100644 index 0000000..06c135f --- /dev/null +++ b/vendor/github.com/yuin/goldmark/.gitignore @@ -0,0 +1,19 @@ +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, build with `go test -c` +*.test +*.pprof + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +.DS_Store +fuzz/corpus +fuzz/crashers +fuzz/suppressions +fuzz/fuzz-fuzz.zip diff --git a/vendor/github.com/yuin/goldmark/.golangci.yml b/vendor/github.com/yuin/goldmark/.golangci.yml new file mode 100644 index 0000000..39fe61d --- /dev/null +++ b/vendor/github.com/yuin/goldmark/.golangci.yml @@ -0,0 +1,105 @@ +run: + deadline: 10m + +issues: + exclude-use-default: false + exclude-rules: + - path: _test.go + linters: + - errcheck + - lll + exclude: + - "Package util" + +linters: + disable-all: true + enable: + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - typecheck + - unused + - gofmt + - godot + - makezero + - misspell + - revive + - wastedassign + - lll + +linters-settings: + revive: + severity: "warning" + confidence: 0.8 + rules: + - name: blank-imports + severity: warning + disabled: false + - name: context-as-argument + severity: warning + disabled: false + - name: context-keys-type + severity: warning + disabled: false + - name: dot-imports + severity: warning + disabled: true + - name: error-return + severity: warning + disabled: false + - name: error-strings + severity: warning + disabled: false + - name: error-naming + severity: warning + disabled: false + - name: exported + severity: warning + disabled: false + - name: increment-decrement + severity: warning + disabled: false + - name: var-naming + severity: warning + disabled: false + - name: var-declaration + severity: warning + disabled: false + - name: package-comments + severity: warning + disabled: false + - name: range + severity: warning + disabled: false + - name: receiver-naming + severity: warning + disabled: false + - name: time-naming + severity: warning + disabled: false + - name: unexported-return + severity: warning + disabled: false + - name: indent-error-flow + severity: warning + disabled: false + - name: errorf + severity: warning + disabled: false + - name: empty-block + severity: warning + disabled: true + - name: superfluous-else + severity: warning + disabled: false + - name: unused-parameter + severity: warning + disabled: true + - name: unreachable-code + severity: warning + disabled: false + - name: redefines-builtin-id + severity: warning + disabled: false diff --git a/vendor/github.com/yuin/goldmark/LICENSE b/vendor/github.com/yuin/goldmark/LICENSE new file mode 100644 index 0000000..dc5b2a6 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 Yusuke Inuzuka + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/yuin/goldmark/Makefile b/vendor/github.com/yuin/goldmark/Makefile new file mode 100644 index 0000000..b0bb052 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/Makefile @@ -0,0 +1,13 @@ +.PHONY: test fuzz lint + +lint: + golangci-lint run -c .golangci.yml ./... + +test: + go test -coverprofile=profile.out -coverpkg=github.com/yuin/goldmark,github.com/yuin/goldmark/ast,github.com/yuin/goldmark/extension,github.com/yuin/goldmark/extension/ast,github.com/yuin/goldmark/parser,github.com/yuin/goldmark/renderer,github.com/yuin/goldmark/renderer/html,github.com/yuin/goldmark/text,github.com/yuin/goldmark/util ./... + +cov: test + go tool cover -html=profile.out + +fuzz: + cd ./fuzz && go test -fuzz=Fuzz diff --git a/vendor/github.com/yuin/goldmark/README.md b/vendor/github.com/yuin/goldmark/README.md new file mode 100644 index 0000000..8d9d83f --- /dev/null +++ b/vendor/github.com/yuin/goldmark/README.md @@ -0,0 +1,557 @@ +goldmark +========================================== + +[![https://pkg.go.dev/github.com/yuin/goldmark](https://pkg.go.dev/badge/github.com/yuin/goldmark.svg)](https://pkg.go.dev/github.com/yuin/goldmark) +[![https://github.com/yuin/goldmark/actions?query=workflow:test](https://github.com/yuin/goldmark/workflows/test/badge.svg?branch=master&event=push)](https://github.com/yuin/goldmark/actions?query=workflow:test) +[![https://coveralls.io/github/yuin/goldmark](https://coveralls.io/repos/github/yuin/goldmark/badge.svg?branch=master)](https://coveralls.io/github/yuin/goldmark) +[![https://goreportcard.com/report/github.com/yuin/goldmark](https://goreportcard.com/badge/github.com/yuin/goldmark)](https://goreportcard.com/report/github.com/yuin/goldmark) + +> A Markdown parser written in Go. Easy to extend, standards-compliant, well-structured. + +goldmark is compliant with CommonMark 0.30. + +Motivation +---------------------- +I needed a Markdown parser for Go that satisfies the following requirements: + +- Easy to extend. + - Markdown is poor in document expressions compared to other light markup languages such as reStructuredText. + - We have extensions to the Markdown syntax, e.g. PHP Markdown Extra, GitHub Flavored Markdown. +- Standards-compliant. + - Markdown has many dialects. + - GitHub-Flavored Markdown is widely used and is based upon CommonMark, effectively mooting the question of whether or not CommonMark is an ideal specification. + - CommonMark is complicated and hard to implement. +- Well-structured. + - AST-based; preserves source position of nodes. +- Written in pure Go. + +[golang-commonmark](https://gitlab.com/golang-commonmark/markdown) may be a good choice, but it seems to be a copy of [markdown-it](https://github.com/markdown-it). + +[blackfriday.v2](https://github.com/russross/blackfriday/tree/v2) is a fast and widely-used implementation, but is not CommonMark-compliant and cannot be extended from outside of the package, since its AST uses structs instead of interfaces. + +Furthermore, its behavior differs from other implementations in some cases, especially regarding lists: [Deep nested lists don't output correctly #329](https://github.com/russross/blackfriday/issues/329), [List block cannot have a second line #244](https://github.com/russross/blackfriday/issues/244), etc. + +This behavior sometimes causes problems. If you migrate your Markdown text from GitHub to blackfriday-based wikis, many lists will immediately be broken. + +As mentioned above, CommonMark is complicated and hard to implement, so Markdown parsers based on CommonMark are few and far between. + +Features +---------------------- + +- **Standards-compliant.** goldmark is fully compliant with the latest [CommonMark](https://commonmark.org/) specification. +- **Extensible.** Do you want to add a `@username` mention syntax to Markdown? + You can easily do so in goldmark. You can add your AST nodes, + parsers for block-level elements, parsers for inline-level elements, + transformers for paragraphs, transformers for the whole AST structure, and + renderers. +- **Performance.** goldmark's performance is on par with that of cmark, + the CommonMark reference implementation written in C. +- **Robust.** goldmark is tested with `go test --fuzz`. +- **Built-in extensions.** goldmark ships with common extensions like tables, strikethrough, + task lists, and definition lists. +- **Depends only on standard libraries.** + +Installation +---------------------- +```bash +$ go get github.com/yuin/goldmark +``` + + +Usage +---------------------- +Import packages: + +```go +import ( + "bytes" + "github.com/yuin/goldmark" +) +``` + + +Convert Markdown documents with the CommonMark-compliant mode: + +```go +var buf bytes.Buffer +if err := goldmark.Convert(source, &buf); err != nil { + panic(err) +} +``` + +With options +------------------------------ + +```go +var buf bytes.Buffer +if err := goldmark.Convert(source, &buf, parser.WithContext(ctx)); err != nil { + panic(err) +} +``` + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `parser.WithContext` | A `parser.Context` | Context for the parsing phase. | + +Context options +---------------------- + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `parser.WithIDs` | A `parser.IDs` | `IDs` allows you to change logics that are related to element id(ex: Auto heading id generation). | + + +Custom parser and renderer +-------------------------- +```go +import ( + "bytes" + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/extension" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer/html" +) + +md := goldmark.New( + goldmark.WithExtensions(extension.GFM), + goldmark.WithParserOptions( + parser.WithAutoHeadingID(), + ), + goldmark.WithRendererOptions( + html.WithHardWraps(), + html.WithXHTML(), + ), + ) +var buf bytes.Buffer +if err := md.Convert(source, &buf); err != nil { + panic(err) +} +``` + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `goldmark.WithParser` | `parser.Parser` | This option must be passed before `goldmark.WithParserOptions` and `goldmark.WithExtensions` | +| `goldmark.WithRenderer` | `renderer.Renderer` | This option must be passed before `goldmark.WithRendererOptions` and `goldmark.WithExtensions` | +| `goldmark.WithParserOptions` | `...parser.Option` | | +| `goldmark.WithRendererOptions` | `...renderer.Option` | | +| `goldmark.WithExtensions` | `...goldmark.Extender` | | + +Parser and Renderer options +------------------------------ + +### Parser options + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `parser.WithBlockParsers` | A `util.PrioritizedSlice` whose elements are `parser.BlockParser` | Parsers for parsing block level elements. | +| `parser.WithInlineParsers` | A `util.PrioritizedSlice` whose elements are `parser.InlineParser` | Parsers for parsing inline level elements. | +| `parser.WithParagraphTransformers` | A `util.PrioritizedSlice` whose elements are `parser.ParagraphTransformer` | Transformers for transforming paragraph nodes. | +| `parser.WithASTTransformers` | A `util.PrioritizedSlice` whose elements are `parser.ASTTransformer` | Transformers for transforming an AST. | +| `parser.WithAutoHeadingID` | `-` | Enables auto heading ids. | +| `parser.WithAttribute` | `-` | Enables custom attributes. Currently only headings supports attributes. | + +### HTML Renderer options + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `html.WithWriter` | `html.Writer` | `html.Writer` for writing contents to an `io.Writer`. | +| `html.WithHardWraps` | `-` | Render newlines as `
`.| +| `html.WithXHTML` | `-` | Render as XHTML. | +| `html.WithUnsafe` | `-` | By default, goldmark does not render raw HTML or potentially dangerous links. With this option, goldmark renders such content as written. | + +### Built-in extensions + +- `extension.Table` + - [GitHub Flavored Markdown: Tables](https://github.github.com/gfm/#tables-extension-) +- `extension.Strikethrough` + - [GitHub Flavored Markdown: Strikethrough](https://github.github.com/gfm/#strikethrough-extension-) +- `extension.Linkify` + - [GitHub Flavored Markdown: Autolinks](https://github.github.com/gfm/#autolinks-extension-) +- `extension.TaskList` + - [GitHub Flavored Markdown: Task list items](https://github.github.com/gfm/#task-list-items-extension-) +- `extension.GFM` + - This extension enables Table, Strikethrough, Linkify and TaskList. + - This extension does not filter tags defined in [6.11: Disallowed Raw HTML (extension)](https://github.github.com/gfm/#disallowed-raw-html-extension-). + If you need to filter HTML tags, see [Security](#security). + - If you need to parse github emojis, you can use [goldmark-emoji](https://github.com/yuin/goldmark-emoji) extension. +- `extension.DefinitionList` + - [PHP Markdown Extra: Definition lists](https://michelf.ca/projects/php-markdown/extra/#def-list) +- `extension.Footnote` + - [PHP Markdown Extra: Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes) +- `extension.Typographer` + - This extension substitutes punctuations with typographic entities like [smartypants](https://daringfireball.net/projects/smartypants/). +- `extension.CJK` + - This extension is a shortcut for CJK related functionalities. + +### Attributes +The `parser.WithAttribute` option allows you to define attributes on some elements. + +Currently only headings support attributes. + +**Attributes are being discussed in the +[CommonMark forum](https://talk.commonmark.org/t/consistent-attribute-syntax/272). +This syntax may possibly change in the future.** + + +#### Headings + +``` +## heading ## {#id .className attrName=attrValue class="class1 class2"} + +## heading {#id .className attrName=attrValue class="class1 class2"} +``` + +``` +heading {#id .className attrName=attrValue} +============ +``` + +### Table extension +The Table extension implements [Table(extension)](https://github.github.com/gfm/#tables-extension-), as +defined in [GitHub Flavored Markdown Spec](https://github.github.com/gfm/). + +Specs are defined for XHTML, so specs use some deprecated attributes for HTML5. + +You can override alignment rendering method via options. + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `extension.WithTableCellAlignMethod` | `extension.TableCellAlignMethod` | Option indicates how are table cells aligned. | + +### Typographer extension + +The Typographer extension translates plain ASCII punctuation characters into typographic-punctuation HTML entities. + +Default substitutions are: + +| Punctuation | Default entity | +| ------------ | ---------- | +| `'` | `‘`, `’` | +| `"` | `“`, `”` | +| `--` | `–` | +| `---` | `—` | +| `...` | `…` | +| `<<` | `«` | +| `>>` | `»` | + +You can override the default substitutions via `extensions.WithTypographicSubstitutions`: + +```go +markdown := goldmark.New( + goldmark.WithExtensions( + extension.NewTypographer( + extension.WithTypographicSubstitutions(extension.TypographicSubstitutions{ + extension.LeftSingleQuote: []byte("‚"), + extension.RightSingleQuote: nil, // nil disables a substitution + }), + ), + ), +) +``` + +### Linkify extension + +The Linkify extension implements [Autolinks(extension)](https://github.github.com/gfm/#autolinks-extension-), as +defined in [GitHub Flavored Markdown Spec](https://github.github.com/gfm/). + +Since the spec does not define details about URLs, there are numerous ambiguous cases. + +You can override autolinking patterns via options. + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `extension.WithLinkifyAllowedProtocols` | `[][]byte` | List of allowed protocols such as `[][]byte{ []byte("http:") }` | +| `extension.WithLinkifyURLRegexp` | `*regexp.Regexp` | Regexp that defines URLs, including protocols | +| `extension.WithLinkifyWWWRegexp` | `*regexp.Regexp` | Regexp that defines URL starting with `www.`. This pattern corresponds to [the extended www autolink](https://github.github.com/gfm/#extended-www-autolink) | +| `extension.WithLinkifyEmailRegexp` | `*regexp.Regexp` | Regexp that defines email addresses` | + +Example, using [xurls](https://github.com/mvdan/xurls): + +```go +import "mvdan.cc/xurls/v2" + +markdown := goldmark.New( + goldmark.WithRendererOptions( + html.WithXHTML(), + html.WithUnsafe(), + ), + goldmark.WithExtensions( + extension.NewLinkify( + extension.WithLinkifyAllowedProtocols([][]byte{ + []byte("http:"), + []byte("https:"), + }), + extension.WithLinkifyURLRegexp( + xurls.Strict, + ), + ), + ), +) +``` + +### Footnotes extension + +The Footnote extension implements [PHP Markdown Extra: Footnotes](https://michelf.ca/projects/php-markdown/extra/#footnotes). + +This extension has some options: + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `extension.WithFootnoteIDPrefix` | `[]byte` | a prefix for the id attributes.| +| `extension.WithFootnoteIDPrefixFunction` | `func(gast.Node) []byte` | a function that determines the id attribute for given Node.| +| `extension.WithFootnoteLinkTitle` | `[]byte` | an optional title attribute for footnote links.| +| `extension.WithFootnoteBacklinkTitle` | `[]byte` | an optional title attribute for footnote backlinks. | +| `extension.WithFootnoteLinkClass` | `[]byte` | a class for footnote links. This defaults to `footnote-ref`. | +| `extension.WithFootnoteBacklinkClass` | `[]byte` | a class for footnote backlinks. This defaults to `footnote-backref`. | +| `extension.WithFootnoteBacklinkHTML` | `[]byte` | a class for footnote backlinks. This defaults to `↩︎`. | + +Some options can have special substitutions. Occurrences of “^^” in the string will be replaced by the corresponding footnote number in the HTML output. Occurrences of “%%” will be replaced by a number for the reference (footnotes can have multiple references). + +`extension.WithFootnoteIDPrefix` and `extension.WithFootnoteIDPrefixFunction` are useful if you have multiple Markdown documents displayed inside one HTML document to avoid footnote ids to clash each other. + +`extension.WithFootnoteIDPrefix` sets fixed id prefix, so you may write codes like the following: + +```go +for _, path := range files { + source := readAll(path) + prefix := getPrefix(path) + + markdown := goldmark.New( + goldmark.WithExtensions( + NewFootnote( + WithFootnoteIDPrefix([]byte(path)), + ), + ), + ) + var b bytes.Buffer + err := markdown.Convert(source, &b) + if err != nil { + t.Error(err.Error()) + } +} +``` + +`extension.WithFootnoteIDPrefixFunction` determines an id prefix by calling given function, so you may write codes like the following: + +```go +markdown := goldmark.New( + goldmark.WithExtensions( + NewFootnote( + WithFootnoteIDPrefixFunction(func(n gast.Node) []byte { + v, ok := n.OwnerDocument().Meta()["footnote-prefix"] + if ok { + return util.StringToReadOnlyBytes(v.(string)) + } + return nil + }), + ), + ), +) + +for _, path := range files { + source := readAll(path) + var b bytes.Buffer + + doc := markdown.Parser().Parse(text.NewReader(source)) + doc.Meta()["footnote-prefix"] = getPrefix(path) + err := markdown.Renderer().Render(&b, source, doc) +} +``` + +You can use [goldmark-meta](https://github.com/yuin/goldmark-meta) to define a id prefix in the markdown document: + + +```markdown +--- +title: document title +slug: article1 +footnote-prefix: article1 +--- + +# My article + +``` + +### CJK extension +CommonMark gives compatibilities a high priority and original markdown was designed by westerners. So CommonMark lacks considerations for languages like CJK. + +This extension provides additional options for CJK users. + +| Functional option | Type | Description | +| ----------------- | ---- | ----------- | +| `extension.WithEastAsianLineBreaks` | `...extension.EastAsianLineBreaksStyle` | Soft line breaks are rendered as a newline. Some asian users will see it as an unnecessary space. With this option, soft line breaks between east asian wide characters will be ignored. | +| `extension.WithEscapedSpace` | `-` | Without spaces around an emphasis started with east asian punctuations, it is not interpreted as an emphasis(as defined in CommonMark spec). With this option, you can avoid this inconvenient behavior by putting 'not rendered' spaces around an emphasis like `太郎は\ **「こんにちわ」**\ といった`. | + +#### Styles of Line Breaking + +| Style | Description | +| ----- | ----------- | +| `EastAsianLineBreaksStyleSimple` | Soft line breaks are ignored if both sides of the break are east asian wide character. This behavior is the same as [`east_asian_line_breaks`](https://pandoc.org/MANUAL.html#extension-east_asian_line_breaks) in Pandoc. | +| `EastAsianLineBreaksCSS3Draft` | This option implements CSS text level3 [Segment Break Transformation Rules](https://drafts.csswg.org/css-text-3/#line-break-transform) with [some enhancements](https://github.com/w3c/csswg-drafts/issues/5086). | + +#### Example of `EastAsianLineBreaksStyleSimple` + +Input Markdown: + +```md +私はプログラマーです。 +東京の会社に勤めています。 +GoでWebアプリケーションを開発しています。 +``` + +Output: + +```html +

私はプログラマーです。東京の会社に勤めています。\nGoでWebアプリケーションを開発しています。

+``` + +#### Example of `EastAsianLineBreaksCSS3Draft` + +Input Markdown: + +```md +私はプログラマーです。 +東京の会社に勤めています。 +GoでWebアプリケーションを開発しています。 +``` + +Output: + +```html +

私はプログラマーです。東京の会社に勤めています。GoでWebアプリケーションを開発しています。

+``` + +Security +-------------------- +By default, goldmark does not render raw HTML or potentially-dangerous URLs. +If you need to gain more control over untrusted contents, it is recommended that you +use an HTML sanitizer such as [bluemonday](https://github.com/microcosm-cc/bluemonday). + +Benchmark +-------------------- +You can run this benchmark in the `_benchmark` directory. + +### against other golang libraries + +blackfriday v2 seems to be the fastest, but as it is not CommonMark compliant, its performance cannot be directly compared to that of the CommonMark-compliant libraries. + +goldmark, meanwhile, builds a clean, extensible AST structure, achieves full compliance with +CommonMark, and consumes less memory, all while being reasonably fast. + +- MBP 2019 13″(i5, 16GB), Go1.17 + +``` +BenchmarkMarkdown/Blackfriday-v2-8 302 3743747 ns/op 3290445 B/op 20050 allocs/op +BenchmarkMarkdown/GoldMark-8 280 4200974 ns/op 2559738 B/op 13435 allocs/op +BenchmarkMarkdown/CommonMark-8 226 5283686 ns/op 2702490 B/op 20792 allocs/op +BenchmarkMarkdown/Lute-8 12 92652857 ns/op 10602649 B/op 40555 allocs/op +BenchmarkMarkdown/GoMarkdown-8 13 81380167 ns/op 2245002 B/op 22889 allocs/op +``` + +### against cmark (CommonMark reference implementation written in C) + +- MBP 2019 13″(i5, 16GB), Go1.17 + +``` +----------- cmark ----------- +file: _data.md +iteration: 50 +average: 0.0044073057 sec +------- goldmark ------- +file: _data.md +iteration: 50 +average: 0.0041611990 sec +``` + +As you can see, goldmark's performance is on par with cmark's. + +Extensions +-------------------- + +- [goldmark-meta](https://github.com/yuin/goldmark-meta): A YAML metadata + extension for the goldmark Markdown parser. +- [goldmark-highlighting](https://github.com/yuin/goldmark-highlighting): A syntax-highlighting extension + for the goldmark markdown parser. +- [goldmark-emoji](https://github.com/yuin/goldmark-emoji): An emoji + extension for the goldmark Markdown parser. +- [goldmark-mathjax](https://github.com/litao91/goldmark-mathjax): Mathjax support for the goldmark markdown parser +- [goldmark-pdf](https://github.com/stephenafamo/goldmark-pdf): A PDF renderer that can be passed to `goldmark.WithRenderer()`. +- [goldmark-hashtag](https://github.com/abhinav/goldmark-hashtag): Adds support for `#hashtag`-based tagging to goldmark. +- [goldmark-wikilink](https://github.com/abhinav/goldmark-wikilink): Adds support for `[[wiki]]`-style links to goldmark. +- [goldmark-anchor](https://github.com/abhinav/goldmark-anchor): Adds anchors (permalinks) next to all headers in a document. +- [goldmark-figure](https://github.com/mangoumbrella/goldmark-figure): Adds support for rendering paragraphs starting with an image to `
` elements. +- [goldmark-frontmatter](https://github.com/abhinav/goldmark-frontmatter): Adds support for YAML, TOML, and custom front matter to documents. +- [goldmark-toc](https://github.com/abhinav/goldmark-toc): Adds support for generating tables-of-contents for goldmark documents. +- [goldmark-mermaid](https://github.com/abhinav/goldmark-mermaid): Adds support for rendering [Mermaid](https://mermaid-js.github.io/mermaid/) diagrams in goldmark documents. +- [goldmark-pikchr](https://github.com/jchenry/goldmark-pikchr): Adds support for rendering [Pikchr](https://pikchr.org/home/doc/trunk/homepage.md) diagrams in goldmark documents. +- [goldmark-embed](https://github.com/13rac1/goldmark-embed): Adds support for rendering embeds from YouTube links. +- [goldmark-latex](https://github.com/soypat/goldmark-latex): A $\LaTeX$ renderer that can be passed to `goldmark.WithRenderer()`. +- [goldmark-fences](https://github.com/stefanfritsch/goldmark-fences): Support for pandoc-style [fenced divs](https://pandoc.org/MANUAL.html#divs-and-spans) in goldmark. +- [goldmark-d2](https://github.com/FurqanSoftware/goldmark-d2): Adds support for [D2](https://d2lang.com/) diagrams. +- [goldmark-katex](https://github.com/FurqanSoftware/goldmark-katex): Adds support for [KaTeX](https://katex.org/) math and equations. +- [goldmark-img64](https://github.com/tenkoh/goldmark-img64): Adds support for embedding images into the document as DataURL (base64 encoded). + + +goldmark internal(for extension developers) +---------------------------------------------- +### Overview +goldmark's Markdown processing is outlined in the diagram below. + +``` + + | + V + +-------- parser.Parser --------------------------- + | 1. Parse block elements into AST + | 1. If a parsed block is a paragraph, apply + | ast.ParagraphTransformer + | 2. Traverse AST and parse blocks. + | 1. Process delimiters(emphasis) at the end of + | block parsing + | 3. Apply parser.ASTTransformers to AST + | + V + + | + V + +------- renderer.Renderer ------------------------ + | 1. Traverse AST and apply renderer.NodeRenderer + | corespond to the node type + + | + V + +``` + +### Parsing +Markdown documents are read through `text.Reader` interface. + +AST nodes do not have concrete text. AST nodes have segment information of the documents, represented by `text.Segment` . + +`text.Segment` has 3 attributes: `Start`, `End`, `Padding` . + +(TBC) + +**TODO** + +See `extension` directory for examples of extensions. + +Summary: + +1. Define AST Node as a struct in which `ast.BaseBlock` or `ast.BaseInline` is embedded. +2. Write a parser that implements `parser.BlockParser` or `parser.InlineParser`. +3. Write a renderer that implements `renderer.NodeRenderer`. +4. Define your goldmark extension that implements `goldmark.Extender`. + + +Donation +-------------------- +BTC: 1NEDSyUmo4SMTDP83JJQSWi1MvQUGGNMZB + +License +-------------------- +MIT + +Author +-------------------- +Yusuke Inuzuka diff --git a/vendor/github.com/yuin/goldmark/ast/ast.go b/vendor/github.com/yuin/goldmark/ast/ast.go new file mode 100644 index 0000000..67bb0da --- /dev/null +++ b/vendor/github.com/yuin/goldmark/ast/ast.go @@ -0,0 +1,508 @@ +// Package ast defines AST nodes that represent markdown elements. +package ast + +import ( + "bytes" + "fmt" + "strings" + + textm "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +// A NodeType indicates what type a node belongs to. +type NodeType int + +const ( + // TypeBlock indicates that a node is kind of block nodes. + TypeBlock NodeType = iota + 1 + // TypeInline indicates that a node is kind of inline nodes. + TypeInline + // TypeDocument indicates that a node is kind of document nodes. + TypeDocument +) + +// NodeKind indicates more specific type than NodeType. +type NodeKind int + +func (k NodeKind) String() string { + return kindNames[k] +} + +var kindMax NodeKind +var kindNames = []string{""} + +// NewNodeKind returns a new Kind value. +func NewNodeKind(name string) NodeKind { + kindMax++ + kindNames = append(kindNames, name) + return kindMax +} + +// An Attribute is an attribute of the Node. +type Attribute struct { + Name []byte + Value interface{} +} + +// A Node interface defines basic AST node functionalities. +type Node interface { + // Type returns a type of this node. + Type() NodeType + + // Kind returns a kind of this node. + Kind() NodeKind + + // NextSibling returns a next sibling node of this node. + NextSibling() Node + + // PreviousSibling returns a previous sibling node of this node. + PreviousSibling() Node + + // Parent returns a parent node of this node. + Parent() Node + + // SetParent sets a parent node to this node. + SetParent(Node) + + // SetPreviousSibling sets a previous sibling node to this node. + SetPreviousSibling(Node) + + // SetNextSibling sets a next sibling node to this node. + SetNextSibling(Node) + + // HasChildren returns true if this node has any children, otherwise false. + HasChildren() bool + + // ChildCount returns a total number of children. + ChildCount() int + + // FirstChild returns a first child of this node. + FirstChild() Node + + // LastChild returns a last child of this node. + LastChild() Node + + // AppendChild append a node child to the tail of the children. + AppendChild(self, child Node) + + // RemoveChild removes a node child from this node. + // If a node child is not children of this node, RemoveChild nothing to do. + RemoveChild(self, child Node) + + // RemoveChildren removes all children from this node. + RemoveChildren(self Node) + + // SortChildren sorts childrens by comparator. + SortChildren(comparator func(n1, n2 Node) int) + + // ReplaceChild replace a node v1 with a node insertee. + // If v1 is not children of this node, ReplaceChild append a insetee to the + // tail of the children. + ReplaceChild(self, v1, insertee Node) + + // InsertBefore inserts a node insertee before a node v1. + // If v1 is not children of this node, InsertBefore append a insetee to the + // tail of the children. + InsertBefore(self, v1, insertee Node) + + // InsertAfterinserts a node insertee after a node v1. + // If v1 is not children of this node, InsertBefore append a insetee to the + // tail of the children. + InsertAfter(self, v1, insertee Node) + + // OwnerDocument returns this node's owner document. + // If this node is not a child of the Document node, OwnerDocument + // returns nil. + OwnerDocument() *Document + + // Dump dumps an AST tree structure to stdout. + // This function completely aimed for debugging. + // level is a indent level. Implementer should indent informations with + // 2 * level spaces. + Dump(source []byte, level int) + + // Text returns text values of this node. + Text(source []byte) []byte + + // HasBlankPreviousLines returns true if the row before this node is blank, + // otherwise false. + // This method is valid only for block nodes. + HasBlankPreviousLines() bool + + // SetBlankPreviousLines sets whether the row before this node is blank. + // This method is valid only for block nodes. + SetBlankPreviousLines(v bool) + + // Lines returns text segments that hold positions in a source. + // This method is valid only for block nodes. + Lines() *textm.Segments + + // SetLines sets text segments that hold positions in a source. + // This method is valid only for block nodes. + SetLines(*textm.Segments) + + // IsRaw returns true if contents should be rendered as 'raw' contents. + IsRaw() bool + + // SetAttribute sets the given value to the attributes. + SetAttribute(name []byte, value interface{}) + + // SetAttributeString sets the given value to the attributes. + SetAttributeString(name string, value interface{}) + + // Attribute returns a (attribute value, true) if an attribute + // associated with the given name is found, otherwise + // (nil, false) + Attribute(name []byte) (interface{}, bool) + + // AttributeString returns a (attribute value, true) if an attribute + // associated with the given name is found, otherwise + // (nil, false) + AttributeString(name string) (interface{}, bool) + + // Attributes returns a list of attributes. + // This may be a nil if there are no attributes. + Attributes() []Attribute + + // RemoveAttributes removes all attributes from this node. + RemoveAttributes() +} + +// A BaseNode struct implements the Node interface partialliy. +type BaseNode struct { + firstChild Node + lastChild Node + parent Node + next Node + prev Node + childCount int + attributes []Attribute +} + +func ensureIsolated(v Node) { + if p := v.Parent(); p != nil { + p.RemoveChild(p, v) + } +} + +// HasChildren implements Node.HasChildren . +func (n *BaseNode) HasChildren() bool { + return n.firstChild != nil +} + +// SetPreviousSibling implements Node.SetPreviousSibling . +func (n *BaseNode) SetPreviousSibling(v Node) { + n.prev = v +} + +// SetNextSibling implements Node.SetNextSibling . +func (n *BaseNode) SetNextSibling(v Node) { + n.next = v +} + +// PreviousSibling implements Node.PreviousSibling . +func (n *BaseNode) PreviousSibling() Node { + return n.prev +} + +// NextSibling implements Node.NextSibling . +func (n *BaseNode) NextSibling() Node { + return n.next +} + +// RemoveChild implements Node.RemoveChild . +func (n *BaseNode) RemoveChild(self, v Node) { + if v.Parent() != self { + return + } + n.childCount-- + prev := v.PreviousSibling() + next := v.NextSibling() + if prev != nil { + prev.SetNextSibling(next) + } else { + n.firstChild = next + } + if next != nil { + next.SetPreviousSibling(prev) + } else { + n.lastChild = prev + } + v.SetParent(nil) + v.SetPreviousSibling(nil) + v.SetNextSibling(nil) +} + +// RemoveChildren implements Node.RemoveChildren . +func (n *BaseNode) RemoveChildren(self Node) { + for c := n.firstChild; c != nil; { + c.SetParent(nil) + c.SetPreviousSibling(nil) + next := c.NextSibling() + c.SetNextSibling(nil) + c = next + } + n.firstChild = nil + n.lastChild = nil + n.childCount = 0 +} + +// SortChildren implements Node.SortChildren. +func (n *BaseNode) SortChildren(comparator func(n1, n2 Node) int) { + var sorted Node + current := n.firstChild + for current != nil { + next := current.NextSibling() + if sorted == nil || comparator(sorted, current) >= 0 { + current.SetNextSibling(sorted) + if sorted != nil { + sorted.SetPreviousSibling(current) + } + sorted = current + sorted.SetPreviousSibling(nil) + } else { + c := sorted + for c.NextSibling() != nil && comparator(c.NextSibling(), current) < 0 { + c = c.NextSibling() + } + current.SetNextSibling(c.NextSibling()) + current.SetPreviousSibling(c) + if c.NextSibling() != nil { + c.NextSibling().SetPreviousSibling(current) + } + c.SetNextSibling(current) + } + current = next + } + n.firstChild = sorted + for c := n.firstChild; c != nil; c = c.NextSibling() { + n.lastChild = c + } +} + +// FirstChild implements Node.FirstChild . +func (n *BaseNode) FirstChild() Node { + return n.firstChild +} + +// LastChild implements Node.LastChild . +func (n *BaseNode) LastChild() Node { + return n.lastChild +} + +// ChildCount implements Node.ChildCount . +func (n *BaseNode) ChildCount() int { + return n.childCount +} + +// Parent implements Node.Parent . +func (n *BaseNode) Parent() Node { + return n.parent +} + +// SetParent implements Node.SetParent . +func (n *BaseNode) SetParent(v Node) { + n.parent = v +} + +// AppendChild implements Node.AppendChild . +func (n *BaseNode) AppendChild(self, v Node) { + ensureIsolated(v) + if n.firstChild == nil { + n.firstChild = v + v.SetNextSibling(nil) + v.SetPreviousSibling(nil) + } else { + last := n.lastChild + last.SetNextSibling(v) + v.SetPreviousSibling(last) + } + v.SetParent(self) + n.lastChild = v + n.childCount++ +} + +// ReplaceChild implements Node.ReplaceChild . +func (n *BaseNode) ReplaceChild(self, v1, insertee Node) { + n.InsertBefore(self, v1, insertee) + n.RemoveChild(self, v1) +} + +// InsertAfter implements Node.InsertAfter . +func (n *BaseNode) InsertAfter(self, v1, insertee Node) { + n.InsertBefore(self, v1.NextSibling(), insertee) +} + +// InsertBefore implements Node.InsertBefore . +func (n *BaseNode) InsertBefore(self, v1, insertee Node) { + n.childCount++ + if v1 == nil { + n.AppendChild(self, insertee) + return + } + ensureIsolated(insertee) + if v1.Parent() == self { + c := v1 + prev := c.PreviousSibling() + if prev != nil { + prev.SetNextSibling(insertee) + insertee.SetPreviousSibling(prev) + } else { + n.firstChild = insertee + insertee.SetPreviousSibling(nil) + } + insertee.SetNextSibling(c) + c.SetPreviousSibling(insertee) + insertee.SetParent(self) + } +} + +// OwnerDocument implements Node.OwnerDocument. +func (n *BaseNode) OwnerDocument() *Document { + d := n.Parent() + for { + p := d.Parent() + if p == nil { + if v, ok := d.(*Document); ok { + return v + } + break + } + d = p + } + return nil +} + +// Text implements Node.Text . +func (n *BaseNode) Text(source []byte) []byte { + var buf bytes.Buffer + for c := n.firstChild; c != nil; c = c.NextSibling() { + buf.Write(c.Text(source)) + } + return buf.Bytes() +} + +// SetAttribute implements Node.SetAttribute. +func (n *BaseNode) SetAttribute(name []byte, value interface{}) { + if n.attributes == nil { + n.attributes = make([]Attribute, 0, 10) + } else { + for i, a := range n.attributes { + if bytes.Equal(a.Name, name) { + n.attributes[i].Name = name + n.attributes[i].Value = value + return + } + } + } + n.attributes = append(n.attributes, Attribute{name, value}) +} + +// SetAttributeString implements Node.SetAttributeString. +func (n *BaseNode) SetAttributeString(name string, value interface{}) { + n.SetAttribute(util.StringToReadOnlyBytes(name), value) +} + +// Attribute implements Node.Attribute. +func (n *BaseNode) Attribute(name []byte) (interface{}, bool) { + if n.attributes == nil { + return nil, false + } + for i, a := range n.attributes { + if bytes.Equal(a.Name, name) { + return n.attributes[i].Value, true + } + } + return nil, false +} + +// AttributeString implements Node.AttributeString. +func (n *BaseNode) AttributeString(s string) (interface{}, bool) { + return n.Attribute(util.StringToReadOnlyBytes(s)) +} + +// Attributes implements Node.Attributes. +func (n *BaseNode) Attributes() []Attribute { + return n.attributes +} + +// RemoveAttributes implements Node.RemoveAttributes. +func (n *BaseNode) RemoveAttributes() { + n.attributes = nil +} + +// DumpHelper is a helper function to implement Node.Dump. +// kv is pairs of an attribute name and an attribute value. +// cb is a function called after wrote a name and attributes. +func DumpHelper(v Node, source []byte, level int, kv map[string]string, cb func(int)) { + name := v.Kind().String() + indent := strings.Repeat(" ", level) + fmt.Printf("%s%s {\n", indent, name) + indent2 := strings.Repeat(" ", level+1) + if v.Type() == TypeBlock { + fmt.Printf("%sRawText: \"", indent2) + for i := 0; i < v.Lines().Len(); i++ { + line := v.Lines().At(i) + fmt.Printf("%s", line.Value(source)) + } + fmt.Printf("\"\n") + fmt.Printf("%sHasBlankPreviousLines: %v\n", indent2, v.HasBlankPreviousLines()) + } + for name, value := range kv { + fmt.Printf("%s%s: %s\n", indent2, name, value) + } + if cb != nil { + cb(level + 1) + } + for c := v.FirstChild(); c != nil; c = c.NextSibling() { + c.Dump(source, level+1) + } + fmt.Printf("%s}\n", indent) +} + +// WalkStatus represents a current status of the Walk function. +type WalkStatus int + +const ( + // WalkStop indicates no more walking needed. + WalkStop WalkStatus = iota + 1 + + // WalkSkipChildren indicates that Walk wont walk on children of current + // node. + WalkSkipChildren + + // WalkContinue indicates that Walk can continue to walk. + WalkContinue +) + +// Walker is a function that will be called when Walk find a +// new node. +// entering is set true before walks children, false after walked children. +// If Walker returns error, Walk function immediately stop walking. +type Walker func(n Node, entering bool) (WalkStatus, error) + +// Walk walks a AST tree by the depth first search algorithm. +func Walk(n Node, walker Walker) error { + _, err := walkHelper(n, walker) + return err +} + +func walkHelper(n Node, walker Walker) (WalkStatus, error) { + status, err := walker(n, true) + if err != nil || status == WalkStop { + return status, err + } + if status != WalkSkipChildren { + for c := n.FirstChild(); c != nil; c = c.NextSibling() { + if st, err := walkHelper(c, walker); err != nil || st == WalkStop { + return WalkStop, err + } + } + } + status, err = walker(n, false) + if err != nil || status == WalkStop { + return WalkStop, err + } + return WalkContinue, nil +} diff --git a/vendor/github.com/yuin/goldmark/ast/block.go b/vendor/github.com/yuin/goldmark/ast/block.go new file mode 100644 index 0000000..c5d4738 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/ast/block.go @@ -0,0 +1,508 @@ +package ast + +import ( + "fmt" + "strings" + + textm "github.com/yuin/goldmark/text" +) + +// A BaseBlock struct implements the Node interface partialliy. +type BaseBlock struct { + BaseNode + blankPreviousLines bool + lines *textm.Segments +} + +// Type implements Node.Type. +func (b *BaseBlock) Type() NodeType { + return TypeBlock +} + +// IsRaw implements Node.IsRaw. +func (b *BaseBlock) IsRaw() bool { + return false +} + +// HasBlankPreviousLines implements Node.HasBlankPreviousLines. +func (b *BaseBlock) HasBlankPreviousLines() bool { + return b.blankPreviousLines +} + +// SetBlankPreviousLines implements Node.SetBlankPreviousLines. +func (b *BaseBlock) SetBlankPreviousLines(v bool) { + b.blankPreviousLines = v +} + +// Lines implements Node.Lines. +func (b *BaseBlock) Lines() *textm.Segments { + if b.lines == nil { + b.lines = textm.NewSegments() + } + return b.lines +} + +// SetLines implements Node.SetLines. +func (b *BaseBlock) SetLines(v *textm.Segments) { + b.lines = v +} + +// A Document struct is a root node of Markdown text. +type Document struct { + BaseBlock + + meta map[string]interface{} +} + +// KindDocument is a NodeKind of the Document node. +var KindDocument = NewNodeKind("Document") + +// Dump implements Node.Dump . +func (n *Document) Dump(source []byte, level int) { + DumpHelper(n, source, level, nil, nil) +} + +// Type implements Node.Type . +func (n *Document) Type() NodeType { + return TypeDocument +} + +// Kind implements Node.Kind. +func (n *Document) Kind() NodeKind { + return KindDocument +} + +// OwnerDocument implements Node.OwnerDocument. +func (n *Document) OwnerDocument() *Document { + return n +} + +// Meta returns metadata of this document. +func (n *Document) Meta() map[string]interface{} { + if n.meta == nil { + n.meta = map[string]interface{}{} + } + return n.meta +} + +// SetMeta sets given metadata to this document. +func (n *Document) SetMeta(meta map[string]interface{}) { + if n.meta == nil { + n.meta = map[string]interface{}{} + } + for k, v := range meta { + n.meta[k] = v + } +} + +// AddMeta adds given metadata to this document. +func (n *Document) AddMeta(key string, value interface{}) { + if n.meta == nil { + n.meta = map[string]interface{}{} + } + n.meta[key] = value +} + +// NewDocument returns a new Document node. +func NewDocument() *Document { + return &Document{ + BaseBlock: BaseBlock{}, + meta: nil, + } +} + +// A TextBlock struct is a node whose lines +// should be rendered without any containers. +type TextBlock struct { + BaseBlock +} + +// Dump implements Node.Dump . +func (n *TextBlock) Dump(source []byte, level int) { + DumpHelper(n, source, level, nil, nil) +} + +// KindTextBlock is a NodeKind of the TextBlock node. +var KindTextBlock = NewNodeKind("TextBlock") + +// Kind implements Node.Kind. +func (n *TextBlock) Kind() NodeKind { + return KindTextBlock +} + +// NewTextBlock returns a new TextBlock node. +func NewTextBlock() *TextBlock { + return &TextBlock{ + BaseBlock: BaseBlock{}, + } +} + +// A Paragraph struct represents a paragraph of Markdown text. +type Paragraph struct { + BaseBlock +} + +// Dump implements Node.Dump . +func (n *Paragraph) Dump(source []byte, level int) { + DumpHelper(n, source, level, nil, nil) +} + +// KindParagraph is a NodeKind of the Paragraph node. +var KindParagraph = NewNodeKind("Paragraph") + +// Kind implements Node.Kind. +func (n *Paragraph) Kind() NodeKind { + return KindParagraph +} + +// NewParagraph returns a new Paragraph node. +func NewParagraph() *Paragraph { + return &Paragraph{ + BaseBlock: BaseBlock{}, + } +} + +// IsParagraph returns true if the given node implements the Paragraph interface, +// otherwise false. +func IsParagraph(node Node) bool { + _, ok := node.(*Paragraph) + return ok +} + +// A Heading struct represents headings like SetextHeading and ATXHeading. +type Heading struct { + BaseBlock + // Level returns a level of this heading. + // This value is between 1 and 6. + Level int +} + +// Dump implements Node.Dump . +func (n *Heading) Dump(source []byte, level int) { + m := map[string]string{ + "Level": fmt.Sprintf("%d", n.Level), + } + DumpHelper(n, source, level, m, nil) +} + +// KindHeading is a NodeKind of the Heading node. +var KindHeading = NewNodeKind("Heading") + +// Kind implements Node.Kind. +func (n *Heading) Kind() NodeKind { + return KindHeading +} + +// NewHeading returns a new Heading node. +func NewHeading(level int) *Heading { + return &Heading{ + BaseBlock: BaseBlock{}, + Level: level, + } +} + +// A ThematicBreak struct represents a thematic break of Markdown text. +type ThematicBreak struct { + BaseBlock +} + +// Dump implements Node.Dump . +func (n *ThematicBreak) Dump(source []byte, level int) { + DumpHelper(n, source, level, nil, nil) +} + +// KindThematicBreak is a NodeKind of the ThematicBreak node. +var KindThematicBreak = NewNodeKind("ThematicBreak") + +// Kind implements Node.Kind. +func (n *ThematicBreak) Kind() NodeKind { + return KindThematicBreak +} + +// NewThematicBreak returns a new ThematicBreak node. +func NewThematicBreak() *ThematicBreak { + return &ThematicBreak{ + BaseBlock: BaseBlock{}, + } +} + +// A CodeBlock interface represents an indented code block of Markdown text. +type CodeBlock struct { + BaseBlock +} + +// IsRaw implements Node.IsRaw. +func (n *CodeBlock) IsRaw() bool { + return true +} + +// Dump implements Node.Dump . +func (n *CodeBlock) Dump(source []byte, level int) { + DumpHelper(n, source, level, nil, nil) +} + +// KindCodeBlock is a NodeKind of the CodeBlock node. +var KindCodeBlock = NewNodeKind("CodeBlock") + +// Kind implements Node.Kind. +func (n *CodeBlock) Kind() NodeKind { + return KindCodeBlock +} + +// NewCodeBlock returns a new CodeBlock node. +func NewCodeBlock() *CodeBlock { + return &CodeBlock{ + BaseBlock: BaseBlock{}, + } +} + +// A FencedCodeBlock struct represents a fenced code block of Markdown text. +type FencedCodeBlock struct { + BaseBlock + // Info returns a info text of this fenced code block. + Info *Text + + language []byte +} + +// Language returns an language in an info string. +// Language returns nil if this node does not have an info string. +func (n *FencedCodeBlock) Language(source []byte) []byte { + if n.language == nil && n.Info != nil { + segment := n.Info.Segment + info := segment.Value(source) + i := 0 + for ; i < len(info); i++ { + if info[i] == ' ' { + break + } + } + n.language = info[:i] + } + return n.language +} + +// IsRaw implements Node.IsRaw. +func (n *FencedCodeBlock) IsRaw() bool { + return true +} + +// Dump implements Node.Dump . +func (n *FencedCodeBlock) Dump(source []byte, level int) { + m := map[string]string{} + if n.Info != nil { + m["Info"] = fmt.Sprintf("\"%s\"", n.Info.Text(source)) + } + DumpHelper(n, source, level, m, nil) +} + +// KindFencedCodeBlock is a NodeKind of the FencedCodeBlock node. +var KindFencedCodeBlock = NewNodeKind("FencedCodeBlock") + +// Kind implements Node.Kind. +func (n *FencedCodeBlock) Kind() NodeKind { + return KindFencedCodeBlock +} + +// NewFencedCodeBlock return a new FencedCodeBlock node. +func NewFencedCodeBlock(info *Text) *FencedCodeBlock { + return &FencedCodeBlock{ + BaseBlock: BaseBlock{}, + Info: info, + } +} + +// A Blockquote struct represents an blockquote block of Markdown text. +type Blockquote struct { + BaseBlock +} + +// Dump implements Node.Dump . +func (n *Blockquote) Dump(source []byte, level int) { + DumpHelper(n, source, level, nil, nil) +} + +// KindBlockquote is a NodeKind of the Blockquote node. +var KindBlockquote = NewNodeKind("Blockquote") + +// Kind implements Node.Kind. +func (n *Blockquote) Kind() NodeKind { + return KindBlockquote +} + +// NewBlockquote returns a new Blockquote node. +func NewBlockquote() *Blockquote { + return &Blockquote{ + BaseBlock: BaseBlock{}, + } +} + +// A List struct represents a list of Markdown text. +type List struct { + BaseBlock + + // Marker is a marker character like '-', '+', ')' and '.'. + Marker byte + + // IsTight is a true if this list is a 'tight' list. + // See https://spec.commonmark.org/0.30/#loose for details. + IsTight bool + + // Start is an initial number of this ordered list. + // If this list is not an ordered list, Start is 0. + Start int +} + +// IsOrdered returns true if this list is an ordered list, otherwise false. +func (l *List) IsOrdered() bool { + return l.Marker == '.' || l.Marker == ')' +} + +// CanContinue returns true if this list can continue with +// the given mark and a list type, otherwise false. +func (l *List) CanContinue(marker byte, isOrdered bool) bool { + return marker == l.Marker && isOrdered == l.IsOrdered() +} + +// Dump implements Node.Dump. +func (l *List) Dump(source []byte, level int) { + m := map[string]string{ + "Ordered": fmt.Sprintf("%v", l.IsOrdered()), + "Marker": fmt.Sprintf("%c", l.Marker), + "Tight": fmt.Sprintf("%v", l.IsTight), + } + if l.IsOrdered() { + m["Start"] = fmt.Sprintf("%d", l.Start) + } + DumpHelper(l, source, level, m, nil) +} + +// KindList is a NodeKind of the List node. +var KindList = NewNodeKind("List") + +// Kind implements Node.Kind. +func (l *List) Kind() NodeKind { + return KindList +} + +// NewList returns a new List node. +func NewList(marker byte) *List { + return &List{ + BaseBlock: BaseBlock{}, + Marker: marker, + IsTight: true, + } +} + +// A ListItem struct represents a list item of Markdown text. +type ListItem struct { + BaseBlock + + // Offset is an offset position of this item. + Offset int +} + +// Dump implements Node.Dump. +func (n *ListItem) Dump(source []byte, level int) { + m := map[string]string{ + "Offset": fmt.Sprintf("%d", n.Offset), + } + DumpHelper(n, source, level, m, nil) +} + +// KindListItem is a NodeKind of the ListItem node. +var KindListItem = NewNodeKind("ListItem") + +// Kind implements Node.Kind. +func (n *ListItem) Kind() NodeKind { + return KindListItem +} + +// NewListItem returns a new ListItem node. +func NewListItem(offset int) *ListItem { + return &ListItem{ + BaseBlock: BaseBlock{}, + Offset: offset, + } +} + +// HTMLBlockType represents kinds of an html blocks. +// See https://spec.commonmark.org/0.30/#html-blocks +type HTMLBlockType int + +const ( + // HTMLBlockType1 represents type 1 html blocks. + HTMLBlockType1 HTMLBlockType = iota + 1 + // HTMLBlockType2 represents type 2 html blocks. + HTMLBlockType2 + // HTMLBlockType3 represents type 3 html blocks. + HTMLBlockType3 + // HTMLBlockType4 represents type 4 html blocks. + HTMLBlockType4 + // HTMLBlockType5 represents type 5 html blocks. + HTMLBlockType5 + // HTMLBlockType6 represents type 6 html blocks. + HTMLBlockType6 + // HTMLBlockType7 represents type 7 html blocks. + HTMLBlockType7 +) + +// An HTMLBlock struct represents an html block of Markdown text. +type HTMLBlock struct { + BaseBlock + + // Type is a type of this html block. + HTMLBlockType HTMLBlockType + + // ClosureLine is a line that closes this html block. + ClosureLine textm.Segment +} + +// IsRaw implements Node.IsRaw. +func (n *HTMLBlock) IsRaw() bool { + return true +} + +// HasClosure returns true if this html block has a closure line, +// otherwise false. +func (n *HTMLBlock) HasClosure() bool { + return n.ClosureLine.Start >= 0 +} + +// Dump implements Node.Dump. +func (n *HTMLBlock) Dump(source []byte, level int) { + indent := strings.Repeat(" ", level) + fmt.Printf("%s%s {\n", indent, "HTMLBlock") + indent2 := strings.Repeat(" ", level+1) + fmt.Printf("%sRawText: \"", indent2) + for i := 0; i < n.Lines().Len(); i++ { + s := n.Lines().At(i) + fmt.Print(string(source[s.Start:s.Stop])) + } + fmt.Printf("\"\n") + for c := n.FirstChild(); c != nil; c = c.NextSibling() { + c.Dump(source, level+1) + } + if n.HasClosure() { + cl := n.ClosureLine + fmt.Printf("%sClosure: \"%s\"\n", indent2, string(cl.Value(source))) + } + fmt.Printf("%s}\n", indent) +} + +// KindHTMLBlock is a NodeKind of the HTMLBlock node. +var KindHTMLBlock = NewNodeKind("HTMLBlock") + +// Kind implements Node.Kind. +func (n *HTMLBlock) Kind() NodeKind { + return KindHTMLBlock +} + +// NewHTMLBlock returns a new HTMLBlock node. +func NewHTMLBlock(typ HTMLBlockType) *HTMLBlock { + return &HTMLBlock{ + BaseBlock: BaseBlock{}, + HTMLBlockType: typ, + ClosureLine: textm.NewSegment(-1, -1), + } +} diff --git a/vendor/github.com/yuin/goldmark/ast/inline.go b/vendor/github.com/yuin/goldmark/ast/inline.go new file mode 100644 index 0000000..7e4c51f --- /dev/null +++ b/vendor/github.com/yuin/goldmark/ast/inline.go @@ -0,0 +1,549 @@ +package ast + +import ( + "fmt" + "strings" + + textm "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +// A BaseInline struct implements the Node interface partialliy. +type BaseInline struct { + BaseNode +} + +// Type implements Node.Type. +func (b *BaseInline) Type() NodeType { + return TypeInline +} + +// IsRaw implements Node.IsRaw. +func (b *BaseInline) IsRaw() bool { + return false +} + +// HasBlankPreviousLines implements Node.HasBlankPreviousLines. +func (b *BaseInline) HasBlankPreviousLines() bool { + panic("can not call with inline nodes.") +} + +// SetBlankPreviousLines implements Node.SetBlankPreviousLines. +func (b *BaseInline) SetBlankPreviousLines(v bool) { + panic("can not call with inline nodes.") +} + +// Lines implements Node.Lines. +func (b *BaseInline) Lines() *textm.Segments { + panic("can not call with inline nodes.") +} + +// SetLines implements Node.SetLines. +func (b *BaseInline) SetLines(v *textm.Segments) { + panic("can not call with inline nodes.") +} + +// A Text struct represents a textual content of the Markdown text. +type Text struct { + BaseInline + // Segment is a position in a source text. + Segment textm.Segment + + flags uint8 +} + +const ( + textSoftLineBreak = 1 << iota + textHardLineBreak + textRaw + textCode +) + +func textFlagsString(flags uint8) string { + buf := []string{} + if flags&textSoftLineBreak != 0 { + buf = append(buf, "SoftLineBreak") + } + if flags&textHardLineBreak != 0 { + buf = append(buf, "HardLineBreak") + } + if flags&textRaw != 0 { + buf = append(buf, "Raw") + } + if flags&textCode != 0 { + buf = append(buf, "Code") + } + return strings.Join(buf, ", ") +} + +// Inline implements Inline.Inline. +func (n *Text) Inline() { +} + +// SoftLineBreak returns true if this node ends with a new line, +// otherwise false. +func (n *Text) SoftLineBreak() bool { + return n.flags&textSoftLineBreak != 0 +} + +// SetSoftLineBreak sets whether this node ends with a new line. +func (n *Text) SetSoftLineBreak(v bool) { + if v { + n.flags |= textSoftLineBreak + } else { + n.flags = n.flags &^ textSoftLineBreak + } +} + +// IsRaw returns true if this text should be rendered without unescaping +// back slash escapes and resolving references. +func (n *Text) IsRaw() bool { + return n.flags&textRaw != 0 +} + +// SetRaw sets whether this text should be rendered as raw contents. +func (n *Text) SetRaw(v bool) { + if v { + n.flags |= textRaw + } else { + n.flags = n.flags &^ textRaw + } +} + +// HardLineBreak returns true if this node ends with a hard line break. +// See https://spec.commonmark.org/0.30/#hard-line-breaks for details. +func (n *Text) HardLineBreak() bool { + return n.flags&textHardLineBreak != 0 +} + +// SetHardLineBreak sets whether this node ends with a hard line break. +func (n *Text) SetHardLineBreak(v bool) { + if v { + n.flags |= textHardLineBreak + } else { + n.flags = n.flags &^ textHardLineBreak + } +} + +// Merge merges a Node n into this node. +// Merge returns true if the given node has been merged, otherwise false. +func (n *Text) Merge(node Node, source []byte) bool { + t, ok := node.(*Text) + if !ok { + return false + } + if n.Segment.Stop != t.Segment.Start || t.Segment.Padding != 0 || + source[n.Segment.Stop-1] == '\n' || t.IsRaw() != n.IsRaw() { + return false + } + n.Segment.Stop = t.Segment.Stop + n.SetSoftLineBreak(t.SoftLineBreak()) + n.SetHardLineBreak(t.HardLineBreak()) + return true +} + +// Text implements Node.Text. +func (n *Text) Text(source []byte) []byte { + return n.Segment.Value(source) +} + +// Dump implements Node.Dump. +func (n *Text) Dump(source []byte, level int) { + fs := textFlagsString(n.flags) + if len(fs) != 0 { + fs = "(" + fs + ")" + } + fmt.Printf("%sText%s: \"%s\"\n", strings.Repeat(" ", level), fs, strings.TrimRight(string(n.Text(source)), "\n")) +} + +// KindText is a NodeKind of the Text node. +var KindText = NewNodeKind("Text") + +// Kind implements Node.Kind. +func (n *Text) Kind() NodeKind { + return KindText +} + +// NewText returns a new Text node. +func NewText() *Text { + return &Text{ + BaseInline: BaseInline{}, + } +} + +// NewTextSegment returns a new Text node with the given source position. +func NewTextSegment(v textm.Segment) *Text { + return &Text{ + BaseInline: BaseInline{}, + Segment: v, + } +} + +// NewRawTextSegment returns a new Text node with the given source position. +// The new node should be rendered as raw contents. +func NewRawTextSegment(v textm.Segment) *Text { + t := &Text{ + BaseInline: BaseInline{}, + Segment: v, + } + t.SetRaw(true) + return t +} + +// MergeOrAppendTextSegment merges a given s into the last child of the parent if +// it can be merged, otherwise creates a new Text node and appends it to after current +// last child. +func MergeOrAppendTextSegment(parent Node, s textm.Segment) { + last := parent.LastChild() + t, ok := last.(*Text) + if ok && t.Segment.Stop == s.Start && !t.SoftLineBreak() { + t.Segment = t.Segment.WithStop(s.Stop) + } else { + parent.AppendChild(parent, NewTextSegment(s)) + } +} + +// MergeOrReplaceTextSegment merges a given s into a previous sibling of the node n +// if a previous sibling of the node n is *Text, otherwise replaces Node n with s. +func MergeOrReplaceTextSegment(parent Node, n Node, s textm.Segment) { + prev := n.PreviousSibling() + if t, ok := prev.(*Text); ok && t.Segment.Stop == s.Start && !t.SoftLineBreak() { + t.Segment = t.Segment.WithStop(s.Stop) + parent.RemoveChild(parent, n) + } else { + parent.ReplaceChild(parent, n, NewTextSegment(s)) + } +} + +// A String struct is a textual content that has a concrete value. +type String struct { + BaseInline + + Value []byte + flags uint8 +} + +// Inline implements Inline.Inline. +func (n *String) Inline() { +} + +// IsRaw returns true if this text should be rendered without unescaping +// back slash escapes and resolving references. +func (n *String) IsRaw() bool { + return n.flags&textRaw != 0 +} + +// SetRaw sets whether this text should be rendered as raw contents. +func (n *String) SetRaw(v bool) { + if v { + n.flags |= textRaw + } else { + n.flags = n.flags &^ textRaw + } +} + +// IsCode returns true if this text should be rendered without any +// modifications. +func (n *String) IsCode() bool { + return n.flags&textCode != 0 +} + +// SetCode sets whether this text should be rendered without any modifications. +func (n *String) SetCode(v bool) { + if v { + n.flags |= textCode + } else { + n.flags = n.flags &^ textCode + } +} + +// Text implements Node.Text. +func (n *String) Text(source []byte) []byte { + return n.Value +} + +// Dump implements Node.Dump. +func (n *String) Dump(source []byte, level int) { + fs := textFlagsString(n.flags) + if len(fs) != 0 { + fs = "(" + fs + ")" + } + fmt.Printf("%sString%s: \"%s\"\n", strings.Repeat(" ", level), fs, strings.TrimRight(string(n.Value), "\n")) +} + +// KindString is a NodeKind of the String node. +var KindString = NewNodeKind("String") + +// Kind implements Node.Kind. +func (n *String) Kind() NodeKind { + return KindString +} + +// NewString returns a new String node. +func NewString(v []byte) *String { + return &String{ + Value: v, + } +} + +// A CodeSpan struct represents a code span of Markdown text. +type CodeSpan struct { + BaseInline +} + +// Inline implements Inline.Inline . +func (n *CodeSpan) Inline() { +} + +// IsBlank returns true if this node consists of spaces, otherwise false. +func (n *CodeSpan) IsBlank(source []byte) bool { + for c := n.FirstChild(); c != nil; c = c.NextSibling() { + text := c.(*Text).Segment + if !util.IsBlank(text.Value(source)) { + return false + } + } + return true +} + +// Dump implements Node.Dump. +func (n *CodeSpan) Dump(source []byte, level int) { + DumpHelper(n, source, level, nil, nil) +} + +// KindCodeSpan is a NodeKind of the CodeSpan node. +var KindCodeSpan = NewNodeKind("CodeSpan") + +// Kind implements Node.Kind. +func (n *CodeSpan) Kind() NodeKind { + return KindCodeSpan +} + +// NewCodeSpan returns a new CodeSpan node. +func NewCodeSpan() *CodeSpan { + return &CodeSpan{ + BaseInline: BaseInline{}, + } +} + +// An Emphasis struct represents an emphasis of Markdown text. +type Emphasis struct { + BaseInline + + // Level is a level of the emphasis. + Level int +} + +// Dump implements Node.Dump. +func (n *Emphasis) Dump(source []byte, level int) { + m := map[string]string{ + "Level": fmt.Sprintf("%v", n.Level), + } + DumpHelper(n, source, level, m, nil) +} + +// KindEmphasis is a NodeKind of the Emphasis node. +var KindEmphasis = NewNodeKind("Emphasis") + +// Kind implements Node.Kind. +func (n *Emphasis) Kind() NodeKind { + return KindEmphasis +} + +// NewEmphasis returns a new Emphasis node with the given level. +func NewEmphasis(level int) *Emphasis { + return &Emphasis{ + BaseInline: BaseInline{}, + Level: level, + } +} + +type baseLink struct { + BaseInline + + // Destination is a destination(URL) of this link. + Destination []byte + + // Title is a title of this link. + Title []byte +} + +// Inline implements Inline.Inline. +func (n *baseLink) Inline() { +} + +// A Link struct represents a link of the Markdown text. +type Link struct { + baseLink +} + +// Dump implements Node.Dump. +func (n *Link) Dump(source []byte, level int) { + m := map[string]string{} + m["Destination"] = string(n.Destination) + m["Title"] = string(n.Title) + DumpHelper(n, source, level, m, nil) +} + +// KindLink is a NodeKind of the Link node. +var KindLink = NewNodeKind("Link") + +// Kind implements Node.Kind. +func (n *Link) Kind() NodeKind { + return KindLink +} + +// NewLink returns a new Link node. +func NewLink() *Link { + c := &Link{ + baseLink: baseLink{ + BaseInline: BaseInline{}, + }, + } + return c +} + +// An Image struct represents an image of the Markdown text. +type Image struct { + baseLink +} + +// Dump implements Node.Dump. +func (n *Image) Dump(source []byte, level int) { + m := map[string]string{} + m["Destination"] = string(n.Destination) + m["Title"] = string(n.Title) + DumpHelper(n, source, level, m, nil) +} + +// KindImage is a NodeKind of the Image node. +var KindImage = NewNodeKind("Image") + +// Kind implements Node.Kind. +func (n *Image) Kind() NodeKind { + return KindImage +} + +// NewImage returns a new Image node. +func NewImage(link *Link) *Image { + c := &Image{ + baseLink: baseLink{ + BaseInline: BaseInline{}, + }, + } + c.Destination = link.Destination + c.Title = link.Title + for n := link.FirstChild(); n != nil; { + next := n.NextSibling() + link.RemoveChild(link, n) + c.AppendChild(c, n) + n = next + } + + return c +} + +// AutoLinkType defines kind of auto links. +type AutoLinkType int + +const ( + // AutoLinkEmail indicates that an autolink is an email address. + AutoLinkEmail AutoLinkType = iota + 1 + // AutoLinkURL indicates that an autolink is a generic URL. + AutoLinkURL +) + +// An AutoLink struct represents an autolink of the Markdown text. +type AutoLink struct { + BaseInline + // Type is a type of this autolink. + AutoLinkType AutoLinkType + + // Protocol specified a protocol of the link. + Protocol []byte + + value *Text +} + +// Inline implements Inline.Inline. +func (n *AutoLink) Inline() {} + +// Dump implements Node.Dump. +func (n *AutoLink) Dump(source []byte, level int) { + segment := n.value.Segment + m := map[string]string{ + "Value": string(segment.Value(source)), + } + DumpHelper(n, source, level, m, nil) +} + +// KindAutoLink is a NodeKind of the AutoLink node. +var KindAutoLink = NewNodeKind("AutoLink") + +// Kind implements Node.Kind. +func (n *AutoLink) Kind() NodeKind { + return KindAutoLink +} + +// URL returns an url of this node. +func (n *AutoLink) URL(source []byte) []byte { + if n.Protocol != nil { + s := n.value.Segment + ret := make([]byte, 0, len(n.Protocol)+s.Len()+3) + ret = append(ret, n.Protocol...) + ret = append(ret, ':', '/', '/') + ret = append(ret, n.value.Text(source)...) + return ret + } + return n.value.Text(source) +} + +// Label returns a label of this node. +func (n *AutoLink) Label(source []byte) []byte { + return n.value.Text(source) +} + +// NewAutoLink returns a new AutoLink node. +func NewAutoLink(typ AutoLinkType, value *Text) *AutoLink { + return &AutoLink{ + BaseInline: BaseInline{}, + value: value, + AutoLinkType: typ, + } +} + +// A RawHTML struct represents an inline raw HTML of the Markdown text. +type RawHTML struct { + BaseInline + Segments *textm.Segments +} + +// Inline implements Inline.Inline. +func (n *RawHTML) Inline() {} + +// Dump implements Node.Dump. +func (n *RawHTML) Dump(source []byte, level int) { + m := map[string]string{} + t := []string{} + for i := 0; i < n.Segments.Len(); i++ { + segment := n.Segments.At(i) + t = append(t, string(segment.Value(source))) + } + m["RawText"] = strings.Join(t, "") + DumpHelper(n, source, level, m, nil) +} + +// KindRawHTML is a NodeKind of the RawHTML node. +var KindRawHTML = NewNodeKind("RawHTML") + +// Kind implements Node.Kind. +func (n *RawHTML) Kind() NodeKind { + return KindRawHTML +} + +// NewRawHTML returns a new RawHTML node. +func NewRawHTML() *RawHTML { + return &RawHTML{ + Segments: textm.NewSegments(), + } +} diff --git a/vendor/github.com/yuin/goldmark/extension/ast/definition_list.go b/vendor/github.com/yuin/goldmark/extension/ast/definition_list.go new file mode 100644 index 0000000..1beffb3 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/ast/definition_list.go @@ -0,0 +1,83 @@ +package ast + +import ( + gast "github.com/yuin/goldmark/ast" +) + +// A DefinitionList struct represents a definition list of Markdown +// (PHPMarkdownExtra) text. +type DefinitionList struct { + gast.BaseBlock + Offset int + TemporaryParagraph *gast.Paragraph +} + +// Dump implements Node.Dump. +func (n *DefinitionList) Dump(source []byte, level int) { + gast.DumpHelper(n, source, level, nil, nil) +} + +// KindDefinitionList is a NodeKind of the DefinitionList node. +var KindDefinitionList = gast.NewNodeKind("DefinitionList") + +// Kind implements Node.Kind. +func (n *DefinitionList) Kind() gast.NodeKind { + return KindDefinitionList +} + +// NewDefinitionList returns a new DefinitionList node. +func NewDefinitionList(offset int, para *gast.Paragraph) *DefinitionList { + return &DefinitionList{ + Offset: offset, + TemporaryParagraph: para, + } +} + +// A DefinitionTerm struct represents a definition list term of Markdown +// (PHPMarkdownExtra) text. +type DefinitionTerm struct { + gast.BaseBlock +} + +// Dump implements Node.Dump. +func (n *DefinitionTerm) Dump(source []byte, level int) { + gast.DumpHelper(n, source, level, nil, nil) +} + +// KindDefinitionTerm is a NodeKind of the DefinitionTerm node. +var KindDefinitionTerm = gast.NewNodeKind("DefinitionTerm") + +// Kind implements Node.Kind. +func (n *DefinitionTerm) Kind() gast.NodeKind { + return KindDefinitionTerm +} + +// NewDefinitionTerm returns a new DefinitionTerm node. +func NewDefinitionTerm() *DefinitionTerm { + return &DefinitionTerm{} +} + +// A DefinitionDescription struct represents a definition list description of Markdown +// (PHPMarkdownExtra) text. +type DefinitionDescription struct { + gast.BaseBlock + IsTight bool +} + +// Dump implements Node.Dump. +func (n *DefinitionDescription) Dump(source []byte, level int) { + gast.DumpHelper(n, source, level, nil, nil) +} + +// KindDefinitionDescription is a NodeKind of the DefinitionDescription node. +var KindDefinitionDescription = gast.NewNodeKind("DefinitionDescription") + +// Kind implements Node.Kind. +func (n *DefinitionDescription) Kind() gast.NodeKind { + return KindDefinitionDescription +} + +// NewDefinitionDescription returns a new DefinitionDescription node. +func NewDefinitionDescription() *DefinitionDescription { + return &DefinitionDescription{} +} diff --git a/vendor/github.com/yuin/goldmark/extension/ast/footnote.go b/vendor/github.com/yuin/goldmark/extension/ast/footnote.go new file mode 100644 index 0000000..b24eafe --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/ast/footnote.go @@ -0,0 +1,138 @@ +package ast + +import ( + "fmt" + + gast "github.com/yuin/goldmark/ast" +) + +// A FootnoteLink struct represents a link to a footnote of Markdown +// (PHP Markdown Extra) text. +type FootnoteLink struct { + gast.BaseInline + Index int + RefCount int + RefIndex int +} + +// Dump implements Node.Dump. +func (n *FootnoteLink) Dump(source []byte, level int) { + m := map[string]string{} + m["Index"] = fmt.Sprintf("%v", n.Index) + m["RefCount"] = fmt.Sprintf("%v", n.RefCount) + m["RefIndex"] = fmt.Sprintf("%v", n.RefIndex) + gast.DumpHelper(n, source, level, m, nil) +} + +// KindFootnoteLink is a NodeKind of the FootnoteLink node. +var KindFootnoteLink = gast.NewNodeKind("FootnoteLink") + +// Kind implements Node.Kind. +func (n *FootnoteLink) Kind() gast.NodeKind { + return KindFootnoteLink +} + +// NewFootnoteLink returns a new FootnoteLink node. +func NewFootnoteLink(index int) *FootnoteLink { + return &FootnoteLink{ + Index: index, + RefCount: 0, + RefIndex: 0, + } +} + +// A FootnoteBacklink struct represents a link to a footnote of Markdown +// (PHP Markdown Extra) text. +type FootnoteBacklink struct { + gast.BaseInline + Index int + RefCount int + RefIndex int +} + +// Dump implements Node.Dump. +func (n *FootnoteBacklink) Dump(source []byte, level int) { + m := map[string]string{} + m["Index"] = fmt.Sprintf("%v", n.Index) + m["RefCount"] = fmt.Sprintf("%v", n.RefCount) + m["RefIndex"] = fmt.Sprintf("%v", n.RefIndex) + gast.DumpHelper(n, source, level, m, nil) +} + +// KindFootnoteBacklink is a NodeKind of the FootnoteBacklink node. +var KindFootnoteBacklink = gast.NewNodeKind("FootnoteBacklink") + +// Kind implements Node.Kind. +func (n *FootnoteBacklink) Kind() gast.NodeKind { + return KindFootnoteBacklink +} + +// NewFootnoteBacklink returns a new FootnoteBacklink node. +func NewFootnoteBacklink(index int) *FootnoteBacklink { + return &FootnoteBacklink{ + Index: index, + RefCount: 0, + RefIndex: 0, + } +} + +// A Footnote struct represents a footnote of Markdown +// (PHP Markdown Extra) text. +type Footnote struct { + gast.BaseBlock + Ref []byte + Index int +} + +// Dump implements Node.Dump. +func (n *Footnote) Dump(source []byte, level int) { + m := map[string]string{} + m["Index"] = fmt.Sprintf("%v", n.Index) + m["Ref"] = string(n.Ref) + gast.DumpHelper(n, source, level, m, nil) +} + +// KindFootnote is a NodeKind of the Footnote node. +var KindFootnote = gast.NewNodeKind("Footnote") + +// Kind implements Node.Kind. +func (n *Footnote) Kind() gast.NodeKind { + return KindFootnote +} + +// NewFootnote returns a new Footnote node. +func NewFootnote(ref []byte) *Footnote { + return &Footnote{ + Ref: ref, + Index: -1, + } +} + +// A FootnoteList struct represents footnotes of Markdown +// (PHP Markdown Extra) text. +type FootnoteList struct { + gast.BaseBlock + Count int +} + +// Dump implements Node.Dump. +func (n *FootnoteList) Dump(source []byte, level int) { + m := map[string]string{} + m["Count"] = fmt.Sprintf("%v", n.Count) + gast.DumpHelper(n, source, level, m, nil) +} + +// KindFootnoteList is a NodeKind of the FootnoteList node. +var KindFootnoteList = gast.NewNodeKind("FootnoteList") + +// Kind implements Node.Kind. +func (n *FootnoteList) Kind() gast.NodeKind { + return KindFootnoteList +} + +// NewFootnoteList returns a new FootnoteList node. +func NewFootnoteList() *FootnoteList { + return &FootnoteList{ + Count: 0, + } +} diff --git a/vendor/github.com/yuin/goldmark/extension/ast/strikethrough.go b/vendor/github.com/yuin/goldmark/extension/ast/strikethrough.go new file mode 100644 index 0000000..a9216b7 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/ast/strikethrough.go @@ -0,0 +1,29 @@ +// Package ast defines AST nodes that represents extension's elements +package ast + +import ( + gast "github.com/yuin/goldmark/ast" +) + +// A Strikethrough struct represents a strikethrough of GFM text. +type Strikethrough struct { + gast.BaseInline +} + +// Dump implements Node.Dump. +func (n *Strikethrough) Dump(source []byte, level int) { + gast.DumpHelper(n, source, level, nil, nil) +} + +// KindStrikethrough is a NodeKind of the Strikethrough node. +var KindStrikethrough = gast.NewNodeKind("Strikethrough") + +// Kind implements Node.Kind. +func (n *Strikethrough) Kind() gast.NodeKind { + return KindStrikethrough +} + +// NewStrikethrough returns a new Strikethrough node. +func NewStrikethrough() *Strikethrough { + return &Strikethrough{} +} diff --git a/vendor/github.com/yuin/goldmark/extension/ast/table.go b/vendor/github.com/yuin/goldmark/extension/ast/table.go new file mode 100644 index 0000000..4142e33 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/ast/table.go @@ -0,0 +1,158 @@ +package ast + +import ( + "fmt" + "strings" + + gast "github.com/yuin/goldmark/ast" +) + +// Alignment is a text alignment of table cells. +type Alignment int + +const ( + // AlignLeft indicates text should be left justified. + AlignLeft Alignment = iota + 1 + + // AlignRight indicates text should be right justified. + AlignRight + + // AlignCenter indicates text should be centered. + AlignCenter + + // AlignNone indicates text should be aligned by default manner. + AlignNone +) + +func (a Alignment) String() string { + switch a { + case AlignLeft: + return "left" + case AlignRight: + return "right" + case AlignCenter: + return "center" + case AlignNone: + return "none" + } + return "" +} + +// A Table struct represents a table of Markdown(GFM) text. +type Table struct { + gast.BaseBlock + + // Alignments returns alignments of the columns. + Alignments []Alignment +} + +// Dump implements Node.Dump. +func (n *Table) Dump(source []byte, level int) { + gast.DumpHelper(n, source, level, nil, func(level int) { + indent := strings.Repeat(" ", level) + fmt.Printf("%sAlignments {\n", indent) + for i, alignment := range n.Alignments { + indent2 := strings.Repeat(" ", level+1) + fmt.Printf("%s%s", indent2, alignment.String()) + if i != len(n.Alignments)-1 { + fmt.Println("") + } + } + fmt.Printf("\n%s}\n", indent) + }) +} + +// KindTable is a NodeKind of the Table node. +var KindTable = gast.NewNodeKind("Table") + +// Kind implements Node.Kind. +func (n *Table) Kind() gast.NodeKind { + return KindTable +} + +// NewTable returns a new Table node. +func NewTable() *Table { + return &Table{ + Alignments: []Alignment{}, + } +} + +// A TableRow struct represents a table row of Markdown(GFM) text. +type TableRow struct { + gast.BaseBlock + Alignments []Alignment +} + +// Dump implements Node.Dump. +func (n *TableRow) Dump(source []byte, level int) { + gast.DumpHelper(n, source, level, nil, nil) +} + +// KindTableRow is a NodeKind of the TableRow node. +var KindTableRow = gast.NewNodeKind("TableRow") + +// Kind implements Node.Kind. +func (n *TableRow) Kind() gast.NodeKind { + return KindTableRow +} + +// NewTableRow returns a new TableRow node. +func NewTableRow(alignments []Alignment) *TableRow { + return &TableRow{Alignments: alignments} +} + +// A TableHeader struct represents a table header of Markdown(GFM) text. +type TableHeader struct { + gast.BaseBlock + Alignments []Alignment +} + +// KindTableHeader is a NodeKind of the TableHeader node. +var KindTableHeader = gast.NewNodeKind("TableHeader") + +// Kind implements Node.Kind. +func (n *TableHeader) Kind() gast.NodeKind { + return KindTableHeader +} + +// Dump implements Node.Dump. +func (n *TableHeader) Dump(source []byte, level int) { + gast.DumpHelper(n, source, level, nil, nil) +} + +// NewTableHeader returns a new TableHeader node. +func NewTableHeader(row *TableRow) *TableHeader { + n := &TableHeader{} + for c := row.FirstChild(); c != nil; { + next := c.NextSibling() + n.AppendChild(n, c) + c = next + } + return n +} + +// A TableCell struct represents a table cell of a Markdown(GFM) text. +type TableCell struct { + gast.BaseBlock + Alignment Alignment +} + +// Dump implements Node.Dump. +func (n *TableCell) Dump(source []byte, level int) { + gast.DumpHelper(n, source, level, nil, nil) +} + +// KindTableCell is a NodeKind of the TableCell node. +var KindTableCell = gast.NewNodeKind("TableCell") + +// Kind implements Node.Kind. +func (n *TableCell) Kind() gast.NodeKind { + return KindTableCell +} + +// NewTableCell returns a new TableCell node. +func NewTableCell() *TableCell { + return &TableCell{ + Alignment: AlignNone, + } +} diff --git a/vendor/github.com/yuin/goldmark/extension/ast/tasklist.go b/vendor/github.com/yuin/goldmark/extension/ast/tasklist.go new file mode 100644 index 0000000..670cc14 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/ast/tasklist.go @@ -0,0 +1,35 @@ +package ast + +import ( + "fmt" + gast "github.com/yuin/goldmark/ast" +) + +// A TaskCheckBox struct represents a checkbox of a task list. +type TaskCheckBox struct { + gast.BaseInline + IsChecked bool +} + +// Dump implements Node.Dump. +func (n *TaskCheckBox) Dump(source []byte, level int) { + m := map[string]string{ + "Checked": fmt.Sprintf("%v", n.IsChecked), + } + gast.DumpHelper(n, source, level, m, nil) +} + +// KindTaskCheckBox is a NodeKind of the TaskCheckBox node. +var KindTaskCheckBox = gast.NewNodeKind("TaskCheckBox") + +// Kind implements Node.Kind. +func (n *TaskCheckBox) Kind() gast.NodeKind { + return KindTaskCheckBox +} + +// NewTaskCheckBox returns a new TaskCheckBox node. +func NewTaskCheckBox(checked bool) *TaskCheckBox { + return &TaskCheckBox{ + IsChecked: checked, + } +} diff --git a/vendor/github.com/yuin/goldmark/extension/cjk.go b/vendor/github.com/yuin/goldmark/extension/cjk.go new file mode 100644 index 0000000..a3238c2 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/cjk.go @@ -0,0 +1,72 @@ +package extension + +import ( + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer/html" +) + +// A CJKOption sets options for CJK support mostly for HTML based renderers. +type CJKOption func(*cjk) + +// A EastAsianLineBreaks is a style of east asian line breaks. +type EastAsianLineBreaks int + +const ( + //EastAsianLineBreaksNone renders line breaks as it is. + EastAsianLineBreaksNone EastAsianLineBreaks = iota + // EastAsianLineBreaksSimple is a style where soft line breaks are ignored + // if both sides of the break are east asian wide characters. + EastAsianLineBreaksSimple + // EastAsianLineBreaksCSS3Draft is a style where soft line breaks are ignored + // even if only one side of the break is an east asian wide character. + EastAsianLineBreaksCSS3Draft +) + +// WithEastAsianLineBreaks is a functional option that indicates whether softline breaks +// between east asian wide characters should be ignored. +// style defauts to [EastAsianLineBreaksSimple] . +func WithEastAsianLineBreaks(style ...EastAsianLineBreaks) CJKOption { + return func(c *cjk) { + if len(style) == 0 { + c.EastAsianLineBreaks = EastAsianLineBreaksSimple + return + } + c.EastAsianLineBreaks = style[0] + } +} + +// WithEscapedSpace is a functional option that indicates that a '\' escaped half-space(0x20) should not be rendered. +func WithEscapedSpace() CJKOption { + return func(c *cjk) { + c.EscapedSpace = true + } +} + +type cjk struct { + EastAsianLineBreaks EastAsianLineBreaks + EscapedSpace bool +} + +// CJK is a goldmark extension that provides functionalities for CJK languages. +var CJK = NewCJK(WithEastAsianLineBreaks(), WithEscapedSpace()) + +// NewCJK returns a new extension with given options. +func NewCJK(opts ...CJKOption) goldmark.Extender { + e := &cjk{ + EastAsianLineBreaks: EastAsianLineBreaksNone, + } + for _, opt := range opts { + opt(e) + } + return e +} + +func (e *cjk) Extend(m goldmark.Markdown) { + m.Renderer().AddOptions(html.WithEastAsianLineBreaks( + html.EastAsianLineBreaks(e.EastAsianLineBreaks))) + if e.EscapedSpace { + m.Renderer().AddOptions(html.WithWriter(html.NewWriter(html.WithEscapedSpace()))) + m.Parser().AddOptions(parser.WithEscapedSpace()) + } +} diff --git a/vendor/github.com/yuin/goldmark/extension/definition_list.go b/vendor/github.com/yuin/goldmark/extension/definition_list.go new file mode 100644 index 0000000..3e64dcf --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/definition_list.go @@ -0,0 +1,274 @@ +package extension + +import ( + "github.com/yuin/goldmark" + gast "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/extension/ast" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/renderer/html" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type definitionListParser struct { +} + +var defaultDefinitionListParser = &definitionListParser{} + +// NewDefinitionListParser return a new parser.BlockParser that +// can parse PHP Markdown Extra Definition lists. +func NewDefinitionListParser() parser.BlockParser { + return defaultDefinitionListParser +} + +func (b *definitionListParser) Trigger() []byte { + return []byte{':'} +} + +func (b *definitionListParser) Open(parent gast.Node, reader text.Reader, pc parser.Context) (gast.Node, parser.State) { + if _, ok := parent.(*ast.DefinitionList); ok { + return nil, parser.NoChildren + } + line, _ := reader.PeekLine() + pos := pc.BlockOffset() + indent := pc.BlockIndent() + if pos < 0 || line[pos] != ':' || indent != 0 { + return nil, parser.NoChildren + } + + last := parent.LastChild() + // need 1 or more spaces after ':' + w, _ := util.IndentWidth(line[pos+1:], pos+1) + if w < 1 { + return nil, parser.NoChildren + } + if w >= 8 { // starts with indented code + w = 5 + } + w += pos + 1 /* 1 = ':' */ + + para, lastIsParagraph := last.(*gast.Paragraph) + var list *ast.DefinitionList + status := parser.HasChildren + var ok bool + if lastIsParagraph { + list, ok = last.PreviousSibling().(*ast.DefinitionList) + if ok { // is not first item + list.Offset = w + list.TemporaryParagraph = para + } else { // is first item + list = ast.NewDefinitionList(w, para) + status |= parser.RequireParagraph + } + } else if list, ok = last.(*ast.DefinitionList); ok { // multiple description + list.Offset = w + list.TemporaryParagraph = nil + } else { + return nil, parser.NoChildren + } + + return list, status +} + +func (b *definitionListParser) Continue(node gast.Node, reader text.Reader, pc parser.Context) parser.State { + line, _ := reader.PeekLine() + if util.IsBlank(line) { + return parser.Continue | parser.HasChildren + } + list, _ := node.(*ast.DefinitionList) + w, _ := util.IndentWidth(line, reader.LineOffset()) + if w < list.Offset { + return parser.Close + } + pos, padding := util.IndentPosition(line, reader.LineOffset(), list.Offset) + reader.AdvanceAndSetPadding(pos, padding) + return parser.Continue | parser.HasChildren +} + +func (b *definitionListParser) Close(node gast.Node, reader text.Reader, pc parser.Context) { + // nothing to do +} + +func (b *definitionListParser) CanInterruptParagraph() bool { + return true +} + +func (b *definitionListParser) CanAcceptIndentedLine() bool { + return false +} + +type definitionDescriptionParser struct { +} + +var defaultDefinitionDescriptionParser = &definitionDescriptionParser{} + +// NewDefinitionDescriptionParser return a new parser.BlockParser that +// can parse definition description starts with ':'. +func NewDefinitionDescriptionParser() parser.BlockParser { + return defaultDefinitionDescriptionParser +} + +func (b *definitionDescriptionParser) Trigger() []byte { + return []byte{':'} +} + +func (b *definitionDescriptionParser) Open( + parent gast.Node, reader text.Reader, pc parser.Context) (gast.Node, parser.State) { + line, _ := reader.PeekLine() + pos := pc.BlockOffset() + indent := pc.BlockIndent() + if pos < 0 || line[pos] != ':' || indent != 0 { + return nil, parser.NoChildren + } + list, _ := parent.(*ast.DefinitionList) + if list == nil { + return nil, parser.NoChildren + } + para := list.TemporaryParagraph + list.TemporaryParagraph = nil + if para != nil { + lines := para.Lines() + l := lines.Len() + for i := 0; i < l; i++ { + term := ast.NewDefinitionTerm() + segment := lines.At(i) + term.Lines().Append(segment.TrimRightSpace(reader.Source())) + list.AppendChild(list, term) + } + para.Parent().RemoveChild(para.Parent(), para) + } + cpos, padding := util.IndentPosition(line[pos+1:], pos+1, list.Offset-pos-1) + reader.AdvanceAndSetPadding(cpos+1, padding) + + return ast.NewDefinitionDescription(), parser.HasChildren +} + +func (b *definitionDescriptionParser) Continue(node gast.Node, reader text.Reader, pc parser.Context) parser.State { + // definitionListParser detects end of the description. + // so this method will never be called. + return parser.Continue | parser.HasChildren +} + +func (b *definitionDescriptionParser) Close(node gast.Node, reader text.Reader, pc parser.Context) { + desc := node.(*ast.DefinitionDescription) + desc.IsTight = !desc.HasBlankPreviousLines() + if desc.IsTight { + for gc := desc.FirstChild(); gc != nil; gc = gc.NextSibling() { + paragraph, ok := gc.(*gast.Paragraph) + if ok { + textBlock := gast.NewTextBlock() + textBlock.SetLines(paragraph.Lines()) + desc.ReplaceChild(desc, paragraph, textBlock) + } + } + } +} + +func (b *definitionDescriptionParser) CanInterruptParagraph() bool { + return true +} + +func (b *definitionDescriptionParser) CanAcceptIndentedLine() bool { + return false +} + +// DefinitionListHTMLRenderer is a renderer.NodeRenderer implementation that +// renders DefinitionList nodes. +type DefinitionListHTMLRenderer struct { + html.Config +} + +// NewDefinitionListHTMLRenderer returns a new DefinitionListHTMLRenderer. +func NewDefinitionListHTMLRenderer(opts ...html.Option) renderer.NodeRenderer { + r := &DefinitionListHTMLRenderer{ + Config: html.NewConfig(), + } + for _, opt := range opts { + opt.SetHTMLOption(&r.Config) + } + return r +} + +// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs. +func (r *DefinitionListHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { + reg.Register(ast.KindDefinitionList, r.renderDefinitionList) + reg.Register(ast.KindDefinitionTerm, r.renderDefinitionTerm) + reg.Register(ast.KindDefinitionDescription, r.renderDefinitionDescription) +} + +// DefinitionListAttributeFilter defines attribute names which dl elements can have. +var DefinitionListAttributeFilter = html.GlobalAttributeFilter + +func (r *DefinitionListHTMLRenderer) renderDefinitionList( + w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) { + if entering { + if n.Attributes() != nil { + _, _ = w.WriteString("\n") + } else { + _, _ = w.WriteString("
\n") + } + } else { + _, _ = w.WriteString("
\n") + } + return gast.WalkContinue, nil +} + +// DefinitionTermAttributeFilter defines attribute names which dd elements can have. +var DefinitionTermAttributeFilter = html.GlobalAttributeFilter + +func (r *DefinitionListHTMLRenderer) renderDefinitionTerm( + w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) { + if entering { + if n.Attributes() != nil { + _, _ = w.WriteString("') + } else { + _, _ = w.WriteString("
") + } + } else { + _, _ = w.WriteString("
\n") + } + return gast.WalkContinue, nil +} + +// DefinitionDescriptionAttributeFilter defines attribute names which dd elements can have. +var DefinitionDescriptionAttributeFilter = html.GlobalAttributeFilter + +func (r *DefinitionListHTMLRenderer) renderDefinitionDescription( + w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { + if entering { + n := node.(*ast.DefinitionDescription) + _, _ = w.WriteString("") + } else { + _, _ = w.WriteString(">\n") + } + } else { + _, _ = w.WriteString("\n") + } + return gast.WalkContinue, nil +} + +type definitionList struct { +} + +// DefinitionList is an extension that allow you to use PHP Markdown Extra Definition lists. +var DefinitionList = &definitionList{} + +func (e *definitionList) Extend(m goldmark.Markdown) { + m.Parser().AddOptions(parser.WithBlockParsers( + util.Prioritized(NewDefinitionListParser(), 101), + util.Prioritized(NewDefinitionDescriptionParser(), 102), + )) + m.Renderer().AddOptions(renderer.WithNodeRenderers( + util.Prioritized(NewDefinitionListHTMLRenderer(), 500), + )) +} diff --git a/vendor/github.com/yuin/goldmark/extension/footnote.go b/vendor/github.com/yuin/goldmark/extension/footnote.go new file mode 100644 index 0000000..d1b67aa --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/footnote.go @@ -0,0 +1,691 @@ +package extension + +import ( + "bytes" + "fmt" + "strconv" + + "github.com/yuin/goldmark" + gast "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/extension/ast" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/renderer/html" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +var footnoteListKey = parser.NewContextKey() +var footnoteLinkListKey = parser.NewContextKey() + +type footnoteBlockParser struct { +} + +var defaultFootnoteBlockParser = &footnoteBlockParser{} + +// NewFootnoteBlockParser returns a new parser.BlockParser that can parse +// footnotes of the Markdown(PHP Markdown Extra) text. +func NewFootnoteBlockParser() parser.BlockParser { + return defaultFootnoteBlockParser +} + +func (b *footnoteBlockParser) Trigger() []byte { + return []byte{'['} +} + +func (b *footnoteBlockParser) Open(parent gast.Node, reader text.Reader, pc parser.Context) (gast.Node, parser.State) { + line, segment := reader.PeekLine() + pos := pc.BlockOffset() + if pos < 0 || line[pos] != '[' { + return nil, parser.NoChildren + } + pos++ + if pos > len(line)-1 || line[pos] != '^' { + return nil, parser.NoChildren + } + open := pos + 1 + var closes int + closure := util.FindClosure(line[pos+1:], '[', ']', false, false) //nolint:staticcheck + closes = pos + 1 + closure + next := closes + 1 + if closure > -1 { + if next >= len(line) || line[next] != ':' { + return nil, parser.NoChildren + } + } else { + return nil, parser.NoChildren + } + padding := segment.Padding + label := reader.Value(text.NewSegment(segment.Start+open-padding, segment.Start+closes-padding)) + if util.IsBlank(label) { + return nil, parser.NoChildren + } + item := ast.NewFootnote(label) + + pos = next + 1 - padding + if pos >= len(line) { + reader.Advance(pos) + return item, parser.NoChildren + } + reader.AdvanceAndSetPadding(pos, padding) + return item, parser.HasChildren +} + +func (b *footnoteBlockParser) Continue(node gast.Node, reader text.Reader, pc parser.Context) parser.State { + line, _ := reader.PeekLine() + if util.IsBlank(line) { + return parser.Continue | parser.HasChildren + } + childpos, padding := util.IndentPosition(line, reader.LineOffset(), 4) + if childpos < 0 { + return parser.Close + } + reader.AdvanceAndSetPadding(childpos, padding) + return parser.Continue | parser.HasChildren +} + +func (b *footnoteBlockParser) Close(node gast.Node, reader text.Reader, pc parser.Context) { + var list *ast.FootnoteList + if tlist := pc.Get(footnoteListKey); tlist != nil { + list = tlist.(*ast.FootnoteList) + } else { + list = ast.NewFootnoteList() + pc.Set(footnoteListKey, list) + node.Parent().InsertBefore(node.Parent(), node, list) + } + node.Parent().RemoveChild(node.Parent(), node) + list.AppendChild(list, node) +} + +func (b *footnoteBlockParser) CanInterruptParagraph() bool { + return true +} + +func (b *footnoteBlockParser) CanAcceptIndentedLine() bool { + return false +} + +type footnoteParser struct { +} + +var defaultFootnoteParser = &footnoteParser{} + +// NewFootnoteParser returns a new parser.InlineParser that can parse +// footnote links of the Markdown(PHP Markdown Extra) text. +func NewFootnoteParser() parser.InlineParser { + return defaultFootnoteParser +} + +func (s *footnoteParser) Trigger() []byte { + // footnote syntax probably conflict with the image syntax. + // So we need trigger this parser with '!'. + return []byte{'!', '['} +} + +func (s *footnoteParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node { + line, segment := block.PeekLine() + pos := 1 + if len(line) > 0 && line[0] == '!' { + pos++ + } + if pos >= len(line) || line[pos] != '^' { + return nil + } + pos++ + if pos >= len(line) { + return nil + } + open := pos + closure := util.FindClosure(line[pos:], '[', ']', false, false) //nolint:staticcheck + if closure < 0 { + return nil + } + closes := pos + closure + value := block.Value(text.NewSegment(segment.Start+open, segment.Start+closes)) + block.Advance(closes + 1) + + var list *ast.FootnoteList + if tlist := pc.Get(footnoteListKey); tlist != nil { + list = tlist.(*ast.FootnoteList) + } + if list == nil { + return nil + } + index := 0 + for def := list.FirstChild(); def != nil; def = def.NextSibling() { + d := def.(*ast.Footnote) + if bytes.Equal(d.Ref, value) { + if d.Index < 0 { + list.Count++ + d.Index = list.Count + } + index = d.Index + break + } + } + if index == 0 { + return nil + } + + fnlink := ast.NewFootnoteLink(index) + var fnlist []*ast.FootnoteLink + if tmp := pc.Get(footnoteLinkListKey); tmp != nil { + fnlist = tmp.([]*ast.FootnoteLink) + } else { + fnlist = []*ast.FootnoteLink{} + pc.Set(footnoteLinkListKey, fnlist) + } + pc.Set(footnoteLinkListKey, append(fnlist, fnlink)) + if line[0] == '!' { + parent.AppendChild(parent, gast.NewTextSegment(text.NewSegment(segment.Start, segment.Start+1))) + } + + return fnlink +} + +type footnoteASTTransformer struct { +} + +var defaultFootnoteASTTransformer = &footnoteASTTransformer{} + +// NewFootnoteASTTransformer returns a new parser.ASTTransformer that +// insert a footnote list to the last of the document. +func NewFootnoteASTTransformer() parser.ASTTransformer { + return defaultFootnoteASTTransformer +} + +func (a *footnoteASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) { + var list *ast.FootnoteList + var fnlist []*ast.FootnoteLink + if tmp := pc.Get(footnoteListKey); tmp != nil { + list = tmp.(*ast.FootnoteList) + } + if tmp := pc.Get(footnoteLinkListKey); tmp != nil { + fnlist = tmp.([]*ast.FootnoteLink) + } + + pc.Set(footnoteListKey, nil) + pc.Set(footnoteLinkListKey, nil) + + if list == nil { + return + } + + counter := map[int]int{} + if fnlist != nil { + for _, fnlink := range fnlist { + if fnlink.Index >= 0 { + counter[fnlink.Index]++ + } + } + refCounter := map[int]int{} + for _, fnlink := range fnlist { + fnlink.RefCount = counter[fnlink.Index] + if _, ok := refCounter[fnlink.Index]; !ok { + refCounter[fnlink.Index] = 0 + } + fnlink.RefIndex = refCounter[fnlink.Index] + refCounter[fnlink.Index]++ + } + } + for footnote := list.FirstChild(); footnote != nil; { + var container gast.Node = footnote + next := footnote.NextSibling() + if fc := container.LastChild(); fc != nil && gast.IsParagraph(fc) { + container = fc + } + fn := footnote.(*ast.Footnote) + index := fn.Index + if index < 0 { + list.RemoveChild(list, footnote) + } else { + refCount := counter[index] + backLink := ast.NewFootnoteBacklink(index) + backLink.RefCount = refCount + backLink.RefIndex = 0 + container.AppendChild(container, backLink) + if refCount > 1 { + for i := 1; i < refCount; i++ { + backLink := ast.NewFootnoteBacklink(index) + backLink.RefCount = refCount + backLink.RefIndex = i + container.AppendChild(container, backLink) + } + } + } + footnote = next + } + list.SortChildren(func(n1, n2 gast.Node) int { + if n1.(*ast.Footnote).Index < n2.(*ast.Footnote).Index { + return -1 + } + return 1 + }) + if list.Count <= 0 { + list.Parent().RemoveChild(list.Parent(), list) + return + } + + node.AppendChild(node, list) +} + +// FootnoteConfig holds configuration values for the footnote extension. +// +// Link* and Backlink* configurations have some variables: +// Occurrences of “^^” in the string will be replaced by the +// corresponding footnote number in the HTML output. +// Occurrences of “%%” will be replaced by a number for the +// reference (footnotes can have multiple references). +type FootnoteConfig struct { + html.Config + + // IDPrefix is a prefix for the id attributes generated by footnotes. + IDPrefix []byte + + // IDPrefix is a function that determines the id attribute for given Node. + IDPrefixFunction func(gast.Node) []byte + + // LinkTitle is an optional title attribute for footnote links. + LinkTitle []byte + + // BacklinkTitle is an optional title attribute for footnote backlinks. + BacklinkTitle []byte + + // LinkClass is a class for footnote links. + LinkClass []byte + + // BacklinkClass is a class for footnote backlinks. + BacklinkClass []byte + + // BacklinkHTML is an HTML content for footnote backlinks. + BacklinkHTML []byte +} + +// FootnoteOption interface is a functional option interface for the extension. +type FootnoteOption interface { + renderer.Option + // SetFootnoteOption sets given option to the extension. + SetFootnoteOption(*FootnoteConfig) +} + +// NewFootnoteConfig returns a new Config with defaults. +func NewFootnoteConfig() FootnoteConfig { + return FootnoteConfig{ + Config: html.NewConfig(), + LinkTitle: []byte(""), + BacklinkTitle: []byte(""), + LinkClass: []byte("footnote-ref"), + BacklinkClass: []byte("footnote-backref"), + BacklinkHTML: []byte("↩︎"), + } +} + +// SetOption implements renderer.SetOptioner. +func (c *FootnoteConfig) SetOption(name renderer.OptionName, value interface{}) { + switch name { + case optFootnoteIDPrefixFunction: + c.IDPrefixFunction = value.(func(gast.Node) []byte) + case optFootnoteIDPrefix: + c.IDPrefix = value.([]byte) + case optFootnoteLinkTitle: + c.LinkTitle = value.([]byte) + case optFootnoteBacklinkTitle: + c.BacklinkTitle = value.([]byte) + case optFootnoteLinkClass: + c.LinkClass = value.([]byte) + case optFootnoteBacklinkClass: + c.BacklinkClass = value.([]byte) + case optFootnoteBacklinkHTML: + c.BacklinkHTML = value.([]byte) + default: + c.Config.SetOption(name, value) + } +} + +type withFootnoteHTMLOptions struct { + value []html.Option +} + +func (o *withFootnoteHTMLOptions) SetConfig(c *renderer.Config) { + if o.value != nil { + for _, v := range o.value { + v.(renderer.Option).SetConfig(c) + } + } +} + +func (o *withFootnoteHTMLOptions) SetFootnoteOption(c *FootnoteConfig) { + if o.value != nil { + for _, v := range o.value { + v.SetHTMLOption(&c.Config) + } + } +} + +// WithFootnoteHTMLOptions is functional option that wraps goldmark HTMLRenderer options. +func WithFootnoteHTMLOptions(opts ...html.Option) FootnoteOption { + return &withFootnoteHTMLOptions{opts} +} + +const optFootnoteIDPrefix renderer.OptionName = "FootnoteIDPrefix" + +type withFootnoteIDPrefix struct { + value []byte +} + +func (o *withFootnoteIDPrefix) SetConfig(c *renderer.Config) { + c.Options[optFootnoteIDPrefix] = o.value +} + +func (o *withFootnoteIDPrefix) SetFootnoteOption(c *FootnoteConfig) { + c.IDPrefix = o.value +} + +// WithFootnoteIDPrefix is a functional option that is a prefix for the id attributes generated by footnotes. +func WithFootnoteIDPrefix(a []byte) FootnoteOption { + return &withFootnoteIDPrefix{a} +} + +const optFootnoteIDPrefixFunction renderer.OptionName = "FootnoteIDPrefixFunction" + +type withFootnoteIDPrefixFunction struct { + value func(gast.Node) []byte +} + +func (o *withFootnoteIDPrefixFunction) SetConfig(c *renderer.Config) { + c.Options[optFootnoteIDPrefixFunction] = o.value +} + +func (o *withFootnoteIDPrefixFunction) SetFootnoteOption(c *FootnoteConfig) { + c.IDPrefixFunction = o.value +} + +// WithFootnoteIDPrefixFunction is a functional option that is a prefix for the id attributes generated by footnotes. +func WithFootnoteIDPrefixFunction(a func(gast.Node) []byte) FootnoteOption { + return &withFootnoteIDPrefixFunction{a} +} + +const optFootnoteLinkTitle renderer.OptionName = "FootnoteLinkTitle" + +type withFootnoteLinkTitle struct { + value []byte +} + +func (o *withFootnoteLinkTitle) SetConfig(c *renderer.Config) { + c.Options[optFootnoteLinkTitle] = o.value +} + +func (o *withFootnoteLinkTitle) SetFootnoteOption(c *FootnoteConfig) { + c.LinkTitle = o.value +} + +// WithFootnoteLinkTitle is a functional option that is an optional title attribute for footnote links. +func WithFootnoteLinkTitle(a []byte) FootnoteOption { + return &withFootnoteLinkTitle{a} +} + +const optFootnoteBacklinkTitle renderer.OptionName = "FootnoteBacklinkTitle" + +type withFootnoteBacklinkTitle struct { + value []byte +} + +func (o *withFootnoteBacklinkTitle) SetConfig(c *renderer.Config) { + c.Options[optFootnoteBacklinkTitle] = o.value +} + +func (o *withFootnoteBacklinkTitle) SetFootnoteOption(c *FootnoteConfig) { + c.BacklinkTitle = o.value +} + +// WithFootnoteBacklinkTitle is a functional option that is an optional title attribute for footnote backlinks. +func WithFootnoteBacklinkTitle(a []byte) FootnoteOption { + return &withFootnoteBacklinkTitle{a} +} + +const optFootnoteLinkClass renderer.OptionName = "FootnoteLinkClass" + +type withFootnoteLinkClass struct { + value []byte +} + +func (o *withFootnoteLinkClass) SetConfig(c *renderer.Config) { + c.Options[optFootnoteLinkClass] = o.value +} + +func (o *withFootnoteLinkClass) SetFootnoteOption(c *FootnoteConfig) { + c.LinkClass = o.value +} + +// WithFootnoteLinkClass is a functional option that is a class for footnote links. +func WithFootnoteLinkClass(a []byte) FootnoteOption { + return &withFootnoteLinkClass{a} +} + +const optFootnoteBacklinkClass renderer.OptionName = "FootnoteBacklinkClass" + +type withFootnoteBacklinkClass struct { + value []byte +} + +func (o *withFootnoteBacklinkClass) SetConfig(c *renderer.Config) { + c.Options[optFootnoteBacklinkClass] = o.value +} + +func (o *withFootnoteBacklinkClass) SetFootnoteOption(c *FootnoteConfig) { + c.BacklinkClass = o.value +} + +// WithFootnoteBacklinkClass is a functional option that is a class for footnote backlinks. +func WithFootnoteBacklinkClass(a []byte) FootnoteOption { + return &withFootnoteBacklinkClass{a} +} + +const optFootnoteBacklinkHTML renderer.OptionName = "FootnoteBacklinkHTML" + +type withFootnoteBacklinkHTML struct { + value []byte +} + +func (o *withFootnoteBacklinkHTML) SetConfig(c *renderer.Config) { + c.Options[optFootnoteBacklinkHTML] = o.value +} + +func (o *withFootnoteBacklinkHTML) SetFootnoteOption(c *FootnoteConfig) { + c.BacklinkHTML = o.value +} + +// WithFootnoteBacklinkHTML is an HTML content for footnote backlinks. +func WithFootnoteBacklinkHTML(a []byte) FootnoteOption { + return &withFootnoteBacklinkHTML{a} +} + +// FootnoteHTMLRenderer is a renderer.NodeRenderer implementation that +// renders FootnoteLink nodes. +type FootnoteHTMLRenderer struct { + FootnoteConfig +} + +// NewFootnoteHTMLRenderer returns a new FootnoteHTMLRenderer. +func NewFootnoteHTMLRenderer(opts ...FootnoteOption) renderer.NodeRenderer { + r := &FootnoteHTMLRenderer{ + FootnoteConfig: NewFootnoteConfig(), + } + for _, opt := range opts { + opt.SetFootnoteOption(&r.FootnoteConfig) + } + return r +} + +// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs. +func (r *FootnoteHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { + reg.Register(ast.KindFootnoteLink, r.renderFootnoteLink) + reg.Register(ast.KindFootnoteBacklink, r.renderFootnoteBacklink) + reg.Register(ast.KindFootnote, r.renderFootnote) + reg.Register(ast.KindFootnoteList, r.renderFootnoteList) +} + +func (r *FootnoteHTMLRenderer) renderFootnoteLink( + w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { + if entering { + n := node.(*ast.FootnoteLink) + is := strconv.Itoa(n.Index) + _, _ = w.WriteString(``) + + _, _ = w.WriteString(is) + _, _ = w.WriteString(``) + } + return gast.WalkContinue, nil +} + +func (r *FootnoteHTMLRenderer) renderFootnoteBacklink( + w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { + if entering { + n := node.(*ast.FootnoteBacklink) + is := strconv.Itoa(n.Index) + _, _ = w.WriteString(` `) + _, _ = w.Write(applyFootnoteTemplate(r.FootnoteConfig.BacklinkHTML, n.Index, n.RefCount)) + _, _ = w.WriteString(``) + } + return gast.WalkContinue, nil +} + +func (r *FootnoteHTMLRenderer) renderFootnote( + w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { + n := node.(*ast.Footnote) + is := strconv.Itoa(n.Index) + if entering { + _, _ = w.WriteString(`
  • \n") + } else { + _, _ = w.WriteString("
  • \n") + } + return gast.WalkContinue, nil +} + +func (r *FootnoteHTMLRenderer) renderFootnoteList( + w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { + if entering { + _, _ = w.WriteString(`
    ') + if r.Config.XHTML { + _, _ = w.WriteString("\n
    \n") + } else { + _, _ = w.WriteString("\n
    \n") + } + _, _ = w.WriteString("
      \n") + } else { + _, _ = w.WriteString("
    \n") + _, _ = w.WriteString("
    \n") + } + return gast.WalkContinue, nil +} + +func (r *FootnoteHTMLRenderer) idPrefix(node gast.Node) []byte { + if r.FootnoteConfig.IDPrefix != nil { + return r.FootnoteConfig.IDPrefix + } + if r.FootnoteConfig.IDPrefixFunction != nil { + return r.FootnoteConfig.IDPrefixFunction(node) + } + return []byte("") +} + +func applyFootnoteTemplate(b []byte, index, refCount int) []byte { + fast := true + for i, c := range b { + if i != 0 { + if b[i-1] == '^' && c == '^' { + fast = false + break + } + if b[i-1] == '%' && c == '%' { + fast = false + break + } + } + } + if fast { + return b + } + is := []byte(strconv.Itoa(index)) + rs := []byte(strconv.Itoa(refCount)) + ret := bytes.Replace(b, []byte("^^"), is, -1) + return bytes.Replace(ret, []byte("%%"), rs, -1) +} + +type footnote struct { + options []FootnoteOption +} + +// Footnote is an extension that allow you to use PHP Markdown Extra Footnotes. +var Footnote = &footnote{ + options: []FootnoteOption{}, +} + +// NewFootnote returns a new extension with given options. +func NewFootnote(opts ...FootnoteOption) goldmark.Extender { + return &footnote{ + options: opts, + } +} + +func (e *footnote) Extend(m goldmark.Markdown) { + m.Parser().AddOptions( + parser.WithBlockParsers( + util.Prioritized(NewFootnoteBlockParser(), 999), + ), + parser.WithInlineParsers( + util.Prioritized(NewFootnoteParser(), 101), + ), + parser.WithASTTransformers( + util.Prioritized(NewFootnoteASTTransformer(), 999), + ), + ) + m.Renderer().AddOptions(renderer.WithNodeRenderers( + util.Prioritized(NewFootnoteHTMLRenderer(e.options...), 500), + )) +} diff --git a/vendor/github.com/yuin/goldmark/extension/gfm.go b/vendor/github.com/yuin/goldmark/extension/gfm.go new file mode 100644 index 0000000..a570fbd --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/gfm.go @@ -0,0 +1,18 @@ +package extension + +import ( + "github.com/yuin/goldmark" +) + +type gfm struct { +} + +// GFM is an extension that provides Github Flavored markdown functionalities. +var GFM = &gfm{} + +func (e *gfm) Extend(m goldmark.Markdown) { + Linkify.Extend(m) + Table.Extend(m) + Strikethrough.Extend(m) + TaskList.Extend(m) +} diff --git a/vendor/github.com/yuin/goldmark/extension/linkify.go b/vendor/github.com/yuin/goldmark/extension/linkify.go new file mode 100644 index 0000000..0f23e90 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/linkify.go @@ -0,0 +1,320 @@ +package extension + +import ( + "bytes" + "regexp" + + "github.com/yuin/goldmark" + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +var wwwURLRegxp = regexp.MustCompile(`^www\.[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]+(?:[/#?][-a-zA-Z0-9@:%_\+.~#!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) //nolint:golint,lll + +var urlRegexp = regexp.MustCompile(`^(?:http|https|ftp)://[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-z]+(?::\d+)?(?:[/#?][-a-zA-Z0-9@:%_+.~#$!?&/=\(\);,'">\^{}\[\]` + "`" + `]*)?`) //nolint:golint,lll + +// An LinkifyConfig struct is a data structure that holds configuration of the +// Linkify extension. +type LinkifyConfig struct { + AllowedProtocols [][]byte + URLRegexp *regexp.Regexp + WWWRegexp *regexp.Regexp + EmailRegexp *regexp.Regexp +} + +const ( + optLinkifyAllowedProtocols parser.OptionName = "LinkifyAllowedProtocols" + optLinkifyURLRegexp parser.OptionName = "LinkifyURLRegexp" + optLinkifyWWWRegexp parser.OptionName = "LinkifyWWWRegexp" + optLinkifyEmailRegexp parser.OptionName = "LinkifyEmailRegexp" +) + +// SetOption implements SetOptioner. +func (c *LinkifyConfig) SetOption(name parser.OptionName, value interface{}) { + switch name { + case optLinkifyAllowedProtocols: + c.AllowedProtocols = value.([][]byte) + case optLinkifyURLRegexp: + c.URLRegexp = value.(*regexp.Regexp) + case optLinkifyWWWRegexp: + c.WWWRegexp = value.(*regexp.Regexp) + case optLinkifyEmailRegexp: + c.EmailRegexp = value.(*regexp.Regexp) + } +} + +// A LinkifyOption interface sets options for the LinkifyOption. +type LinkifyOption interface { + parser.Option + SetLinkifyOption(*LinkifyConfig) +} + +type withLinkifyAllowedProtocols struct { + value [][]byte +} + +func (o *withLinkifyAllowedProtocols) SetParserOption(c *parser.Config) { + c.Options[optLinkifyAllowedProtocols] = o.value +} + +func (o *withLinkifyAllowedProtocols) SetLinkifyOption(p *LinkifyConfig) { + p.AllowedProtocols = o.value +} + +// WithLinkifyAllowedProtocols is a functional option that specify allowed +// protocols in autolinks. Each protocol must end with ':' like +// 'http:' . +func WithLinkifyAllowedProtocols(value [][]byte) LinkifyOption { + return &withLinkifyAllowedProtocols{ + value: value, + } +} + +type withLinkifyURLRegexp struct { + value *regexp.Regexp +} + +func (o *withLinkifyURLRegexp) SetParserOption(c *parser.Config) { + c.Options[optLinkifyURLRegexp] = o.value +} + +func (o *withLinkifyURLRegexp) SetLinkifyOption(p *LinkifyConfig) { + p.URLRegexp = o.value +} + +// WithLinkifyURLRegexp is a functional option that specify +// a pattern of the URL including a protocol. +func WithLinkifyURLRegexp(value *regexp.Regexp) LinkifyOption { + return &withLinkifyURLRegexp{ + value: value, + } +} + +type withLinkifyWWWRegexp struct { + value *regexp.Regexp +} + +func (o *withLinkifyWWWRegexp) SetParserOption(c *parser.Config) { + c.Options[optLinkifyWWWRegexp] = o.value +} + +func (o *withLinkifyWWWRegexp) SetLinkifyOption(p *LinkifyConfig) { + p.WWWRegexp = o.value +} + +// WithLinkifyWWWRegexp is a functional option that specify +// a pattern of the URL without a protocol. +// This pattern must start with 'www.' . +func WithLinkifyWWWRegexp(value *regexp.Regexp) LinkifyOption { + return &withLinkifyWWWRegexp{ + value: value, + } +} + +type withLinkifyEmailRegexp struct { + value *regexp.Regexp +} + +func (o *withLinkifyEmailRegexp) SetParserOption(c *parser.Config) { + c.Options[optLinkifyEmailRegexp] = o.value +} + +func (o *withLinkifyEmailRegexp) SetLinkifyOption(p *LinkifyConfig) { + p.EmailRegexp = o.value +} + +// WithLinkifyEmailRegexp is a functional otpion that specify +// a pattern of the email address. +func WithLinkifyEmailRegexp(value *regexp.Regexp) LinkifyOption { + return &withLinkifyEmailRegexp{ + value: value, + } +} + +type linkifyParser struct { + LinkifyConfig +} + +// NewLinkifyParser return a new InlineParser can parse +// text that seems like a URL. +func NewLinkifyParser(opts ...LinkifyOption) parser.InlineParser { + p := &linkifyParser{ + LinkifyConfig: LinkifyConfig{ + AllowedProtocols: nil, + URLRegexp: urlRegexp, + WWWRegexp: wwwURLRegxp, + }, + } + for _, o := range opts { + o.SetLinkifyOption(&p.LinkifyConfig) + } + return p +} + +func (s *linkifyParser) Trigger() []byte { + // ' ' indicates any white spaces and a line head + return []byte{' ', '*', '_', '~', '('} +} + +var ( + protoHTTP = []byte("http:") + protoHTTPS = []byte("https:") + protoFTP = []byte("ftp:") + domainWWW = []byte("www.") +) + +func (s *linkifyParser) Parse(parent ast.Node, block text.Reader, pc parser.Context) ast.Node { + if pc.IsInLinkLabel() { + return nil + } + line, segment := block.PeekLine() + consumes := 0 + start := segment.Start + c := line[0] + // advance if current position is not a line head. + if c == ' ' || c == '*' || c == '_' || c == '~' || c == '(' { + consumes++ + start++ + line = line[1:] + } + + var m []int + var protocol []byte + var typ ast.AutoLinkType = ast.AutoLinkURL + if s.LinkifyConfig.AllowedProtocols == nil { + if bytes.HasPrefix(line, protoHTTP) || bytes.HasPrefix(line, protoHTTPS) || bytes.HasPrefix(line, protoFTP) { + m = s.LinkifyConfig.URLRegexp.FindSubmatchIndex(line) + } + } else { + for _, prefix := range s.LinkifyConfig.AllowedProtocols { + if bytes.HasPrefix(line, prefix) { + m = s.LinkifyConfig.URLRegexp.FindSubmatchIndex(line) + break + } + } + } + if m == nil && bytes.HasPrefix(line, domainWWW) { + m = s.LinkifyConfig.WWWRegexp.FindSubmatchIndex(line) + protocol = []byte("http") + } + if m != nil && m[0] != 0 { + m = nil + } + if m != nil && m[0] == 0 { + lastChar := line[m[1]-1] + if lastChar == '.' { + m[1]-- + } else if lastChar == ')' { + closing := 0 + for i := m[1] - 1; i >= m[0]; i-- { + if line[i] == ')' { + closing++ + } else if line[i] == '(' { + closing-- + } + } + if closing > 0 { + m[1] -= closing + } + } else if lastChar == ';' { + i := m[1] - 2 + for ; i >= m[0]; i-- { + if util.IsAlphaNumeric(line[i]) { + continue + } + break + } + if i != m[1]-2 { + if line[i] == '&' { + m[1] -= m[1] - i + } + } + } + } + if m == nil { + if len(line) > 0 && util.IsPunct(line[0]) { + return nil + } + typ = ast.AutoLinkEmail + stop := -1 + if s.LinkifyConfig.EmailRegexp == nil { + stop = util.FindEmailIndex(line) + } else { + m := s.LinkifyConfig.EmailRegexp.FindSubmatchIndex(line) + if m != nil && m[0] == 0 { + stop = m[1] + } + } + if stop < 0 { + return nil + } + at := bytes.IndexByte(line, '@') + m = []int{0, stop, at, stop - 1} + if m == nil || bytes.IndexByte(line[m[2]:m[3]], '.') < 0 { + return nil + } + lastChar := line[m[1]-1] + if lastChar == '.' { + m[1]-- + } + if m[1] < len(line) { + nextChar := line[m[1]] + if nextChar == '-' || nextChar == '_' { + return nil + } + } + } + if m == nil { + return nil + } + if consumes != 0 { + s := segment.WithStop(segment.Start + 1) + ast.MergeOrAppendTextSegment(parent, s) + } + i := m[1] - 1 + for ; i > 0; i-- { + c := line[i] + switch c { + case '?', '!', '.', ',', ':', '*', '_', '~': + default: + goto endfor + } + } +endfor: + i++ + consumes += i + block.Advance(consumes) + n := ast.NewTextSegment(text.NewSegment(start, start+i)) + link := ast.NewAutoLink(typ, n) + link.Protocol = protocol + return link +} + +func (s *linkifyParser) CloseBlock(parent ast.Node, pc parser.Context) { + // nothing to do +} + +type linkify struct { + options []LinkifyOption +} + +// Linkify is an extension that allow you to parse text that seems like a URL. +var Linkify = &linkify{} + +// NewLinkify creates a new [goldmark.Extender] that +// allow you to parse text that seems like a URL. +func NewLinkify(opts ...LinkifyOption) goldmark.Extender { + return &linkify{ + options: opts, + } +} + +func (e *linkify) Extend(m goldmark.Markdown) { + m.Parser().AddOptions( + parser.WithInlineParsers( + util.Prioritized(NewLinkifyParser(e.options...), 999), + ), + ) +} diff --git a/vendor/github.com/yuin/goldmark/extension/package.go b/vendor/github.com/yuin/goldmark/extension/package.go new file mode 100644 index 0000000..2ec1d1e --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/package.go @@ -0,0 +1,2 @@ +// Package extension is a collection of builtin extensions. +package extension diff --git a/vendor/github.com/yuin/goldmark/extension/strikethrough.go b/vendor/github.com/yuin/goldmark/extension/strikethrough.go new file mode 100644 index 0000000..7d13569 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/strikethrough.go @@ -0,0 +1,117 @@ +package extension + +import ( + "github.com/yuin/goldmark" + gast "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/extension/ast" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/renderer/html" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type strikethroughDelimiterProcessor struct { +} + +func (p *strikethroughDelimiterProcessor) IsDelimiter(b byte) bool { + return b == '~' +} + +func (p *strikethroughDelimiterProcessor) CanOpenCloser(opener, closer *parser.Delimiter) bool { + return opener.Char == closer.Char +} + +func (p *strikethroughDelimiterProcessor) OnMatch(consumes int) gast.Node { + return ast.NewStrikethrough() +} + +var defaultStrikethroughDelimiterProcessor = &strikethroughDelimiterProcessor{} + +type strikethroughParser struct { +} + +var defaultStrikethroughParser = &strikethroughParser{} + +// NewStrikethroughParser return a new InlineParser that parses +// strikethrough expressions. +func NewStrikethroughParser() parser.InlineParser { + return defaultStrikethroughParser +} + +func (s *strikethroughParser) Trigger() []byte { + return []byte{'~'} +} + +func (s *strikethroughParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node { + before := block.PrecendingCharacter() + line, segment := block.PeekLine() + node := parser.ScanDelimiter(line, before, 2, defaultStrikethroughDelimiterProcessor) + if node == nil { + return nil + } + node.Segment = segment.WithStop(segment.Start + node.OriginalLength) + block.Advance(node.OriginalLength) + pc.PushDelimiter(node) + return node +} + +func (s *strikethroughParser) CloseBlock(parent gast.Node, pc parser.Context) { + // nothing to do +} + +// StrikethroughHTMLRenderer is a renderer.NodeRenderer implementation that +// renders Strikethrough nodes. +type StrikethroughHTMLRenderer struct { + html.Config +} + +// NewStrikethroughHTMLRenderer returns a new StrikethroughHTMLRenderer. +func NewStrikethroughHTMLRenderer(opts ...html.Option) renderer.NodeRenderer { + r := &StrikethroughHTMLRenderer{ + Config: html.NewConfig(), + } + for _, opt := range opts { + opt.SetHTMLOption(&r.Config) + } + return r +} + +// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs. +func (r *StrikethroughHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { + reg.Register(ast.KindStrikethrough, r.renderStrikethrough) +} + +// StrikethroughAttributeFilter defines attribute names which dd elements can have. +var StrikethroughAttributeFilter = html.GlobalAttributeFilter + +func (r *StrikethroughHTMLRenderer) renderStrikethrough( + w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) { + if entering { + if n.Attributes() != nil { + _, _ = w.WriteString("') + } else { + _, _ = w.WriteString("") + } + } else { + _, _ = w.WriteString("") + } + return gast.WalkContinue, nil +} + +type strikethrough struct { +} + +// Strikethrough is an extension that allow you to use strikethrough expression like '~~text~~' . +var Strikethrough = &strikethrough{} + +func (e *strikethrough) Extend(m goldmark.Markdown) { + m.Parser().AddOptions(parser.WithInlineParsers( + util.Prioritized(NewStrikethroughParser(), 500), + )) + m.Renderer().AddOptions(renderer.WithNodeRenderers( + util.Prioritized(NewStrikethroughHTMLRenderer(), 500), + )) +} diff --git a/vendor/github.com/yuin/goldmark/extension/table.go b/vendor/github.com/yuin/goldmark/extension/table.go new file mode 100644 index 0000000..2fe7a51 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/table.go @@ -0,0 +1,564 @@ +package extension + +import ( + "bytes" + "fmt" + "regexp" + + "github.com/yuin/goldmark" + gast "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/extension/ast" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/renderer/html" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +var escapedPipeCellListKey = parser.NewContextKey() + +type escapedPipeCell struct { + Cell *ast.TableCell + Pos []int + Transformed bool +} + +// TableCellAlignMethod indicates how are table cells aligned in HTML format. +type TableCellAlignMethod int + +const ( + // TableCellAlignDefault renders alignments by default method. + // With XHTML, alignments are rendered as an align attribute. + // With HTML5, alignments are rendered as a style attribute. + TableCellAlignDefault TableCellAlignMethod = iota + + // TableCellAlignAttribute renders alignments as an align attribute. + TableCellAlignAttribute + + // TableCellAlignStyle renders alignments as a style attribute. + TableCellAlignStyle + + // TableCellAlignNone does not care about alignments. + // If you using classes or other styles, you can add these attributes + // in an ASTTransformer. + TableCellAlignNone +) + +// TableConfig struct holds options for the extension. +type TableConfig struct { + html.Config + + // TableCellAlignMethod indicates how are table celss aligned. + TableCellAlignMethod TableCellAlignMethod +} + +// TableOption interface is a functional option interface for the extension. +type TableOption interface { + renderer.Option + // SetTableOption sets given option to the extension. + SetTableOption(*TableConfig) +} + +// NewTableConfig returns a new Config with defaults. +func NewTableConfig() TableConfig { + return TableConfig{ + Config: html.NewConfig(), + TableCellAlignMethod: TableCellAlignDefault, + } +} + +// SetOption implements renderer.SetOptioner. +func (c *TableConfig) SetOption(name renderer.OptionName, value interface{}) { + switch name { + case optTableCellAlignMethod: + c.TableCellAlignMethod = value.(TableCellAlignMethod) + default: + c.Config.SetOption(name, value) + } +} + +type withTableHTMLOptions struct { + value []html.Option +} + +func (o *withTableHTMLOptions) SetConfig(c *renderer.Config) { + if o.value != nil { + for _, v := range o.value { + v.(renderer.Option).SetConfig(c) + } + } +} + +func (o *withTableHTMLOptions) SetTableOption(c *TableConfig) { + if o.value != nil { + for _, v := range o.value { + v.SetHTMLOption(&c.Config) + } + } +} + +// WithTableHTMLOptions is functional option that wraps goldmark HTMLRenderer options. +func WithTableHTMLOptions(opts ...html.Option) TableOption { + return &withTableHTMLOptions{opts} +} + +const optTableCellAlignMethod renderer.OptionName = "TableTableCellAlignMethod" + +type withTableCellAlignMethod struct { + value TableCellAlignMethod +} + +func (o *withTableCellAlignMethod) SetConfig(c *renderer.Config) { + c.Options[optTableCellAlignMethod] = o.value +} + +func (o *withTableCellAlignMethod) SetTableOption(c *TableConfig) { + c.TableCellAlignMethod = o.value +} + +// WithTableCellAlignMethod is a functional option that indicates how are table cells aligned in HTML format. +func WithTableCellAlignMethod(a TableCellAlignMethod) TableOption { + return &withTableCellAlignMethod{a} +} + +func isTableDelim(bs []byte) bool { + if w, _ := util.IndentWidth(bs, 0); w > 3 { + return false + } + for _, b := range bs { + if !(util.IsSpace(b) || b == '-' || b == '|' || b == ':') { + return false + } + } + return true +} + +var tableDelimLeft = regexp.MustCompile(`^\s*\:\-+\s*$`) +var tableDelimRight = regexp.MustCompile(`^\s*\-+\:\s*$`) +var tableDelimCenter = regexp.MustCompile(`^\s*\:\-+\:\s*$`) +var tableDelimNone = regexp.MustCompile(`^\s*\-+\s*$`) + +type tableParagraphTransformer struct { +} + +var defaultTableParagraphTransformer = &tableParagraphTransformer{} + +// NewTableParagraphTransformer returns a new ParagraphTransformer +// that can transform paragraphs into tables. +func NewTableParagraphTransformer() parser.ParagraphTransformer { + return defaultTableParagraphTransformer +} + +func (b *tableParagraphTransformer) Transform(node *gast.Paragraph, reader text.Reader, pc parser.Context) { + lines := node.Lines() + if lines.Len() < 2 { + return + } + for i := 1; i < lines.Len(); i++ { + alignments := b.parseDelimiter(lines.At(i), reader) + if alignments == nil { + continue + } + header := b.parseRow(lines.At(i-1), alignments, true, reader, pc) + if header == nil || len(alignments) != header.ChildCount() { + return + } + table := ast.NewTable() + table.Alignments = alignments + table.AppendChild(table, ast.NewTableHeader(header)) + for j := i + 1; j < lines.Len(); j++ { + table.AppendChild(table, b.parseRow(lines.At(j), alignments, false, reader, pc)) + } + node.Lines().SetSliced(0, i-1) + node.Parent().InsertAfter(node.Parent(), node, table) + if node.Lines().Len() == 0 { + node.Parent().RemoveChild(node.Parent(), node) + } else { + last := node.Lines().At(i - 2) + last.Stop = last.Stop - 1 // trim last newline(\n) + node.Lines().Set(i-2, last) + } + } +} + +func (b *tableParagraphTransformer) parseRow(segment text.Segment, + alignments []ast.Alignment, isHeader bool, reader text.Reader, pc parser.Context) *ast.TableRow { + source := reader.Source() + line := segment.Value(source) + pos := 0 + pos += util.TrimLeftSpaceLength(line) + limit := len(line) + limit -= util.TrimRightSpaceLength(line) + row := ast.NewTableRow(alignments) + if len(line) > 0 && line[pos] == '|' { + pos++ + } + if len(line) > 0 && line[limit-1] == '|' { + limit-- + } + i := 0 + for ; pos < limit; i++ { + alignment := ast.AlignNone + if i >= len(alignments) { + if !isHeader { + return row + } + } else { + alignment = alignments[i] + } + + var escapedCell *escapedPipeCell + node := ast.NewTableCell() + node.Alignment = alignment + hasBacktick := false + closure := pos + for ; closure < limit; closure++ { + if line[closure] == '`' { + hasBacktick = true + } + if line[closure] == '|' { + if closure == 0 || line[closure-1] != '\\' { + break + } else if hasBacktick { + if escapedCell == nil { + escapedCell = &escapedPipeCell{node, []int{}, false} + escapedList := pc.ComputeIfAbsent(escapedPipeCellListKey, + func() interface{} { + return []*escapedPipeCell{} + }).([]*escapedPipeCell) + escapedList = append(escapedList, escapedCell) + pc.Set(escapedPipeCellListKey, escapedList) + } + escapedCell.Pos = append(escapedCell.Pos, segment.Start+closure-1) + } + } + } + seg := text.NewSegment(segment.Start+pos, segment.Start+closure) + seg = seg.TrimLeftSpace(source) + seg = seg.TrimRightSpace(source) + node.Lines().Append(seg) + row.AppendChild(row, node) + pos = closure + 1 + } + for ; i < len(alignments); i++ { + row.AppendChild(row, ast.NewTableCell()) + } + return row +} + +func (b *tableParagraphTransformer) parseDelimiter(segment text.Segment, reader text.Reader) []ast.Alignment { + + line := segment.Value(reader.Source()) + if !isTableDelim(line) { + return nil + } + cols := bytes.Split(line, []byte{'|'}) + if util.IsBlank(cols[0]) { + cols = cols[1:] + } + if len(cols) > 0 && util.IsBlank(cols[len(cols)-1]) { + cols = cols[:len(cols)-1] + } + + var alignments []ast.Alignment + for _, col := range cols { + if tableDelimLeft.Match(col) { + alignments = append(alignments, ast.AlignLeft) + } else if tableDelimRight.Match(col) { + alignments = append(alignments, ast.AlignRight) + } else if tableDelimCenter.Match(col) { + alignments = append(alignments, ast.AlignCenter) + } else if tableDelimNone.Match(col) { + alignments = append(alignments, ast.AlignNone) + } else { + return nil + } + } + return alignments +} + +type tableASTTransformer struct { +} + +var defaultTableASTTransformer = &tableASTTransformer{} + +// NewTableASTTransformer returns a parser.ASTTransformer for tables. +func NewTableASTTransformer() parser.ASTTransformer { + return defaultTableASTTransformer +} + +func (a *tableASTTransformer) Transform(node *gast.Document, reader text.Reader, pc parser.Context) { + lst := pc.Get(escapedPipeCellListKey) + if lst == nil { + return + } + pc.Set(escapedPipeCellListKey, nil) + for _, v := range lst.([]*escapedPipeCell) { + if v.Transformed { + continue + } + _ = gast.Walk(v.Cell, func(n gast.Node, entering bool) (gast.WalkStatus, error) { + if !entering || n.Kind() != gast.KindCodeSpan { + return gast.WalkContinue, nil + } + + for c := n.FirstChild(); c != nil; { + next := c.NextSibling() + if c.Kind() != gast.KindText { + c = next + continue + } + parent := c.Parent() + ts := &c.(*gast.Text).Segment + n := c + for _, v := range lst.([]*escapedPipeCell) { + for _, pos := range v.Pos { + if ts.Start <= pos && pos < ts.Stop { + segment := n.(*gast.Text).Segment + n1 := gast.NewRawTextSegment(segment.WithStop(pos)) + n2 := gast.NewRawTextSegment(segment.WithStart(pos + 1)) + parent.InsertAfter(parent, n, n1) + parent.InsertAfter(parent, n1, n2) + parent.RemoveChild(parent, n) + n = n2 + v.Transformed = true + } + } + } + c = next + } + return gast.WalkContinue, nil + }) + } +} + +// TableHTMLRenderer is a renderer.NodeRenderer implementation that +// renders Table nodes. +type TableHTMLRenderer struct { + TableConfig +} + +// NewTableHTMLRenderer returns a new TableHTMLRenderer. +func NewTableHTMLRenderer(opts ...TableOption) renderer.NodeRenderer { + r := &TableHTMLRenderer{ + TableConfig: NewTableConfig(), + } + for _, opt := range opts { + opt.SetTableOption(&r.TableConfig) + } + return r +} + +// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs. +func (r *TableHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { + reg.Register(ast.KindTable, r.renderTable) + reg.Register(ast.KindTableHeader, r.renderTableHeader) + reg.Register(ast.KindTableRow, r.renderTableRow) + reg.Register(ast.KindTableCell, r.renderTableCell) +} + +// TableAttributeFilter defines attribute names which table elements can have. +var TableAttributeFilter = html.GlobalAttributeFilter.Extend( + []byte("align"), // [Deprecated] + []byte("bgcolor"), // [Deprecated] + []byte("border"), // [Deprecated] + []byte("cellpadding"), // [Deprecated] + []byte("cellspacing"), // [Deprecated] + []byte("frame"), // [Deprecated] + []byte("rules"), // [Deprecated] + []byte("summary"), // [Deprecated] + []byte("width"), // [Deprecated] +) + +func (r *TableHTMLRenderer) renderTable( + w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) { + if entering { + _, _ = w.WriteString("\n") + } else { + _, _ = w.WriteString("\n") + } + return gast.WalkContinue, nil +} + +// TableHeaderAttributeFilter defines attribute names which elements can have. +var TableHeaderAttributeFilter = html.GlobalAttributeFilter.Extend( + []byte("align"), // [Deprecated since HTML4] [Obsolete since HTML5] + []byte("bgcolor"), // [Not Standardized] + []byte("char"), // [Deprecated since HTML4] [Obsolete since HTML5] + []byte("charoff"), // [Deprecated since HTML4] [Obsolete since HTML5] + []byte("valign"), // [Deprecated since HTML4] [Obsolete since HTML5] +) + +func (r *TableHTMLRenderer) renderTableHeader( + w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) { + if entering { + _, _ = w.WriteString("\n") + _, _ = w.WriteString("\n") // Header has no separate handle + } else { + _, _ = w.WriteString("\n") + _, _ = w.WriteString("\n") + if n.NextSibling() != nil { + _, _ = w.WriteString("\n") + } + } + return gast.WalkContinue, nil +} + +// TableRowAttributeFilter defines attribute names which elements can have. +var TableRowAttributeFilter = html.GlobalAttributeFilter.Extend( + []byte("align"), // [Obsolete since HTML5] + []byte("bgcolor"), // [Obsolete since HTML5] + []byte("char"), // [Obsolete since HTML5] + []byte("charoff"), // [Obsolete since HTML5] + []byte("valign"), // [Obsolete since HTML5] +) + +func (r *TableHTMLRenderer) renderTableRow( + w util.BufWriter, source []byte, n gast.Node, entering bool) (gast.WalkStatus, error) { + if entering { + _, _ = w.WriteString("\n") + } else { + _, _ = w.WriteString("\n") + if n.Parent().LastChild() == n { + _, _ = w.WriteString("\n") + } + } + return gast.WalkContinue, nil +} + +// TableThCellAttributeFilter defines attribute names which table cells can have. +var TableThCellAttributeFilter = html.GlobalAttributeFilter.Extend( + []byte("abbr"), // [OK] Contains a short abbreviated description of the cell's content [NOT OK in ] + + []byte("align"), // [Obsolete since HTML5] + []byte("axis"), // [Obsolete since HTML5] + []byte("bgcolor"), // [Not Standardized] + []byte("char"), // [Obsolete since HTML5] + []byte("charoff"), // [Obsolete since HTML5] + + []byte("colspan"), // [OK] Number of columns that the cell is to span + []byte("headers"), // [OK] This attribute contains a list of space-separated + // strings, each corresponding to the id attribute of the elements that apply to this element + + []byte("height"), // [Deprecated since HTML4] [Obsolete since HTML5] + + []byte("rowspan"), // [OK] Number of rows that the cell is to span + []byte("scope"), // [OK] This enumerated attribute defines the cells that + // the header (defined in the ) element relates to [NOT OK in ] + + []byte("valign"), // [Obsolete since HTML5] + []byte("width"), // [Deprecated since HTML4] [Obsolete since HTML5] +) + +// TableTdCellAttributeFilter defines attribute names which table cells can have. +var TableTdCellAttributeFilter = html.GlobalAttributeFilter.Extend( + []byte("abbr"), // [Obsolete since HTML5] [OK in ] + []byte("align"), // [Obsolete since HTML5] + []byte("axis"), // [Obsolete since HTML5] + []byte("bgcolor"), // [Not Standardized] + []byte("char"), // [Obsolete since HTML5] + []byte("charoff"), // [Obsolete since HTML5] + + []byte("colspan"), // [OK] Number of columns that the cell is to span + []byte("headers"), // [OK] This attribute contains a list of space-separated + // strings, each corresponding to the id attribute of the elements that apply to this element + + []byte("height"), // [Deprecated since HTML4] [Obsolete since HTML5] + + []byte("rowspan"), // [OK] Number of rows that the cell is to span + + []byte("scope"), // [Obsolete since HTML5] [OK in ] + []byte("valign"), // [Obsolete since HTML5] + []byte("width"), // [Deprecated since HTML4] [Obsolete since HTML5] +) + +func (r *TableHTMLRenderer) renderTableCell( + w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { + n := node.(*ast.TableCell) + tag := "td" + if n.Parent().Kind() == ast.KindTableHeader { + tag = "th" + } + if entering { + fmt.Fprintf(w, "<%s", tag) + if n.Alignment != ast.AlignNone { + amethod := r.TableConfig.TableCellAlignMethod + if amethod == TableCellAlignDefault { + if r.Config.XHTML { + amethod = TableCellAlignAttribute + } else { + amethod = TableCellAlignStyle + } + } + switch amethod { + case TableCellAlignAttribute: + if _, ok := n.AttributeString("align"); !ok { // Skip align render if overridden + fmt.Fprintf(w, ` align="%s"`, n.Alignment.String()) + } + case TableCellAlignStyle: + v, ok := n.AttributeString("style") + var cob util.CopyOnWriteBuffer + if ok { + cob = util.NewCopyOnWriteBuffer(v.([]byte)) + cob.AppendByte(';') + } + style := fmt.Sprintf("text-align:%s", n.Alignment.String()) + cob.AppendString(style) + n.SetAttributeString("style", cob.Bytes()) + } + } + if n.Attributes() != nil { + if tag == "td" { + html.RenderAttributes(w, n, TableTdCellAttributeFilter) // + } else { + html.RenderAttributes(w, n, TableThCellAttributeFilter) // + } + } + _ = w.WriteByte('>') + } else { + fmt.Fprintf(w, "\n", tag) + } + return gast.WalkContinue, nil +} + +type table struct { + options []TableOption +} + +// Table is an extension that allow you to use GFM tables . +var Table = &table{ + options: []TableOption{}, +} + +// NewTable returns a new extension with given options. +func NewTable(opts ...TableOption) goldmark.Extender { + return &table{ + options: opts, + } +} + +func (e *table) Extend(m goldmark.Markdown) { + m.Parser().AddOptions( + parser.WithParagraphTransformers( + util.Prioritized(NewTableParagraphTransformer(), 200), + ), + parser.WithASTTransformers( + util.Prioritized(defaultTableASTTransformer, 0), + ), + ) + m.Renderer().AddOptions(renderer.WithNodeRenderers( + util.Prioritized(NewTableHTMLRenderer(e.options...), 500), + )) +} diff --git a/vendor/github.com/yuin/goldmark/extension/tasklist.go b/vendor/github.com/yuin/goldmark/extension/tasklist.go new file mode 100644 index 0000000..4467ebf --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/tasklist.go @@ -0,0 +1,120 @@ +package extension + +import ( + "regexp" + + "github.com/yuin/goldmark" + gast "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/extension/ast" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/renderer/html" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +var taskListRegexp = regexp.MustCompile(`^\[([\sxX])\]\s*`) + +type taskCheckBoxParser struct { +} + +var defaultTaskCheckBoxParser = &taskCheckBoxParser{} + +// NewTaskCheckBoxParser returns a new InlineParser that can parse +// checkboxes in list items. +// This parser must take precedence over the parser.LinkParser. +func NewTaskCheckBoxParser() parser.InlineParser { + return defaultTaskCheckBoxParser +} + +func (s *taskCheckBoxParser) Trigger() []byte { + return []byte{'['} +} + +func (s *taskCheckBoxParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node { + // Given AST structure must be like + // - List + // - ListItem : parent.Parent + // - TextBlock : parent + // (current line) + if parent.Parent() == nil || parent.Parent().FirstChild() != parent { + return nil + } + + if parent.HasChildren() { + return nil + } + if _, ok := parent.Parent().(*gast.ListItem); !ok { + return nil + } + line, _ := block.PeekLine() + m := taskListRegexp.FindSubmatchIndex(line) + if m == nil { + return nil + } + value := line[m[2]:m[3]][0] + block.Advance(m[1]) + checked := value == 'x' || value == 'X' + return ast.NewTaskCheckBox(checked) +} + +func (s *taskCheckBoxParser) CloseBlock(parent gast.Node, pc parser.Context) { + // nothing to do +} + +// TaskCheckBoxHTMLRenderer is a renderer.NodeRenderer implementation that +// renders checkboxes in list items. +type TaskCheckBoxHTMLRenderer struct { + html.Config +} + +// NewTaskCheckBoxHTMLRenderer returns a new TaskCheckBoxHTMLRenderer. +func NewTaskCheckBoxHTMLRenderer(opts ...html.Option) renderer.NodeRenderer { + r := &TaskCheckBoxHTMLRenderer{ + Config: html.NewConfig(), + } + for _, opt := range opts { + opt.SetHTMLOption(&r.Config) + } + return r +} + +// RegisterFuncs implements renderer.NodeRenderer.RegisterFuncs. +func (r *TaskCheckBoxHTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { + reg.Register(ast.KindTaskCheckBox, r.renderTaskCheckBox) +} + +func (r *TaskCheckBoxHTMLRenderer) renderTaskCheckBox( + w util.BufWriter, source []byte, node gast.Node, entering bool) (gast.WalkStatus, error) { + if !entering { + return gast.WalkContinue, nil + } + n := node.(*ast.TaskCheckBox) + + if n.IsChecked { + _, _ = w.WriteString(` ") + } else { + _, _ = w.WriteString("> ") + } + return gast.WalkContinue, nil +} + +type taskList struct { +} + +// TaskList is an extension that allow you to use GFM task lists. +var TaskList = &taskList{} + +func (e *taskList) Extend(m goldmark.Markdown) { + m.Parser().AddOptions(parser.WithInlineParsers( + util.Prioritized(NewTaskCheckBoxParser(), 0), + )) + m.Renderer().AddOptions(renderer.WithNodeRenderers( + util.Prioritized(NewTaskCheckBoxHTMLRenderer(), 500), + )) +} diff --git a/vendor/github.com/yuin/goldmark/extension/typographer.go b/vendor/github.com/yuin/goldmark/extension/typographer.go new file mode 100644 index 0000000..259c4f7 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/extension/typographer.go @@ -0,0 +1,348 @@ +package extension + +import ( + "unicode" + + "github.com/yuin/goldmark" + gast "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +var uncloseCounterKey = parser.NewContextKey() + +type unclosedCounter struct { + Single int + Double int +} + +func (u *unclosedCounter) Reset() { + u.Single = 0 + u.Double = 0 +} + +func getUnclosedCounter(pc parser.Context) *unclosedCounter { + v := pc.Get(uncloseCounterKey) + if v == nil { + v = &unclosedCounter{} + pc.Set(uncloseCounterKey, v) + } + return v.(*unclosedCounter) +} + +// TypographicPunctuation is a key of the punctuations that can be replaced with +// typographic entities. +type TypographicPunctuation int + +const ( + // LeftSingleQuote is ' . + LeftSingleQuote TypographicPunctuation = iota + 1 + // RightSingleQuote is ' . + RightSingleQuote + // LeftDoubleQuote is " . + LeftDoubleQuote + // RightDoubleQuote is " . + RightDoubleQuote + // EnDash is -- . + EnDash + // EmDash is --- . + EmDash + // Ellipsis is ... . + Ellipsis + // LeftAngleQuote is << . + LeftAngleQuote + // RightAngleQuote is >> . + RightAngleQuote + // Apostrophe is ' . + Apostrophe + + typographicPunctuationMax +) + +// An TypographerConfig struct is a data structure that holds configuration of the +// Typographer extension. +type TypographerConfig struct { + Substitutions [][]byte +} + +func newDefaultSubstitutions() [][]byte { + replacements := make([][]byte, typographicPunctuationMax) + replacements[LeftSingleQuote] = []byte("‘") + replacements[RightSingleQuote] = []byte("’") + replacements[LeftDoubleQuote] = []byte("“") + replacements[RightDoubleQuote] = []byte("”") + replacements[EnDash] = []byte("–") + replacements[EmDash] = []byte("—") + replacements[Ellipsis] = []byte("…") + replacements[LeftAngleQuote] = []byte("«") + replacements[RightAngleQuote] = []byte("»") + replacements[Apostrophe] = []byte("’") + + return replacements +} + +// SetOption implements SetOptioner. +func (b *TypographerConfig) SetOption(name parser.OptionName, value interface{}) { + switch name { + case optTypographicSubstitutions: + b.Substitutions = value.([][]byte) + } +} + +// A TypographerOption interface sets options for the TypographerParser. +type TypographerOption interface { + parser.Option + SetTypographerOption(*TypographerConfig) +} + +const optTypographicSubstitutions parser.OptionName = "TypographicSubstitutions" + +// TypographicSubstitutions is a list of the substitutions for the Typographer extension. +type TypographicSubstitutions map[TypographicPunctuation][]byte + +type withTypographicSubstitutions struct { + value [][]byte +} + +func (o *withTypographicSubstitutions) SetParserOption(c *parser.Config) { + c.Options[optTypographicSubstitutions] = o.value +} + +func (o *withTypographicSubstitutions) SetTypographerOption(p *TypographerConfig) { + p.Substitutions = o.value +} + +// WithTypographicSubstitutions is a functional otpion that specify replacement text +// for punctuations. +func WithTypographicSubstitutions(values map[TypographicPunctuation][]byte) TypographerOption { + replacements := newDefaultSubstitutions() + for k, v := range values { + replacements[k] = v + } + + return &withTypographicSubstitutions{replacements} +} + +type typographerDelimiterProcessor struct { +} + +func (p *typographerDelimiterProcessor) IsDelimiter(b byte) bool { + return b == '\'' || b == '"' +} + +func (p *typographerDelimiterProcessor) CanOpenCloser(opener, closer *parser.Delimiter) bool { + return opener.Char == closer.Char +} + +func (p *typographerDelimiterProcessor) OnMatch(consumes int) gast.Node { + return nil +} + +var defaultTypographerDelimiterProcessor = &typographerDelimiterProcessor{} + +type typographerParser struct { + TypographerConfig +} + +// NewTypographerParser return a new InlineParser that parses +// typographer expressions. +func NewTypographerParser(opts ...TypographerOption) parser.InlineParser { + p := &typographerParser{ + TypographerConfig: TypographerConfig{ + Substitutions: newDefaultSubstitutions(), + }, + } + for _, o := range opts { + o.SetTypographerOption(&p.TypographerConfig) + } + return p +} + +func (s *typographerParser) Trigger() []byte { + return []byte{'\'', '"', '-', '.', ',', '<', '>', '*', '['} +} + +func (s *typographerParser) Parse(parent gast.Node, block text.Reader, pc parser.Context) gast.Node { + line, _ := block.PeekLine() + c := line[0] + if len(line) > 2 { + if c == '-' { + if s.Substitutions[EmDash] != nil && line[1] == '-' && line[2] == '-' { // --- + node := gast.NewString(s.Substitutions[EmDash]) + node.SetCode(true) + block.Advance(3) + return node + } + } else if c == '.' { + if s.Substitutions[Ellipsis] != nil && line[1] == '.' && line[2] == '.' { // ... + node := gast.NewString(s.Substitutions[Ellipsis]) + node.SetCode(true) + block.Advance(3) + return node + } + return nil + } + } + if len(line) > 1 { + if c == '<' { + if s.Substitutions[LeftAngleQuote] != nil && line[1] == '<' { // << + node := gast.NewString(s.Substitutions[LeftAngleQuote]) + node.SetCode(true) + block.Advance(2) + return node + } + return nil + } else if c == '>' { + if s.Substitutions[RightAngleQuote] != nil && line[1] == '>' { // >> + node := gast.NewString(s.Substitutions[RightAngleQuote]) + node.SetCode(true) + block.Advance(2) + return node + } + return nil + } else if s.Substitutions[EnDash] != nil && c == '-' && line[1] == '-' { // -- + node := gast.NewString(s.Substitutions[EnDash]) + node.SetCode(true) + block.Advance(2) + return node + } + } + if c == '\'' || c == '"' { + before := block.PrecendingCharacter() + d := parser.ScanDelimiter(line, before, 1, defaultTypographerDelimiterProcessor) + if d == nil { + return nil + } + counter := getUnclosedCounter(pc) + if c == '\'' { + if s.Substitutions[Apostrophe] != nil { + // Handle decade abbrevations such as '90s + if d.CanOpen && !d.CanClose && len(line) > 3 && + util.IsNumeric(line[1]) && util.IsNumeric(line[2]) && line[3] == 's' { + after := rune(' ') + if len(line) > 4 { + after = util.ToRune(line, 4) + } + if len(line) == 3 || util.IsSpaceRune(after) || util.IsPunctRune(after) { + node := gast.NewString(s.Substitutions[Apostrophe]) + node.SetCode(true) + block.Advance(1) + return node + } + } + // special cases: 'twas, 'em, 'net + if len(line) > 1 && (unicode.IsPunct(before) || unicode.IsSpace(before)) && + (line[1] == 't' || line[1] == 'e' || line[1] == 'n' || line[1] == 'l') { + node := gast.NewString(s.Substitutions[Apostrophe]) + node.SetCode(true) + block.Advance(1) + return node + } + // Convert normal apostrophes. This is probably more flexible than necessary but + // converts any apostrophe in between two alphanumerics. + if len(line) > 1 && (unicode.IsDigit(before) || unicode.IsLetter(before)) && + (unicode.IsLetter(util.ToRune(line, 1))) { + node := gast.NewString(s.Substitutions[Apostrophe]) + node.SetCode(true) + block.Advance(1) + return node + } + } + if s.Substitutions[LeftSingleQuote] != nil && d.CanOpen && !d.CanClose { + nt := LeftSingleQuote + // special cases: Alice's, I'm, Don't, You'd + if len(line) > 1 && (line[1] == 's' || line[1] == 'm' || line[1] == 't' || line[1] == 'd') && + (len(line) < 3 || util.IsPunct(line[2]) || util.IsSpace(line[2])) { + nt = RightSingleQuote + } + // special cases: I've, I'll, You're + if len(line) > 2 && ((line[1] == 'v' && line[2] == 'e') || + (line[1] == 'l' && line[2] == 'l') || (line[1] == 'r' && line[2] == 'e')) && + (len(line) < 4 || util.IsPunct(line[3]) || util.IsSpace(line[3])) { + nt = RightSingleQuote + } + if nt == LeftSingleQuote { + counter.Single++ + } + + node := gast.NewString(s.Substitutions[nt]) + node.SetCode(true) + block.Advance(1) + return node + } + if s.Substitutions[RightSingleQuote] != nil { + // plural possesive and abbreviations: Smiths', doin' + if len(line) > 1 && unicode.IsSpace(util.ToRune(line, 0)) || unicode.IsPunct(util.ToRune(line, 0)) && + (len(line) > 2 && !unicode.IsDigit(util.ToRune(line, 1))) { + node := gast.NewString(s.Substitutions[RightSingleQuote]) + node.SetCode(true) + block.Advance(1) + return node + } + } + if s.Substitutions[RightSingleQuote] != nil && counter.Single > 0 { + isClose := d.CanClose && !d.CanOpen + maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && unicode.IsPunct(util.ToRune(line, 1)) && + (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2]))) + if isClose || maybeClose { + node := gast.NewString(s.Substitutions[RightSingleQuote]) + node.SetCode(true) + block.Advance(1) + counter.Single-- + return node + } + } + } + if c == '"' { + if s.Substitutions[LeftDoubleQuote] != nil && d.CanOpen && !d.CanClose { + node := gast.NewString(s.Substitutions[LeftDoubleQuote]) + node.SetCode(true) + block.Advance(1) + counter.Double++ + return node + } + if s.Substitutions[RightDoubleQuote] != nil && counter.Double > 0 { + isClose := d.CanClose && !d.CanOpen + maybeClose := d.CanClose && d.CanOpen && len(line) > 1 && (unicode.IsPunct(util.ToRune(line, 1))) && + (len(line) == 2 || (len(line) > 2 && util.IsPunct(line[2]) || util.IsSpace(line[2]))) + if isClose || maybeClose { + // special case: "Monitor 21"" + if len(line) > 1 && line[1] == '"' && unicode.IsDigit(before) { + return nil + } + node := gast.NewString(s.Substitutions[RightDoubleQuote]) + node.SetCode(true) + block.Advance(1) + counter.Double-- + return node + } + } + } + } + return nil +} + +func (s *typographerParser) CloseBlock(parent gast.Node, pc parser.Context) { + getUnclosedCounter(pc).Reset() +} + +type typographer struct { + options []TypographerOption +} + +// Typographer is an extension that replaces punctuations with typographic entities. +var Typographer = &typographer{} + +// NewTypographer returns a new Extender that replaces punctuations with typographic entities. +func NewTypographer(opts ...TypographerOption) goldmark.Extender { + return &typographer{ + options: opts, + } +} + +func (e *typographer) Extend(m goldmark.Markdown) { + m.Parser().AddOptions(parser.WithInlineParsers( + util.Prioritized(NewTypographerParser(e.options...), 9999), + )) +} diff --git a/vendor/github.com/yuin/goldmark/markdown.go b/vendor/github.com/yuin/goldmark/markdown.go new file mode 100644 index 0000000..86d12e2 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/markdown.go @@ -0,0 +1,140 @@ +// Package goldmark implements functions to convert markdown text to a desired format. +package goldmark + +import ( + "github.com/yuin/goldmark/parser" + "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/renderer/html" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" + "io" +) + +// DefaultParser returns a new Parser that is configured by default values. +func DefaultParser() parser.Parser { + return parser.NewParser(parser.WithBlockParsers(parser.DefaultBlockParsers()...), + parser.WithInlineParsers(parser.DefaultInlineParsers()...), + parser.WithParagraphTransformers(parser.DefaultParagraphTransformers()...), + ) +} + +// DefaultRenderer returns a new Renderer that is configured by default values. +func DefaultRenderer() renderer.Renderer { + return renderer.NewRenderer(renderer.WithNodeRenderers(util.Prioritized(html.NewRenderer(), 1000))) +} + +var defaultMarkdown = New() + +// Convert interprets a UTF-8 bytes source in Markdown and +// write rendered contents to a writer w. +func Convert(source []byte, w io.Writer, opts ...parser.ParseOption) error { + return defaultMarkdown.Convert(source, w, opts...) +} + +// A Markdown interface offers functions to convert Markdown text to +// a desired format. +type Markdown interface { + // Convert interprets a UTF-8 bytes source in Markdown and write rendered + // contents to a writer w. + Convert(source []byte, writer io.Writer, opts ...parser.ParseOption) error + + // Parser returns a Parser that will be used for conversion. + Parser() parser.Parser + + // SetParser sets a Parser to this object. + SetParser(parser.Parser) + + // Parser returns a Renderer that will be used for conversion. + Renderer() renderer.Renderer + + // SetRenderer sets a Renderer to this object. + SetRenderer(renderer.Renderer) +} + +// Option is a functional option type for Markdown objects. +type Option func(*markdown) + +// WithExtensions adds extensions. +func WithExtensions(ext ...Extender) Option { + return func(m *markdown) { + m.extensions = append(m.extensions, ext...) + } +} + +// WithParser allows you to override the default parser. +func WithParser(p parser.Parser) Option { + return func(m *markdown) { + m.parser = p + } +} + +// WithParserOptions applies options for the parser. +func WithParserOptions(opts ...parser.Option) Option { + return func(m *markdown) { + m.parser.AddOptions(opts...) + } +} + +// WithRenderer allows you to override the default renderer. +func WithRenderer(r renderer.Renderer) Option { + return func(m *markdown) { + m.renderer = r + } +} + +// WithRendererOptions applies options for the renderer. +func WithRendererOptions(opts ...renderer.Option) Option { + return func(m *markdown) { + m.renderer.AddOptions(opts...) + } +} + +type markdown struct { + parser parser.Parser + renderer renderer.Renderer + extensions []Extender +} + +// New returns a new Markdown with given options. +func New(options ...Option) Markdown { + md := &markdown{ + parser: DefaultParser(), + renderer: DefaultRenderer(), + extensions: []Extender{}, + } + for _, opt := range options { + opt(md) + } + for _, e := range md.extensions { + e.Extend(md) + } + return md +} + +func (m *markdown) Convert(source []byte, writer io.Writer, opts ...parser.ParseOption) error { + reader := text.NewReader(source) + doc := m.parser.Parse(reader, opts...) + return m.renderer.Render(writer, source, doc) +} + +func (m *markdown) Parser() parser.Parser { + return m.parser +} + +func (m *markdown) SetParser(v parser.Parser) { + m.parser = v +} + +func (m *markdown) Renderer() renderer.Renderer { + return m.renderer +} + +func (m *markdown) SetRenderer(v renderer.Renderer) { + m.renderer = v +} + +// An Extender interface is used for extending Markdown. +type Extender interface { + // Extend extends the Markdown. + Extend(Markdown) +} diff --git a/vendor/github.com/yuin/goldmark/parser/attribute.go b/vendor/github.com/yuin/goldmark/parser/attribute.go new file mode 100644 index 0000000..42985f4 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/attribute.go @@ -0,0 +1,329 @@ +package parser + +import ( + "bytes" + "io" + "strconv" + + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +var attrNameID = []byte("id") +var attrNameClass = []byte("class") + +// An Attribute is an attribute of the markdown elements. +type Attribute struct { + Name []byte + Value interface{} +} + +// An Attributes is a collection of attributes. +type Attributes []Attribute + +// Find returns a (value, true) if an attribute correspond with given name is found, otherwise (nil, false). +func (as Attributes) Find(name []byte) (interface{}, bool) { + for _, a := range as { + if bytes.Equal(a.Name, name) { + return a.Value, true + } + } + return nil, false +} + +func (as Attributes) findUpdate(name []byte, cb func(v interface{}) interface{}) bool { + for i, a := range as { + if bytes.Equal(a.Name, name) { + as[i].Value = cb(a.Value) + return true + } + } + return false +} + +// ParseAttributes parses attributes into a map. +// ParseAttributes returns a parsed attributes and true if could parse +// attributes, otherwise nil and false. +func ParseAttributes(reader text.Reader) (Attributes, bool) { + savedLine, savedPosition := reader.Position() + reader.SkipSpaces() + if reader.Peek() != '{' { + reader.SetPosition(savedLine, savedPosition) + return nil, false + } + reader.Advance(1) + attrs := Attributes{} + for { + if reader.Peek() == '}' { + reader.Advance(1) + return attrs, true + } + attr, ok := parseAttribute(reader) + if !ok { + reader.SetPosition(savedLine, savedPosition) + return nil, false + } + if bytes.Equal(attr.Name, attrNameClass) { + if !attrs.findUpdate(attrNameClass, func(v interface{}) interface{} { + ret := make([]byte, 0, len(v.([]byte))+1+len(attr.Value.([]byte))) + ret = append(ret, v.([]byte)...) + return append(append(ret, ' '), attr.Value.([]byte)...) + }) { + attrs = append(attrs, attr) + } + } else { + attrs = append(attrs, attr) + } + reader.SkipSpaces() + if reader.Peek() == ',' { + reader.Advance(1) + reader.SkipSpaces() + } + } +} + +func parseAttribute(reader text.Reader) (Attribute, bool) { + reader.SkipSpaces() + c := reader.Peek() + if c == '#' || c == '.' { + reader.Advance(1) + line, _ := reader.PeekLine() + i := 0 + // HTML5 allows any kind of characters as id, but XHTML restricts characters for id. + // CommonMark is basically defined for XHTML(even though it is legacy). + // So we restrict id characters. + for ; i < len(line) && !util.IsSpace(line[i]) && + (!util.IsPunct(line[i]) || line[i] == '_' || + line[i] == '-' || line[i] == ':' || line[i] == '.'); i++ { + } + name := attrNameClass + if c == '#' { + name = attrNameID + } + reader.Advance(i) + return Attribute{Name: name, Value: line[0:i]}, true + } + line, _ := reader.PeekLine() + if len(line) == 0 { + return Attribute{}, false + } + c = line[0] + if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + c == '_' || c == ':') { + return Attribute{}, false + } + i := 0 + for ; i < len(line); i++ { + c = line[i] + if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '_' || c == ':' || c == '.' || c == '-') { + break + } + } + name := line[:i] + reader.Advance(i) + reader.SkipSpaces() + c = reader.Peek() + if c != '=' { + return Attribute{}, false + } + reader.Advance(1) + reader.SkipSpaces() + value, ok := parseAttributeValue(reader) + if !ok { + return Attribute{}, false + } + if bytes.Equal(name, attrNameClass) { + if _, ok = value.([]byte); !ok { + return Attribute{}, false + } + } + return Attribute{Name: name, Value: value}, true +} + +func parseAttributeValue(reader text.Reader) (interface{}, bool) { + reader.SkipSpaces() + c := reader.Peek() + var value interface{} + var ok bool + switch c { + case text.EOF: + return Attribute{}, false + case '{': + value, ok = ParseAttributes(reader) + case '[': + value, ok = parseAttributeArray(reader) + case '"': + value, ok = parseAttributeString(reader) + default: + if c == '-' || c == '+' || util.IsNumeric(c) { + value, ok = parseAttributeNumber(reader) + } else { + value, ok = parseAttributeOthers(reader) + } + } + if !ok { + return nil, false + } + return value, true +} + +func parseAttributeArray(reader text.Reader) ([]interface{}, bool) { + reader.Advance(1) // skip [ + ret := []interface{}{} + for i := 0; ; i++ { + c := reader.Peek() + comma := false + if i != 0 && c == ',' { + reader.Advance(1) + comma = true + } + if c == ']' { + if !comma { + reader.Advance(1) + return ret, true + } + return nil, false + } + reader.SkipSpaces() + value, ok := parseAttributeValue(reader) + if !ok { + return nil, false + } + ret = append(ret, value) + reader.SkipSpaces() + } +} + +func parseAttributeString(reader text.Reader) ([]byte, bool) { + reader.Advance(1) // skip " + line, _ := reader.PeekLine() + i := 0 + l := len(line) + var buf bytes.Buffer + for i < l { + c := line[i] + if c == '\\' && i != l-1 { + n := line[i+1] + switch n { + case '"', '/', '\\': + buf.WriteByte(n) + i += 2 + case 'b': + buf.WriteString("\b") + i += 2 + case 'f': + buf.WriteString("\f") + i += 2 + case 'n': + buf.WriteString("\n") + i += 2 + case 'r': + buf.WriteString("\r") + i += 2 + case 't': + buf.WriteString("\t") + i += 2 + default: + buf.WriteByte('\\') + i++ + } + continue + } + if c == '"' { + reader.Advance(i + 1) + return buf.Bytes(), true + } + buf.WriteByte(c) + i++ + } + return nil, false +} + +func scanAttributeDecimal(reader text.Reader, w io.ByteWriter) { + for { + c := reader.Peek() + if util.IsNumeric(c) { + _ = w.WriteByte(c) + } else { + return + } + reader.Advance(1) + } +} + +func parseAttributeNumber(reader text.Reader) (float64, bool) { + sign := 1 + c := reader.Peek() + if c == '-' { + sign = -1 + reader.Advance(1) + } else if c == '+' { + reader.Advance(1) + } + var buf bytes.Buffer + if !util.IsNumeric(reader.Peek()) { + return 0, false + } + scanAttributeDecimal(reader, &buf) + if buf.Len() == 0 { + return 0, false + } + c = reader.Peek() + if c == '.' { + buf.WriteByte(c) + reader.Advance(1) + scanAttributeDecimal(reader, &buf) + } + c = reader.Peek() + if c == 'e' || c == 'E' { + buf.WriteByte(c) + reader.Advance(1) + c = reader.Peek() + if c == '-' || c == '+' { + buf.WriteByte(c) + reader.Advance(1) + } + scanAttributeDecimal(reader, &buf) + } + f, err := strconv.ParseFloat(buf.String(), 64) + if err != nil { + return 0, false + } + return float64(sign) * f, true +} + +var bytesTrue = []byte("true") +var bytesFalse = []byte("false") +var bytesNull = []byte("null") + +func parseAttributeOthers(reader text.Reader) (interface{}, bool) { + line, _ := reader.PeekLine() + c := line[0] + if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + c == '_' || c == ':') { + return nil, false + } + i := 0 + for ; i < len(line); i++ { + c := line[i] + if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || + (c >= '0' && c <= '9') || + c == '_' || c == ':' || c == '.' || c == '-') { + break + } + } + value := line[:i] + reader.Advance(i) + if bytes.Equal(value, bytesTrue) { + return true, true + } + if bytes.Equal(value, bytesFalse) { + return false, true + } + if bytes.Equal(value, bytesNull) { + return nil, true + } + return value, true +} diff --git a/vendor/github.com/yuin/goldmark/parser/atx_heading.go b/vendor/github.com/yuin/goldmark/parser/atx_heading.go new file mode 100644 index 0000000..dae5e84 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/atx_heading.go @@ -0,0 +1,248 @@ +package parser + +import ( + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +// A HeadingConfig struct is a data structure that holds configuration of the renderers related to headings. +type HeadingConfig struct { + AutoHeadingID bool + Attribute bool +} + +// SetOption implements SetOptioner. +func (b *HeadingConfig) SetOption(name OptionName, _ interface{}) { + switch name { + case optAutoHeadingID: + b.AutoHeadingID = true + case optAttribute: + b.Attribute = true + } +} + +// A HeadingOption interface sets options for heading parsers. +type HeadingOption interface { + Option + SetHeadingOption(*HeadingConfig) +} + +// AutoHeadingID is an option name that enables auto IDs for headings. +const optAutoHeadingID OptionName = "AutoHeadingID" + +type withAutoHeadingID struct { +} + +func (o *withAutoHeadingID) SetParserOption(c *Config) { + c.Options[optAutoHeadingID] = true +} + +func (o *withAutoHeadingID) SetHeadingOption(p *HeadingConfig) { + p.AutoHeadingID = true +} + +// WithAutoHeadingID is a functional option that enables custom heading ids and +// auto generated heading ids. +func WithAutoHeadingID() HeadingOption { + return &withAutoHeadingID{} +} + +type withHeadingAttribute struct { + Option +} + +func (o *withHeadingAttribute) SetHeadingOption(p *HeadingConfig) { + p.Attribute = true +} + +// WithHeadingAttribute is a functional option that enables custom heading attributes. +func WithHeadingAttribute() HeadingOption { + return &withHeadingAttribute{WithAttribute()} +} + +type atxHeadingParser struct { + HeadingConfig +} + +// NewATXHeadingParser return a new BlockParser that can parse ATX headings. +func NewATXHeadingParser(opts ...HeadingOption) BlockParser { + p := &atxHeadingParser{} + for _, o := range opts { + o.SetHeadingOption(&p.HeadingConfig) + } + return p +} + +func (b *atxHeadingParser) Trigger() []byte { + return []byte{'#'} +} + +func (b *atxHeadingParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { + line, segment := reader.PeekLine() + pos := pc.BlockOffset() + if pos < 0 { + return nil, NoChildren + } + i := pos + for ; i < len(line) && line[i] == '#'; i++ { + } + level := i - pos + if i == pos || level > 6 { + return nil, NoChildren + } + if i == len(line) { // alone '#' (without a new line character) + return ast.NewHeading(level), NoChildren + } + l := util.TrimLeftSpaceLength(line[i:]) + if l == 0 { + return nil, NoChildren + } + start := i + l + if start >= len(line) { + start = len(line) - 1 + } + origstart := start + stop := len(line) - util.TrimRightSpaceLength(line) + + node := ast.NewHeading(level) + parsed := false + if b.Attribute { // handles special case like ### heading ### {#id} + start-- + closureClose := -1 + closureOpen := -1 + for j := start; j < stop; { + c := line[j] + if util.IsEscapedPunctuation(line, j) { + j += 2 + } else if util.IsSpace(c) && j < stop-1 && line[j+1] == '#' { + closureOpen = j + 1 + k := j + 1 + for ; k < stop && line[k] == '#'; k++ { + } + closureClose = k + break + } else { + j++ + } + } + if closureClose > 0 { + reader.Advance(closureClose) + attrs, ok := ParseAttributes(reader) + rest, _ := reader.PeekLine() + parsed = ok && util.IsBlank(rest) + if parsed { + for _, attr := range attrs { + node.SetAttribute(attr.Name, attr.Value) + } + node.Lines().Append(text.NewSegment( + segment.Start+start+1-segment.Padding, + segment.Start+closureOpen-segment.Padding)) + } + } + } + if !parsed { + start = origstart + stop := len(line) - util.TrimRightSpaceLength(line) + if stop <= start { // empty headings like '##[space]' + stop = start + } else { + i = stop - 1 + for ; line[i] == '#' && i >= start; i-- { + } + if i != stop-1 && !util.IsSpace(line[i]) { + i = stop - 1 + } + i++ + stop = i + } + + if len(util.TrimRight(line[start:stop], []byte{'#'})) != 0 { // empty heading like '### ###' + node.Lines().Append(text.NewSegment(segment.Start+start-segment.Padding, segment.Start+stop-segment.Padding)) + } + } + return node, NoChildren +} + +func (b *atxHeadingParser) Continue(node ast.Node, reader text.Reader, pc Context) State { + return Close +} + +func (b *atxHeadingParser) Close(node ast.Node, reader text.Reader, pc Context) { + if b.Attribute { + _, ok := node.AttributeString("id") + if !ok { + parseLastLineAttributes(node, reader, pc) + } + } + + if b.AutoHeadingID { + id, ok := node.AttributeString("id") + if !ok { + generateAutoHeadingID(node.(*ast.Heading), reader, pc) + } else { + pc.IDs().Put(id.([]byte)) + } + } +} + +func (b *atxHeadingParser) CanInterruptParagraph() bool { + return true +} + +func (b *atxHeadingParser) CanAcceptIndentedLine() bool { + return false +} + +func generateAutoHeadingID(node *ast.Heading, reader text.Reader, pc Context) { + var line []byte + lastIndex := node.Lines().Len() - 1 + if lastIndex > -1 { + lastLine := node.Lines().At(lastIndex) + line = lastLine.Value(reader.Source()) + } + headingID := pc.IDs().Generate(line, ast.KindHeading) + node.SetAttribute(attrNameID, headingID) +} + +func parseLastLineAttributes(node ast.Node, reader text.Reader, pc Context) { + lastIndex := node.Lines().Len() - 1 + if lastIndex < 0 { // empty headings + return + } + lastLine := node.Lines().At(lastIndex) + line := lastLine.Value(reader.Source()) + lr := text.NewReader(line) + var attrs Attributes + var ok bool + var start text.Segment + var sl int + var end text.Segment + for { + c := lr.Peek() + if c == text.EOF { + break + } + if c == '\\' { + lr.Advance(1) + if lr.Peek() == '{' { + lr.Advance(1) + } + continue + } + if c == '{' { + sl, start = lr.Position() + attrs, ok = ParseAttributes(lr) + _, end = lr.Position() + lr.SetPosition(sl, start) + } + lr.Advance(1) + } + if ok && util.IsBlank(line[end.Start:]) { + for _, attr := range attrs { + node.SetAttribute(attr.Name, attr.Value) + } + lastLine.Stop = lastLine.Start + start.Start + node.Lines().Set(lastIndex, lastLine) + } +} diff --git a/vendor/github.com/yuin/goldmark/parser/auto_link.go b/vendor/github.com/yuin/goldmark/parser/auto_link.go new file mode 100644 index 0000000..726a505 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/auto_link.go @@ -0,0 +1,42 @@ +package parser + +import ( + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type autoLinkParser struct { +} + +var defaultAutoLinkParser = &autoLinkParser{} + +// NewAutoLinkParser returns a new InlineParser that parses autolinks +// surrounded by '<' and '>' . +func NewAutoLinkParser() InlineParser { + return defaultAutoLinkParser +} + +func (s *autoLinkParser) Trigger() []byte { + return []byte{'<'} +} + +func (s *autoLinkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.Node { + line, segment := block.PeekLine() + stop := util.FindEmailIndex(line[1:]) + typ := ast.AutoLinkType(ast.AutoLinkEmail) + if stop < 0 { + stop = util.FindURLIndex(line[1:]) + typ = ast.AutoLinkURL + } + if stop < 0 { + return nil + } + stop++ + if stop >= len(line) || line[stop] != '>' { + return nil + } + value := ast.NewTextSegment(text.NewSegment(segment.Start+1, segment.Start+stop)) + block.Advance(stop + 1) + return ast.NewAutoLink(typ, value) +} diff --git a/vendor/github.com/yuin/goldmark/parser/blockquote.go b/vendor/github.com/yuin/goldmark/parser/blockquote.go new file mode 100644 index 0000000..e7778dc --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/blockquote.go @@ -0,0 +1,69 @@ +package parser + +import ( + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type blockquoteParser struct { +} + +var defaultBlockquoteParser = &blockquoteParser{} + +// NewBlockquoteParser returns a new BlockParser that +// parses blockquotes. +func NewBlockquoteParser() BlockParser { + return defaultBlockquoteParser +} + +func (b *blockquoteParser) process(reader text.Reader) bool { + line, _ := reader.PeekLine() + w, pos := util.IndentWidth(line, reader.LineOffset()) + if w > 3 || pos >= len(line) || line[pos] != '>' { + return false + } + pos++ + if pos >= len(line) || line[pos] == '\n' { + reader.Advance(pos) + return true + } + if line[pos] == ' ' || line[pos] == '\t' { + pos++ + } + reader.Advance(pos) + if line[pos-1] == '\t' { + reader.SetPadding(2) + } + return true +} + +func (b *blockquoteParser) Trigger() []byte { + return []byte{'>'} +} + +func (b *blockquoteParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { + if b.process(reader) { + return ast.NewBlockquote(), HasChildren + } + return nil, NoChildren +} + +func (b *blockquoteParser) Continue(node ast.Node, reader text.Reader, pc Context) State { + if b.process(reader) { + return Continue | HasChildren + } + return Close +} + +func (b *blockquoteParser) Close(node ast.Node, reader text.Reader, pc Context) { + // nothing to do +} + +func (b *blockquoteParser) CanInterruptParagraph() bool { + return true +} + +func (b *blockquoteParser) CanAcceptIndentedLine() bool { + return false +} diff --git a/vendor/github.com/yuin/goldmark/parser/code_block.go b/vendor/github.com/yuin/goldmark/parser/code_block.go new file mode 100644 index 0000000..732f18c --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/code_block.go @@ -0,0 +1,100 @@ +package parser + +import ( + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type codeBlockParser struct { +} + +// CodeBlockParser is a BlockParser implementation that parses indented code blocks. +var defaultCodeBlockParser = &codeBlockParser{} + +// NewCodeBlockParser returns a new BlockParser that +// parses code blocks. +func NewCodeBlockParser() BlockParser { + return defaultCodeBlockParser +} + +func (b *codeBlockParser) Trigger() []byte { + return nil +} + +func (b *codeBlockParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { + line, segment := reader.PeekLine() + pos, padding := util.IndentPosition(line, reader.LineOffset(), 4) + if pos < 0 || util.IsBlank(line) { + return nil, NoChildren + } + node := ast.NewCodeBlock() + reader.AdvanceAndSetPadding(pos, padding) + _, segment = reader.PeekLine() + // if code block line starts with a tab, keep a tab as it is. + if segment.Padding != 0 { + preserveLeadingTabInCodeBlock(&segment, reader, 0) + } + node.Lines().Append(segment) + reader.Advance(segment.Len() - 1) + return node, NoChildren + +} + +func (b *codeBlockParser) Continue(node ast.Node, reader text.Reader, pc Context) State { + line, segment := reader.PeekLine() + if util.IsBlank(line) { + node.Lines().Append(segment.TrimLeftSpaceWidth(4, reader.Source())) + return Continue | NoChildren + } + pos, padding := util.IndentPosition(line, reader.LineOffset(), 4) + if pos < 0 { + return Close + } + reader.AdvanceAndSetPadding(pos, padding) + _, segment = reader.PeekLine() + + // if code block line starts with a tab, keep a tab as it is. + if segment.Padding != 0 { + preserveLeadingTabInCodeBlock(&segment, reader, 0) + } + + node.Lines().Append(segment) + reader.Advance(segment.Len() - 1) + return Continue | NoChildren +} + +func (b *codeBlockParser) Close(node ast.Node, reader text.Reader, pc Context) { + // trim trailing blank lines + lines := node.Lines() + length := lines.Len() - 1 + source := reader.Source() + for length >= 0 { + line := lines.At(length) + if util.IsBlank(line.Value(source)) { + length-- + } else { + break + } + } + lines.SetSliced(0, length+1) +} + +func (b *codeBlockParser) CanInterruptParagraph() bool { + return false +} + +func (b *codeBlockParser) CanAcceptIndentedLine() bool { + return true +} + +func preserveLeadingTabInCodeBlock(segment *text.Segment, reader text.Reader, indent int) { + offsetWithPadding := reader.LineOffset() + indent + sl, ss := reader.Position() + reader.SetPosition(sl, text.NewSegment(ss.Start-1, ss.Stop)) + if offsetWithPadding == reader.LineOffset() { + segment.Padding = 0 + segment.Start-- + } + reader.SetPosition(sl, ss) +} diff --git a/vendor/github.com/yuin/goldmark/parser/code_span.go b/vendor/github.com/yuin/goldmark/parser/code_span.go new file mode 100644 index 0000000..a74b09b --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/code_span.go @@ -0,0 +1,84 @@ +package parser + +import ( + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" +) + +type codeSpanParser struct { +} + +var defaultCodeSpanParser = &codeSpanParser{} + +// NewCodeSpanParser return a new InlineParser that parses inline codes +// surrounded by '`' . +func NewCodeSpanParser() InlineParser { + return defaultCodeSpanParser +} + +func (s *codeSpanParser) Trigger() []byte { + return []byte{'`'} +} + +func (s *codeSpanParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.Node { + line, startSegment := block.PeekLine() + opener := 0 + for ; opener < len(line) && line[opener] == '`'; opener++ { + } + block.Advance(opener) + l, pos := block.Position() + node := ast.NewCodeSpan() + for { + line, segment := block.PeekLine() + if line == nil { + block.SetPosition(l, pos) + return ast.NewTextSegment(startSegment.WithStop(startSegment.Start + opener)) + } + for i := 0; i < len(line); i++ { + c := line[i] + if c == '`' { + oldi := i + for ; i < len(line) && line[i] == '`'; i++ { + } + closure := i - oldi + if closure == opener && (i >= len(line) || line[i] != '`') { + segment = segment.WithStop(segment.Start + i - closure) + if !segment.IsEmpty() { + node.AppendChild(node, ast.NewRawTextSegment(segment)) + } + block.Advance(i) + goto end + } + } + } + node.AppendChild(node, ast.NewRawTextSegment(segment)) + block.AdvanceLine() + } +end: + if !node.IsBlank(block.Source()) { + // trim first halfspace and last halfspace + segment := node.FirstChild().(*ast.Text).Segment + shouldTrimmed := true + if !(!segment.IsEmpty() && isSpaceOrNewline(block.Source()[segment.Start])) { + shouldTrimmed = false + } + segment = node.LastChild().(*ast.Text).Segment + if !(!segment.IsEmpty() && isSpaceOrNewline(block.Source()[segment.Stop-1])) { + shouldTrimmed = false + } + if shouldTrimmed { + t := node.FirstChild().(*ast.Text) + segment := t.Segment + t.Segment = segment.WithStart(segment.Start + 1) + t = node.LastChild().(*ast.Text) + segment = node.LastChild().(*ast.Text).Segment + t.Segment = segment.WithStop(segment.Stop - 1) + } + + } + return node +} + +func isSpaceOrNewline(c byte) bool { + return c == ' ' || c == '\n' +} diff --git a/vendor/github.com/yuin/goldmark/parser/delimiter.go b/vendor/github.com/yuin/goldmark/parser/delimiter.go new file mode 100644 index 0000000..d097e3f --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/delimiter.go @@ -0,0 +1,238 @@ +package parser + +import ( + "fmt" + "strings" + + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +// A DelimiterProcessor interface provides a set of functions about +// Delimiter nodes. +type DelimiterProcessor interface { + // IsDelimiter returns true if given character is a delimiter, otherwise false. + IsDelimiter(byte) bool + + // CanOpenCloser returns true if given opener can close given closer, otherwise false. + CanOpenCloser(opener, closer *Delimiter) bool + + // OnMatch will be called when new matched delimiter found. + // OnMatch should return a new Node correspond to the matched delimiter. + OnMatch(consumes int) ast.Node +} + +// A Delimiter struct represents a delimiter like '*' of the Markdown text. +type Delimiter struct { + ast.BaseInline + + Segment text.Segment + + // CanOpen is set true if this delimiter can open a span for a new node. + // See https://spec.commonmark.org/0.30/#can-open-emphasis for details. + CanOpen bool + + // CanClose is set true if this delimiter can close a span for a new node. + // See https://spec.commonmark.org/0.30/#can-open-emphasis for details. + CanClose bool + + // Length is a remaining length of this delimiter. + Length int + + // OriginalLength is a original length of this delimiter. + OriginalLength int + + // Char is a character of this delimiter. + Char byte + + // PreviousDelimiter is a previous sibling delimiter node of this delimiter. + PreviousDelimiter *Delimiter + + // NextDelimiter is a next sibling delimiter node of this delimiter. + NextDelimiter *Delimiter + + // Processor is a DelimiterProcessor associated with this delimiter. + Processor DelimiterProcessor +} + +// Inline implements Inline.Inline. +func (d *Delimiter) Inline() {} + +// Dump implements Node.Dump. +func (d *Delimiter) Dump(source []byte, level int) { + fmt.Printf("%sDelimiter: \"%s\"\n", strings.Repeat(" ", level), string(d.Text(source))) +} + +var kindDelimiter = ast.NewNodeKind("Delimiter") + +// Kind implements Node.Kind. +func (d *Delimiter) Kind() ast.NodeKind { + return kindDelimiter +} + +// Text implements Node.Text. +func (d *Delimiter) Text(source []byte) []byte { + return d.Segment.Value(source) +} + +// ConsumeCharacters consumes delimiters. +func (d *Delimiter) ConsumeCharacters(n int) { + d.Length -= n + d.Segment = d.Segment.WithStop(d.Segment.Start + d.Length) +} + +// CalcComsumption calculates how many characters should be used for opening +// a new span correspond to given closer. +func (d *Delimiter) CalcComsumption(closer *Delimiter) int { + if (d.CanClose || closer.CanOpen) && (d.OriginalLength+closer.OriginalLength)%3 == 0 && closer.OriginalLength%3 != 0 { + return 0 + } + if d.Length >= 2 && closer.Length >= 2 { + return 2 + } + return 1 +} + +// NewDelimiter returns a new Delimiter node. +func NewDelimiter(canOpen, canClose bool, length int, char byte, processor DelimiterProcessor) *Delimiter { + c := &Delimiter{ + BaseInline: ast.BaseInline{}, + CanOpen: canOpen, + CanClose: canClose, + Length: length, + OriginalLength: length, + Char: char, + PreviousDelimiter: nil, + NextDelimiter: nil, + Processor: processor, + } + return c +} + +// ScanDelimiter scans a delimiter by given DelimiterProcessor. +func ScanDelimiter(line []byte, before rune, min int, processor DelimiterProcessor) *Delimiter { + i := 0 + c := line[i] + j := i + if !processor.IsDelimiter(c) { + return nil + } + for ; j < len(line) && c == line[j]; j++ { + } + if (j - i) >= min { + after := rune(' ') + if j != len(line) { + after = util.ToRune(line, j) + } + + var canOpen, canClose bool + beforeIsPunctuation := util.IsPunctRune(before) + beforeIsWhitespace := util.IsSpaceRune(before) + afterIsPunctuation := util.IsPunctRune(after) + afterIsWhitespace := util.IsSpaceRune(after) + + isLeft := !afterIsWhitespace && + (!afterIsPunctuation || beforeIsWhitespace || beforeIsPunctuation) + isRight := !beforeIsWhitespace && + (!beforeIsPunctuation || afterIsWhitespace || afterIsPunctuation) + + if line[i] == '_' { + canOpen = isLeft && (!isRight || beforeIsPunctuation) + canClose = isRight && (!isLeft || afterIsPunctuation) + } else { + canOpen = isLeft + canClose = isRight + } + return NewDelimiter(canOpen, canClose, j-i, c, processor) + } + return nil +} + +// ProcessDelimiters processes the delimiter list in the context. +// Processing will be stop when reaching the bottom. +// +// If you implement an inline parser that can have other inline nodes as +// children, you should call this function when nesting span has closed. +func ProcessDelimiters(bottom ast.Node, pc Context) { + lastDelimiter := pc.LastDelimiter() + if lastDelimiter == nil { + return + } + var closer *Delimiter + if bottom != nil { + if bottom != lastDelimiter { + for c := lastDelimiter.PreviousSibling(); c != nil && c != bottom; { + if d, ok := c.(*Delimiter); ok { + closer = d + } + c = c.PreviousSibling() + } + } + } else { + closer = pc.FirstDelimiter() + } + if closer == nil { + pc.ClearDelimiters(bottom) + return + } + for closer != nil { + if !closer.CanClose { + closer = closer.NextDelimiter + continue + } + consume := 0 + found := false + maybeOpener := false + var opener *Delimiter + for opener = closer.PreviousDelimiter; opener != nil && opener != bottom; opener = opener.PreviousDelimiter { + if opener.CanOpen && opener.Processor.CanOpenCloser(opener, closer) { + maybeOpener = true + consume = opener.CalcComsumption(closer) + if consume > 0 { + found = true + break + } + } + } + if !found { + next := closer.NextDelimiter + if !maybeOpener && !closer.CanOpen { + pc.RemoveDelimiter(closer) + } + closer = next + continue + } + opener.ConsumeCharacters(consume) + closer.ConsumeCharacters(consume) + + node := opener.Processor.OnMatch(consume) + + parent := opener.Parent() + child := opener.NextSibling() + + for child != nil && child != closer { + next := child.NextSibling() + node.AppendChild(node, child) + child = next + } + parent.InsertAfter(parent, opener, node) + + for c := opener.NextDelimiter; c != nil && c != closer; { + next := c.NextDelimiter + pc.RemoveDelimiter(c) + c = next + } + + if opener.Length == 0 { + pc.RemoveDelimiter(opener) + } + + if closer.Length == 0 { + next := closer.NextDelimiter + pc.RemoveDelimiter(closer) + closer = next + } + } + pc.ClearDelimiters(bottom) +} diff --git a/vendor/github.com/yuin/goldmark/parser/emphasis.go b/vendor/github.com/yuin/goldmark/parser/emphasis.go new file mode 100644 index 0000000..4886471 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/emphasis.go @@ -0,0 +1,50 @@ +package parser + +import ( + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" +) + +type emphasisDelimiterProcessor struct { +} + +func (p *emphasisDelimiterProcessor) IsDelimiter(b byte) bool { + return b == '*' || b == '_' +} + +func (p *emphasisDelimiterProcessor) CanOpenCloser(opener, closer *Delimiter) bool { + return opener.Char == closer.Char +} + +func (p *emphasisDelimiterProcessor) OnMatch(consumes int) ast.Node { + return ast.NewEmphasis(consumes) +} + +var defaultEmphasisDelimiterProcessor = &emphasisDelimiterProcessor{} + +type emphasisParser struct { +} + +var defaultEmphasisParser = &emphasisParser{} + +// NewEmphasisParser return a new InlineParser that parses emphasises. +func NewEmphasisParser() InlineParser { + return defaultEmphasisParser +} + +func (s *emphasisParser) Trigger() []byte { + return []byte{'*', '_'} +} + +func (s *emphasisParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.Node { + before := block.PrecendingCharacter() + line, segment := block.PeekLine() + node := ScanDelimiter(line, before, 1, defaultEmphasisDelimiterProcessor) + if node == nil { + return nil + } + node.Segment = segment.WithStop(segment.Start + node.OriginalLength) + block.Advance(node.OriginalLength) + pc.PushDelimiter(node) + return node +} diff --git a/vendor/github.com/yuin/goldmark/parser/fcode_block.go b/vendor/github.com/yuin/goldmark/parser/fcode_block.go new file mode 100644 index 0000000..e51a35a --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/fcode_block.go @@ -0,0 +1,121 @@ +package parser + +import ( + "bytes" + + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type fencedCodeBlockParser struct { +} + +var defaultFencedCodeBlockParser = &fencedCodeBlockParser{} + +// NewFencedCodeBlockParser returns a new BlockParser that +// parses fenced code blocks. +func NewFencedCodeBlockParser() BlockParser { + return defaultFencedCodeBlockParser +} + +type fenceData struct { + char byte + indent int + length int + node ast.Node +} + +var fencedCodeBlockInfoKey = NewContextKey() + +func (b *fencedCodeBlockParser) Trigger() []byte { + return []byte{'~', '`'} +} + +func (b *fencedCodeBlockParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { + line, segment := reader.PeekLine() + pos := pc.BlockOffset() + if pos < 0 || (line[pos] != '`' && line[pos] != '~') { + return nil, NoChildren + } + findent := pos + fenceChar := line[pos] + i := pos + for ; i < len(line) && line[i] == fenceChar; i++ { + } + oFenceLength := i - pos + if oFenceLength < 3 { + return nil, NoChildren + } + var info *ast.Text + if i < len(line)-1 { + rest := line[i:] + left := util.TrimLeftSpaceLength(rest) + right := util.TrimRightSpaceLength(rest) + if left < len(rest)-right { + infoStart, infoStop := segment.Start-segment.Padding+i+left, segment.Stop-right + value := rest[left : len(rest)-right] + if fenceChar == '`' && bytes.IndexByte(value, '`') > -1 { + return nil, NoChildren + } else if infoStart != infoStop { + info = ast.NewTextSegment(text.NewSegment(infoStart, infoStop)) + } + } + } + node := ast.NewFencedCodeBlock(info) + pc.Set(fencedCodeBlockInfoKey, &fenceData{fenceChar, findent, oFenceLength, node}) + return node, NoChildren + +} + +func (b *fencedCodeBlockParser) Continue(node ast.Node, reader text.Reader, pc Context) State { + line, segment := reader.PeekLine() + fdata := pc.Get(fencedCodeBlockInfoKey).(*fenceData) + + w, pos := util.IndentWidth(line, reader.LineOffset()) + if w < 4 { + i := pos + for ; i < len(line) && line[i] == fdata.char; i++ { + } + length := i - pos + if length >= fdata.length && util.IsBlank(line[i:]) { + newline := 1 + if line[len(line)-1] != '\n' { + newline = 0 + } + reader.Advance(segment.Stop - segment.Start - newline + segment.Padding) + return Close + } + } + pos, padding := util.IndentPositionPadding(line, reader.LineOffset(), segment.Padding, fdata.indent) + if pos < 0 { + pos = util.FirstNonSpacePosition(line) + if pos < 0 { + pos = 0 + } + padding = 0 + } + seg := text.NewSegmentPadding(segment.Start+pos, segment.Stop, padding) + // if code block line starts with a tab, keep a tab as it is. + if padding != 0 { + preserveLeadingTabInCodeBlock(&seg, reader, fdata.indent) + } + node.Lines().Append(seg) + reader.AdvanceAndSetPadding(segment.Stop-segment.Start-pos-1, padding) + return Continue | NoChildren +} + +func (b *fencedCodeBlockParser) Close(node ast.Node, reader text.Reader, pc Context) { + fdata := pc.Get(fencedCodeBlockInfoKey).(*fenceData) + if fdata.node == node { + pc.Set(fencedCodeBlockInfoKey, nil) + } +} + +func (b *fencedCodeBlockParser) CanInterruptParagraph() bool { + return true +} + +func (b *fencedCodeBlockParser) CanAcceptIndentedLine() bool { + return false +} diff --git a/vendor/github.com/yuin/goldmark/parser/html_block.go b/vendor/github.com/yuin/goldmark/parser/html_block.go new file mode 100644 index 0000000..bf0258b --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/html_block.go @@ -0,0 +1,229 @@ +package parser + +import ( + "bytes" + "regexp" + "strings" + + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +var allowedBlockTags = map[string]bool{ + "address": true, + "article": true, + "aside": true, + "base": true, + "basefont": true, + "blockquote": true, + "body": true, + "caption": true, + "center": true, + "col": true, + "colgroup": true, + "dd": true, + "details": true, + "dialog": true, + "dir": true, + "div": true, + "dl": true, + "dt": true, + "fieldset": true, + "figcaption": true, + "figure": true, + "footer": true, + "form": true, + "frame": true, + "frameset": true, + "h1": true, + "h2": true, + "h3": true, + "h4": true, + "h5": true, + "h6": true, + "head": true, + "header": true, + "hr": true, + "html": true, + "iframe": true, + "legend": true, + "li": true, + "link": true, + "main": true, + "menu": true, + "menuitem": true, + "meta": true, + "nav": true, + "noframes": true, + "ol": true, + "optgroup": true, + "option": true, + "p": true, + "param": true, + "section": true, + "source": true, + "summary": true, + "table": true, + "tbody": true, + "td": true, + "tfoot": true, + "th": true, + "thead": true, + "title": true, + "tr": true, + "track": true, + "ul": true, +} + +var htmlBlockType1OpenRegexp = regexp.MustCompile(`(?i)^[ ]{0,3}<(script|pre|style|textarea)(?:\s.*|>.*|/>.*|)(?:\r\n|\n)?$`) //nolint:golint,lll +var htmlBlockType1CloseRegexp = regexp.MustCompile(`(?i)^.*.*`) + +var htmlBlockType2OpenRegexp = regexp.MustCompile(`^[ ]{0,3}'} + +var htmlBlockType3OpenRegexp = regexp.MustCompile(`^[ ]{0,3}<\?`) +var htmlBlockType3Close = []byte{'?', '>'} + +var htmlBlockType4OpenRegexp = regexp.MustCompile(`^[ ]{0,3}'} + +var htmlBlockType5OpenRegexp = regexp.MustCompile(`^[ ]{0,3}<\!\[CDATA\[`) +var htmlBlockType5Close = []byte{']', ']', '>'} + +var htmlBlockType6Regexp = regexp.MustCompile(`^[ ]{0,3}<(?:/[ ]*)?([a-zA-Z]+[a-zA-Z0-9\-]*)(?:[ ].*|>.*|/>.*|)(?:\r\n|\n)?$`) //nolint:golint,lll + +var htmlBlockType7Regexp = regexp.MustCompile(`^[ ]{0,3}<(/[ ]*)?([a-zA-Z]+[a-zA-Z0-9\-]*)(` + attributePattern + `*)[ ]*(?:>|/>)[ ]*(?:\r\n|\n)?$`) //nolint:golint,lll + +type htmlBlockParser struct { +} + +var defaultHTMLBlockParser = &htmlBlockParser{} + +// NewHTMLBlockParser return a new BlockParser that can parse html +// blocks. +func NewHTMLBlockParser() BlockParser { + return defaultHTMLBlockParser +} + +func (b *htmlBlockParser) Trigger() []byte { + return []byte{'<'} +} + +func (b *htmlBlockParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { + var node *ast.HTMLBlock + line, segment := reader.PeekLine() + last := pc.LastOpenedBlock().Node + if pos := pc.BlockOffset(); pos < 0 || line[pos] != '<' { + return nil, NoChildren + } + + if m := htmlBlockType1OpenRegexp.FindSubmatchIndex(line); m != nil { + node = ast.NewHTMLBlock(ast.HTMLBlockType1) + } else if htmlBlockType2OpenRegexp.Match(line) { + node = ast.NewHTMLBlock(ast.HTMLBlockType2) + } else if htmlBlockType3OpenRegexp.Match(line) { + node = ast.NewHTMLBlock(ast.HTMLBlockType3) + } else if htmlBlockType4OpenRegexp.Match(line) { + node = ast.NewHTMLBlock(ast.HTMLBlockType4) + } else if htmlBlockType5OpenRegexp.Match(line) { + node = ast.NewHTMLBlock(ast.HTMLBlockType5) + } else if match := htmlBlockType7Regexp.FindSubmatchIndex(line); match != nil { + isCloseTag := match[2] > -1 && bytes.Equal(line[match[2]:match[3]], []byte("/")) + hasAttr := match[6] != match[7] + tagName := strings.ToLower(string(line[match[4]:match[5]])) + _, ok := allowedBlockTags[tagName] + if ok { + node = ast.NewHTMLBlock(ast.HTMLBlockType6) + } else if tagName != "script" && tagName != "style" && + tagName != "pre" && !ast.IsParagraph(last) && !(isCloseTag && hasAttr) { // type 7 can not interrupt paragraph + node = ast.NewHTMLBlock(ast.HTMLBlockType7) + } + } + if node == nil { + if match := htmlBlockType6Regexp.FindSubmatchIndex(line); match != nil { + tagName := string(line[match[2]:match[3]]) + _, ok := allowedBlockTags[strings.ToLower(tagName)] + if ok { + node = ast.NewHTMLBlock(ast.HTMLBlockType6) + } + } + } + if node != nil { + reader.Advance(segment.Len() - util.TrimRightSpaceLength(line)) + node.Lines().Append(segment) + return node, NoChildren + } + return nil, NoChildren +} + +func (b *htmlBlockParser) Continue(node ast.Node, reader text.Reader, pc Context) State { + htmlBlock := node.(*ast.HTMLBlock) + lines := htmlBlock.Lines() + line, segment := reader.PeekLine() + var closurePattern []byte + + switch htmlBlock.HTMLBlockType { + case ast.HTMLBlockType1: + if lines.Len() == 1 { + firstLine := lines.At(0) + if htmlBlockType1CloseRegexp.Match(firstLine.Value(reader.Source())) { + return Close + } + } + if htmlBlockType1CloseRegexp.Match(line) { + htmlBlock.ClosureLine = segment + reader.Advance(segment.Len() - util.TrimRightSpaceLength(line)) + return Close + } + case ast.HTMLBlockType2: + closurePattern = htmlBlockType2Close + fallthrough + case ast.HTMLBlockType3: + if closurePattern == nil { + closurePattern = htmlBlockType3Close + } + fallthrough + case ast.HTMLBlockType4: + if closurePattern == nil { + closurePattern = htmlBlockType4Close + } + fallthrough + case ast.HTMLBlockType5: + if closurePattern == nil { + closurePattern = htmlBlockType5Close + } + + if lines.Len() == 1 { + firstLine := lines.At(0) + if bytes.Contains(firstLine.Value(reader.Source()), closurePattern) { + return Close + } + } + if bytes.Contains(line, closurePattern) { + htmlBlock.ClosureLine = segment + reader.Advance(segment.Len()) + return Close + } + + case ast.HTMLBlockType6, ast.HTMLBlockType7: + if util.IsBlank(line) { + return Close + } + } + node.Lines().Append(segment) + reader.Advance(segment.Len() - util.TrimRightSpaceLength(line)) + return Continue | NoChildren +} + +func (b *htmlBlockParser) Close(node ast.Node, reader text.Reader, pc Context) { + // nothing to do +} + +func (b *htmlBlockParser) CanInterruptParagraph() bool { + return true +} + +func (b *htmlBlockParser) CanAcceptIndentedLine() bool { + return false +} diff --git a/vendor/github.com/yuin/goldmark/parser/link.go b/vendor/github.com/yuin/goldmark/parser/link.go new file mode 100644 index 0000000..57840bd --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/link.go @@ -0,0 +1,410 @@ +package parser + +import ( + "fmt" + "strings" + + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +var linkLabelStateKey = NewContextKey() + +type linkLabelState struct { + ast.BaseInline + + Segment text.Segment + + IsImage bool + + Prev *linkLabelState + + Next *linkLabelState + + First *linkLabelState + + Last *linkLabelState +} + +func newLinkLabelState(segment text.Segment, isImage bool) *linkLabelState { + return &linkLabelState{ + Segment: segment, + IsImage: isImage, + } +} + +func (s *linkLabelState) Text(source []byte) []byte { + return s.Segment.Value(source) +} + +func (s *linkLabelState) Dump(source []byte, level int) { + fmt.Printf("%slinkLabelState: \"%s\"\n", strings.Repeat(" ", level), s.Text(source)) +} + +var kindLinkLabelState = ast.NewNodeKind("LinkLabelState") + +func (s *linkLabelState) Kind() ast.NodeKind { + return kindLinkLabelState +} + +func linkLabelStateLength(v *linkLabelState) int { + if v == nil || v.Last == nil || v.First == nil { + return 0 + } + return v.Last.Segment.Stop - v.First.Segment.Start +} + +func pushLinkLabelState(pc Context, v *linkLabelState) { + tlist := pc.Get(linkLabelStateKey) + var list *linkLabelState + if tlist == nil { + list = v + v.First = v + v.Last = v + pc.Set(linkLabelStateKey, list) + } else { + list = tlist.(*linkLabelState) + l := list.Last + list.Last = v + l.Next = v + v.Prev = l + } +} + +func removeLinkLabelState(pc Context, d *linkLabelState) { + tlist := pc.Get(linkLabelStateKey) + var list *linkLabelState + if tlist == nil { + return + } + list = tlist.(*linkLabelState) + + if d.Prev == nil { + list = d.Next + if list != nil { + list.First = d + list.Last = d.Last + list.Prev = nil + pc.Set(linkLabelStateKey, list) + } else { + pc.Set(linkLabelStateKey, nil) + } + } else { + d.Prev.Next = d.Next + if d.Next != nil { + d.Next.Prev = d.Prev + } + } + if list != nil && d.Next == nil { + list.Last = d.Prev + } + d.Next = nil + d.Prev = nil + d.First = nil + d.Last = nil +} + +type linkParser struct { +} + +var defaultLinkParser = &linkParser{} + +// NewLinkParser return a new InlineParser that parses links. +func NewLinkParser() InlineParser { + return defaultLinkParser +} + +func (s *linkParser) Trigger() []byte { + return []byte{'!', '[', ']'} +} + +var linkBottom = NewContextKey() + +func (s *linkParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.Node { + line, segment := block.PeekLine() + if line[0] == '!' { + if len(line) > 1 && line[1] == '[' { + block.Advance(1) + pc.Set(linkBottom, pc.LastDelimiter()) + return processLinkLabelOpen(block, segment.Start+1, true, pc) + } + return nil + } + if line[0] == '[' { + pc.Set(linkBottom, pc.LastDelimiter()) + return processLinkLabelOpen(block, segment.Start, false, pc) + } + + // line[0] == ']' + tlist := pc.Get(linkLabelStateKey) + if tlist == nil { + return nil + } + last := tlist.(*linkLabelState).Last + if last == nil { + return nil + } + block.Advance(1) + removeLinkLabelState(pc, last) + // CommonMark spec says: + // > A link label can have at most 999 characters inside the square brackets. + if linkLabelStateLength(tlist.(*linkLabelState)) > 998 { + ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment) + return nil + } + + if !last.IsImage && s.containsLink(last) { // a link in a link text is not allowed + ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment) + return nil + } + + c := block.Peek() + l, pos := block.Position() + var link *ast.Link + var hasValue bool + if c == '(' { // normal link + link = s.parseLink(parent, last, block, pc) + } else if c == '[' { // reference link + link, hasValue = s.parseReferenceLink(parent, last, block, pc) + if link == nil && hasValue { + ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment) + return nil + } + } + + if link == nil { + // maybe shortcut reference link + block.SetPosition(l, pos) + ssegment := text.NewSegment(last.Segment.Stop, segment.Start) + maybeReference := block.Value(ssegment) + // CommonMark spec says: + // > A link label can have at most 999 characters inside the square brackets. + if len(maybeReference) > 999 { + ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment) + return nil + } + + ref, ok := pc.Reference(util.ToLinkReference(maybeReference)) + if !ok { + ast.MergeOrReplaceTextSegment(last.Parent(), last, last.Segment) + return nil + } + link = ast.NewLink() + s.processLinkLabel(parent, link, last, pc) + link.Title = ref.Title() + link.Destination = ref.Destination() + } + if last.IsImage { + last.Parent().RemoveChild(last.Parent(), last) + return ast.NewImage(link) + } + last.Parent().RemoveChild(last.Parent(), last) + return link +} + +func (s *linkParser) containsLink(n ast.Node) bool { + if n == nil { + return false + } + for c := n; c != nil; c = c.NextSibling() { + if _, ok := c.(*ast.Link); ok { + return true + } + if s.containsLink(c.FirstChild()) { + return true + } + } + return false +} + +func processLinkLabelOpen(block text.Reader, pos int, isImage bool, pc Context) *linkLabelState { + start := pos + if isImage { + start-- + } + state := newLinkLabelState(text.NewSegment(start, pos+1), isImage) + pushLinkLabelState(pc, state) + block.Advance(1) + return state +} + +func (s *linkParser) processLinkLabel(parent ast.Node, link *ast.Link, last *linkLabelState, pc Context) { + var bottom ast.Node + if v := pc.Get(linkBottom); v != nil { + bottom = v.(ast.Node) + } + pc.Set(linkBottom, nil) + ProcessDelimiters(bottom, pc) + for c := last.NextSibling(); c != nil; { + next := c.NextSibling() + parent.RemoveChild(parent, c) + link.AppendChild(link, c) + c = next + } +} + +var linkFindClosureOptions text.FindClosureOptions = text.FindClosureOptions{ + Nesting: false, + Newline: true, + Advance: true, +} + +func (s *linkParser) parseReferenceLink(parent ast.Node, last *linkLabelState, + block text.Reader, pc Context) (*ast.Link, bool) { + _, orgpos := block.Position() + block.Advance(1) // skip '[' + segments, found := block.FindClosure('[', ']', linkFindClosureOptions) + if !found { + return nil, false + } + + var maybeReference []byte + if segments.Len() == 1 { // avoid allocate a new byte slice + maybeReference = block.Value(segments.At(0)) + } else { + maybeReference = []byte{} + for i := 0; i < segments.Len(); i++ { + s := segments.At(i) + maybeReference = append(maybeReference, block.Value(s)...) + } + } + if util.IsBlank(maybeReference) { // collapsed reference link + s := text.NewSegment(last.Segment.Stop, orgpos.Start-1) + maybeReference = block.Value(s) + } + // CommonMark spec says: + // > A link label can have at most 999 characters inside the square brackets. + if len(maybeReference) > 999 { + return nil, true + } + + ref, ok := pc.Reference(util.ToLinkReference(maybeReference)) + if !ok { + return nil, true + } + + link := ast.NewLink() + s.processLinkLabel(parent, link, last, pc) + link.Title = ref.Title() + link.Destination = ref.Destination() + return link, true +} + +func (s *linkParser) parseLink(parent ast.Node, last *linkLabelState, block text.Reader, pc Context) *ast.Link { + block.Advance(1) // skip '(' + block.SkipSpaces() + var title []byte + var destination []byte + var ok bool + if block.Peek() == ')' { // empty link like '[link]()' + block.Advance(1) + } else { + destination, ok = parseLinkDestination(block) + if !ok { + return nil + } + block.SkipSpaces() + if block.Peek() == ')' { + block.Advance(1) + } else { + title, ok = parseLinkTitle(block) + if !ok { + return nil + } + block.SkipSpaces() + if block.Peek() == ')' { + block.Advance(1) + } else { + return nil + } + } + } + + link := ast.NewLink() + s.processLinkLabel(parent, link, last, pc) + link.Destination = destination + link.Title = title + return link +} + +func parseLinkDestination(block text.Reader) ([]byte, bool) { + block.SkipSpaces() + line, _ := block.PeekLine() + if block.Peek() == '<' { + i := 1 + for i < len(line) { + c := line[i] + if c == '\\' && i < len(line)-1 && util.IsPunct(line[i+1]) { + i += 2 + continue + } else if c == '>' { + block.Advance(i + 1) + return line[1:i], true + } + i++ + } + return nil, false + } + opened := 0 + i := 0 + for i < len(line) { + c := line[i] + if c == '\\' && i < len(line)-1 && util.IsPunct(line[i+1]) { + i += 2 + continue + } else if c == '(' { + opened++ + } else if c == ')' { + opened-- + if opened < 0 { + break + } + } else if util.IsSpace(c) { + break + } + i++ + } + block.Advance(i) + return line[:i], len(line[:i]) != 0 +} + +func parseLinkTitle(block text.Reader) ([]byte, bool) { + block.SkipSpaces() + opener := block.Peek() + if opener != '"' && opener != '\'' && opener != '(' { + return nil, false + } + closer := opener + if opener == '(' { + closer = ')' + } + block.Advance(1) + segments, found := block.FindClosure(opener, closer, linkFindClosureOptions) + if found { + if segments.Len() == 1 { + return block.Value(segments.At(0)), true + } + var title []byte + for i := 0; i < segments.Len(); i++ { + s := segments.At(i) + title = append(title, block.Value(s)...) + } + return title, true + } + return nil, false +} + +func (s *linkParser) CloseBlock(parent ast.Node, block text.Reader, pc Context) { + pc.Set(linkBottom, nil) + tlist := pc.Get(linkLabelStateKey) + if tlist == nil { + return + } + for s := tlist.(*linkLabelState); s != nil; { + next := s.Next + removeLinkLabelState(pc, s) + s.Parent().ReplaceChild(s.Parent(), s, ast.NewTextSegment(s.Segment)) + s = next + } +} diff --git a/vendor/github.com/yuin/goldmark/parser/link_ref.go b/vendor/github.com/yuin/goldmark/parser/link_ref.go new file mode 100644 index 0000000..ea3f654 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/link_ref.go @@ -0,0 +1,152 @@ +package parser + +import ( + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type linkReferenceParagraphTransformer struct { +} + +// LinkReferenceParagraphTransformer is a ParagraphTransformer implementation +// that parses and extracts link reference from paragraphs. +var LinkReferenceParagraphTransformer = &linkReferenceParagraphTransformer{} + +func (p *linkReferenceParagraphTransformer) Transform(node *ast.Paragraph, reader text.Reader, pc Context) { + lines := node.Lines() + block := text.NewBlockReader(reader.Source(), lines) + removes := [][2]int{} + for { + start, end := parseLinkReferenceDefinition(block, pc) + if start > -1 { + if start == end { + end++ + } + removes = append(removes, [2]int{start, end}) + continue + } + break + } + + offset := 0 + for _, remove := range removes { + if lines.Len() == 0 { + break + } + s := lines.Sliced(remove[1]-offset, lines.Len()) + lines.SetSliced(0, remove[0]-offset) + lines.AppendAll(s) + offset = remove[1] + } + + if lines.Len() == 0 { + t := ast.NewTextBlock() + t.SetBlankPreviousLines(node.HasBlankPreviousLines()) + node.Parent().ReplaceChild(node.Parent(), node, t) + return + } + + node.SetLines(lines) +} + +func parseLinkReferenceDefinition(block text.Reader, pc Context) (int, int) { + block.SkipSpaces() + line, _ := block.PeekLine() + if line == nil { + return -1, -1 + } + startLine, _ := block.Position() + width, pos := util.IndentWidth(line, 0) + if width > 3 { + return -1, -1 + } + if width != 0 { + pos++ + } + if line[pos] != '[' { + return -1, -1 + } + block.Advance(pos + 1) + segments, found := block.FindClosure('[', ']', linkFindClosureOptions) + if !found { + return -1, -1 + } + var label []byte + if segments.Len() == 1 { + label = block.Value(segments.At(0)) + } else { + for i := 0; i < segments.Len(); i++ { + s := segments.At(i) + label = append(label, block.Value(s)...) + } + } + if util.IsBlank(label) { + return -1, -1 + } + if block.Peek() != ':' { + return -1, -1 + } + block.Advance(1) + block.SkipSpaces() + destination, ok := parseLinkDestination(block) + if !ok { + return -1, -1 + } + line, _ = block.PeekLine() + isNewLine := line == nil || util.IsBlank(line) + + endLine, _ := block.Position() + _, spaces, _ := block.SkipSpaces() + opener := block.Peek() + if opener != '"' && opener != '\'' && opener != '(' { + if !isNewLine { + return -1, -1 + } + ref := NewReference(label, destination, nil) + pc.AddReference(ref) + return startLine, endLine + 1 + } + if spaces == 0 { + return -1, -1 + } + block.Advance(1) + closer := opener + if opener == '(' { + closer = ')' + } + segments, found = block.FindClosure(opener, closer, linkFindClosureOptions) + if !found { + if !isNewLine { + return -1, -1 + } + ref := NewReference(label, destination, nil) + pc.AddReference(ref) + block.AdvanceLine() + return startLine, endLine + 1 + } + var title []byte + if segments.Len() == 1 { + title = block.Value(segments.At(0)) + } else { + for i := 0; i < segments.Len(); i++ { + s := segments.At(i) + title = append(title, block.Value(s)...) + } + } + + line, _ = block.PeekLine() + if line != nil && !util.IsBlank(line) { + if !isNewLine { + return -1, -1 + } + ref := NewReference(label, destination, title) + pc.AddReference(ref) + return startLine, endLine + } + + endLine, _ = block.Position() + ref := NewReference(label, destination, title) + pc.AddReference(ref) + return startLine, endLine + 1 +} diff --git a/vendor/github.com/yuin/goldmark/parser/list.go b/vendor/github.com/yuin/goldmark/parser/list.go new file mode 100644 index 0000000..3e0eea6 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/list.go @@ -0,0 +1,287 @@ +package parser + +import ( + "strconv" + + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type listItemType int + +const ( + notList listItemType = iota + bulletList + orderedList +) + +var skipListParserKey = NewContextKey() +var emptyListItemWithBlankLines = NewContextKey() +var listItemFlagValue interface{} = true + +// Same as +// `^(([ ]*)([\-\*\+]))(\s+.*)?\n?$`.FindSubmatchIndex or +// `^(([ ]*)(\d{1,9}[\.\)]))(\s+.*)?\n?$`.FindSubmatchIndex. +func parseListItem(line []byte) ([6]int, listItemType) { + i := 0 + l := len(line) + ret := [6]int{} + for ; i < l && line[i] == ' '; i++ { + c := line[i] + if c == '\t' { + return ret, notList + } + } + if i > 3 { + return ret, notList + } + ret[0] = 0 + ret[1] = i + ret[2] = i + var typ listItemType + if i < l && (line[i] == '-' || line[i] == '*' || line[i] == '+') { + i++ + ret[3] = i + typ = bulletList + } else if i < l { + for ; i < l && util.IsNumeric(line[i]); i++ { + } + ret[3] = i + if ret[3] == ret[2] || ret[3]-ret[2] > 9 { + return ret, notList + } + if i < l && (line[i] == '.' || line[i] == ')') { + i++ + ret[3] = i + } else { + return ret, notList + } + typ = orderedList + } else { + return ret, notList + } + if i < l && line[i] != '\n' { + w, _ := util.IndentWidth(line[i:], 0) + if w == 0 { + return ret, notList + } + } + if i >= l { + ret[4] = -1 + ret[5] = -1 + return ret, typ + } + ret[4] = i + ret[5] = len(line) + if line[ret[5]-1] == '\n' && line[i] != '\n' { + ret[5]-- + } + return ret, typ +} + +func matchesListItem(source []byte, strict bool) ([6]int, listItemType) { + m, typ := parseListItem(source) + if typ != notList && (!strict || strict && m[1] < 4) { + return m, typ + } + return m, notList +} + +func calcListOffset(source []byte, match [6]int) int { + var offset int + if match[4] < 0 || util.IsBlank(source[match[4]:]) { // list item starts with a blank line + offset = 1 + } else { + offset, _ = util.IndentWidth(source[match[4]:], match[4]) + if offset > 4 { // offseted codeblock + offset = 1 + } + } + return offset +} + +func lastOffset(node ast.Node) int { + lastChild := node.LastChild() + if lastChild != nil { + return lastChild.(*ast.ListItem).Offset + } + return 0 +} + +type listParser struct { +} + +var defaultListParser = &listParser{} + +// NewListParser returns a new BlockParser that +// parses lists. +// This parser must take precedence over the ListItemParser. +func NewListParser() BlockParser { + return defaultListParser +} + +func (b *listParser) Trigger() []byte { + return []byte{'-', '+', '*', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} +} + +func (b *listParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { + last := pc.LastOpenedBlock().Node + if _, lok := last.(*ast.List); lok || pc.Get(skipListParserKey) != nil { + pc.Set(skipListParserKey, nil) + return nil, NoChildren + } + line, _ := reader.PeekLine() + match, typ := matchesListItem(line, true) + if typ == notList { + return nil, NoChildren + } + start := -1 + if typ == orderedList { + number := line[match[2] : match[3]-1] + start, _ = strconv.Atoi(string(number)) + } + + if ast.IsParagraph(last) && last.Parent() == parent { + // we allow only lists starting with 1 to interrupt paragraphs. + if typ == orderedList && start != 1 { + return nil, NoChildren + } + //an empty list item cannot interrupt a paragraph: + if match[4] < 0 || util.IsBlank(line[match[4]:match[5]]) { + return nil, NoChildren + } + } + + marker := line[match[3]-1] + node := ast.NewList(marker) + if start > -1 { + node.Start = start + } + pc.Set(emptyListItemWithBlankLines, nil) + return node, HasChildren +} + +func (b *listParser) Continue(node ast.Node, reader text.Reader, pc Context) State { + list := node.(*ast.List) + line, _ := reader.PeekLine() + if util.IsBlank(line) { + if node.LastChild().ChildCount() == 0 { + pc.Set(emptyListItemWithBlankLines, listItemFlagValue) + } + return Continue | HasChildren + } + + // "offset" means a width that bar indicates. + // - aaaaaaaa + // |----| + // + // If the indent is less than the last offset like + // - a + // - b <--- current line + // it maybe a new child of the list. + // + // Empty list items can have multiple blanklines + // + // - <--- 1st item is an empty thus "offset" is unknown + // + // + // - <--- current line + // + // -> 1 list with 2 blank items + // + // So if the last item is an empty, it maybe a new child of the list. + // + offset := lastOffset(node) + lastIsEmpty := node.LastChild().ChildCount() == 0 + indent, _ := util.IndentWidth(line, reader.LineOffset()) + + if indent < offset || lastIsEmpty { + if indent < 4 { + match, typ := matchesListItem(line, false) // may have a leading spaces more than 3 + if typ != notList && match[1]-offset < 4 { + marker := line[match[3]-1] + if !list.CanContinue(marker, typ == orderedList) { + return Close + } + // Thematic Breaks take precedence over lists + if isThematicBreak(line[match[3]-1:], 0) { + isHeading := false + last := pc.LastOpenedBlock().Node + if ast.IsParagraph(last) { + c, ok := matchesSetextHeadingBar(line[match[3]-1:]) + if ok && c == '-' { + isHeading = true + } + } + if !isHeading { + return Close + } + } + return Continue | HasChildren + } + } + if !lastIsEmpty { + return Close + } + } + + if lastIsEmpty && indent < offset { + return Close + } + + // Non empty items can not exist next to an empty list item + // with blank lines. So we need to close the current list + // + // - + // + // foo + // + // -> 1 list with 1 blank items and 1 paragraph + if pc.Get(emptyListItemWithBlankLines) != nil { + return Close + } + return Continue | HasChildren +} + +func (b *listParser) Close(node ast.Node, reader text.Reader, pc Context) { + list := node.(*ast.List) + + for c := node.FirstChild(); c != nil && list.IsTight; c = c.NextSibling() { + if c.FirstChild() != nil && c.FirstChild() != c.LastChild() { + for c1 := c.FirstChild().NextSibling(); c1 != nil; c1 = c1.NextSibling() { + if c1.HasBlankPreviousLines() { + list.IsTight = false + break + } + } + } + if c != node.FirstChild() { + if c.HasBlankPreviousLines() { + list.IsTight = false + } + } + } + + if list.IsTight { + for child := node.FirstChild(); child != nil; child = child.NextSibling() { + for gc := child.FirstChild(); gc != nil; { + paragraph, ok := gc.(*ast.Paragraph) + gc = gc.NextSibling() + if ok { + textBlock := ast.NewTextBlock() + textBlock.SetLines(paragraph.Lines()) + child.ReplaceChild(child, paragraph, textBlock) + } + } + } + } +} + +func (b *listParser) CanInterruptParagraph() bool { + return true +} + +func (b *listParser) CanAcceptIndentedLine() bool { + return false +} diff --git a/vendor/github.com/yuin/goldmark/parser/list_item.go b/vendor/github.com/yuin/goldmark/parser/list_item.go new file mode 100644 index 0000000..81357a9 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/list_item.go @@ -0,0 +1,90 @@ +package parser + +import ( + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type listItemParser struct { +} + +var defaultListItemParser = &listItemParser{} + +// NewListItemParser returns a new BlockParser that +// parses list items. +func NewListItemParser() BlockParser { + return defaultListItemParser +} + +func (b *listItemParser) Trigger() []byte { + return []byte{'-', '+', '*', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'} +} + +func (b *listItemParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { + list, lok := parent.(*ast.List) + if !lok { // list item must be a child of a list + return nil, NoChildren + } + offset := lastOffset(list) + line, _ := reader.PeekLine() + match, typ := matchesListItem(line, false) + if typ == notList { + return nil, NoChildren + } + if match[1]-offset > 3 { + return nil, NoChildren + } + + pc.Set(emptyListItemWithBlankLines, nil) + + itemOffset := calcListOffset(line, match) + node := ast.NewListItem(match[3] + itemOffset) + if match[4] < 0 || util.IsBlank(line[match[4]:match[5]]) { + return node, NoChildren + } + + pos, padding := util.IndentPosition(line[match[4]:], match[4], itemOffset) + child := match[3] + pos + reader.AdvanceAndSetPadding(child, padding) + return node, HasChildren +} + +func (b *listItemParser) Continue(node ast.Node, reader text.Reader, pc Context) State { + line, _ := reader.PeekLine() + if util.IsBlank(line) { + reader.Advance(len(line) - 1) + return Continue | HasChildren + } + + offset := lastOffset(node.Parent()) + isEmpty := node.ChildCount() == 0 + indent, _ := util.IndentWidth(line, reader.LineOffset()) + if (isEmpty || indent < offset) && indent < 4 { + _, typ := matchesListItem(line, true) + // new list item found + if typ != notList { + pc.Set(skipListParserKey, listItemFlagValue) + return Close + } + if !isEmpty { + return Close + } + } + pos, padding := util.IndentPosition(line, reader.LineOffset(), offset) + reader.AdvanceAndSetPadding(pos, padding) + + return Continue | HasChildren +} + +func (b *listItemParser) Close(node ast.Node, reader text.Reader, pc Context) { + // nothing to do +} + +func (b *listItemParser) CanInterruptParagraph() bool { + return true +} + +func (b *listItemParser) CanAcceptIndentedLine() bool { + return false +} diff --git a/vendor/github.com/yuin/goldmark/parser/paragraph.go b/vendor/github.com/yuin/goldmark/parser/paragraph.go new file mode 100644 index 0000000..9d3fa38 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/paragraph.go @@ -0,0 +1,72 @@ +package parser + +import ( + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type paragraphParser struct { +} + +var defaultParagraphParser = ¶graphParser{} + +// NewParagraphParser returns a new BlockParser that +// parses paragraphs. +func NewParagraphParser() BlockParser { + return defaultParagraphParser +} + +func (b *paragraphParser) Trigger() []byte { + return nil +} + +func (b *paragraphParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { + _, segment := reader.PeekLine() + segment = segment.TrimLeftSpace(reader.Source()) + if segment.IsEmpty() { + return nil, NoChildren + } + node := ast.NewParagraph() + node.Lines().Append(segment) + reader.Advance(segment.Len() - 1) + return node, NoChildren +} + +func (b *paragraphParser) Continue(node ast.Node, reader text.Reader, pc Context) State { + line, segment := reader.PeekLine() + if util.IsBlank(line) { + return Close + } + node.Lines().Append(segment) + reader.Advance(segment.Len() - 1) + return Continue | NoChildren +} + +func (b *paragraphParser) Close(node ast.Node, reader text.Reader, pc Context) { + lines := node.Lines() + if lines.Len() != 0 { + // trim leading spaces + for i := 0; i < lines.Len(); i++ { + l := lines.At(i) + lines.Set(i, l.TrimLeftSpace(reader.Source())) + } + + // trim trailing spaces + length := lines.Len() + lastLine := node.Lines().At(length - 1) + node.Lines().Set(length-1, lastLine.TrimRightSpace(reader.Source())) + } + if lines.Len() == 0 { + node.Parent().RemoveChild(node.Parent(), node) + return + } +} + +func (b *paragraphParser) CanInterruptParagraph() bool { + return false +} + +func (b *paragraphParser) CanAcceptIndentedLine() bool { + return false +} diff --git a/vendor/github.com/yuin/goldmark/parser/parser.go b/vendor/github.com/yuin/goldmark/parser/parser.go new file mode 100644 index 0000000..5cc2175 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/parser.go @@ -0,0 +1,1259 @@ +// Package parser contains stuff that are related to parsing a Markdown text. +package parser + +import ( + "fmt" + "strings" + "sync" + + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +// A Reference interface represents a link reference in Markdown text. +type Reference interface { + // String implements Stringer. + String() string + + // Label returns a label of the reference. + Label() []byte + + // Destination returns a destination(URL) of the reference. + Destination() []byte + + // Title returns a title of the reference. + Title() []byte +} + +type reference struct { + label []byte + destination []byte + title []byte +} + +// NewReference returns a new Reference. +func NewReference(label, destination, title []byte) Reference { + return &reference{label, destination, title} +} + +func (r *reference) Label() []byte { + return r.label +} + +func (r *reference) Destination() []byte { + return r.destination +} + +func (r *reference) Title() []byte { + return r.title +} + +func (r *reference) String() string { + return fmt.Sprintf("Reference{Label:%s, Destination:%s, Title:%s}", r.label, r.destination, r.title) +} + +// An IDs interface is a collection of the element ids. +type IDs interface { + // Generate generates a new element id. + Generate(value []byte, kind ast.NodeKind) []byte + + // Put puts a given element id to the used ids table. + Put(value []byte) +} + +type ids struct { + values map[string]bool +} + +func newIDs() IDs { + return &ids{ + values: map[string]bool{}, + } +} + +func (s *ids) Generate(value []byte, kind ast.NodeKind) []byte { + value = util.TrimLeftSpace(value) + value = util.TrimRightSpace(value) + result := []byte{} + for i := 0; i < len(value); { + v := value[i] + l := util.UTF8Len(v) + i += int(l) + if l != 1 { + continue + } + if util.IsAlphaNumeric(v) { + if 'A' <= v && v <= 'Z' { + v += 'a' - 'A' + } + result = append(result, v) + } else if util.IsSpace(v) || v == '-' || v == '_' { + result = append(result, '-') + } + } + if len(result) == 0 { + if kind == ast.KindHeading { + result = []byte("heading") + } else { + result = []byte("id") + } + } + if _, ok := s.values[util.BytesToReadOnlyString(result)]; !ok { + s.values[util.BytesToReadOnlyString(result)] = true + return result + } + for i := 1; ; i++ { + newResult := fmt.Sprintf("%s-%d", result, i) + if _, ok := s.values[newResult]; !ok { + s.values[newResult] = true + return []byte(newResult) + } + + } +} + +func (s *ids) Put(value []byte) { + s.values[util.BytesToReadOnlyString(value)] = true +} + +// ContextKey is a key that is used to set arbitrary values to the context. +type ContextKey int + +// ContextKeyMax is a maximum value of the ContextKey. +var ContextKeyMax ContextKey + +// NewContextKey return a new ContextKey value. +func NewContextKey() ContextKey { + ContextKeyMax++ + return ContextKeyMax +} + +// A Context interface holds a information that are necessary to parse +// Markdown text. +type Context interface { + // String implements Stringer. + String() string + + // Get returns a value associated with the given key. + Get(ContextKey) interface{} + + // ComputeIfAbsent computes a value if a value associated with the given key is absent and returns the value. + ComputeIfAbsent(ContextKey, func() interface{}) interface{} + + // Set sets the given value to the context. + Set(ContextKey, interface{}) + + // AddReference adds the given reference to this context. + AddReference(Reference) + + // Reference returns (a reference, true) if a reference associated with + // the given label exists, otherwise (nil, false). + Reference(label string) (Reference, bool) + + // References returns a list of references. + References() []Reference + + // IDs returns a collection of the element ids. + IDs() IDs + + // BlockOffset returns a first non-space character position on current line. + // This value is valid only for BlockParser.Open. + // BlockOffset returns -1 if current line is blank. + BlockOffset() int + + // BlockOffset sets a first non-space character position on current line. + // This value is valid only for BlockParser.Open. + SetBlockOffset(int) + + // BlockIndent returns an indent width on current line. + // This value is valid only for BlockParser.Open. + // BlockIndent returns -1 if current line is blank. + BlockIndent() int + + // BlockIndent sets an indent width on current line. + // This value is valid only for BlockParser.Open. + SetBlockIndent(int) + + // FirstDelimiter returns a first delimiter of the current delimiter list. + FirstDelimiter() *Delimiter + + // LastDelimiter returns a last delimiter of the current delimiter list. + LastDelimiter() *Delimiter + + // PushDelimiter appends the given delimiter to the tail of the current + // delimiter list. + PushDelimiter(delimiter *Delimiter) + + // RemoveDelimiter removes the given delimiter from the current delimiter list. + RemoveDelimiter(d *Delimiter) + + // ClearDelimiters clears the current delimiter list. + ClearDelimiters(bottom ast.Node) + + // OpenedBlocks returns a list of nodes that are currently in parsing. + OpenedBlocks() []Block + + // SetOpenedBlocks sets a list of nodes that are currently in parsing. + SetOpenedBlocks([]Block) + + // LastOpenedBlock returns a last node that is currently in parsing. + LastOpenedBlock() Block + + // IsInLinkLabel returns true if current position seems to be in link label. + IsInLinkLabel() bool +} + +// A ContextConfig struct is a data structure that holds configuration of the Context. +type ContextConfig struct { + IDs IDs +} + +// An ContextOption is a functional option type for the Context. +type ContextOption func(*ContextConfig) + +// WithIDs is a functional option for the Context. +func WithIDs(ids IDs) ContextOption { + return func(c *ContextConfig) { + c.IDs = ids + } +} + +type parseContext struct { + store []interface{} + ids IDs + refs map[string]Reference + blockOffset int + blockIndent int + delimiters *Delimiter + lastDelimiter *Delimiter + openedBlocks []Block +} + +// NewContext returns a new Context. +func NewContext(options ...ContextOption) Context { + cfg := &ContextConfig{ + IDs: newIDs(), + } + for _, option := range options { + option(cfg) + } + + return &parseContext{ + store: make([]interface{}, ContextKeyMax+1), + refs: map[string]Reference{}, + ids: cfg.IDs, + blockOffset: -1, + blockIndent: -1, + delimiters: nil, + lastDelimiter: nil, + openedBlocks: []Block{}, + } +} + +func (p *parseContext) Get(key ContextKey) interface{} { + return p.store[key] +} + +func (p *parseContext) ComputeIfAbsent(key ContextKey, f func() interface{}) interface{} { + v := p.store[key] + if v == nil { + v = f() + p.store[key] = v + } + return v +} + +func (p *parseContext) Set(key ContextKey, value interface{}) { + p.store[key] = value +} + +func (p *parseContext) IDs() IDs { + return p.ids +} + +func (p *parseContext) BlockOffset() int { + return p.blockOffset +} + +func (p *parseContext) SetBlockOffset(v int) { + p.blockOffset = v +} + +func (p *parseContext) BlockIndent() int { + return p.blockIndent +} + +func (p *parseContext) SetBlockIndent(v int) { + p.blockIndent = v +} + +func (p *parseContext) LastDelimiter() *Delimiter { + return p.lastDelimiter +} + +func (p *parseContext) FirstDelimiter() *Delimiter { + return p.delimiters +} + +func (p *parseContext) PushDelimiter(d *Delimiter) { + if p.delimiters == nil { + p.delimiters = d + p.lastDelimiter = d + } else { + l := p.lastDelimiter + p.lastDelimiter = d + l.NextDelimiter = d + d.PreviousDelimiter = l + } +} + +func (p *parseContext) RemoveDelimiter(d *Delimiter) { + if d.PreviousDelimiter == nil { + p.delimiters = d.NextDelimiter + } else { + d.PreviousDelimiter.NextDelimiter = d.NextDelimiter + if d.NextDelimiter != nil { + d.NextDelimiter.PreviousDelimiter = d.PreviousDelimiter + } + } + if d.NextDelimiter == nil { + p.lastDelimiter = d.PreviousDelimiter + } + if p.delimiters != nil { + p.delimiters.PreviousDelimiter = nil + } + if p.lastDelimiter != nil { + p.lastDelimiter.NextDelimiter = nil + } + d.NextDelimiter = nil + d.PreviousDelimiter = nil + if d.Length != 0 { + ast.MergeOrReplaceTextSegment(d.Parent(), d, d.Segment) + } else { + d.Parent().RemoveChild(d.Parent(), d) + } +} + +func (p *parseContext) ClearDelimiters(bottom ast.Node) { + if p.lastDelimiter == nil { + return + } + var c ast.Node + for c = p.lastDelimiter; c != nil && c != bottom; { + prev := c.PreviousSibling() + if d, ok := c.(*Delimiter); ok { + p.RemoveDelimiter(d) + } + c = prev + } +} + +func (p *parseContext) AddReference(ref Reference) { + key := util.ToLinkReference(ref.Label()) + if _, ok := p.refs[key]; !ok { + p.refs[key] = ref + } +} + +func (p *parseContext) Reference(label string) (Reference, bool) { + v, ok := p.refs[label] + return v, ok +} + +func (p *parseContext) References() []Reference { + ret := make([]Reference, 0, len(p.refs)) + for _, v := range p.refs { + ret = append(ret, v) + } + return ret +} + +func (p *parseContext) String() string { + refs := []string{} + for _, r := range p.refs { + refs = append(refs, r.String()) + } + + return fmt.Sprintf("Context{Store:%#v, Refs:%s}", p.store, strings.Join(refs, ",")) +} + +func (p *parseContext) OpenedBlocks() []Block { + return p.openedBlocks +} + +func (p *parseContext) SetOpenedBlocks(v []Block) { + p.openedBlocks = v +} + +func (p *parseContext) LastOpenedBlock() Block { + if l := len(p.openedBlocks); l != 0 { + return p.openedBlocks[l-1] + } + return Block{} +} + +func (p *parseContext) IsInLinkLabel() bool { + tlist := p.Get(linkLabelStateKey) + return tlist != nil +} + +// State represents parser's state. +// State is designed to use as a bit flag. +type State int + +const ( + // None is a default value of the [State]. + None State = 1 << iota + + // Continue indicates parser can continue parsing. + Continue + + // Close indicates parser cannot parse anymore. + Close + + // HasChildren indicates parser may have child blocks. + HasChildren + + // NoChildren indicates parser does not have child blocks. + NoChildren + + // RequireParagraph indicates parser requires that the last node + // must be a paragraph and is not converted to other nodes by + // ParagraphTransformers. + RequireParagraph +) + +// A Config struct is a data structure that holds configuration of the Parser. +type Config struct { + Options map[OptionName]interface{} + BlockParsers util.PrioritizedSlice /**/ + InlineParsers util.PrioritizedSlice /**/ + ParagraphTransformers util.PrioritizedSlice /**/ + ASTTransformers util.PrioritizedSlice /**/ + EscapedSpace bool +} + +// NewConfig returns a new Config. +func NewConfig() *Config { + return &Config{ + Options: map[OptionName]interface{}{}, + BlockParsers: util.PrioritizedSlice{}, + InlineParsers: util.PrioritizedSlice{}, + ParagraphTransformers: util.PrioritizedSlice{}, + ASTTransformers: util.PrioritizedSlice{}, + } +} + +// An Option interface is a functional option type for the Parser. +type Option interface { + SetParserOption(*Config) +} + +// OptionName is a name of parser options. +type OptionName string + +// Attribute is an option name that spacify attributes of elements. +const optAttribute OptionName = "Attribute" + +type withAttribute struct { +} + +func (o *withAttribute) SetParserOption(c *Config) { + c.Options[optAttribute] = true +} + +// WithAttribute is a functional option that enables custom attributes. +func WithAttribute() Option { + return &withAttribute{} +} + +// A Parser interface parses Markdown text into AST nodes. +type Parser interface { + // Parse parses the given Markdown text into AST nodes. + Parse(reader text.Reader, opts ...ParseOption) ast.Node + + // AddOption adds the given option to this parser. + AddOptions(...Option) +} + +// A SetOptioner interface sets the given option to the object. +type SetOptioner interface { + // SetOption sets the given option to the object. + // Unacceptable options may be passed. + // Thus implementations must ignore unacceptable options. + SetOption(name OptionName, value interface{}) +} + +// A BlockParser interface parses a block level element like Paragraph, List, +// Blockquote etc. +type BlockParser interface { + // Trigger returns a list of characters that triggers Parse method of + // this parser. + // If Trigger returns a nil, Open will be called with any lines. + Trigger() []byte + + // Open parses the current line and returns a result of parsing. + // + // Open must not parse beyond the current line. + // If Open has been able to parse the current line, Open must advance a reader + // position by consumed byte length. + // + // If Open has not been able to parse the current line, Open should returns + // (nil, NoChildren). If Open has been able to parse the current line, Open + // should returns a new Block node and returns HasChildren or NoChildren. + Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) + + // Continue parses the current line and returns a result of parsing. + // + // Continue must not parse beyond the current line. + // If Continue has been able to parse the current line, Continue must advance + // a reader position by consumed byte length. + // + // If Continue has not been able to parse the current line, Continue should + // returns Close. If Continue has been able to parse the current line, + // Continue should returns (Continue | NoChildren) or + // (Continue | HasChildren) + Continue(node ast.Node, reader text.Reader, pc Context) State + + // Close will be called when the parser returns Close. + Close(node ast.Node, reader text.Reader, pc Context) + + // CanInterruptParagraph returns true if the parser can interrupt paragraphs, + // otherwise false. + CanInterruptParagraph() bool + + // CanAcceptIndentedLine returns true if the parser can open new node when + // the given line is being indented more than 3 spaces. + CanAcceptIndentedLine() bool +} + +// An InlineParser interface parses an inline level element like CodeSpan, Link etc. +type InlineParser interface { + // Trigger returns a list of characters that triggers Parse method of + // this parser. + // Trigger characters must be a punctuation or a halfspace. + // Halfspaces triggers this parser when character is any spaces characters or + // a head of line + Trigger() []byte + + // Parse parse the given block into an inline node. + // + // Parse can parse beyond the current line. + // If Parse has been able to parse the current line, it must advance a reader + // position by consumed byte length. + Parse(parent ast.Node, block text.Reader, pc Context) ast.Node +} + +// A CloseBlocker interface is a callback function that will be +// called when block is closed in the inline parsing. +type CloseBlocker interface { + // CloseBlock will be called when a block is closed. + CloseBlock(parent ast.Node, block text.Reader, pc Context) +} + +// A ParagraphTransformer transforms parsed Paragraph nodes. +// For example, link references are searched in parsed Paragraphs. +type ParagraphTransformer interface { + // Transform transforms the given paragraph. + Transform(node *ast.Paragraph, reader text.Reader, pc Context) +} + +// ASTTransformer transforms entire Markdown document AST tree. +type ASTTransformer interface { + // Transform transforms the given AST tree. + Transform(node *ast.Document, reader text.Reader, pc Context) +} + +// DefaultBlockParsers returns a new list of default BlockParsers. +// Priorities of default BlockParsers are: +// +// SetextHeadingParser, 100 +// ThematicBreakParser, 200 +// ListParser, 300 +// ListItemParser, 400 +// CodeBlockParser, 500 +// ATXHeadingParser, 600 +// FencedCodeBlockParser, 700 +// BlockquoteParser, 800 +// HTMLBlockParser, 900 +// ParagraphParser, 1000 +func DefaultBlockParsers() []util.PrioritizedValue { + return []util.PrioritizedValue{ + util.Prioritized(NewSetextHeadingParser(), 100), + util.Prioritized(NewThematicBreakParser(), 200), + util.Prioritized(NewListParser(), 300), + util.Prioritized(NewListItemParser(), 400), + util.Prioritized(NewCodeBlockParser(), 500), + util.Prioritized(NewATXHeadingParser(), 600), + util.Prioritized(NewFencedCodeBlockParser(), 700), + util.Prioritized(NewBlockquoteParser(), 800), + util.Prioritized(NewHTMLBlockParser(), 900), + util.Prioritized(NewParagraphParser(), 1000), + } +} + +// DefaultInlineParsers returns a new list of default InlineParsers. +// Priorities of default InlineParsers are: +// +// CodeSpanParser, 100 +// LinkParser, 200 +// AutoLinkParser, 300 +// RawHTMLParser, 400 +// EmphasisParser, 500 +func DefaultInlineParsers() []util.PrioritizedValue { + return []util.PrioritizedValue{ + util.Prioritized(NewCodeSpanParser(), 100), + util.Prioritized(NewLinkParser(), 200), + util.Prioritized(NewAutoLinkParser(), 300), + util.Prioritized(NewRawHTMLParser(), 400), + util.Prioritized(NewEmphasisParser(), 500), + } +} + +// DefaultParagraphTransformers returns a new list of default ParagraphTransformers. +// Priorities of default ParagraphTransformers are: +// +// LinkReferenceParagraphTransformer, 100 +func DefaultParagraphTransformers() []util.PrioritizedValue { + return []util.PrioritizedValue{ + util.Prioritized(LinkReferenceParagraphTransformer, 100), + } +} + +// A Block struct holds a node and correspond parser pair. +type Block struct { + // Node is a BlockNode. + Node ast.Node + // Parser is a BlockParser. + Parser BlockParser +} + +type parser struct { + options map[OptionName]interface{} + blockParsers [256][]BlockParser + freeBlockParsers []BlockParser + inlineParsers [256][]InlineParser + closeBlockers []CloseBlocker + paragraphTransformers []ParagraphTransformer + astTransformers []ASTTransformer + escapedSpace bool + config *Config + initSync sync.Once +} + +type withBlockParsers struct { + value []util.PrioritizedValue +} + +func (o *withBlockParsers) SetParserOption(c *Config) { + c.BlockParsers = append(c.BlockParsers, o.value...) +} + +// WithBlockParsers is a functional option that allow you to add +// BlockParsers to the parser. +func WithBlockParsers(bs ...util.PrioritizedValue) Option { + return &withBlockParsers{bs} +} + +type withInlineParsers struct { + value []util.PrioritizedValue +} + +func (o *withInlineParsers) SetParserOption(c *Config) { + c.InlineParsers = append(c.InlineParsers, o.value...) +} + +// WithInlineParsers is a functional option that allow you to add +// InlineParsers to the parser. +func WithInlineParsers(bs ...util.PrioritizedValue) Option { + return &withInlineParsers{bs} +} + +type withParagraphTransformers struct { + value []util.PrioritizedValue +} + +func (o *withParagraphTransformers) SetParserOption(c *Config) { + c.ParagraphTransformers = append(c.ParagraphTransformers, o.value...) +} + +// WithParagraphTransformers is a functional option that allow you to add +// ParagraphTransformers to the parser. +func WithParagraphTransformers(ps ...util.PrioritizedValue) Option { + return &withParagraphTransformers{ps} +} + +type withASTTransformers struct { + value []util.PrioritizedValue +} + +func (o *withASTTransformers) SetParserOption(c *Config) { + c.ASTTransformers = append(c.ASTTransformers, o.value...) +} + +// WithASTTransformers is a functional option that allow you to add +// ASTTransformers to the parser. +func WithASTTransformers(ps ...util.PrioritizedValue) Option { + return &withASTTransformers{ps} +} + +type withEscapedSpace struct { +} + +func (o *withEscapedSpace) SetParserOption(c *Config) { + c.EscapedSpace = true +} + +// WithEscapedSpace is a functional option indicates that a '\' escaped half-space(0x20) should not trigger parsers. +func WithEscapedSpace() Option { + return &withEscapedSpace{} +} + +type withOption struct { + name OptionName + value interface{} +} + +func (o *withOption) SetParserOption(c *Config) { + c.Options[o.name] = o.value +} + +// WithOption is a functional option that allow you to set +// an arbitrary option to the parser. +func WithOption(name OptionName, value interface{}) Option { + return &withOption{name, value} +} + +// NewParser returns a new Parser with given options. +func NewParser(options ...Option) Parser { + config := NewConfig() + for _, opt := range options { + opt.SetParserOption(config) + } + + p := &parser{ + options: map[OptionName]interface{}{}, + config: config, + } + + return p +} + +func (p *parser) AddOptions(opts ...Option) { + for _, opt := range opts { + opt.SetParserOption(p.config) + } +} + +func (p *parser) addBlockParser(v util.PrioritizedValue, options map[OptionName]interface{}) { + bp, ok := v.Value.(BlockParser) + if !ok { + panic(fmt.Sprintf("%v is not a BlockParser", v.Value)) + } + tcs := bp.Trigger() + so, ok := v.Value.(SetOptioner) + if ok { + for oname, ovalue := range options { + so.SetOption(oname, ovalue) + } + } + if tcs == nil { + p.freeBlockParsers = append(p.freeBlockParsers, bp) + } else { + for _, tc := range tcs { + if p.blockParsers[tc] == nil { + p.blockParsers[tc] = []BlockParser{} + } + p.blockParsers[tc] = append(p.blockParsers[tc], bp) + } + } +} + +func (p *parser) addInlineParser(v util.PrioritizedValue, options map[OptionName]interface{}) { + ip, ok := v.Value.(InlineParser) + if !ok { + panic(fmt.Sprintf("%v is not a InlineParser", v.Value)) + } + tcs := ip.Trigger() + so, ok := v.Value.(SetOptioner) + if ok { + for oname, ovalue := range options { + so.SetOption(oname, ovalue) + } + } + if cb, ok := ip.(CloseBlocker); ok { + p.closeBlockers = append(p.closeBlockers, cb) + } + for _, tc := range tcs { + if p.inlineParsers[tc] == nil { + p.inlineParsers[tc] = []InlineParser{} + } + p.inlineParsers[tc] = append(p.inlineParsers[tc], ip) + } +} + +func (p *parser) addParagraphTransformer(v util.PrioritizedValue, options map[OptionName]interface{}) { + pt, ok := v.Value.(ParagraphTransformer) + if !ok { + panic(fmt.Sprintf("%v is not a ParagraphTransformer", v.Value)) + } + so, ok := v.Value.(SetOptioner) + if ok { + for oname, ovalue := range options { + so.SetOption(oname, ovalue) + } + } + p.paragraphTransformers = append(p.paragraphTransformers, pt) +} + +func (p *parser) addASTTransformer(v util.PrioritizedValue, options map[OptionName]interface{}) { + at, ok := v.Value.(ASTTransformer) + if !ok { + panic(fmt.Sprintf("%v is not a ASTTransformer", v.Value)) + } + so, ok := v.Value.(SetOptioner) + if ok { + for oname, ovalue := range options { + so.SetOption(oname, ovalue) + } + } + p.astTransformers = append(p.astTransformers, at) +} + +// A ParseConfig struct is a data structure that holds configuration of the Parser.Parse. +type ParseConfig struct { + Context Context +} + +// A ParseOption is a functional option type for the Parser.Parse. +type ParseOption func(c *ParseConfig) + +// WithContext is a functional option that allow you to override +// a default context. +func WithContext(context Context) ParseOption { + return func(c *ParseConfig) { + c.Context = context + } +} + +func (p *parser) Parse(reader text.Reader, opts ...ParseOption) ast.Node { + p.initSync.Do(func() { + p.config.BlockParsers.Sort() + for _, v := range p.config.BlockParsers { + p.addBlockParser(v, p.config.Options) + } + for i := range p.blockParsers { + if p.blockParsers[i] != nil { + p.blockParsers[i] = append(p.blockParsers[i], p.freeBlockParsers...) + } + } + + p.config.InlineParsers.Sort() + for _, v := range p.config.InlineParsers { + p.addInlineParser(v, p.config.Options) + } + p.config.ParagraphTransformers.Sort() + for _, v := range p.config.ParagraphTransformers { + p.addParagraphTransformer(v, p.config.Options) + } + p.config.ASTTransformers.Sort() + for _, v := range p.config.ASTTransformers { + p.addASTTransformer(v, p.config.Options) + } + p.escapedSpace = p.config.EscapedSpace + p.config = nil + }) + c := &ParseConfig{} + for _, opt := range opts { + opt(c) + } + if c.Context == nil { + c.Context = NewContext() + } + pc := c.Context + root := ast.NewDocument() + p.parseBlocks(root, reader, pc) + + blockReader := text.NewBlockReader(reader.Source(), nil) + p.walkBlock(root, func(node ast.Node) { + p.parseBlock(blockReader, node, pc) + }) + for _, at := range p.astTransformers { + at.Transform(root, reader, pc) + } + // root.Dump(reader.Source(), 0) + return root +} + +func (p *parser) transformParagraph(node *ast.Paragraph, reader text.Reader, pc Context) bool { + for _, pt := range p.paragraphTransformers { + pt.Transform(node, reader, pc) + if node.Parent() == nil { + return true + } + } + return false +} + +func (p *parser) closeBlocks(from, to int, reader text.Reader, pc Context) { + blocks := pc.OpenedBlocks() + for i := from; i >= to; i-- { + node := blocks[i].Node + paragraph, ok := node.(*ast.Paragraph) + if ok && node.Parent() != nil { + p.transformParagraph(paragraph, reader, pc) + } + if node.Parent() != nil { // closes only if node has not been transformed + blocks[i].Parser.Close(blocks[i].Node, reader, pc) + } + } + if from == len(blocks)-1 { + blocks = blocks[0:to] + } else { + blocks = append(blocks[0:to], blocks[from+1:]...) + } + pc.SetOpenedBlocks(blocks) +} + +type blockOpenResult int + +const ( + paragraphContinuation blockOpenResult = iota + 1 + newBlocksOpened + noBlocksOpened +) + +func (p *parser) openBlocks(parent ast.Node, blankLine bool, reader text.Reader, pc Context) blockOpenResult { + result := blockOpenResult(noBlocksOpened) + continuable := false + lastBlock := pc.LastOpenedBlock() + if lastBlock.Node != nil { + continuable = ast.IsParagraph(lastBlock.Node) + } +retry: + var bps []BlockParser + line, _ := reader.PeekLine() + w, pos := util.IndentWidth(line, reader.LineOffset()) + if w >= len(line) { + pc.SetBlockOffset(-1) + pc.SetBlockIndent(-1) + } else { + pc.SetBlockOffset(pos) + pc.SetBlockIndent(w) + } + if line == nil || line[0] == '\n' { + goto continuable + } + bps = p.freeBlockParsers + if pos < len(line) { + bps = p.blockParsers[line[pos]] + if bps == nil { + bps = p.freeBlockParsers + } + } + if bps == nil { + goto continuable + } + + for _, bp := range bps { + if continuable && result == noBlocksOpened && !bp.CanInterruptParagraph() { + continue + } + if w > 3 && !bp.CanAcceptIndentedLine() { + continue + } + lastBlock = pc.LastOpenedBlock() + last := lastBlock.Node + node, state := bp.Open(parent, reader, pc) + if node != nil { + // Parser requires last node to be a paragraph. + // With table extension: + // + // 0 + // -: + // - + // + // '-' on 3rd line seems a Setext heading because 1st and 2nd lines + // are being paragraph when the Settext heading parser tries to parse the 3rd + // line. + // But 1st line and 2nd line are a table. Thus this paragraph will be transformed + // by a paragraph transformer. So this text should be converted to a table and + // an empty list. + if state&RequireParagraph != 0 { + if last == parent.LastChild() { + // Opened paragraph may be transformed by ParagraphTransformers in + // closeBlocks(). + lastBlock.Parser.Close(last, reader, pc) + blocks := pc.OpenedBlocks() + pc.SetOpenedBlocks(blocks[0 : len(blocks)-1]) + if p.transformParagraph(last.(*ast.Paragraph), reader, pc) { + // Paragraph has been transformed. + // So this parser is considered as failing. + continuable = false + goto retry + } + } + } + node.SetBlankPreviousLines(blankLine) + if last != nil && last.Parent() == nil { + lastPos := len(pc.OpenedBlocks()) - 1 + p.closeBlocks(lastPos, lastPos, reader, pc) + } + parent.AppendChild(parent, node) + result = newBlocksOpened + be := Block{node, bp} + pc.SetOpenedBlocks(append(pc.OpenedBlocks(), be)) + if state&HasChildren != 0 { + parent = node + goto retry // try child block + } + break // no children, can not open more blocks on this line + } + } + +continuable: + if result == noBlocksOpened && continuable { + state := lastBlock.Parser.Continue(lastBlock.Node, reader, pc) + if state&Continue != 0 { + result = paragraphContinuation + } + } + return result +} + +type lineStat struct { + lineNum int + level int + isBlank bool +} + +func isBlankLine(lineNum, level int, stats []lineStat) bool { + ret := true + for i := len(stats) - 1 - level; i >= 0; i-- { + ret = false + s := stats[i] + if s.lineNum == lineNum { + if s.level < level && s.isBlank { + return true + } else if s.level == level { + return s.isBlank + } + } + if s.lineNum < lineNum { + return ret + } + } + return ret +} + +func (p *parser) parseBlocks(parent ast.Node, reader text.Reader, pc Context) { + pc.SetOpenedBlocks([]Block{}) + blankLines := make([]lineStat, 0, 128) + var isBlank bool + for { // process blocks separated by blank lines + _, lines, ok := reader.SkipBlankLines() + if !ok { + return + } + lineNum, _ := reader.Position() + if lines != 0 { + blankLines = blankLines[0:0] + l := len(pc.OpenedBlocks()) + for i := 0; i < l; i++ { + blankLines = append(blankLines, lineStat{lineNum - 1, i, lines != 0}) + } + } + isBlank = isBlankLine(lineNum-1, 0, blankLines) + // first, we try to open blocks + if p.openBlocks(parent, isBlank, reader, pc) != newBlocksOpened { + return + } + reader.AdvanceLine() + for { // process opened blocks line by line + openedBlocks := pc.OpenedBlocks() + l := len(openedBlocks) + if l == 0 { + break + } + lastIndex := l - 1 + for i := 0; i < l; i++ { + be := openedBlocks[i] + line, _ := reader.PeekLine() + if line == nil { + p.closeBlocks(lastIndex, 0, reader, pc) + reader.AdvanceLine() + return + } + lineNum, _ := reader.Position() + blankLines = append(blankLines, lineStat{lineNum, i, util.IsBlank(line)}) + // If node is a paragraph, p.openBlocks determines whether it is continuable. + // So we do not process paragraphs here. + if !ast.IsParagraph(be.Node) { + state := be.Parser.Continue(be.Node, reader, pc) + if state&Continue != 0 { + // When current node is a container block and has no children, + // we try to open new child nodes + if state&HasChildren != 0 && i == lastIndex { + isBlank = isBlankLine(lineNum-1, i, blankLines) + p.openBlocks(be.Node, isBlank, reader, pc) + break + } + continue + } + } + // current node may be closed or lazy continuation + isBlank = isBlankLine(lineNum-1, i, blankLines) + thisParent := parent + if i != 0 { + thisParent = openedBlocks[i-1].Node + } + lastNode := openedBlocks[lastIndex].Node + result := p.openBlocks(thisParent, isBlank, reader, pc) + if result != paragraphContinuation { + // lastNode is a paragraph and was transformed by the paragraph + // transformers. + if openedBlocks[lastIndex].Node != lastNode { + lastIndex-- + } + p.closeBlocks(lastIndex, i, reader, pc) + } + break + } + + reader.AdvanceLine() + } + } +} + +func (p *parser) walkBlock(block ast.Node, cb func(node ast.Node)) { + for c := block.FirstChild(); c != nil; c = c.NextSibling() { + p.walkBlock(c, cb) + } + cb(block) +} + +const ( + lineBreakHard uint8 = 1 << iota + lineBreakSoft + lineBreakVisible +) + +func (p *parser) parseBlock(block text.BlockReader, parent ast.Node, pc Context) { + if parent.IsRaw() { + return + } + escaped := false + source := block.Source() + block.Reset(parent.Lines()) + for { + retry: + line, _ := block.PeekLine() + if line == nil { + break + } + lineLength := len(line) + var lineBreakFlags uint8 + hasNewLine := line[lineLength-1] == '\n' + if ((lineLength >= 3 && line[lineLength-2] == '\\' && + line[lineLength-3] != '\\') || (lineLength == 2 && line[lineLength-2] == '\\')) && hasNewLine { // ends with \\n + lineLength -= 2 + lineBreakFlags |= lineBreakHard | lineBreakVisible + } else if ((lineLength >= 4 && line[lineLength-3] == '\\' && line[lineLength-2] == '\r' && + line[lineLength-4] != '\\') || (lineLength == 3 && line[lineLength-3] == '\\' && line[lineLength-2] == '\r')) && + hasNewLine { // ends with \\r\n + lineLength -= 3 + lineBreakFlags |= lineBreakHard | lineBreakVisible + } else if lineLength >= 3 && line[lineLength-3] == ' ' && line[lineLength-2] == ' ' && + hasNewLine { // ends with [space][space]\n + lineLength -= 3 + lineBreakFlags |= lineBreakHard + } else if lineLength >= 4 && line[lineLength-4] == ' ' && line[lineLength-3] == ' ' && + line[lineLength-2] == '\r' && hasNewLine { // ends with [space][space]\r\n + lineLength -= 4 + lineBreakFlags |= lineBreakHard + } else if hasNewLine { + // If the line ends with a newline character, but it is not a hardlineBreak, then it is a softLinebreak + // If the line ends with a hardlineBreak, then it cannot end with a softLinebreak + // See https://spec.commonmark.org/0.30/#soft-line-breaks + lineBreakFlags |= lineBreakSoft + } + + l, startPosition := block.Position() + n := 0 + for i := 0; i < lineLength; i++ { + c := line[i] + if c == '\n' { + break + } + isSpace := util.IsSpace(c) && c != '\r' && c != '\n' + isPunct := util.IsPunct(c) + if (isPunct && !escaped) || isSpace && !(escaped && p.escapedSpace) || i == 0 { + parserChar := c + if isSpace || (i == 0 && !isPunct) { + parserChar = ' ' + } + ips := p.inlineParsers[parserChar] + if ips != nil { + block.Advance(n) + n = 0 + savedLine, savedPosition := block.Position() + if i != 0 { + _, currentPosition := block.Position() + ast.MergeOrAppendTextSegment(parent, startPosition.Between(currentPosition)) + _, startPosition = block.Position() + } + var inlineNode ast.Node + for _, ip := range ips { + inlineNode = ip.Parse(parent, block, pc) + if inlineNode != nil { + break + } + block.SetPosition(savedLine, savedPosition) + } + if inlineNode != nil { + parent.AppendChild(parent, inlineNode) + goto retry + } + } + } + if escaped { + escaped = false + n++ + continue + } + + if c == '\\' { + escaped = true + n++ + continue + } + + escaped = false + n++ + } + if n != 0 { + block.Advance(n) + } + currentL, currentPosition := block.Position() + if l != currentL { + continue + } + diff := startPosition.Between(currentPosition) + var text *ast.Text + if lineBreakFlags&(lineBreakHard|lineBreakVisible) == lineBreakHard|lineBreakVisible { + text = ast.NewTextSegment(diff) + } else { + text = ast.NewTextSegment(diff.TrimRightSpace(source)) + } + text.SetSoftLineBreak(lineBreakFlags&lineBreakSoft != 0) + text.SetHardLineBreak(lineBreakFlags&lineBreakHard != 0) + parent.AppendChild(parent, text) + block.AdvanceLine() + } + + ProcessDelimiters(nil, pc) + for _, ip := range p.closeBlockers { + ip.CloseBlock(parent, block, pc) + } +} diff --git a/vendor/github.com/yuin/goldmark/parser/raw_html.go b/vendor/github.com/yuin/goldmark/parser/raw_html.go new file mode 100644 index 0000000..2b3dbc2 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/raw_html.go @@ -0,0 +1,162 @@ +package parser + +import ( + "bytes" + "regexp" + + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type rawHTMLParser struct { +} + +var defaultRawHTMLParser = &rawHTMLParser{} + +// NewRawHTMLParser return a new InlineParser that can parse +// inline htmls. +func NewRawHTMLParser() InlineParser { + return defaultRawHTMLParser +} + +func (s *rawHTMLParser) Trigger() []byte { + return []byte{'<'} +} + +func (s *rawHTMLParser) Parse(parent ast.Node, block text.Reader, pc Context) ast.Node { + line, _ := block.PeekLine() + if len(line) > 1 && util.IsAlphaNumeric(line[1]) { + return s.parseMultiLineRegexp(openTagRegexp, block, pc) + } + if len(line) > 2 && line[1] == '/' && util.IsAlphaNumeric(line[2]) { + return s.parseMultiLineRegexp(closeTagRegexp, block, pc) + } + if bytes.HasPrefix(line, openComment) { + return s.parseComment(block, pc) + } + if bytes.HasPrefix(line, openProcessingInstruction) { + return s.parseUntil(block, closeProcessingInstruction, pc) + } + if len(line) > 2 && line[1] == '!' && line[2] >= 'A' && line[2] <= 'Z' { + return s.parseUntil(block, closeDecl, pc) + } + if bytes.HasPrefix(line, openCDATA) { + return s.parseUntil(block, closeCDATA, pc) + } + return nil +} + +var tagnamePattern = `([A-Za-z][A-Za-z0-9-]*)` +var spaceOrOneNewline = `(?:[ \t]|(?:\r\n|\n){0,1})` +var attributePattern = `(?:[\r\n \t]+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:[\r\n \t]*=[\r\n \t]*(?:[^\"'=<>` + "`" + `\x00-\x20]+|'[^']*'|"[^"]*"))?)` //nolint:golint,lll +var openTagRegexp = regexp.MustCompile("^<" + tagnamePattern + attributePattern + `*` + spaceOrOneNewline + `*/?>`) +var closeTagRegexp = regexp.MustCompile("^`) + +var openProcessingInstruction = []byte("") +var openCDATA = []byte("") +var closeDecl = []byte(">") +var emptyComment = []byte("") +var invalidComment1 = []byte("") +var invalidComment2 = []byte("") +var openComment = []byte("") +var doubleHyphen = []byte("--") + +func (s *rawHTMLParser) parseComment(block text.Reader, pc Context) ast.Node { + savedLine, savedSegment := block.Position() + node := ast.NewRawHTML() + line, segment := block.PeekLine() + if bytes.HasPrefix(line, emptyComment) { + node.Segments.Append(segment.WithStop(segment.Start + len(emptyComment))) + block.Advance(len(emptyComment)) + return node + } + if bytes.HasPrefix(line, invalidComment1) || bytes.HasPrefix(line, invalidComment2) { + return nil + } + offset := len(openComment) + line = line[offset:] + for { + hindex := bytes.Index(line, doubleHyphen) + if hindex > -1 { + hindex += offset + } + index := bytes.Index(line, closeComment) + offset + if index > -1 && hindex == index { + if index == 0 || len(line) < 2 || line[index-offset-1] != '-' { + node.Segments.Append(segment.WithStop(segment.Start + index + len(closeComment))) + block.Advance(index + len(closeComment)) + return node + } + } + if hindex > 0 { + break + } + node.Segments.Append(segment) + block.AdvanceLine() + line, segment = block.PeekLine() + offset = 0 + if line == nil { + break + } + } + block.SetPosition(savedLine, savedSegment) + return nil +} + +func (s *rawHTMLParser) parseUntil(block text.Reader, closer []byte, pc Context) ast.Node { + savedLine, savedSegment := block.Position() + node := ast.NewRawHTML() + for { + line, segment := block.PeekLine() + if line == nil { + break + } + index := bytes.Index(line, closer) + if index > -1 { + node.Segments.Append(segment.WithStop(segment.Start + index + len(closer))) + block.Advance(index + len(closer)) + return node + } + node.Segments.Append(segment) + block.AdvanceLine() + } + block.SetPosition(savedLine, savedSegment) + return nil +} + +func (s *rawHTMLParser) parseMultiLineRegexp(reg *regexp.Regexp, block text.Reader, pc Context) ast.Node { + sline, ssegment := block.Position() + if block.Match(reg) { + node := ast.NewRawHTML() + eline, esegment := block.Position() + block.SetPosition(sline, ssegment) + for { + line, segment := block.PeekLine() + if line == nil { + break + } + l, _ := block.Position() + start := segment.Start + if l == sline { + start = ssegment.Start + } + end := segment.Stop + if l == eline { + end = esegment.Start + } + + node.Segments.Append(text.NewSegment(start, end)) + if l == eline { + block.Advance(end - start) + break + } + block.AdvanceLine() + } + return node + } + return nil +} diff --git a/vendor/github.com/yuin/goldmark/parser/setext_headings.go b/vendor/github.com/yuin/goldmark/parser/setext_headings.go new file mode 100644 index 0000000..915bcc1 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/setext_headings.go @@ -0,0 +1,126 @@ +package parser + +import ( + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +var temporaryParagraphKey = NewContextKey() + +type setextHeadingParser struct { + HeadingConfig +} + +func matchesSetextHeadingBar(line []byte) (byte, bool) { + start := 0 + end := len(line) + space := util.TrimLeftLength(line, []byte{' '}) + if space > 3 { + return 0, false + } + start += space + level1 := util.TrimLeftLength(line[start:end], []byte{'='}) + c := byte('=') + var level2 int + if level1 == 0 { + level2 = util.TrimLeftLength(line[start:end], []byte{'-'}) + c = '-' + } + if util.IsSpace(line[end-1]) { + end -= util.TrimRightSpaceLength(line[start:end]) + } + if !((level1 > 0 && start+level1 == end) || (level2 > 0 && start+level2 == end)) { + return 0, false + } + return c, true +} + +// NewSetextHeadingParser return a new BlockParser that can parse Setext headings. +func NewSetextHeadingParser(opts ...HeadingOption) BlockParser { + p := &setextHeadingParser{} + for _, o := range opts { + o.SetHeadingOption(&p.HeadingConfig) + } + return p +} + +func (b *setextHeadingParser) Trigger() []byte { + return []byte{'-', '='} +} + +func (b *setextHeadingParser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { + last := pc.LastOpenedBlock().Node + if last == nil { + return nil, NoChildren + } + paragraph, ok := last.(*ast.Paragraph) + if !ok || paragraph.Parent() != parent { + return nil, NoChildren + } + line, segment := reader.PeekLine() + c, ok := matchesSetextHeadingBar(line) + if !ok { + return nil, NoChildren + } + level := 1 + if c == '-' { + level = 2 + } + node := ast.NewHeading(level) + node.Lines().Append(segment) + pc.Set(temporaryParagraphKey, last) + return node, NoChildren | RequireParagraph +} + +func (b *setextHeadingParser) Continue(node ast.Node, reader text.Reader, pc Context) State { + return Close +} + +func (b *setextHeadingParser) Close(node ast.Node, reader text.Reader, pc Context) { + heading := node.(*ast.Heading) + segment := node.Lines().At(0) + heading.Lines().Clear() + tmp := pc.Get(temporaryParagraphKey).(*ast.Paragraph) + pc.Set(temporaryParagraphKey, nil) + if tmp.Lines().Len() == 0 { + next := heading.NextSibling() + segment = segment.TrimLeftSpace(reader.Source()) + if next == nil || !ast.IsParagraph(next) { + para := ast.NewParagraph() + para.Lines().Append(segment) + heading.Parent().InsertAfter(heading.Parent(), heading, para) + } else { + next.Lines().Unshift(segment) + } + heading.Parent().RemoveChild(heading.Parent(), heading) + } else { + heading.SetLines(tmp.Lines()) + heading.SetBlankPreviousLines(tmp.HasBlankPreviousLines()) + tp := tmp.Parent() + if tp != nil { + tp.RemoveChild(tp, tmp) + } + } + + if b.Attribute { + parseLastLineAttributes(node, reader, pc) + } + + if b.AutoHeadingID { + id, ok := node.AttributeString("id") + if !ok { + generateAutoHeadingID(heading, reader, pc) + } else { + pc.IDs().Put(id.([]byte)) + } + } +} + +func (b *setextHeadingParser) CanInterruptParagraph() bool { + return true +} + +func (b *setextHeadingParser) CanAcceptIndentedLine() bool { + return false +} diff --git a/vendor/github.com/yuin/goldmark/parser/thematic_break.go b/vendor/github.com/yuin/goldmark/parser/thematic_break.go new file mode 100644 index 0000000..db20a1e --- /dev/null +++ b/vendor/github.com/yuin/goldmark/parser/thematic_break.go @@ -0,0 +1,75 @@ +package parser + +import ( + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/text" + "github.com/yuin/goldmark/util" +) + +type thematicBreakPraser struct { +} + +var defaultThematicBreakPraser = &thematicBreakPraser{} + +// NewThematicBreakParser returns a new BlockParser that +// parses thematic breaks. +func NewThematicBreakParser() BlockParser { + return defaultThematicBreakPraser +} + +func isThematicBreak(line []byte, offset int) bool { + w, pos := util.IndentWidth(line, offset) + if w > 3 { + return false + } + mark := byte(0) + count := 0 + for i := pos; i < len(line); i++ { + c := line[i] + if util.IsSpace(c) { + continue + } + if mark == 0 { + mark = c + count = 1 + if mark == '*' || mark == '-' || mark == '_' { + continue + } + return false + } + if c != mark { + return false + } + count++ + } + return count > 2 +} + +func (b *thematicBreakPraser) Trigger() []byte { + return []byte{'-', '*', '_'} +} + +func (b *thematicBreakPraser) Open(parent ast.Node, reader text.Reader, pc Context) (ast.Node, State) { + line, segment := reader.PeekLine() + if isThematicBreak(line, reader.LineOffset()) { + reader.Advance(segment.Len() - 1) + return ast.NewThematicBreak(), NoChildren + } + return nil, NoChildren +} + +func (b *thematicBreakPraser) Continue(node ast.Node, reader text.Reader, pc Context) State { + return Close +} + +func (b *thematicBreakPraser) Close(node ast.Node, reader text.Reader, pc Context) { + // nothing to do +} + +func (b *thematicBreakPraser) CanInterruptParagraph() bool { + return true +} + +func (b *thematicBreakPraser) CanAcceptIndentedLine() bool { + return false +} diff --git a/vendor/github.com/yuin/goldmark/renderer/html/html.go b/vendor/github.com/yuin/goldmark/renderer/html/html.go new file mode 100644 index 0000000..8738c2a --- /dev/null +++ b/vendor/github.com/yuin/goldmark/renderer/html/html.go @@ -0,0 +1,1019 @@ +// Package html implements renderer that outputs HTMLs. +package html + +import ( + "bytes" + "fmt" + "strconv" + "unicode" + "unicode/utf8" + + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/renderer" + "github.com/yuin/goldmark/util" +) + +// A Config struct has configurations for the HTML based renderers. +type Config struct { + Writer Writer + HardWraps bool + EastAsianLineBreaks EastAsianLineBreaks + XHTML bool + Unsafe bool +} + +// NewConfig returns a new Config with defaults. +func NewConfig() Config { + return Config{ + Writer: DefaultWriter, + HardWraps: false, + EastAsianLineBreaks: EastAsianLineBreaksNone, + XHTML: false, + Unsafe: false, + } +} + +// SetOption implements renderer.NodeRenderer.SetOption. +func (c *Config) SetOption(name renderer.OptionName, value interface{}) { + switch name { + case optHardWraps: + c.HardWraps = value.(bool) + case optEastAsianLineBreaks: + c.EastAsianLineBreaks = value.(EastAsianLineBreaks) + case optXHTML: + c.XHTML = value.(bool) + case optUnsafe: + c.Unsafe = value.(bool) + case optTextWriter: + c.Writer = value.(Writer) + } +} + +// An Option interface sets options for HTML based renderers. +type Option interface { + SetHTMLOption(*Config) +} + +// TextWriter is an option name used in WithWriter. +const optTextWriter renderer.OptionName = "Writer" + +type withWriter struct { + value Writer +} + +func (o *withWriter) SetConfig(c *renderer.Config) { + c.Options[optTextWriter] = o.value +} + +func (o *withWriter) SetHTMLOption(c *Config) { + c.Writer = o.value +} + +// WithWriter is a functional option that allow you to set the given writer to +// the renderer. +func WithWriter(writer Writer) interface { + renderer.Option + Option +} { + return &withWriter{writer} +} + +// HardWraps is an option name used in WithHardWraps. +const optHardWraps renderer.OptionName = "HardWraps" + +type withHardWraps struct { +} + +func (o *withHardWraps) SetConfig(c *renderer.Config) { + c.Options[optHardWraps] = true +} + +func (o *withHardWraps) SetHTMLOption(c *Config) { + c.HardWraps = true +} + +// WithHardWraps is a functional option that indicates whether softline breaks +// should be rendered as '
    '. +func WithHardWraps() interface { + renderer.Option + Option +} { + return &withHardWraps{} +} + +// EastAsianLineBreaks is an option name used in WithEastAsianLineBreaks. +const optEastAsianLineBreaks renderer.OptionName = "EastAsianLineBreaks" + +// A EastAsianLineBreaks is a style of east asian line breaks. +type EastAsianLineBreaks int + +const ( + //EastAsianLineBreaksNone renders line breaks as it is. + EastAsianLineBreaksNone EastAsianLineBreaks = iota + // EastAsianLineBreaksSimple follows east_asian_line_breaks in Pandoc. + EastAsianLineBreaksSimple + // EastAsianLineBreaksCSS3Draft follows CSS text level3 "Segment Break Transformation Rules" with some enhancements. + EastAsianLineBreaksCSS3Draft +) + +func (b EastAsianLineBreaks) softLineBreak(thisLastRune rune, siblingFirstRune rune) bool { + switch b { + case EastAsianLineBreaksNone: + return false + case EastAsianLineBreaksSimple: + return !(util.IsEastAsianWideRune(thisLastRune) && util.IsEastAsianWideRune(siblingFirstRune)) + case EastAsianLineBreaksCSS3Draft: + return eastAsianLineBreaksCSS3DraftSoftLineBreak(thisLastRune, siblingFirstRune) + } + return false +} + +func eastAsianLineBreaksCSS3DraftSoftLineBreak(thisLastRune rune, siblingFirstRune rune) bool { + // Implements CSS text level3 Segment Break Transformation Rules with some enhancements. + // References: + // - https://www.w3.org/TR/2020/WD-css-text-3-20200429/#line-break-transform + // - https://github.com/w3c/csswg-drafts/issues/5086 + + // Rule1: + // If the character immediately before or immediately after the segment break is + // the zero-width space character (U+200B), then the break is removed, leaving behind the zero-width space. + if thisLastRune == '\u200B' || siblingFirstRune == '\u200B' { + return false + } + + // Rule2: + // Otherwise, if the East Asian Width property of both the character before and after the segment break is + // F, W, or H (not A), and neither side is Hangul, then the segment break is removed. + thisLastRuneEastAsianWidth := util.EastAsianWidth(thisLastRune) + siblingFirstRuneEastAsianWidth := util.EastAsianWidth(siblingFirstRune) + if (thisLastRuneEastAsianWidth == "F" || + thisLastRuneEastAsianWidth == "W" || + thisLastRuneEastAsianWidth == "H") && + (siblingFirstRuneEastAsianWidth == "F" || + siblingFirstRuneEastAsianWidth == "W" || + siblingFirstRuneEastAsianWidth == "H") { + return unicode.Is(unicode.Hangul, thisLastRune) || unicode.Is(unicode.Hangul, siblingFirstRune) + } + + // Rule3: + // Otherwise, if either the character before or after the segment break belongs to + // the space-discarding character set and it is a Unicode Punctuation (P*) or U+3000, + // then the segment break is removed. + if util.IsSpaceDiscardingUnicodeRune(thisLastRune) || + unicode.IsPunct(thisLastRune) || + thisLastRune == '\u3000' || + util.IsSpaceDiscardingUnicodeRune(siblingFirstRune) || + unicode.IsPunct(siblingFirstRune) || + siblingFirstRune == '\u3000' { + return false + } + + // Rule4: + // Otherwise, the segment break is converted to a space (U+0020). + return true +} + +type withEastAsianLineBreaks struct { + eastAsianLineBreaksStyle EastAsianLineBreaks +} + +func (o *withEastAsianLineBreaks) SetConfig(c *renderer.Config) { + c.Options[optEastAsianLineBreaks] = o.eastAsianLineBreaksStyle +} + +func (o *withEastAsianLineBreaks) SetHTMLOption(c *Config) { + c.EastAsianLineBreaks = o.eastAsianLineBreaksStyle +} + +// WithEastAsianLineBreaks is a functional option that indicates whether softline breaks +// between east asian wide characters should be ignored. +func WithEastAsianLineBreaks(e EastAsianLineBreaks) interface { + renderer.Option + Option +} { + return &withEastAsianLineBreaks{e} +} + +// XHTML is an option name used in WithXHTML. +const optXHTML renderer.OptionName = "XHTML" + +type withXHTML struct { +} + +func (o *withXHTML) SetConfig(c *renderer.Config) { + c.Options[optXHTML] = true +} + +func (o *withXHTML) SetHTMLOption(c *Config) { + c.XHTML = true +} + +// WithXHTML is a functional option indicates that nodes should be rendered in +// xhtml instead of HTML5. +func WithXHTML() interface { + Option + renderer.Option +} { + return &withXHTML{} +} + +// Unsafe is an option name used in WithUnsafe. +const optUnsafe renderer.OptionName = "Unsafe" + +type withUnsafe struct { +} + +func (o *withUnsafe) SetConfig(c *renderer.Config) { + c.Options[optUnsafe] = true +} + +func (o *withUnsafe) SetHTMLOption(c *Config) { + c.Unsafe = true +} + +// WithUnsafe is a functional option that renders dangerous contents +// (raw htmls and potentially dangerous links) as it is. +func WithUnsafe() interface { + renderer.Option + Option +} { + return &withUnsafe{} +} + +// A Renderer struct is an implementation of renderer.NodeRenderer that renders +// nodes as (X)HTML. +type Renderer struct { + Config +} + +// NewRenderer returns a new Renderer with given options. +func NewRenderer(opts ...Option) renderer.NodeRenderer { + r := &Renderer{ + Config: NewConfig(), + } + + for _, opt := range opts { + opt.SetHTMLOption(&r.Config) + } + return r +} + +// RegisterFuncs implements NodeRenderer.RegisterFuncs . +func (r *Renderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { + // blocks + + reg.Register(ast.KindDocument, r.renderDocument) + reg.Register(ast.KindHeading, r.renderHeading) + reg.Register(ast.KindBlockquote, r.renderBlockquote) + reg.Register(ast.KindCodeBlock, r.renderCodeBlock) + reg.Register(ast.KindFencedCodeBlock, r.renderFencedCodeBlock) + reg.Register(ast.KindHTMLBlock, r.renderHTMLBlock) + reg.Register(ast.KindList, r.renderList) + reg.Register(ast.KindListItem, r.renderListItem) + reg.Register(ast.KindParagraph, r.renderParagraph) + reg.Register(ast.KindTextBlock, r.renderTextBlock) + reg.Register(ast.KindThematicBreak, r.renderThematicBreak) + + // inlines + + reg.Register(ast.KindAutoLink, r.renderAutoLink) + reg.Register(ast.KindCodeSpan, r.renderCodeSpan) + reg.Register(ast.KindEmphasis, r.renderEmphasis) + reg.Register(ast.KindImage, r.renderImage) + reg.Register(ast.KindLink, r.renderLink) + reg.Register(ast.KindRawHTML, r.renderRawHTML) + reg.Register(ast.KindText, r.renderText) + reg.Register(ast.KindString, r.renderString) +} + +func (r *Renderer) writeLines(w util.BufWriter, source []byte, n ast.Node) { + l := n.Lines().Len() + for i := 0; i < l; i++ { + line := n.Lines().At(i) + r.Writer.RawWrite(w, line.Value(source)) + } +} + +// GlobalAttributeFilter defines attribute names which any elements can have. +var GlobalAttributeFilter = util.NewBytesFilter( + []byte("accesskey"), + []byte("autocapitalize"), + []byte("autofocus"), + []byte("class"), + []byte("contenteditable"), + []byte("dir"), + []byte("draggable"), + []byte("enterkeyhint"), + []byte("hidden"), + []byte("id"), + []byte("inert"), + []byte("inputmode"), + []byte("is"), + []byte("itemid"), + []byte("itemprop"), + []byte("itemref"), + []byte("itemscope"), + []byte("itemtype"), + []byte("lang"), + []byte("part"), + []byte("role"), + []byte("slot"), + []byte("spellcheck"), + []byte("style"), + []byte("tabindex"), + []byte("title"), + []byte("translate"), +) + +func (r *Renderer) renderDocument( + w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + // nothing to do + return ast.WalkContinue, nil +} + +// HeadingAttributeFilter defines attribute names which heading elements can have. +var HeadingAttributeFilter = GlobalAttributeFilter + +func (r *Renderer) renderHeading( + w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + n := node.(*ast.Heading) + if entering { + _, _ = w.WriteString("') + } else { + _, _ = w.WriteString("\n") + } + return ast.WalkContinue, nil +} + +// BlockquoteAttributeFilter defines attribute names which blockquote elements can have. +var BlockquoteAttributeFilter = GlobalAttributeFilter.Extend( + []byte("cite"), +) + +func (r *Renderer) renderBlockquote( + w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { + if entering { + if n.Attributes() != nil { + _, _ = w.WriteString("') + } else { + _, _ = w.WriteString("
    \n") + } + } else { + _, _ = w.WriteString("
    \n") + } + return ast.WalkContinue, nil +} + +func (r *Renderer) renderCodeBlock(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { + if entering { + _, _ = w.WriteString("
    ")
    +		r.writeLines(w, source, n)
    +	} else {
    +		_, _ = w.WriteString("
    \n") + } + return ast.WalkContinue, nil +} + +func (r *Renderer) renderFencedCodeBlock( + w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + n := node.(*ast.FencedCodeBlock) + if entering { + _, _ = w.WriteString("
    ')
    +		r.writeLines(w, source, n)
    +	} else {
    +		_, _ = w.WriteString("
    \n") + } + return ast.WalkContinue, nil +} + +func (r *Renderer) renderHTMLBlock( + w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + n := node.(*ast.HTMLBlock) + if entering { + if r.Unsafe { + l := n.Lines().Len() + for i := 0; i < l; i++ { + line := n.Lines().At(i) + r.Writer.SecureWrite(w, line.Value(source)) + } + } else { + _, _ = w.WriteString("\n") + } + } else { + if n.HasClosure() { + if r.Unsafe { + closure := n.ClosureLine + r.Writer.SecureWrite(w, closure.Value(source)) + } else { + _, _ = w.WriteString("\n") + } + } + } + return ast.WalkContinue, nil +} + +// ListAttributeFilter defines attribute names which list elements can have. +var ListAttributeFilter = GlobalAttributeFilter.Extend( + []byte("start"), + []byte("reversed"), + []byte("type"), +) + +func (r *Renderer) renderList(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + n := node.(*ast.List) + tag := "ul" + if n.IsOrdered() { + tag = "ol" + } + if entering { + _ = w.WriteByte('<') + _, _ = w.WriteString(tag) + if n.IsOrdered() && n.Start != 1 { + fmt.Fprintf(w, " start=\"%d\"", n.Start) + } + if n.Attributes() != nil { + RenderAttributes(w, n, ListAttributeFilter) + } + _, _ = w.WriteString(">\n") + } else { + _, _ = w.WriteString("\n") + } + return ast.WalkContinue, nil +} + +// ListItemAttributeFilter defines attribute names which list item elements can have. +var ListItemAttributeFilter = GlobalAttributeFilter.Extend( + []byte("value"), +) + +func (r *Renderer) renderListItem(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { + if entering { + if n.Attributes() != nil { + _, _ = w.WriteString("') + } else { + _, _ = w.WriteString("
  • ") + } + fc := n.FirstChild() + if fc != nil { + if _, ok := fc.(*ast.TextBlock); !ok { + _ = w.WriteByte('\n') + } + } + } else { + _, _ = w.WriteString("
  • \n") + } + return ast.WalkContinue, nil +} + +// ParagraphAttributeFilter defines attribute names which paragraph elements can have. +var ParagraphAttributeFilter = GlobalAttributeFilter + +func (r *Renderer) renderParagraph(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { + if entering { + if n.Attributes() != nil { + _, _ = w.WriteString("') + } else { + _, _ = w.WriteString("

    ") + } + } else { + _, _ = w.WriteString("

    \n") + } + return ast.WalkContinue, nil +} + +func (r *Renderer) renderTextBlock(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { + if !entering { + if n.NextSibling() != nil && n.FirstChild() != nil { + _ = w.WriteByte('\n') + } + } + return ast.WalkContinue, nil +} + +// ThematicAttributeFilter defines attribute names which hr elements can have. +var ThematicAttributeFilter = GlobalAttributeFilter.Extend( + []byte("align"), // [Deprecated] + []byte("color"), // [Not Standardized] + []byte("noshade"), // [Deprecated] + []byte("size"), // [Deprecated] + []byte("width"), // [Deprecated] +) + +func (r *Renderer) renderThematicBreak( + w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { + if !entering { + return ast.WalkContinue, nil + } + _, _ = w.WriteString("\n") + } else { + _, _ = w.WriteString(">\n") + } + return ast.WalkContinue, nil +} + +// LinkAttributeFilter defines attribute names which link elements can have. +var LinkAttributeFilter = GlobalAttributeFilter.Extend( + []byte("download"), + // []byte("href"), + []byte("hreflang"), + []byte("media"), + []byte("ping"), + []byte("referrerpolicy"), + []byte("rel"), + []byte("shape"), + []byte("target"), +) + +func (r *Renderer) renderAutoLink( + w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + n := node.(*ast.AutoLink) + if !entering { + return ast.WalkContinue, nil + } + _, _ = w.WriteString(`') + } else { + _, _ = w.WriteString(`">`) + } + _, _ = w.Write(util.EscapeHTML(label)) + _, _ = w.WriteString(``) + return ast.WalkContinue, nil +} + +// CodeAttributeFilter defines attribute names which code elements can have. +var CodeAttributeFilter = GlobalAttributeFilter + +func (r *Renderer) renderCodeSpan(w util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) { + if entering { + if n.Attributes() != nil { + _, _ = w.WriteString("') + } else { + _, _ = w.WriteString("") + } + for c := n.FirstChild(); c != nil; c = c.NextSibling() { + segment := c.(*ast.Text).Segment + value := segment.Value(source) + if bytes.HasSuffix(value, []byte("\n")) { + r.Writer.RawWrite(w, value[:len(value)-1]) + r.Writer.RawWrite(w, []byte(" ")) + } else { + r.Writer.RawWrite(w, value) + } + } + return ast.WalkSkipChildren, nil + } + _, _ = w.WriteString("") + return ast.WalkContinue, nil +} + +// EmphasisAttributeFilter defines attribute names which emphasis elements can have. +var EmphasisAttributeFilter = GlobalAttributeFilter + +func (r *Renderer) renderEmphasis( + w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + n := node.(*ast.Emphasis) + tag := "em" + if n.Level == 2 { + tag = "strong" + } + if entering { + _ = w.WriteByte('<') + _, _ = w.WriteString(tag) + if n.Attributes() != nil { + RenderAttributes(w, n, EmphasisAttributeFilter) + } + _ = w.WriteByte('>') + } else { + _, _ = w.WriteString("') + } + return ast.WalkContinue, nil +} + +func (r *Renderer) renderLink(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + n := node.(*ast.Link) + if entering { + _, _ = w.WriteString("') + } else { + _, _ = w.WriteString("") + } + return ast.WalkContinue, nil +} + +// ImageAttributeFilter defines attribute names which image elements can have. +var ImageAttributeFilter = GlobalAttributeFilter.Extend( + []byte("align"), + []byte("border"), + []byte("crossorigin"), + []byte("decoding"), + []byte("height"), + []byte("importance"), + []byte("intrinsicsize"), + []byte("ismap"), + []byte("loading"), + []byte("referrerpolicy"), + []byte("sizes"), + []byte("srcset"), + []byte("usemap"), + []byte("width"), +) + +func (r *Renderer) renderImage(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + if !entering { + return ast.WalkContinue, nil + } + n := node.(*ast.Image) + _, _ = w.WriteString("`)
+	_, _ = w.Write(nodeToHTMLText(n, source))
+	_ = w.WriteByte('") + } else { + _, _ = w.WriteString(">") + } + return ast.WalkSkipChildren, nil +} + +func (r *Renderer) renderRawHTML( + w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + if !entering { + return ast.WalkSkipChildren, nil + } + if r.Unsafe { + n := node.(*ast.RawHTML) + l := n.Segments.Len() + for i := 0; i < l; i++ { + segment := n.Segments.At(i) + _, _ = w.Write(segment.Value(source)) + } + return ast.WalkSkipChildren, nil + } + _, _ = w.WriteString("") + return ast.WalkSkipChildren, nil +} + +func (r *Renderer) renderText(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + if !entering { + return ast.WalkContinue, nil + } + n := node.(*ast.Text) + segment := n.Segment + if n.IsRaw() { + r.Writer.RawWrite(w, segment.Value(source)) + } else { + value := segment.Value(source) + r.Writer.Write(w, value) + if n.HardLineBreak() || (n.SoftLineBreak() && r.HardWraps) { + if r.XHTML { + _, _ = w.WriteString("
    \n") + } else { + _, _ = w.WriteString("
    \n") + } + } else if n.SoftLineBreak() { + if r.EastAsianLineBreaks != EastAsianLineBreaksNone && len(value) != 0 { + sibling := node.NextSibling() + if sibling != nil && sibling.Kind() == ast.KindText { + if siblingText := sibling.(*ast.Text).Text(source); len(siblingText) != 0 { + thisLastRune := util.ToRune(value, len(value)-1) + siblingFirstRune, _ := utf8.DecodeRune(siblingText) + if r.EastAsianLineBreaks.softLineBreak(thisLastRune, siblingFirstRune) { + _ = w.WriteByte('\n') + } + } + } + } else { + _ = w.WriteByte('\n') + } + } + } + return ast.WalkContinue, nil +} + +func (r *Renderer) renderString(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { + if !entering { + return ast.WalkContinue, nil + } + n := node.(*ast.String) + if n.IsCode() { + _, _ = w.Write(n.Value) + } else { + if n.IsRaw() { + r.Writer.RawWrite(w, n.Value) + } else { + r.Writer.Write(w, n.Value) + } + } + return ast.WalkContinue, nil +} + +var dataPrefix = []byte("data-") + +// RenderAttributes renders given node's attributes. +// You can specify attribute names to render by the filter. +// If filter is nil, RenderAttributes renders all attributes. +func RenderAttributes(w util.BufWriter, node ast.Node, filter util.BytesFilter) { + for _, attr := range node.Attributes() { + if filter != nil && !filter.Contains(attr.Name) { + if !bytes.HasPrefix(attr.Name, dataPrefix) { + continue + } + } + _, _ = w.WriteString(" ") + _, _ = w.Write(attr.Name) + _, _ = w.WriteString(`="`) + // TODO: convert numeric values to strings + _, _ = w.Write(util.EscapeHTML(attr.Value.([]byte))) + _ = w.WriteByte('"') + } +} + +// A Writer interface writes textual contents to a writer. +type Writer interface { + // Write writes the given source to writer with resolving references and unescaping + // backslash escaped characters. + Write(writer util.BufWriter, source []byte) + + // RawWrite writes the given source to writer without resolving references and + // unescaping backslash escaped characters. + RawWrite(writer util.BufWriter, source []byte) + + // SecureWrite writes the given source to writer with replacing insecure characters. + SecureWrite(writer util.BufWriter, source []byte) +} + +var replacementCharacter = []byte("\ufffd") + +// A WriterConfig struct has configurations for the HTML based writers. +type WriterConfig struct { + // EscapedSpace is an option that indicates that a '\' escaped half-space(0x20) should not be rendered. + EscapedSpace bool +} + +// A WriterOption interface sets options for HTML based writers. +type WriterOption func(*WriterConfig) + +// WithEscapedSpace is a WriterOption indicates that a '\' escaped half-space(0x20) should not be rendered. +func WithEscapedSpace() WriterOption { + return func(c *WriterConfig) { + c.EscapedSpace = true + } +} + +type defaultWriter struct { + WriterConfig +} + +// NewWriter returns a new Writer. +func NewWriter(opts ...WriterOption) Writer { + w := &defaultWriter{} + for _, opt := range opts { + opt(&w.WriterConfig) + } + return w +} + +func escapeRune(writer util.BufWriter, r rune) { + if r < 256 { + v := util.EscapeHTMLByte(byte(r)) + if v != nil { + _, _ = writer.Write(v) + return + } + } + _, _ = writer.WriteRune(util.ToValidRune(r)) +} + +func (d *defaultWriter) SecureWrite(writer util.BufWriter, source []byte) { + n := 0 + l := len(source) + for i := 0; i < l; i++ { + if source[i] == '\u0000' { + _, _ = writer.Write(source[i-n : i]) + n = 0 + _, _ = writer.Write(replacementCharacter) + continue + } + n++ + } + if n != 0 { + _, _ = writer.Write(source[l-n:]) + } +} + +func (d *defaultWriter) RawWrite(writer util.BufWriter, source []byte) { + n := 0 + l := len(source) + for i := 0; i < l; i++ { + v := util.EscapeHTMLByte(source[i]) + if v != nil { + _, _ = writer.Write(source[i-n : i]) + n = 0 + _, _ = writer.Write(v) + continue + } + n++ + } + if n != 0 { + _, _ = writer.Write(source[l-n:]) + } +} + +func (d *defaultWriter) Write(writer util.BufWriter, source []byte) { + escaped := false + var ok bool + limit := len(source) + n := 0 + for i := 0; i < limit; i++ { + c := source[i] + if escaped { + if util.IsPunct(c) { + d.RawWrite(writer, source[n:i-1]) + n = i + escaped = false + continue + } + if d.EscapedSpace && c == ' ' { + d.RawWrite(writer, source[n:i-1]) + n = i + 1 + escaped = false + continue + } + } + if c == '\x00' { + d.RawWrite(writer, source[n:i]) + d.RawWrite(writer, replacementCharacter) + n = i + 1 + escaped = false + continue + } + if c == '&' { + pos := i + next := i + 1 + if next < limit && source[next] == '#' { + nnext := next + 1 + if nnext < limit { + nc := source[nnext] + // code point like #x22; + if nnext < limit && nc == 'x' || nc == 'X' { + start := nnext + 1 + i, ok = util.ReadWhile(source, [2]int{start, limit}, util.IsHexDecimal) + if ok && i < limit && source[i] == ';' && i-start < 7 { + v, _ := strconv.ParseUint(util.BytesToReadOnlyString(source[start:i]), 16, 32) + d.RawWrite(writer, source[n:pos]) + n = i + 1 + escapeRune(writer, rune(v)) + continue + } + // code point like #1234; + } else if nc >= '0' && nc <= '9' { + start := nnext + i, ok = util.ReadWhile(source, [2]int{start, limit}, util.IsNumeric) + if ok && i < limit && i-start < 8 && source[i] == ';' { + v, _ := strconv.ParseUint(util.BytesToReadOnlyString(source[start:i]), 10, 32) + d.RawWrite(writer, source[n:pos]) + n = i + 1 + escapeRune(writer, rune(v)) + continue + } + } + } + } else { + start := next + i, ok = util.ReadWhile(source, [2]int{start, limit}, util.IsAlphaNumeric) + // entity reference + if ok && i < limit && source[i] == ';' { + name := util.BytesToReadOnlyString(source[start:i]) + entity, ok := util.LookUpHTML5EntityByName(name) + if ok { + d.RawWrite(writer, source[n:pos]) + n = i + 1 + d.RawWrite(writer, entity.Characters) + continue + } + } + } + i = next - 1 + } + if c == '\\' { + escaped = true + continue + } + escaped = false + } + d.RawWrite(writer, source[n:]) +} + +// DefaultWriter is a default instance of the Writer. +var DefaultWriter = NewWriter() + +var bDataImage = []byte("data:image/") +var bPng = []byte("png;") +var bGif = []byte("gif;") +var bJpeg = []byte("jpeg;") +var bWebp = []byte("webp;") +var bSvg = []byte("svg+xml;") +var bJs = []byte("javascript:") +var bVb = []byte("vbscript:") +var bFile = []byte("file:") +var bData = []byte("data:") + +func hasPrefix(s, prefix []byte) bool { + return len(s) >= len(prefix) && bytes.Equal(bytes.ToLower(s[0:len(prefix)]), bytes.ToLower(prefix)) +} + +// IsDangerousURL returns true if the given url seems a potentially dangerous url, +// otherwise false. +func IsDangerousURL(url []byte) bool { + if hasPrefix(url, bDataImage) && len(url) >= 11 { + v := url[11:] + if hasPrefix(v, bPng) || hasPrefix(v, bGif) || + hasPrefix(v, bJpeg) || hasPrefix(v, bWebp) || + hasPrefix(v, bSvg) { + return false + } + return true + } + return hasPrefix(url, bJs) || hasPrefix(url, bVb) || + hasPrefix(url, bFile) || hasPrefix(url, bData) +} + +func nodeToHTMLText(n ast.Node, source []byte) []byte { + var buf bytes.Buffer + for c := n.FirstChild(); c != nil; c = c.NextSibling() { + if s, ok := c.(*ast.String); ok && s.IsCode() { + buf.Write(s.Text(source)) + } else if !c.HasChildren() { + buf.Write(util.EscapeHTML(c.Text(source))) + if t, ok := c.(*ast.Text); ok && t.SoftLineBreak() { + buf.WriteByte('\n') + } + } else { + buf.Write(nodeToHTMLText(c, source)) + } + } + return buf.Bytes() +} diff --git a/vendor/github.com/yuin/goldmark/renderer/renderer.go b/vendor/github.com/yuin/goldmark/renderer/renderer.go new file mode 100644 index 0000000..5b40465 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/renderer/renderer.go @@ -0,0 +1,174 @@ +// Package renderer renders the given AST to certain formats. +package renderer + +import ( + "bufio" + "io" + "sync" + + "github.com/yuin/goldmark/ast" + "github.com/yuin/goldmark/util" +) + +// A Config struct is a data structure that holds configuration of the Renderer. +type Config struct { + Options map[OptionName]interface{} + NodeRenderers util.PrioritizedSlice +} + +// NewConfig returns a new Config. +func NewConfig() *Config { + return &Config{ + Options: map[OptionName]interface{}{}, + NodeRenderers: util.PrioritizedSlice{}, + } +} + +// An OptionName is a name of the option. +type OptionName string + +// An Option interface is a functional option type for the Renderer. +type Option interface { + SetConfig(*Config) +} + +type withNodeRenderers struct { + value []util.PrioritizedValue +} + +func (o *withNodeRenderers) SetConfig(c *Config) { + c.NodeRenderers = append(c.NodeRenderers, o.value...) +} + +// WithNodeRenderers is a functional option that allow you to add +// NodeRenderers to the renderer. +func WithNodeRenderers(ps ...util.PrioritizedValue) Option { + return &withNodeRenderers{ps} +} + +type withOption struct { + name OptionName + value interface{} +} + +func (o *withOption) SetConfig(c *Config) { + c.Options[o.name] = o.value +} + +// WithOption is a functional option that allow you to set +// an arbitrary option to the parser. +func WithOption(name OptionName, value interface{}) Option { + return &withOption{name, value} +} + +// A SetOptioner interface sets given option to the object. +type SetOptioner interface { + // SetOption sets given option to the object. + // Unacceptable options may be passed. + // Thus implementations must ignore unacceptable options. + SetOption(name OptionName, value interface{}) +} + +// NodeRendererFunc is a function that renders a given node. +type NodeRendererFunc func(writer util.BufWriter, source []byte, n ast.Node, entering bool) (ast.WalkStatus, error) + +// A NodeRenderer interface offers NodeRendererFuncs. +type NodeRenderer interface { + // RendererFuncs registers NodeRendererFuncs to given NodeRendererFuncRegisterer. + RegisterFuncs(NodeRendererFuncRegisterer) +} + +// A NodeRendererFuncRegisterer registers given NodeRendererFunc to this object. +type NodeRendererFuncRegisterer interface { + // Register registers given NodeRendererFunc to this object. + Register(ast.NodeKind, NodeRendererFunc) +} + +// A Renderer interface renders given AST node to given +// writer with given Renderer. +type Renderer interface { + Render(w io.Writer, source []byte, n ast.Node) error + + // AddOptions adds given option to this renderer. + AddOptions(...Option) +} + +type renderer struct { + config *Config + options map[OptionName]interface{} + nodeRendererFuncsTmp map[ast.NodeKind]NodeRendererFunc + maxKind int + nodeRendererFuncs []NodeRendererFunc + initSync sync.Once +} + +// NewRenderer returns a new Renderer with given options. +func NewRenderer(options ...Option) Renderer { + config := NewConfig() + for _, opt := range options { + opt.SetConfig(config) + } + + r := &renderer{ + options: map[OptionName]interface{}{}, + config: config, + nodeRendererFuncsTmp: map[ast.NodeKind]NodeRendererFunc{}, + } + + return r +} + +func (r *renderer) AddOptions(opts ...Option) { + for _, opt := range opts { + opt.SetConfig(r.config) + } +} + +func (r *renderer) Register(kind ast.NodeKind, v NodeRendererFunc) { + r.nodeRendererFuncsTmp[kind] = v + if int(kind) > r.maxKind { + r.maxKind = int(kind) + } +} + +// Render renders the given AST node to the given writer with the given Renderer. +func (r *renderer) Render(w io.Writer, source []byte, n ast.Node) error { + r.initSync.Do(func() { + r.options = r.config.Options + r.config.NodeRenderers.Sort() + l := len(r.config.NodeRenderers) + for i := l - 1; i >= 0; i-- { + v := r.config.NodeRenderers[i] + nr, _ := v.Value.(NodeRenderer) + if se, ok := v.Value.(SetOptioner); ok { + for oname, ovalue := range r.options { + se.SetOption(oname, ovalue) + } + } + nr.RegisterFuncs(r) + } + r.nodeRendererFuncs = make([]NodeRendererFunc, r.maxKind+1) + for kind, nr := range r.nodeRendererFuncsTmp { + r.nodeRendererFuncs[kind] = nr + } + r.config = nil + r.nodeRendererFuncsTmp = nil + }) + writer, ok := w.(util.BufWriter) + if !ok { + writer = bufio.NewWriter(w) + } + err := ast.Walk(n, func(n ast.Node, entering bool) (ast.WalkStatus, error) { + s := ast.WalkStatus(ast.WalkContinue) + var err error + f := r.nodeRendererFuncs[n.Kind()] + if f != nil { + s, err = f(writer, source, n, entering) + } + return s, err + }) + if err != nil { + return err + } + return writer.Flush() +} diff --git a/vendor/github.com/yuin/goldmark/text/package.go b/vendor/github.com/yuin/goldmark/text/package.go new file mode 100644 index 0000000..d241ac6 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/text/package.go @@ -0,0 +1,2 @@ +// Package text provides functionalities to manipulate texts. +package text diff --git a/vendor/github.com/yuin/goldmark/text/reader.go b/vendor/github.com/yuin/goldmark/text/reader.go new file mode 100644 index 0000000..b3f97fb --- /dev/null +++ b/vendor/github.com/yuin/goldmark/text/reader.go @@ -0,0 +1,660 @@ +package text + +import ( + "bytes" + "io" + "regexp" + "unicode/utf8" + + "github.com/yuin/goldmark/util" +) + +const invalidValue = -1 + +// EOF indicates the end of file. +const EOF = byte(0xff) + +// A Reader interface provides abstracted method for reading text. +type Reader interface { + io.RuneReader + + // Source returns a source of the reader. + Source() []byte + + // ResetPosition resets positions. + ResetPosition() + + // Peek returns a byte at current position without advancing the internal pointer. + Peek() byte + + // PeekLine returns the current line without advancing the internal pointer. + PeekLine() ([]byte, Segment) + + // PrecendingCharacter returns a character just before current internal pointer. + PrecendingCharacter() rune + + // Value returns a value of the given segment. + Value(Segment) []byte + + // LineOffset returns a distance from the line head to current position. + LineOffset() int + + // Position returns current line number and position. + Position() (int, Segment) + + // SetPosition sets current line number and position. + SetPosition(int, Segment) + + // SetPadding sets padding to the reader. + SetPadding(int) + + // Advance advances the internal pointer. + Advance(int) + + // AdvanceAndSetPadding advances the internal pointer and add padding to the + // reader. + AdvanceAndSetPadding(int, int) + + // AdvanceLine advances the internal pointer to the next line head. + AdvanceLine() + + // SkipSpaces skips space characters and returns a non-blank line. + // If it reaches EOF, returns false. + SkipSpaces() (Segment, int, bool) + + // SkipSpaces skips blank lines and returns a non-blank line. + // If it reaches EOF, returns false. + SkipBlankLines() (Segment, int, bool) + + // Match performs regular expression matching to current line. + Match(reg *regexp.Regexp) bool + + // Match performs regular expression searching to current line. + FindSubMatch(reg *regexp.Regexp) [][]byte + + // FindClosure finds corresponding closure. + FindClosure(opener, closer byte, options FindClosureOptions) (*Segments, bool) +} + +// FindClosureOptions is options for Reader.FindClosure. +type FindClosureOptions struct { + // CodeSpan is a flag for the FindClosure. If this is set to true, + // FindClosure ignores closers in codespans. + CodeSpan bool + + // Nesting is a flag for the FindClosure. If this is set to true, + // FindClosure allows nesting. + Nesting bool + + // Newline is a flag for the FindClosure. If this is set to true, + // FindClosure searches for a closer over multiple lines. + Newline bool + + // Advance is a flag for the FindClosure. If this is set to true, + // FindClosure advances pointers when closer is found. + Advance bool +} + +type reader struct { + source []byte + sourceLength int + line int + peekedLine []byte + pos Segment + head int + lineOffset int +} + +// NewReader return a new Reader that can read UTF-8 bytes . +func NewReader(source []byte) Reader { + r := &reader{ + source: source, + sourceLength: len(source), + } + r.ResetPosition() + return r +} + +func (r *reader) FindClosure(opener, closer byte, options FindClosureOptions) (*Segments, bool) { + return findClosureReader(r, opener, closer, options) +} + +func (r *reader) ResetPosition() { + r.line = -1 + r.head = 0 + r.lineOffset = -1 + r.AdvanceLine() +} + +func (r *reader) Source() []byte { + return r.source +} + +func (r *reader) Value(seg Segment) []byte { + return seg.Value(r.source) +} + +func (r *reader) Peek() byte { + if r.pos.Start >= 0 && r.pos.Start < r.sourceLength { + if r.pos.Padding != 0 { + return space[0] + } + return r.source[r.pos.Start] + } + return EOF +} + +func (r *reader) PeekLine() ([]byte, Segment) { + if r.pos.Start >= 0 && r.pos.Start < r.sourceLength { + if r.peekedLine == nil { + r.peekedLine = r.pos.Value(r.Source()) + } + return r.peekedLine, r.pos + } + return nil, r.pos +} + +// io.RuneReader interface. +func (r *reader) ReadRune() (rune, int, error) { + return readRuneReader(r) +} + +func (r *reader) LineOffset() int { + if r.lineOffset < 0 { + v := 0 + for i := r.head; i < r.pos.Start; i++ { + if r.source[i] == '\t' { + v += util.TabWidth(v) + } else { + v++ + } + } + r.lineOffset = v - r.pos.Padding + } + return r.lineOffset +} + +func (r *reader) PrecendingCharacter() rune { + if r.pos.Start <= 0 { + if r.pos.Padding != 0 { + return rune(' ') + } + return rune('\n') + } + i := r.pos.Start - 1 + for ; i >= 0; i-- { + if utf8.RuneStart(r.source[i]) { + break + } + } + rn, _ := utf8.DecodeRune(r.source[i:]) + return rn +} + +func (r *reader) Advance(n int) { + r.lineOffset = -1 + if n < len(r.peekedLine) && r.pos.Padding == 0 { + r.pos.Start += n + r.peekedLine = nil + return + } + r.peekedLine = nil + l := r.sourceLength + for ; n > 0 && r.pos.Start < l; n-- { + if r.pos.Padding != 0 { + r.pos.Padding-- + continue + } + if r.source[r.pos.Start] == '\n' { + r.AdvanceLine() + continue + } + r.pos.Start++ + } +} + +func (r *reader) AdvanceAndSetPadding(n, padding int) { + r.Advance(n) + if padding > r.pos.Padding { + r.SetPadding(padding) + } +} + +func (r *reader) AdvanceLine() { + r.lineOffset = -1 + r.peekedLine = nil + r.pos.Start = r.pos.Stop + r.head = r.pos.Start + if r.pos.Start < 0 { + return + } + r.pos.Stop = r.sourceLength + for i := r.pos.Start; i < r.sourceLength; i++ { + c := r.source[i] + if c == '\n' { + r.pos.Stop = i + 1 + break + } + } + r.line++ + r.pos.Padding = 0 +} + +func (r *reader) Position() (int, Segment) { + return r.line, r.pos +} + +func (r *reader) SetPosition(line int, pos Segment) { + r.lineOffset = -1 + r.line = line + r.pos = pos +} + +func (r *reader) SetPadding(v int) { + r.pos.Padding = v +} + +func (r *reader) SkipSpaces() (Segment, int, bool) { + return skipSpacesReader(r) +} + +func (r *reader) SkipBlankLines() (Segment, int, bool) { + return skipBlankLinesReader(r) +} + +func (r *reader) Match(reg *regexp.Regexp) bool { + return matchReader(r, reg) +} + +func (r *reader) FindSubMatch(reg *regexp.Regexp) [][]byte { + return findSubMatchReader(r, reg) +} + +// A BlockReader interface is a reader that is optimized for Blocks. +type BlockReader interface { + Reader + // Reset resets current state and sets new segments to the reader. + Reset(segment *Segments) +} + +type blockReader struct { + source []byte + segments *Segments + segmentsLength int + line int + pos Segment + head int + last int + lineOffset int +} + +// NewBlockReader returns a new BlockReader. +func NewBlockReader(source []byte, segments *Segments) BlockReader { + r := &blockReader{ + source: source, + } + if segments != nil { + r.Reset(segments) + } + return r +} + +func (r *blockReader) FindClosure(opener, closer byte, options FindClosureOptions) (*Segments, bool) { + return findClosureReader(r, opener, closer, options) +} + +func (r *blockReader) ResetPosition() { + r.line = -1 + r.head = 0 + r.last = 0 + r.lineOffset = -1 + r.pos.Start = -1 + r.pos.Stop = -1 + r.pos.Padding = 0 + if r.segmentsLength > 0 { + last := r.segments.At(r.segmentsLength - 1) + r.last = last.Stop + } + r.AdvanceLine() +} + +func (r *blockReader) Reset(segments *Segments) { + r.segments = segments + r.segmentsLength = segments.Len() + r.ResetPosition() +} + +func (r *blockReader) Source() []byte { + return r.source +} + +func (r *blockReader) Value(seg Segment) []byte { + line := r.segmentsLength - 1 + ret := make([]byte, 0, seg.Stop-seg.Start+1) + for ; line >= 0; line-- { + if seg.Start >= r.segments.At(line).Start { + break + } + } + i := seg.Start + for ; line < r.segmentsLength; line++ { + s := r.segments.At(line) + if i < 0 { + i = s.Start + } + ret = s.ConcatPadding(ret) + for ; i < seg.Stop && i < s.Stop; i++ { + ret = append(ret, r.source[i]) + } + i = -1 + if s.Stop > seg.Stop { + break + } + } + return ret +} + +// io.RuneReader interface. +func (r *blockReader) ReadRune() (rune, int, error) { + return readRuneReader(r) +} + +func (r *blockReader) PrecendingCharacter() rune { + if r.pos.Padding != 0 { + return rune(' ') + } + if r.segments.Len() < 1 { + return rune('\n') + } + firstSegment := r.segments.At(0) + if r.line == 0 && r.pos.Start <= firstSegment.Start { + return rune('\n') + } + l := len(r.source) + i := r.pos.Start - 1 + for ; i < l && i >= 0; i-- { + if utf8.RuneStart(r.source[i]) { + break + } + } + if i < 0 || i >= l { + return rune('\n') + } + rn, _ := utf8.DecodeRune(r.source[i:]) + return rn +} + +func (r *blockReader) LineOffset() int { + if r.lineOffset < 0 { + v := 0 + for i := r.head; i < r.pos.Start; i++ { + if r.source[i] == '\t' { + v += util.TabWidth(v) + } else { + v++ + } + } + r.lineOffset = v - r.pos.Padding + } + return r.lineOffset +} + +func (r *blockReader) Peek() byte { + if r.line < r.segmentsLength && r.pos.Start >= 0 && r.pos.Start < r.last { + if r.pos.Padding != 0 { + return space[0] + } + return r.source[r.pos.Start] + } + return EOF +} + +func (r *blockReader) PeekLine() ([]byte, Segment) { + if r.line < r.segmentsLength && r.pos.Start >= 0 && r.pos.Start < r.last { + return r.pos.Value(r.source), r.pos + } + return nil, r.pos +} + +func (r *blockReader) Advance(n int) { + r.lineOffset = -1 + + if n < r.pos.Stop-r.pos.Start && r.pos.Padding == 0 { + r.pos.Start += n + return + } + + for ; n > 0; n-- { + if r.pos.Padding != 0 { + r.pos.Padding-- + continue + } + if r.pos.Start >= r.pos.Stop-1 && r.pos.Stop < r.last { + r.AdvanceLine() + continue + } + r.pos.Start++ + } +} + +func (r *blockReader) AdvanceAndSetPadding(n, padding int) { + r.Advance(n) + if padding > r.pos.Padding { + r.SetPadding(padding) + } +} + +func (r *blockReader) AdvanceLine() { + r.SetPosition(r.line+1, NewSegment(invalidValue, invalidValue)) + r.head = r.pos.Start +} + +func (r *blockReader) Position() (int, Segment) { + return r.line, r.pos +} + +func (r *blockReader) SetPosition(line int, pos Segment) { + r.lineOffset = -1 + r.line = line + if pos.Start == invalidValue { + if r.line < r.segmentsLength { + s := r.segments.At(line) + r.head = s.Start + r.pos = s + } + } else { + r.pos = pos + if r.line < r.segmentsLength { + s := r.segments.At(line) + r.head = s.Start + } + } +} + +func (r *blockReader) SetPadding(v int) { + r.lineOffset = -1 + r.pos.Padding = v +} + +func (r *blockReader) SkipSpaces() (Segment, int, bool) { + return skipSpacesReader(r) +} + +func (r *blockReader) SkipBlankLines() (Segment, int, bool) { + return skipBlankLinesReader(r) +} + +func (r *blockReader) Match(reg *regexp.Regexp) bool { + return matchReader(r, reg) +} + +func (r *blockReader) FindSubMatch(reg *regexp.Regexp) [][]byte { + return findSubMatchReader(r, reg) +} + +func skipBlankLinesReader(r Reader) (Segment, int, bool) { + lines := 0 + for { + line, seg := r.PeekLine() + if line == nil { + return seg, lines, false + } + if util.IsBlank(line) { + lines++ + r.AdvanceLine() + } else { + return seg, lines, true + } + } +} + +func skipSpacesReader(r Reader) (Segment, int, bool) { + chars := 0 + for { + line, segment := r.PeekLine() + if line == nil { + return segment, chars, false + } + for i, c := range line { + if util.IsSpace(c) { + chars++ + r.Advance(1) + continue + } + return segment.WithStart(segment.Start + i + 1), chars, true + } + } +} + +func matchReader(r Reader, reg *regexp.Regexp) bool { + oldline, oldseg := r.Position() + match := reg.FindReaderSubmatchIndex(r) + r.SetPosition(oldline, oldseg) + if match == nil { + return false + } + r.Advance(match[1] - match[0]) + return true +} + +func findSubMatchReader(r Reader, reg *regexp.Regexp) [][]byte { + oldLine, oldSeg := r.Position() + match := reg.FindReaderSubmatchIndex(r) + r.SetPosition(oldLine, oldSeg) + if match == nil { + return nil + } + var bb bytes.Buffer + bb.Grow(match[1] - match[0]) + for i := 0; i < match[1]; { + r, size, _ := readRuneReader(r) + i += size + bb.WriteRune(r) + } + bs := bb.Bytes() + var result [][]byte + for i := 0; i < len(match); i += 2 { + if match[i] < 0 { + result = append(result, []byte{}) + continue + } + result = append(result, bs[match[i]:match[i+1]]) + } + + r.SetPosition(oldLine, oldSeg) + r.Advance(match[1] - match[0]) + return result +} + +func readRuneReader(r Reader) (rune, int, error) { + line, _ := r.PeekLine() + if line == nil { + return 0, 0, io.EOF + } + rn, size := utf8.DecodeRune(line) + if rn == utf8.RuneError { + return 0, 0, io.EOF + } + r.Advance(size) + return rn, size, nil +} + +func findClosureReader(r Reader, opener, closer byte, opts FindClosureOptions) (*Segments, bool) { + opened := 1 + codeSpanOpener := 0 + closed := false + orgline, orgpos := r.Position() + var ret *Segments + + for { + bs, seg := r.PeekLine() + if bs == nil { + goto end + } + i := 0 + for i < len(bs) { + c := bs[i] + if opts.CodeSpan && codeSpanOpener != 0 && c == '`' { + codeSpanCloser := 0 + for ; i < len(bs); i++ { + if bs[i] == '`' { + codeSpanCloser++ + } else { + i-- + break + } + } + if codeSpanCloser == codeSpanOpener { + codeSpanOpener = 0 + } + } else if codeSpanOpener == 0 && c == '\\' && i < len(bs)-1 && util.IsPunct(bs[i+1]) { + i += 2 + continue + } else if opts.CodeSpan && codeSpanOpener == 0 && c == '`' { + for ; i < len(bs); i++ { + if bs[i] == '`' { + codeSpanOpener++ + } else { + i-- + break + } + } + } else if (opts.CodeSpan && codeSpanOpener == 0) || !opts.CodeSpan { + if c == closer { + opened-- + if opened == 0 { + if ret == nil { + ret = NewSegments() + } + ret.Append(seg.WithStop(seg.Start + i)) + r.Advance(i + 1) + closed = true + goto end + } + } else if c == opener { + if !opts.Nesting { + goto end + } + opened++ + } + } + i++ + } + if !opts.Newline { + goto end + } + r.AdvanceLine() + if ret == nil { + ret = NewSegments() + } + ret.Append(seg) + } +end: + if !opts.Advance { + r.SetPosition(orgline, orgpos) + } + if closed { + return ret, true + } + return nil, false +} diff --git a/vendor/github.com/yuin/goldmark/text/segment.go b/vendor/github.com/yuin/goldmark/text/segment.go new file mode 100644 index 0000000..badd4bc --- /dev/null +++ b/vendor/github.com/yuin/goldmark/text/segment.go @@ -0,0 +1,209 @@ +package text + +import ( + "bytes" + "github.com/yuin/goldmark/util" +) + +var space = []byte(" ") + +// A Segment struct holds information about source positions. +type Segment struct { + // Start is a start position of the segment. + Start int + + // Stop is a stop position of the segment. + // This value should be excluded. + Stop int + + // Padding is a padding length of the segment. + Padding int +} + +// NewSegment return a new Segment. +func NewSegment(start, stop int) Segment { + return Segment{ + Start: start, + Stop: stop, + Padding: 0, + } +} + +// NewSegmentPadding returns a new Segment with the given padding. +func NewSegmentPadding(start, stop, n int) Segment { + return Segment{ + Start: start, + Stop: stop, + Padding: n, + } +} + +// Value returns a value of the segment. +func (t *Segment) Value(buffer []byte) []byte { + if t.Padding == 0 { + return buffer[t.Start:t.Stop] + } + result := make([]byte, 0, t.Padding+t.Stop-t.Start+1) + result = append(result, bytes.Repeat(space, t.Padding)...) + return append(result, buffer[t.Start:t.Stop]...) +} + +// Len returns a length of the segment. +func (t *Segment) Len() int { + return t.Stop - t.Start + t.Padding +} + +// Between returns a segment between this segment and the given segment. +func (t *Segment) Between(other Segment) Segment { + if t.Stop != other.Stop { + panic("invalid state") + } + return NewSegmentPadding( + t.Start, + other.Start, + t.Padding-other.Padding, + ) +} + +// IsEmpty returns true if this segment is empty, otherwise false. +func (t *Segment) IsEmpty() bool { + return t.Start >= t.Stop && t.Padding == 0 +} + +// TrimRightSpace returns a new segment by slicing off all trailing +// space characters. +func (t *Segment) TrimRightSpace(buffer []byte) Segment { + v := buffer[t.Start:t.Stop] + l := util.TrimRightSpaceLength(v) + if l == len(v) { + return NewSegment(t.Start, t.Start) + } + return NewSegmentPadding(t.Start, t.Stop-l, t.Padding) +} + +// TrimLeftSpace returns a new segment by slicing off all leading +// space characters including padding. +func (t *Segment) TrimLeftSpace(buffer []byte) Segment { + v := buffer[t.Start:t.Stop] + l := util.TrimLeftSpaceLength(v) + return NewSegment(t.Start+l, t.Stop) +} + +// TrimLeftSpaceWidth returns a new segment by slicing off leading space +// characters until the given width. +func (t *Segment) TrimLeftSpaceWidth(width int, buffer []byte) Segment { + padding := t.Padding + for ; width > 0; width-- { + if padding == 0 { + break + } + padding-- + } + if width == 0 { + return NewSegmentPadding(t.Start, t.Stop, padding) + } + text := buffer[t.Start:t.Stop] + start := t.Start + for _, c := range text { + if start >= t.Stop-1 || width <= 0 { + break + } + if c == ' ' { + width-- + } else if c == '\t' { + width -= 4 + } else { + break + } + start++ + } + if width < 0 { + padding = width * -1 + } + return NewSegmentPadding(start, t.Stop, padding) +} + +// WithStart returns a new Segment with same value except Start. +func (t *Segment) WithStart(v int) Segment { + return NewSegmentPadding(v, t.Stop, t.Padding) +} + +// WithStop returns a new Segment with same value except Stop. +func (t *Segment) WithStop(v int) Segment { + return NewSegmentPadding(t.Start, v, t.Padding) +} + +// ConcatPadding concats the padding to the given slice. +func (t *Segment) ConcatPadding(v []byte) []byte { + if t.Padding > 0 { + return append(v, bytes.Repeat(space, t.Padding)...) + } + return v +} + +// Segments is a collection of the Segment. +type Segments struct { + values []Segment +} + +// NewSegments return a new Segments. +func NewSegments() *Segments { + return &Segments{ + values: nil, + } +} + +// Append appends the given segment after the tail of the collection. +func (s *Segments) Append(t Segment) { + if s.values == nil { + s.values = make([]Segment, 0, 20) + } + s.values = append(s.values, t) +} + +// AppendAll appends all elements of given segments after the tail of the collection. +func (s *Segments) AppendAll(t []Segment) { + if s.values == nil { + s.values = make([]Segment, 0, 20) + } + s.values = append(s.values, t...) +} + +// Len returns the length of the collection. +func (s *Segments) Len() int { + if s.values == nil { + return 0 + } + return len(s.values) +} + +// At returns a segment at the given index. +func (s *Segments) At(i int) Segment { + return s.values[i] +} + +// Set sets the given Segment. +func (s *Segments) Set(i int, v Segment) { + s.values[i] = v +} + +// SetSliced replace the collection with a subsliced value. +func (s *Segments) SetSliced(lo, hi int) { + s.values = s.values[lo:hi] +} + +// Sliced returns a subslice of the collection. +func (s *Segments) Sliced(lo, hi int) []Segment { + return s.values[lo:hi] +} + +// Clear delete all element of the collection. +func (s *Segments) Clear() { + s.values = nil +} + +// Unshift insert the given Segment to head of the collection. +func (s *Segments) Unshift(v Segment) { + s.values = append(s.values[0:1], s.values[0:]...) + s.values[0] = v +} diff --git a/vendor/github.com/yuin/goldmark/util/html5entities.go b/vendor/github.com/yuin/goldmark/util/html5entities.go new file mode 100644 index 0000000..dbb5f4f --- /dev/null +++ b/vendor/github.com/yuin/goldmark/util/html5entities.go @@ -0,0 +1,2143 @@ +//nolint:golint,lll,misspell +package util + +// An HTML5Entity struct represents HTML5 entitites. +type HTML5Entity struct { + Name string + CodePoints []int + Characters []byte +} + +// LookUpHTML5EntityByName returns (an HTML5Entity, true) if an entity named +// given name is found, otherwise (nil, false). +func LookUpHTML5EntityByName(name string) (*HTML5Entity, bool) { + v, ok := html5entities[name] + return v, ok +} + +var html5entities = map[string]*HTML5Entity{ + "AElig": {Name: "AElig", CodePoints: []int{198}, Characters: []byte{0xc3, 0x86}}, + "AMP": {Name: "AMP", CodePoints: []int{38}, Characters: []byte{0x26}}, + "Aacute": {Name: "Aacute", CodePoints: []int{193}, Characters: []byte{0xc3, 0x81}}, + "Acirc": {Name: "Acirc", CodePoints: []int{194}, Characters: []byte{0xc3, 0x82}}, + "Acy": {Name: "Acy", CodePoints: []int{1040}, Characters: []byte{0xd0, 0x90}}, + "Afr": {Name: "Afr", CodePoints: []int{120068}, Characters: []byte{0xf0, 0x9d, 0x94, 0x84}}, + "Agrave": {Name: "Agrave", CodePoints: []int{192}, Characters: []byte{0xc3, 0x80}}, + "Alpha": {Name: "Alpha", CodePoints: []int{913}, Characters: []byte{0xce, 0x91}}, + "Amacr": {Name: "Amacr", CodePoints: []int{256}, Characters: []byte{0xc4, 0x80}}, + "And": {Name: "And", CodePoints: []int{10835}, Characters: []byte{0xe2, 0xa9, 0x93}}, + "Aogon": {Name: "Aogon", CodePoints: []int{260}, Characters: []byte{0xc4, 0x84}}, + "Aopf": {Name: "Aopf", CodePoints: []int{120120}, Characters: []byte{0xf0, 0x9d, 0x94, 0xb8}}, + "ApplyFunction": {Name: "ApplyFunction", CodePoints: []int{8289}, Characters: []byte{0xe2, 0x81, 0xa1}}, + "Aring": {Name: "Aring", CodePoints: []int{197}, Characters: []byte{0xc3, 0x85}}, + "Ascr": {Name: "Ascr", CodePoints: []int{119964}, Characters: []byte{0xf0, 0x9d, 0x92, 0x9c}}, + "Assign": {Name: "Assign", CodePoints: []int{8788}, Characters: []byte{0xe2, 0x89, 0x94}}, + "Atilde": {Name: "Atilde", CodePoints: []int{195}, Characters: []byte{0xc3, 0x83}}, + "Auml": {Name: "Auml", CodePoints: []int{196}, Characters: []byte{0xc3, 0x84}}, + "Backslash": {Name: "Backslash", CodePoints: []int{8726}, Characters: []byte{0xe2, 0x88, 0x96}}, + "Barv": {Name: "Barv", CodePoints: []int{10983}, Characters: []byte{0xe2, 0xab, 0xa7}}, + "Barwed": {Name: "Barwed", CodePoints: []int{8966}, Characters: []byte{0xe2, 0x8c, 0x86}}, + "Bcy": {Name: "Bcy", CodePoints: []int{1041}, Characters: []byte{0xd0, 0x91}}, + "Because": {Name: "Because", CodePoints: []int{8757}, Characters: []byte{0xe2, 0x88, 0xb5}}, + "Bernoullis": {Name: "Bernoullis", CodePoints: []int{8492}, Characters: []byte{0xe2, 0x84, 0xac}}, + "Beta": {Name: "Beta", CodePoints: []int{914}, Characters: []byte{0xce, 0x92}}, + "Bfr": {Name: "Bfr", CodePoints: []int{120069}, Characters: []byte{0xf0, 0x9d, 0x94, 0x85}}, + "Bopf": {Name: "Bopf", CodePoints: []int{120121}, Characters: []byte{0xf0, 0x9d, 0x94, 0xb9}}, + "Breve": {Name: "Breve", CodePoints: []int{728}, Characters: []byte{0xcb, 0x98}}, + "Bscr": {Name: "Bscr", CodePoints: []int{8492}, Characters: []byte{0xe2, 0x84, 0xac}}, + "Bumpeq": {Name: "Bumpeq", CodePoints: []int{8782}, Characters: []byte{0xe2, 0x89, 0x8e}}, + "CHcy": {Name: "CHcy", CodePoints: []int{1063}, Characters: []byte{0xd0, 0xa7}}, + "COPY": {Name: "COPY", CodePoints: []int{169}, Characters: []byte{0xc2, 0xa9}}, + "Cacute": {Name: "Cacute", CodePoints: []int{262}, Characters: []byte{0xc4, 0x86}}, + "Cap": {Name: "Cap", CodePoints: []int{8914}, Characters: []byte{0xe2, 0x8b, 0x92}}, + "CapitalDifferentialD": {Name: "CapitalDifferentialD", CodePoints: []int{8517}, Characters: []byte{0xe2, 0x85, 0x85}}, + "Cayleys": {Name: "Cayleys", CodePoints: []int{8493}, Characters: []byte{0xe2, 0x84, 0xad}}, + "Ccaron": {Name: "Ccaron", CodePoints: []int{268}, Characters: []byte{0xc4, 0x8c}}, + "Ccedil": {Name: "Ccedil", CodePoints: []int{199}, Characters: []byte{0xc3, 0x87}}, + "Ccirc": {Name: "Ccirc", CodePoints: []int{264}, Characters: []byte{0xc4, 0x88}}, + "Cconint": {Name: "Cconint", CodePoints: []int{8752}, Characters: []byte{0xe2, 0x88, 0xb0}}, + "Cdot": {Name: "Cdot", CodePoints: []int{266}, Characters: []byte{0xc4, 0x8a}}, + "Cedilla": {Name: "Cedilla", CodePoints: []int{184}, Characters: []byte{0xc2, 0xb8}}, + "CenterDot": {Name: "CenterDot", CodePoints: []int{183}, Characters: []byte{0xc2, 0xb7}}, + "Cfr": {Name: "Cfr", CodePoints: []int{8493}, Characters: []byte{0xe2, 0x84, 0xad}}, + "Chi": {Name: "Chi", CodePoints: []int{935}, Characters: []byte{0xce, 0xa7}}, + "CircleDot": {Name: "CircleDot", CodePoints: []int{8857}, Characters: []byte{0xe2, 0x8a, 0x99}}, + "CircleMinus": {Name: "CircleMinus", CodePoints: []int{8854}, Characters: []byte{0xe2, 0x8a, 0x96}}, + "CirclePlus": {Name: "CirclePlus", CodePoints: []int{8853}, Characters: []byte{0xe2, 0x8a, 0x95}}, + "CircleTimes": {Name: "CircleTimes", CodePoints: []int{8855}, Characters: []byte{0xe2, 0x8a, 0x97}}, + "ClockwiseContourIntegral": {Name: "ClockwiseContourIntegral", CodePoints: []int{8754}, Characters: []byte{0xe2, 0x88, 0xb2}}, + "CloseCurlyDoubleQuote": {Name: "CloseCurlyDoubleQuote", CodePoints: []int{8221}, Characters: []byte{0xe2, 0x80, 0x9d}}, + "CloseCurlyQuote": {Name: "CloseCurlyQuote", CodePoints: []int{8217}, Characters: []byte{0xe2, 0x80, 0x99}}, + "Colon": {Name: "Colon", CodePoints: []int{8759}, Characters: []byte{0xe2, 0x88, 0xb7}}, + "Colone": {Name: "Colone", CodePoints: []int{10868}, Characters: []byte{0xe2, 0xa9, 0xb4}}, + "Congruent": {Name: "Congruent", CodePoints: []int{8801}, Characters: []byte{0xe2, 0x89, 0xa1}}, + "Conint": {Name: "Conint", CodePoints: []int{8751}, Characters: []byte{0xe2, 0x88, 0xaf}}, + "ContourIntegral": {Name: "ContourIntegral", CodePoints: []int{8750}, Characters: []byte{0xe2, 0x88, 0xae}}, + "Copf": {Name: "Copf", CodePoints: []int{8450}, Characters: []byte{0xe2, 0x84, 0x82}}, + "Coproduct": {Name: "Coproduct", CodePoints: []int{8720}, Characters: []byte{0xe2, 0x88, 0x90}}, + "CounterClockwiseContourIntegral": {Name: "CounterClockwiseContourIntegral", CodePoints: []int{8755}, Characters: []byte{0xe2, 0x88, 0xb3}}, + "Cross": {Name: "Cross", CodePoints: []int{10799}, Characters: []byte{0xe2, 0xa8, 0xaf}}, + "Cscr": {Name: "Cscr", CodePoints: []int{119966}, Characters: []byte{0xf0, 0x9d, 0x92, 0x9e}}, + "Cup": {Name: "Cup", CodePoints: []int{8915}, Characters: []byte{0xe2, 0x8b, 0x93}}, + "CupCap": {Name: "CupCap", CodePoints: []int{8781}, Characters: []byte{0xe2, 0x89, 0x8d}}, + "DD": {Name: "DD", CodePoints: []int{8517}, Characters: []byte{0xe2, 0x85, 0x85}}, + "DDotrahd": {Name: "DDotrahd", CodePoints: []int{10513}, Characters: []byte{0xe2, 0xa4, 0x91}}, + "DJcy": {Name: "DJcy", CodePoints: []int{1026}, Characters: []byte{0xd0, 0x82}}, + "DScy": {Name: "DScy", CodePoints: []int{1029}, Characters: []byte{0xd0, 0x85}}, + "DZcy": {Name: "DZcy", CodePoints: []int{1039}, Characters: []byte{0xd0, 0x8f}}, + "Dagger": {Name: "Dagger", CodePoints: []int{8225}, Characters: []byte{0xe2, 0x80, 0xa1}}, + "Darr": {Name: "Darr", CodePoints: []int{8609}, Characters: []byte{0xe2, 0x86, 0xa1}}, + "Dashv": {Name: "Dashv", CodePoints: []int{10980}, Characters: []byte{0xe2, 0xab, 0xa4}}, + "Dcaron": {Name: "Dcaron", CodePoints: []int{270}, Characters: []byte{0xc4, 0x8e}}, + "Dcy": {Name: "Dcy", CodePoints: []int{1044}, Characters: []byte{0xd0, 0x94}}, + "Del": {Name: "Del", CodePoints: []int{8711}, Characters: []byte{0xe2, 0x88, 0x87}}, + "Delta": {Name: "Delta", CodePoints: []int{916}, Characters: []byte{0xce, 0x94}}, + "Dfr": {Name: "Dfr", CodePoints: []int{120071}, Characters: []byte{0xf0, 0x9d, 0x94, 0x87}}, + "DiacriticalAcute": {Name: "DiacriticalAcute", CodePoints: []int{180}, Characters: []byte{0xc2, 0xb4}}, + "DiacriticalDot": {Name: "DiacriticalDot", CodePoints: []int{729}, Characters: []byte{0xcb, 0x99}}, + "DiacriticalDoubleAcute": {Name: "DiacriticalDoubleAcute", CodePoints: []int{733}, Characters: []byte{0xcb, 0x9d}}, + "DiacriticalGrave": {Name: "DiacriticalGrave", CodePoints: []int{96}, Characters: []byte{0x60}}, + "DiacriticalTilde": {Name: "DiacriticalTilde", CodePoints: []int{732}, Characters: []byte{0xcb, 0x9c}}, + "Diamond": {Name: "Diamond", CodePoints: []int{8900}, Characters: []byte{0xe2, 0x8b, 0x84}}, + "DifferentialD": {Name: "DifferentialD", CodePoints: []int{8518}, Characters: []byte{0xe2, 0x85, 0x86}}, + "Dopf": {Name: "Dopf", CodePoints: []int{120123}, Characters: []byte{0xf0, 0x9d, 0x94, 0xbb}}, + "Dot": {Name: "Dot", CodePoints: []int{168}, Characters: []byte{0xc2, 0xa8}}, + "DotDot": {Name: "DotDot", CodePoints: []int{8412}, Characters: []byte{0xe2, 0x83, 0x9c}}, + "DotEqual": {Name: "DotEqual", CodePoints: []int{8784}, Characters: []byte{0xe2, 0x89, 0x90}}, + "DoubleContourIntegral": {Name: "DoubleContourIntegral", CodePoints: []int{8751}, Characters: []byte{0xe2, 0x88, 0xaf}}, + "DoubleDot": {Name: "DoubleDot", CodePoints: []int{168}, Characters: []byte{0xc2, 0xa8}}, + "DoubleDownArrow": {Name: "DoubleDownArrow", CodePoints: []int{8659}, Characters: []byte{0xe2, 0x87, 0x93}}, + "DoubleLeftArrow": {Name: "DoubleLeftArrow", CodePoints: []int{8656}, Characters: []byte{0xe2, 0x87, 0x90}}, + "DoubleLeftRightArrow": {Name: "DoubleLeftRightArrow", CodePoints: []int{8660}, Characters: []byte{0xe2, 0x87, 0x94}}, + "DoubleLeftTee": {Name: "DoubleLeftTee", CodePoints: []int{10980}, Characters: []byte{0xe2, 0xab, 0xa4}}, + "DoubleLongLeftArrow": {Name: "DoubleLongLeftArrow", CodePoints: []int{10232}, Characters: []byte{0xe2, 0x9f, 0xb8}}, + "DoubleLongLeftRightArrow": {Name: "DoubleLongLeftRightArrow", CodePoints: []int{10234}, Characters: []byte{0xe2, 0x9f, 0xba}}, + "DoubleLongRightArrow": {Name: "DoubleLongRightArrow", CodePoints: []int{10233}, Characters: []byte{0xe2, 0x9f, 0xb9}}, + "DoubleRightArrow": {Name: "DoubleRightArrow", CodePoints: []int{8658}, Characters: []byte{0xe2, 0x87, 0x92}}, + "DoubleRightTee": {Name: "DoubleRightTee", CodePoints: []int{8872}, Characters: []byte{0xe2, 0x8a, 0xa8}}, + "DoubleUpArrow": {Name: "DoubleUpArrow", CodePoints: []int{8657}, Characters: []byte{0xe2, 0x87, 0x91}}, + "DoubleUpDownArrow": {Name: "DoubleUpDownArrow", CodePoints: []int{8661}, Characters: []byte{0xe2, 0x87, 0x95}}, + "DoubleVerticalBar": {Name: "DoubleVerticalBar", CodePoints: []int{8741}, Characters: []byte{0xe2, 0x88, 0xa5}}, + "DownArrow": {Name: "DownArrow", CodePoints: []int{8595}, Characters: []byte{0xe2, 0x86, 0x93}}, + "DownArrowBar": {Name: "DownArrowBar", CodePoints: []int{10515}, Characters: []byte{0xe2, 0xa4, 0x93}}, + "DownArrowUpArrow": {Name: "DownArrowUpArrow", CodePoints: []int{8693}, Characters: []byte{0xe2, 0x87, 0xb5}}, + "DownBreve": {Name: "DownBreve", CodePoints: []int{785}, Characters: []byte{0xcc, 0x91}}, + "DownLeftRightVector": {Name: "DownLeftRightVector", CodePoints: []int{10576}, Characters: []byte{0xe2, 0xa5, 0x90}}, + "DownLeftTeeVector": {Name: "DownLeftTeeVector", CodePoints: []int{10590}, Characters: []byte{0xe2, 0xa5, 0x9e}}, + "DownLeftVector": {Name: "DownLeftVector", CodePoints: []int{8637}, Characters: []byte{0xe2, 0x86, 0xbd}}, + "DownLeftVectorBar": {Name: "DownLeftVectorBar", CodePoints: []int{10582}, Characters: []byte{0xe2, 0xa5, 0x96}}, + "DownRightTeeVector": {Name: "DownRightTeeVector", CodePoints: []int{10591}, Characters: []byte{0xe2, 0xa5, 0x9f}}, + "DownRightVector": {Name: "DownRightVector", CodePoints: []int{8641}, Characters: []byte{0xe2, 0x87, 0x81}}, + "DownRightVectorBar": {Name: "DownRightVectorBar", CodePoints: []int{10583}, Characters: []byte{0xe2, 0xa5, 0x97}}, + "DownTee": {Name: "DownTee", CodePoints: []int{8868}, Characters: []byte{0xe2, 0x8a, 0xa4}}, + "DownTeeArrow": {Name: "DownTeeArrow", CodePoints: []int{8615}, Characters: []byte{0xe2, 0x86, 0xa7}}, + "Downarrow": {Name: "Downarrow", CodePoints: []int{8659}, Characters: []byte{0xe2, 0x87, 0x93}}, + "Dscr": {Name: "Dscr", CodePoints: []int{119967}, Characters: []byte{0xf0, 0x9d, 0x92, 0x9f}}, + "Dstrok": {Name: "Dstrok", CodePoints: []int{272}, Characters: []byte{0xc4, 0x90}}, + "ENG": {Name: "ENG", CodePoints: []int{330}, Characters: []byte{0xc5, 0x8a}}, + "ETH": {Name: "ETH", CodePoints: []int{208}, Characters: []byte{0xc3, 0x90}}, + "Eacute": {Name: "Eacute", CodePoints: []int{201}, Characters: []byte{0xc3, 0x89}}, + "Ecaron": {Name: "Ecaron", CodePoints: []int{282}, Characters: []byte{0xc4, 0x9a}}, + "Ecirc": {Name: "Ecirc", CodePoints: []int{202}, Characters: []byte{0xc3, 0x8a}}, + "Ecy": {Name: "Ecy", CodePoints: []int{1069}, Characters: []byte{0xd0, 0xad}}, + "Edot": {Name: "Edot", CodePoints: []int{278}, Characters: []byte{0xc4, 0x96}}, + "Efr": {Name: "Efr", CodePoints: []int{120072}, Characters: []byte{0xf0, 0x9d, 0x94, 0x88}}, + "Egrave": {Name: "Egrave", CodePoints: []int{200}, Characters: []byte{0xc3, 0x88}}, + "Element": {Name: "Element", CodePoints: []int{8712}, Characters: []byte{0xe2, 0x88, 0x88}}, + "Emacr": {Name: "Emacr", CodePoints: []int{274}, Characters: []byte{0xc4, 0x92}}, + "EmptySmallSquare": {Name: "EmptySmallSquare", CodePoints: []int{9723}, Characters: []byte{0xe2, 0x97, 0xbb}}, + "EmptyVerySmallSquare": {Name: "EmptyVerySmallSquare", CodePoints: []int{9643}, Characters: []byte{0xe2, 0x96, 0xab}}, + "Eogon": {Name: "Eogon", CodePoints: []int{280}, Characters: []byte{0xc4, 0x98}}, + "Eopf": {Name: "Eopf", CodePoints: []int{120124}, Characters: []byte{0xf0, 0x9d, 0x94, 0xbc}}, + "Epsilon": {Name: "Epsilon", CodePoints: []int{917}, Characters: []byte{0xce, 0x95}}, + "Equal": {Name: "Equal", CodePoints: []int{10869}, Characters: []byte{0xe2, 0xa9, 0xb5}}, + "EqualTilde": {Name: "EqualTilde", CodePoints: []int{8770}, Characters: []byte{0xe2, 0x89, 0x82}}, + "Equilibrium": {Name: "Equilibrium", CodePoints: []int{8652}, Characters: []byte{0xe2, 0x87, 0x8c}}, + "Escr": {Name: "Escr", CodePoints: []int{8496}, Characters: []byte{0xe2, 0x84, 0xb0}}, + "Esim": {Name: "Esim", CodePoints: []int{10867}, Characters: []byte{0xe2, 0xa9, 0xb3}}, + "Eta": {Name: "Eta", CodePoints: []int{919}, Characters: []byte{0xce, 0x97}}, + "Euml": {Name: "Euml", CodePoints: []int{203}, Characters: []byte{0xc3, 0x8b}}, + "Exists": {Name: "Exists", CodePoints: []int{8707}, Characters: []byte{0xe2, 0x88, 0x83}}, + "ExponentialE": {Name: "ExponentialE", CodePoints: []int{8519}, Characters: []byte{0xe2, 0x85, 0x87}}, + "Fcy": {Name: "Fcy", CodePoints: []int{1060}, Characters: []byte{0xd0, 0xa4}}, + "Ffr": {Name: "Ffr", CodePoints: []int{120073}, Characters: []byte{0xf0, 0x9d, 0x94, 0x89}}, + "FilledSmallSquare": {Name: "FilledSmallSquare", CodePoints: []int{9724}, Characters: []byte{0xe2, 0x97, 0xbc}}, + "FilledVerySmallSquare": {Name: "FilledVerySmallSquare", CodePoints: []int{9642}, Characters: []byte{0xe2, 0x96, 0xaa}}, + "Fopf": {Name: "Fopf", CodePoints: []int{120125}, Characters: []byte{0xf0, 0x9d, 0x94, 0xbd}}, + "ForAll": {Name: "ForAll", CodePoints: []int{8704}, Characters: []byte{0xe2, 0x88, 0x80}}, + "Fouriertrf": {Name: "Fouriertrf", CodePoints: []int{8497}, Characters: []byte{0xe2, 0x84, 0xb1}}, + "Fscr": {Name: "Fscr", CodePoints: []int{8497}, Characters: []byte{0xe2, 0x84, 0xb1}}, + "GJcy": {Name: "GJcy", CodePoints: []int{1027}, Characters: []byte{0xd0, 0x83}}, + "GT": {Name: "GT", CodePoints: []int{62}, Characters: []byte{0x3e}}, + "Gamma": {Name: "Gamma", CodePoints: []int{915}, Characters: []byte{0xce, 0x93}}, + "Gammad": {Name: "Gammad", CodePoints: []int{988}, Characters: []byte{0xcf, 0x9c}}, + "Gbreve": {Name: "Gbreve", CodePoints: []int{286}, Characters: []byte{0xc4, 0x9e}}, + "Gcedil": {Name: "Gcedil", CodePoints: []int{290}, Characters: []byte{0xc4, 0xa2}}, + "Gcirc": {Name: "Gcirc", CodePoints: []int{284}, Characters: []byte{0xc4, 0x9c}}, + "Gcy": {Name: "Gcy", CodePoints: []int{1043}, Characters: []byte{0xd0, 0x93}}, + "Gdot": {Name: "Gdot", CodePoints: []int{288}, Characters: []byte{0xc4, 0xa0}}, + "Gfr": {Name: "Gfr", CodePoints: []int{120074}, Characters: []byte{0xf0, 0x9d, 0x94, 0x8a}}, + "Gg": {Name: "Gg", CodePoints: []int{8921}, Characters: []byte{0xe2, 0x8b, 0x99}}, + "Gopf": {Name: "Gopf", CodePoints: []int{120126}, Characters: []byte{0xf0, 0x9d, 0x94, 0xbe}}, + "GreaterEqual": {Name: "GreaterEqual", CodePoints: []int{8805}, Characters: []byte{0xe2, 0x89, 0xa5}}, + "GreaterEqualLess": {Name: "GreaterEqualLess", CodePoints: []int{8923}, Characters: []byte{0xe2, 0x8b, 0x9b}}, + "GreaterFullEqual": {Name: "GreaterFullEqual", CodePoints: []int{8807}, Characters: []byte{0xe2, 0x89, 0xa7}}, + "GreaterGreater": {Name: "GreaterGreater", CodePoints: []int{10914}, Characters: []byte{0xe2, 0xaa, 0xa2}}, + "GreaterLess": {Name: "GreaterLess", CodePoints: []int{8823}, Characters: []byte{0xe2, 0x89, 0xb7}}, + "GreaterSlantEqual": {Name: "GreaterSlantEqual", CodePoints: []int{10878}, Characters: []byte{0xe2, 0xa9, 0xbe}}, + "GreaterTilde": {Name: "GreaterTilde", CodePoints: []int{8819}, Characters: []byte{0xe2, 0x89, 0xb3}}, + "Gscr": {Name: "Gscr", CodePoints: []int{119970}, Characters: []byte{0xf0, 0x9d, 0x92, 0xa2}}, + "Gt": {Name: "Gt", CodePoints: []int{8811}, Characters: []byte{0xe2, 0x89, 0xab}}, + "HARDcy": {Name: "HARDcy", CodePoints: []int{1066}, Characters: []byte{0xd0, 0xaa}}, + "Hacek": {Name: "Hacek", CodePoints: []int{711}, Characters: []byte{0xcb, 0x87}}, + "Hat": {Name: "Hat", CodePoints: []int{94}, Characters: []byte{0x5e}}, + "Hcirc": {Name: "Hcirc", CodePoints: []int{292}, Characters: []byte{0xc4, 0xa4}}, + "Hfr": {Name: "Hfr", CodePoints: []int{8460}, Characters: []byte{0xe2, 0x84, 0x8c}}, + "HilbertSpace": {Name: "HilbertSpace", CodePoints: []int{8459}, Characters: []byte{0xe2, 0x84, 0x8b}}, + "Hopf": {Name: "Hopf", CodePoints: []int{8461}, Characters: []byte{0xe2, 0x84, 0x8d}}, + "HorizontalLine": {Name: "HorizontalLine", CodePoints: []int{9472}, Characters: []byte{0xe2, 0x94, 0x80}}, + "Hscr": {Name: "Hscr", CodePoints: []int{8459}, Characters: []byte{0xe2, 0x84, 0x8b}}, + "Hstrok": {Name: "Hstrok", CodePoints: []int{294}, Characters: []byte{0xc4, 0xa6}}, + "HumpDownHump": {Name: "HumpDownHump", CodePoints: []int{8782}, Characters: []byte{0xe2, 0x89, 0x8e}}, + "HumpEqual": {Name: "HumpEqual", CodePoints: []int{8783}, Characters: []byte{0xe2, 0x89, 0x8f}}, + "IEcy": {Name: "IEcy", CodePoints: []int{1045}, Characters: []byte{0xd0, 0x95}}, + "IJlig": {Name: "IJlig", CodePoints: []int{306}, Characters: []byte{0xc4, 0xb2}}, + "IOcy": {Name: "IOcy", CodePoints: []int{1025}, Characters: []byte{0xd0, 0x81}}, + "Iacute": {Name: "Iacute", CodePoints: []int{205}, Characters: []byte{0xc3, 0x8d}}, + "Icirc": {Name: "Icirc", CodePoints: []int{206}, Characters: []byte{0xc3, 0x8e}}, + "Icy": {Name: "Icy", CodePoints: []int{1048}, Characters: []byte{0xd0, 0x98}}, + "Idot": {Name: "Idot", CodePoints: []int{304}, Characters: []byte{0xc4, 0xb0}}, + "Ifr": {Name: "Ifr", CodePoints: []int{8465}, Characters: []byte{0xe2, 0x84, 0x91}}, + "Igrave": {Name: "Igrave", CodePoints: []int{204}, Characters: []byte{0xc3, 0x8c}}, + "Im": {Name: "Im", CodePoints: []int{8465}, Characters: []byte{0xe2, 0x84, 0x91}}, + "Imacr": {Name: "Imacr", CodePoints: []int{298}, Characters: []byte{0xc4, 0xaa}}, + "ImaginaryI": {Name: "ImaginaryI", CodePoints: []int{8520}, Characters: []byte{0xe2, 0x85, 0x88}}, + "Implies": {Name: "Implies", CodePoints: []int{8658}, Characters: []byte{0xe2, 0x87, 0x92}}, + "Int": {Name: "Int", CodePoints: []int{8748}, Characters: []byte{0xe2, 0x88, 0xac}}, + "Integral": {Name: "Integral", CodePoints: []int{8747}, Characters: []byte{0xe2, 0x88, 0xab}}, + "Intersection": {Name: "Intersection", CodePoints: []int{8898}, Characters: []byte{0xe2, 0x8b, 0x82}}, + "InvisibleComma": {Name: "InvisibleComma", CodePoints: []int{8291}, Characters: []byte{0xe2, 0x81, 0xa3}}, + "InvisibleTimes": {Name: "InvisibleTimes", CodePoints: []int{8290}, Characters: []byte{0xe2, 0x81, 0xa2}}, + "Iogon": {Name: "Iogon", CodePoints: []int{302}, Characters: []byte{0xc4, 0xae}}, + "Iopf": {Name: "Iopf", CodePoints: []int{120128}, Characters: []byte{0xf0, 0x9d, 0x95, 0x80}}, + "Iota": {Name: "Iota", CodePoints: []int{921}, Characters: []byte{0xce, 0x99}}, + "Iscr": {Name: "Iscr", CodePoints: []int{8464}, Characters: []byte{0xe2, 0x84, 0x90}}, + "Itilde": {Name: "Itilde", CodePoints: []int{296}, Characters: []byte{0xc4, 0xa8}}, + "Iukcy": {Name: "Iukcy", CodePoints: []int{1030}, Characters: []byte{0xd0, 0x86}}, + "Iuml": {Name: "Iuml", CodePoints: []int{207}, Characters: []byte{0xc3, 0x8f}}, + "Jcirc": {Name: "Jcirc", CodePoints: []int{308}, Characters: []byte{0xc4, 0xb4}}, + "Jcy": {Name: "Jcy", CodePoints: []int{1049}, Characters: []byte{0xd0, 0x99}}, + "Jfr": {Name: "Jfr", CodePoints: []int{120077}, Characters: []byte{0xf0, 0x9d, 0x94, 0x8d}}, + "Jopf": {Name: "Jopf", CodePoints: []int{120129}, Characters: []byte{0xf0, 0x9d, 0x95, 0x81}}, + "Jscr": {Name: "Jscr", CodePoints: []int{119973}, Characters: []byte{0xf0, 0x9d, 0x92, 0xa5}}, + "Jsercy": {Name: "Jsercy", CodePoints: []int{1032}, Characters: []byte{0xd0, 0x88}}, + "Jukcy": {Name: "Jukcy", CodePoints: []int{1028}, Characters: []byte{0xd0, 0x84}}, + "KHcy": {Name: "KHcy", CodePoints: []int{1061}, Characters: []byte{0xd0, 0xa5}}, + "KJcy": {Name: "KJcy", CodePoints: []int{1036}, Characters: []byte{0xd0, 0x8c}}, + "Kappa": {Name: "Kappa", CodePoints: []int{922}, Characters: []byte{0xce, 0x9a}}, + "Kcedil": {Name: "Kcedil", CodePoints: []int{310}, Characters: []byte{0xc4, 0xb6}}, + "Kcy": {Name: "Kcy", CodePoints: []int{1050}, Characters: []byte{0xd0, 0x9a}}, + "Kfr": {Name: "Kfr", CodePoints: []int{120078}, Characters: []byte{0xf0, 0x9d, 0x94, 0x8e}}, + "Kopf": {Name: "Kopf", CodePoints: []int{120130}, Characters: []byte{0xf0, 0x9d, 0x95, 0x82}}, + "Kscr": {Name: "Kscr", CodePoints: []int{119974}, Characters: []byte{0xf0, 0x9d, 0x92, 0xa6}}, + "LJcy": {Name: "LJcy", CodePoints: []int{1033}, Characters: []byte{0xd0, 0x89}}, + "LT": {Name: "LT", CodePoints: []int{60}, Characters: []byte{0x3c}}, + "Lacute": {Name: "Lacute", CodePoints: []int{313}, Characters: []byte{0xc4, 0xb9}}, + "Lambda": {Name: "Lambda", CodePoints: []int{923}, Characters: []byte{0xce, 0x9b}}, + "Lang": {Name: "Lang", CodePoints: []int{10218}, Characters: []byte{0xe2, 0x9f, 0xaa}}, + "Laplacetrf": {Name: "Laplacetrf", CodePoints: []int{8466}, Characters: []byte{0xe2, 0x84, 0x92}}, + "Larr": {Name: "Larr", CodePoints: []int{8606}, Characters: []byte{0xe2, 0x86, 0x9e}}, + "Lcaron": {Name: "Lcaron", CodePoints: []int{317}, Characters: []byte{0xc4, 0xbd}}, + "Lcedil": {Name: "Lcedil", CodePoints: []int{315}, Characters: []byte{0xc4, 0xbb}}, + "Lcy": {Name: "Lcy", CodePoints: []int{1051}, Characters: []byte{0xd0, 0x9b}}, + "LeftAngleBracket": {Name: "LeftAngleBracket", CodePoints: []int{10216}, Characters: []byte{0xe2, 0x9f, 0xa8}}, + "LeftArrow": {Name: "LeftArrow", CodePoints: []int{8592}, Characters: []byte{0xe2, 0x86, 0x90}}, + "LeftArrowBar": {Name: "LeftArrowBar", CodePoints: []int{8676}, Characters: []byte{0xe2, 0x87, 0xa4}}, + "LeftArrowRightArrow": {Name: "LeftArrowRightArrow", CodePoints: []int{8646}, Characters: []byte{0xe2, 0x87, 0x86}}, + "LeftCeiling": {Name: "LeftCeiling", CodePoints: []int{8968}, Characters: []byte{0xe2, 0x8c, 0x88}}, + "LeftDoubleBracket": {Name: "LeftDoubleBracket", CodePoints: []int{10214}, Characters: []byte{0xe2, 0x9f, 0xa6}}, + "LeftDownTeeVector": {Name: "LeftDownTeeVector", CodePoints: []int{10593}, Characters: []byte{0xe2, 0xa5, 0xa1}}, + "LeftDownVector": {Name: "LeftDownVector", CodePoints: []int{8643}, Characters: []byte{0xe2, 0x87, 0x83}}, + "LeftDownVectorBar": {Name: "LeftDownVectorBar", CodePoints: []int{10585}, Characters: []byte{0xe2, 0xa5, 0x99}}, + "LeftFloor": {Name: "LeftFloor", CodePoints: []int{8970}, Characters: []byte{0xe2, 0x8c, 0x8a}}, + "LeftRightArrow": {Name: "LeftRightArrow", CodePoints: []int{8596}, Characters: []byte{0xe2, 0x86, 0x94}}, + "LeftRightVector": {Name: "LeftRightVector", CodePoints: []int{10574}, Characters: []byte{0xe2, 0xa5, 0x8e}}, + "LeftTee": {Name: "LeftTee", CodePoints: []int{8867}, Characters: []byte{0xe2, 0x8a, 0xa3}}, + "LeftTeeArrow": {Name: "LeftTeeArrow", CodePoints: []int{8612}, Characters: []byte{0xe2, 0x86, 0xa4}}, + "LeftTeeVector": {Name: "LeftTeeVector", CodePoints: []int{10586}, Characters: []byte{0xe2, 0xa5, 0x9a}}, + "LeftTriangle": {Name: "LeftTriangle", CodePoints: []int{8882}, Characters: []byte{0xe2, 0x8a, 0xb2}}, + "LeftTriangleBar": {Name: "LeftTriangleBar", CodePoints: []int{10703}, Characters: []byte{0xe2, 0xa7, 0x8f}}, + "LeftTriangleEqual": {Name: "LeftTriangleEqual", CodePoints: []int{8884}, Characters: []byte{0xe2, 0x8a, 0xb4}}, + "LeftUpDownVector": {Name: "LeftUpDownVector", CodePoints: []int{10577}, Characters: []byte{0xe2, 0xa5, 0x91}}, + "LeftUpTeeVector": {Name: "LeftUpTeeVector", CodePoints: []int{10592}, Characters: []byte{0xe2, 0xa5, 0xa0}}, + "LeftUpVector": {Name: "LeftUpVector", CodePoints: []int{8639}, Characters: []byte{0xe2, 0x86, 0xbf}}, + "LeftUpVectorBar": {Name: "LeftUpVectorBar", CodePoints: []int{10584}, Characters: []byte{0xe2, 0xa5, 0x98}}, + "LeftVector": {Name: "LeftVector", CodePoints: []int{8636}, Characters: []byte{0xe2, 0x86, 0xbc}}, + "LeftVectorBar": {Name: "LeftVectorBar", CodePoints: []int{10578}, Characters: []byte{0xe2, 0xa5, 0x92}}, + "Leftarrow": {Name: "Leftarrow", CodePoints: []int{8656}, Characters: []byte{0xe2, 0x87, 0x90}}, + "Leftrightarrow": {Name: "Leftrightarrow", CodePoints: []int{8660}, Characters: []byte{0xe2, 0x87, 0x94}}, + "LessEqualGreater": {Name: "LessEqualGreater", CodePoints: []int{8922}, Characters: []byte{0xe2, 0x8b, 0x9a}}, + "LessFullEqual": {Name: "LessFullEqual", CodePoints: []int{8806}, Characters: []byte{0xe2, 0x89, 0xa6}}, + "LessGreater": {Name: "LessGreater", CodePoints: []int{8822}, Characters: []byte{0xe2, 0x89, 0xb6}}, + "LessLess": {Name: "LessLess", CodePoints: []int{10913}, Characters: []byte{0xe2, 0xaa, 0xa1}}, + "LessSlantEqual": {Name: "LessSlantEqual", CodePoints: []int{10877}, Characters: []byte{0xe2, 0xa9, 0xbd}}, + "LessTilde": {Name: "LessTilde", CodePoints: []int{8818}, Characters: []byte{0xe2, 0x89, 0xb2}}, + "Lfr": {Name: "Lfr", CodePoints: []int{120079}, Characters: []byte{0xf0, 0x9d, 0x94, 0x8f}}, + "Ll": {Name: "Ll", CodePoints: []int{8920}, Characters: []byte{0xe2, 0x8b, 0x98}}, + "Lleftarrow": {Name: "Lleftarrow", CodePoints: []int{8666}, Characters: []byte{0xe2, 0x87, 0x9a}}, + "Lmidot": {Name: "Lmidot", CodePoints: []int{319}, Characters: []byte{0xc4, 0xbf}}, + "LongLeftArrow": {Name: "LongLeftArrow", CodePoints: []int{10229}, Characters: []byte{0xe2, 0x9f, 0xb5}}, + "LongLeftRightArrow": {Name: "LongLeftRightArrow", CodePoints: []int{10231}, Characters: []byte{0xe2, 0x9f, 0xb7}}, + "LongRightArrow": {Name: "LongRightArrow", CodePoints: []int{10230}, Characters: []byte{0xe2, 0x9f, 0xb6}}, + "Longleftarrow": {Name: "Longleftarrow", CodePoints: []int{10232}, Characters: []byte{0xe2, 0x9f, 0xb8}}, + "Longleftrightarrow": {Name: "Longleftrightarrow", CodePoints: []int{10234}, Characters: []byte{0xe2, 0x9f, 0xba}}, + "Longrightarrow": {Name: "Longrightarrow", CodePoints: []int{10233}, Characters: []byte{0xe2, 0x9f, 0xb9}}, + "Lopf": {Name: "Lopf", CodePoints: []int{120131}, Characters: []byte{0xf0, 0x9d, 0x95, 0x83}}, + "LowerLeftArrow": {Name: "LowerLeftArrow", CodePoints: []int{8601}, Characters: []byte{0xe2, 0x86, 0x99}}, + "LowerRightArrow": {Name: "LowerRightArrow", CodePoints: []int{8600}, Characters: []byte{0xe2, 0x86, 0x98}}, + "Lscr": {Name: "Lscr", CodePoints: []int{8466}, Characters: []byte{0xe2, 0x84, 0x92}}, + "Lsh": {Name: "Lsh", CodePoints: []int{8624}, Characters: []byte{0xe2, 0x86, 0xb0}}, + "Lstrok": {Name: "Lstrok", CodePoints: []int{321}, Characters: []byte{0xc5, 0x81}}, + "Lt": {Name: "Lt", CodePoints: []int{8810}, Characters: []byte{0xe2, 0x89, 0xaa}}, + "Map": {Name: "Map", CodePoints: []int{10501}, Characters: []byte{0xe2, 0xa4, 0x85}}, + "Mcy": {Name: "Mcy", CodePoints: []int{1052}, Characters: []byte{0xd0, 0x9c}}, + "MediumSpace": {Name: "MediumSpace", CodePoints: []int{8287}, Characters: []byte{0xe2, 0x81, 0x9f}}, + "Mellintrf": {Name: "Mellintrf", CodePoints: []int{8499}, Characters: []byte{0xe2, 0x84, 0xb3}}, + "Mfr": {Name: "Mfr", CodePoints: []int{120080}, Characters: []byte{0xf0, 0x9d, 0x94, 0x90}}, + "MinusPlus": {Name: "MinusPlus", CodePoints: []int{8723}, Characters: []byte{0xe2, 0x88, 0x93}}, + "Mopf": {Name: "Mopf", CodePoints: []int{120132}, Characters: []byte{0xf0, 0x9d, 0x95, 0x84}}, + "Mscr": {Name: "Mscr", CodePoints: []int{8499}, Characters: []byte{0xe2, 0x84, 0xb3}}, + "Mu": {Name: "Mu", CodePoints: []int{924}, Characters: []byte{0xce, 0x9c}}, + "NJcy": {Name: "NJcy", CodePoints: []int{1034}, Characters: []byte{0xd0, 0x8a}}, + "Nacute": {Name: "Nacute", CodePoints: []int{323}, Characters: []byte{0xc5, 0x83}}, + "Ncaron": {Name: "Ncaron", CodePoints: []int{327}, Characters: []byte{0xc5, 0x87}}, + "Ncedil": {Name: "Ncedil", CodePoints: []int{325}, Characters: []byte{0xc5, 0x85}}, + "Ncy": {Name: "Ncy", CodePoints: []int{1053}, Characters: []byte{0xd0, 0x9d}}, + "NegativeMediumSpace": {Name: "NegativeMediumSpace", CodePoints: []int{8203}, Characters: []byte{0xe2, 0x80, 0x8b}}, + "NegativeThickSpace": {Name: "NegativeThickSpace", CodePoints: []int{8203}, Characters: []byte{0xe2, 0x80, 0x8b}}, + "NegativeThinSpace": {Name: "NegativeThinSpace", CodePoints: []int{8203}, Characters: []byte{0xe2, 0x80, 0x8b}}, + "NegativeVeryThinSpace": {Name: "NegativeVeryThinSpace", CodePoints: []int{8203}, Characters: []byte{0xe2, 0x80, 0x8b}}, + "NestedGreaterGreater": {Name: "NestedGreaterGreater", CodePoints: []int{8811}, Characters: []byte{0xe2, 0x89, 0xab}}, + "NestedLessLess": {Name: "NestedLessLess", CodePoints: []int{8810}, Characters: []byte{0xe2, 0x89, 0xaa}}, + "NewLine": {Name: "NewLine", CodePoints: []int{10}, Characters: []byte{0xa}}, + "Nfr": {Name: "Nfr", CodePoints: []int{120081}, Characters: []byte{0xf0, 0x9d, 0x94, 0x91}}, + "NoBreak": {Name: "NoBreak", CodePoints: []int{8288}, Characters: []byte{0xe2, 0x81, 0xa0}}, + "NonBreakingSpace": {Name: "NonBreakingSpace", CodePoints: []int{160}, Characters: []byte{0xc2, 0xa0}}, + "Nopf": {Name: "Nopf", CodePoints: []int{8469}, Characters: []byte{0xe2, 0x84, 0x95}}, + "Not": {Name: "Not", CodePoints: []int{10988}, Characters: []byte{0xe2, 0xab, 0xac}}, + "NotCongruent": {Name: "NotCongruent", CodePoints: []int{8802}, Characters: []byte{0xe2, 0x89, 0xa2}}, + "NotCupCap": {Name: "NotCupCap", CodePoints: []int{8813}, Characters: []byte{0xe2, 0x89, 0xad}}, + "NotDoubleVerticalBar": {Name: "NotDoubleVerticalBar", CodePoints: []int{8742}, Characters: []byte{0xe2, 0x88, 0xa6}}, + "NotElement": {Name: "NotElement", CodePoints: []int{8713}, Characters: []byte{0xe2, 0x88, 0x89}}, + "NotEqual": {Name: "NotEqual", CodePoints: []int{8800}, Characters: []byte{0xe2, 0x89, 0xa0}}, + "NotEqualTilde": {Name: "NotEqualTilde", CodePoints: []int{8770, 824}, Characters: []byte{0xe2, 0x89, 0x82, 0xcc, 0xb8}}, + "NotExists": {Name: "NotExists", CodePoints: []int{8708}, Characters: []byte{0xe2, 0x88, 0x84}}, + "NotGreater": {Name: "NotGreater", CodePoints: []int{8815}, Characters: []byte{0xe2, 0x89, 0xaf}}, + "NotGreaterEqual": {Name: "NotGreaterEqual", CodePoints: []int{8817}, Characters: []byte{0xe2, 0x89, 0xb1}}, + "NotGreaterFullEqual": {Name: "NotGreaterFullEqual", CodePoints: []int{8807, 824}, Characters: []byte{0xe2, 0x89, 0xa7, 0xcc, 0xb8}}, + "NotGreaterGreater": {Name: "NotGreaterGreater", CodePoints: []int{8811, 824}, Characters: []byte{0xe2, 0x89, 0xab, 0xcc, 0xb8}}, + "NotGreaterLess": {Name: "NotGreaterLess", CodePoints: []int{8825}, Characters: []byte{0xe2, 0x89, 0xb9}}, + "NotGreaterSlantEqual": {Name: "NotGreaterSlantEqual", CodePoints: []int{10878, 824}, Characters: []byte{0xe2, 0xa9, 0xbe, 0xcc, 0xb8}}, + "NotGreaterTilde": {Name: "NotGreaterTilde", CodePoints: []int{8821}, Characters: []byte{0xe2, 0x89, 0xb5}}, + "NotHumpDownHump": {Name: "NotHumpDownHump", CodePoints: []int{8782, 824}, Characters: []byte{0xe2, 0x89, 0x8e, 0xcc, 0xb8}}, + "NotHumpEqual": {Name: "NotHumpEqual", CodePoints: []int{8783, 824}, Characters: []byte{0xe2, 0x89, 0x8f, 0xcc, 0xb8}}, + "NotLeftTriangle": {Name: "NotLeftTriangle", CodePoints: []int{8938}, Characters: []byte{0xe2, 0x8b, 0xaa}}, + "NotLeftTriangleBar": {Name: "NotLeftTriangleBar", CodePoints: []int{10703, 824}, Characters: []byte{0xe2, 0xa7, 0x8f, 0xcc, 0xb8}}, + "NotLeftTriangleEqual": {Name: "NotLeftTriangleEqual", CodePoints: []int{8940}, Characters: []byte{0xe2, 0x8b, 0xac}}, + "NotLess": {Name: "NotLess", CodePoints: []int{8814}, Characters: []byte{0xe2, 0x89, 0xae}}, + "NotLessEqual": {Name: "NotLessEqual", CodePoints: []int{8816}, Characters: []byte{0xe2, 0x89, 0xb0}}, + "NotLessGreater": {Name: "NotLessGreater", CodePoints: []int{8824}, Characters: []byte{0xe2, 0x89, 0xb8}}, + "NotLessLess": {Name: "NotLessLess", CodePoints: []int{8810, 824}, Characters: []byte{0xe2, 0x89, 0xaa, 0xcc, 0xb8}}, + "NotLessSlantEqual": {Name: "NotLessSlantEqual", CodePoints: []int{10877, 824}, Characters: []byte{0xe2, 0xa9, 0xbd, 0xcc, 0xb8}}, + "NotLessTilde": {Name: "NotLessTilde", CodePoints: []int{8820}, Characters: []byte{0xe2, 0x89, 0xb4}}, + "NotNestedGreaterGreater": {Name: "NotNestedGreaterGreater", CodePoints: []int{10914, 824}, Characters: []byte{0xe2, 0xaa, 0xa2, 0xcc, 0xb8}}, + "NotNestedLessLess": {Name: "NotNestedLessLess", CodePoints: []int{10913, 824}, Characters: []byte{0xe2, 0xaa, 0xa1, 0xcc, 0xb8}}, + "NotPrecedes": {Name: "NotPrecedes", CodePoints: []int{8832}, Characters: []byte{0xe2, 0x8a, 0x80}}, + "NotPrecedesEqual": {Name: "NotPrecedesEqual", CodePoints: []int{10927, 824}, Characters: []byte{0xe2, 0xaa, 0xaf, 0xcc, 0xb8}}, + "NotPrecedesSlantEqual": {Name: "NotPrecedesSlantEqual", CodePoints: []int{8928}, Characters: []byte{0xe2, 0x8b, 0xa0}}, + "NotReverseElement": {Name: "NotReverseElement", CodePoints: []int{8716}, Characters: []byte{0xe2, 0x88, 0x8c}}, + "NotRightTriangle": {Name: "NotRightTriangle", CodePoints: []int{8939}, Characters: []byte{0xe2, 0x8b, 0xab}}, + "NotRightTriangleBar": {Name: "NotRightTriangleBar", CodePoints: []int{10704, 824}, Characters: []byte{0xe2, 0xa7, 0x90, 0xcc, 0xb8}}, + "NotRightTriangleEqual": {Name: "NotRightTriangleEqual", CodePoints: []int{8941}, Characters: []byte{0xe2, 0x8b, 0xad}}, + "NotSquareSubset": {Name: "NotSquareSubset", CodePoints: []int{8847, 824}, Characters: []byte{0xe2, 0x8a, 0x8f, 0xcc, 0xb8}}, + "NotSquareSubsetEqual": {Name: "NotSquareSubsetEqual", CodePoints: []int{8930}, Characters: []byte{0xe2, 0x8b, 0xa2}}, + "NotSquareSuperset": {Name: "NotSquareSuperset", CodePoints: []int{8848, 824}, Characters: []byte{0xe2, 0x8a, 0x90, 0xcc, 0xb8}}, + "NotSquareSupersetEqual": {Name: "NotSquareSupersetEqual", CodePoints: []int{8931}, Characters: []byte{0xe2, 0x8b, 0xa3}}, + "NotSubset": {Name: "NotSubset", CodePoints: []int{8834, 8402}, Characters: []byte{0xe2, 0x8a, 0x82, 0xe2, 0x83, 0x92}}, + "NotSubsetEqual": {Name: "NotSubsetEqual", CodePoints: []int{8840}, Characters: []byte{0xe2, 0x8a, 0x88}}, + "NotSucceeds": {Name: "NotSucceeds", CodePoints: []int{8833}, Characters: []byte{0xe2, 0x8a, 0x81}}, + "NotSucceedsEqual": {Name: "NotSucceedsEqual", CodePoints: []int{10928, 824}, Characters: []byte{0xe2, 0xaa, 0xb0, 0xcc, 0xb8}}, + "NotSucceedsSlantEqual": {Name: "NotSucceedsSlantEqual", CodePoints: []int{8929}, Characters: []byte{0xe2, 0x8b, 0xa1}}, + "NotSucceedsTilde": {Name: "NotSucceedsTilde", CodePoints: []int{8831, 824}, Characters: []byte{0xe2, 0x89, 0xbf, 0xcc, 0xb8}}, + "NotSuperset": {Name: "NotSuperset", CodePoints: []int{8835, 8402}, Characters: []byte{0xe2, 0x8a, 0x83, 0xe2, 0x83, 0x92}}, + "NotSupersetEqual": {Name: "NotSupersetEqual", CodePoints: []int{8841}, Characters: []byte{0xe2, 0x8a, 0x89}}, + "NotTilde": {Name: "NotTilde", CodePoints: []int{8769}, Characters: []byte{0xe2, 0x89, 0x81}}, + "NotTildeEqual": {Name: "NotTildeEqual", CodePoints: []int{8772}, Characters: []byte{0xe2, 0x89, 0x84}}, + "NotTildeFullEqual": {Name: "NotTildeFullEqual", CodePoints: []int{8775}, Characters: []byte{0xe2, 0x89, 0x87}}, + "NotTildeTilde": {Name: "NotTildeTilde", CodePoints: []int{8777}, Characters: []byte{0xe2, 0x89, 0x89}}, + "NotVerticalBar": {Name: "NotVerticalBar", CodePoints: []int{8740}, Characters: []byte{0xe2, 0x88, 0xa4}}, + "Nscr": {Name: "Nscr", CodePoints: []int{119977}, Characters: []byte{0xf0, 0x9d, 0x92, 0xa9}}, + "Ntilde": {Name: "Ntilde", CodePoints: []int{209}, Characters: []byte{0xc3, 0x91}}, + "Nu": {Name: "Nu", CodePoints: []int{925}, Characters: []byte{0xce, 0x9d}}, + "OElig": {Name: "OElig", CodePoints: []int{338}, Characters: []byte{0xc5, 0x92}}, + "Oacute": {Name: "Oacute", CodePoints: []int{211}, Characters: []byte{0xc3, 0x93}}, + "Ocirc": {Name: "Ocirc", CodePoints: []int{212}, Characters: []byte{0xc3, 0x94}}, + "Ocy": {Name: "Ocy", CodePoints: []int{1054}, Characters: []byte{0xd0, 0x9e}}, + "Odblac": {Name: "Odblac", CodePoints: []int{336}, Characters: []byte{0xc5, 0x90}}, + "Ofr": {Name: "Ofr", CodePoints: []int{120082}, Characters: []byte{0xf0, 0x9d, 0x94, 0x92}}, + "Ograve": {Name: "Ograve", CodePoints: []int{210}, Characters: []byte{0xc3, 0x92}}, + "Omacr": {Name: "Omacr", CodePoints: []int{332}, Characters: []byte{0xc5, 0x8c}}, + "Omega": {Name: "Omega", CodePoints: []int{937}, Characters: []byte{0xce, 0xa9}}, + "Omicron": {Name: "Omicron", CodePoints: []int{927}, Characters: []byte{0xce, 0x9f}}, + "Oopf": {Name: "Oopf", CodePoints: []int{120134}, Characters: []byte{0xf0, 0x9d, 0x95, 0x86}}, + "OpenCurlyDoubleQuote": {Name: "OpenCurlyDoubleQuote", CodePoints: []int{8220}, Characters: []byte{0xe2, 0x80, 0x9c}}, + "OpenCurlyQuote": {Name: "OpenCurlyQuote", CodePoints: []int{8216}, Characters: []byte{0xe2, 0x80, 0x98}}, + "Or": {Name: "Or", CodePoints: []int{10836}, Characters: []byte{0xe2, 0xa9, 0x94}}, + "Oscr": {Name: "Oscr", CodePoints: []int{119978}, Characters: []byte{0xf0, 0x9d, 0x92, 0xaa}}, + "Oslash": {Name: "Oslash", CodePoints: []int{216}, Characters: []byte{0xc3, 0x98}}, + "Otilde": {Name: "Otilde", CodePoints: []int{213}, Characters: []byte{0xc3, 0x95}}, + "Otimes": {Name: "Otimes", CodePoints: []int{10807}, Characters: []byte{0xe2, 0xa8, 0xb7}}, + "Ouml": {Name: "Ouml", CodePoints: []int{214}, Characters: []byte{0xc3, 0x96}}, + "OverBar": {Name: "OverBar", CodePoints: []int{8254}, Characters: []byte{0xe2, 0x80, 0xbe}}, + "OverBrace": {Name: "OverBrace", CodePoints: []int{9182}, Characters: []byte{0xe2, 0x8f, 0x9e}}, + "OverBracket": {Name: "OverBracket", CodePoints: []int{9140}, Characters: []byte{0xe2, 0x8e, 0xb4}}, + "OverParenthesis": {Name: "OverParenthesis", CodePoints: []int{9180}, Characters: []byte{0xe2, 0x8f, 0x9c}}, + "PartialD": {Name: "PartialD", CodePoints: []int{8706}, Characters: []byte{0xe2, 0x88, 0x82}}, + "Pcy": {Name: "Pcy", CodePoints: []int{1055}, Characters: []byte{0xd0, 0x9f}}, + "Pfr": {Name: "Pfr", CodePoints: []int{120083}, Characters: []byte{0xf0, 0x9d, 0x94, 0x93}}, + "Phi": {Name: "Phi", CodePoints: []int{934}, Characters: []byte{0xce, 0xa6}}, + "Pi": {Name: "Pi", CodePoints: []int{928}, Characters: []byte{0xce, 0xa0}}, + "PlusMinus": {Name: "PlusMinus", CodePoints: []int{177}, Characters: []byte{0xc2, 0xb1}}, + "Poincareplane": {Name: "Poincareplane", CodePoints: []int{8460}, Characters: []byte{0xe2, 0x84, 0x8c}}, + "Popf": {Name: "Popf", CodePoints: []int{8473}, Characters: []byte{0xe2, 0x84, 0x99}}, + "Pr": {Name: "Pr", CodePoints: []int{10939}, Characters: []byte{0xe2, 0xaa, 0xbb}}, + "Precedes": {Name: "Precedes", CodePoints: []int{8826}, Characters: []byte{0xe2, 0x89, 0xba}}, + "PrecedesEqual": {Name: "PrecedesEqual", CodePoints: []int{10927}, Characters: []byte{0xe2, 0xaa, 0xaf}}, + "PrecedesSlantEqual": {Name: "PrecedesSlantEqual", CodePoints: []int{8828}, Characters: []byte{0xe2, 0x89, 0xbc}}, + "PrecedesTilde": {Name: "PrecedesTilde", CodePoints: []int{8830}, Characters: []byte{0xe2, 0x89, 0xbe}}, + "Prime": {Name: "Prime", CodePoints: []int{8243}, Characters: []byte{0xe2, 0x80, 0xb3}}, + "Product": {Name: "Product", CodePoints: []int{8719}, Characters: []byte{0xe2, 0x88, 0x8f}}, + "Proportion": {Name: "Proportion", CodePoints: []int{8759}, Characters: []byte{0xe2, 0x88, 0xb7}}, + "Proportional": {Name: "Proportional", CodePoints: []int{8733}, Characters: []byte{0xe2, 0x88, 0x9d}}, + "Pscr": {Name: "Pscr", CodePoints: []int{119979}, Characters: []byte{0xf0, 0x9d, 0x92, 0xab}}, + "Psi": {Name: "Psi", CodePoints: []int{936}, Characters: []byte{0xce, 0xa8}}, + "QUOT": {Name: "QUOT", CodePoints: []int{34}, Characters: []byte{0x22}}, + "Qfr": {Name: "Qfr", CodePoints: []int{120084}, Characters: []byte{0xf0, 0x9d, 0x94, 0x94}}, + "Qopf": {Name: "Qopf", CodePoints: []int{8474}, Characters: []byte{0xe2, 0x84, 0x9a}}, + "Qscr": {Name: "Qscr", CodePoints: []int{119980}, Characters: []byte{0xf0, 0x9d, 0x92, 0xac}}, + "RBarr": {Name: "RBarr", CodePoints: []int{10512}, Characters: []byte{0xe2, 0xa4, 0x90}}, + "REG": {Name: "REG", CodePoints: []int{174}, Characters: []byte{0xc2, 0xae}}, + "Racute": {Name: "Racute", CodePoints: []int{340}, Characters: []byte{0xc5, 0x94}}, + "Rang": {Name: "Rang", CodePoints: []int{10219}, Characters: []byte{0xe2, 0x9f, 0xab}}, + "Rarr": {Name: "Rarr", CodePoints: []int{8608}, Characters: []byte{0xe2, 0x86, 0xa0}}, + "Rarrtl": {Name: "Rarrtl", CodePoints: []int{10518}, Characters: []byte{0xe2, 0xa4, 0x96}}, + "Rcaron": {Name: "Rcaron", CodePoints: []int{344}, Characters: []byte{0xc5, 0x98}}, + "Rcedil": {Name: "Rcedil", CodePoints: []int{342}, Characters: []byte{0xc5, 0x96}}, + "Rcy": {Name: "Rcy", CodePoints: []int{1056}, Characters: []byte{0xd0, 0xa0}}, + "Re": {Name: "Re", CodePoints: []int{8476}, Characters: []byte{0xe2, 0x84, 0x9c}}, + "ReverseElement": {Name: "ReverseElement", CodePoints: []int{8715}, Characters: []byte{0xe2, 0x88, 0x8b}}, + "ReverseEquilibrium": {Name: "ReverseEquilibrium", CodePoints: []int{8651}, Characters: []byte{0xe2, 0x87, 0x8b}}, + "ReverseUpEquilibrium": {Name: "ReverseUpEquilibrium", CodePoints: []int{10607}, Characters: []byte{0xe2, 0xa5, 0xaf}}, + "Rfr": {Name: "Rfr", CodePoints: []int{8476}, Characters: []byte{0xe2, 0x84, 0x9c}}, + "Rho": {Name: "Rho", CodePoints: []int{929}, Characters: []byte{0xce, 0xa1}}, + "RightAngleBracket": {Name: "RightAngleBracket", CodePoints: []int{10217}, Characters: []byte{0xe2, 0x9f, 0xa9}}, + "RightArrow": {Name: "RightArrow", CodePoints: []int{8594}, Characters: []byte{0xe2, 0x86, 0x92}}, + "RightArrowBar": {Name: "RightArrowBar", CodePoints: []int{8677}, Characters: []byte{0xe2, 0x87, 0xa5}}, + "RightArrowLeftArrow": {Name: "RightArrowLeftArrow", CodePoints: []int{8644}, Characters: []byte{0xe2, 0x87, 0x84}}, + "RightCeiling": {Name: "RightCeiling", CodePoints: []int{8969}, Characters: []byte{0xe2, 0x8c, 0x89}}, + "RightDoubleBracket": {Name: "RightDoubleBracket", CodePoints: []int{10215}, Characters: []byte{0xe2, 0x9f, 0xa7}}, + "RightDownTeeVector": {Name: "RightDownTeeVector", CodePoints: []int{10589}, Characters: []byte{0xe2, 0xa5, 0x9d}}, + "RightDownVector": {Name: "RightDownVector", CodePoints: []int{8642}, Characters: []byte{0xe2, 0x87, 0x82}}, + "RightDownVectorBar": {Name: "RightDownVectorBar", CodePoints: []int{10581}, Characters: []byte{0xe2, 0xa5, 0x95}}, + "RightFloor": {Name: "RightFloor", CodePoints: []int{8971}, Characters: []byte{0xe2, 0x8c, 0x8b}}, + "RightTee": {Name: "RightTee", CodePoints: []int{8866}, Characters: []byte{0xe2, 0x8a, 0xa2}}, + "RightTeeArrow": {Name: "RightTeeArrow", CodePoints: []int{8614}, Characters: []byte{0xe2, 0x86, 0xa6}}, + "RightTeeVector": {Name: "RightTeeVector", CodePoints: []int{10587}, Characters: []byte{0xe2, 0xa5, 0x9b}}, + "RightTriangle": {Name: "RightTriangle", CodePoints: []int{8883}, Characters: []byte{0xe2, 0x8a, 0xb3}}, + "RightTriangleBar": {Name: "RightTriangleBar", CodePoints: []int{10704}, Characters: []byte{0xe2, 0xa7, 0x90}}, + "RightTriangleEqual": {Name: "RightTriangleEqual", CodePoints: []int{8885}, Characters: []byte{0xe2, 0x8a, 0xb5}}, + "RightUpDownVector": {Name: "RightUpDownVector", CodePoints: []int{10575}, Characters: []byte{0xe2, 0xa5, 0x8f}}, + "RightUpTeeVector": {Name: "RightUpTeeVector", CodePoints: []int{10588}, Characters: []byte{0xe2, 0xa5, 0x9c}}, + "RightUpVector": {Name: "RightUpVector", CodePoints: []int{8638}, Characters: []byte{0xe2, 0x86, 0xbe}}, + "RightUpVectorBar": {Name: "RightUpVectorBar", CodePoints: []int{10580}, Characters: []byte{0xe2, 0xa5, 0x94}}, + "RightVector": {Name: "RightVector", CodePoints: []int{8640}, Characters: []byte{0xe2, 0x87, 0x80}}, + "RightVectorBar": {Name: "RightVectorBar", CodePoints: []int{10579}, Characters: []byte{0xe2, 0xa5, 0x93}}, + "Rightarrow": {Name: "Rightarrow", CodePoints: []int{8658}, Characters: []byte{0xe2, 0x87, 0x92}}, + "Ropf": {Name: "Ropf", CodePoints: []int{8477}, Characters: []byte{0xe2, 0x84, 0x9d}}, + "RoundImplies": {Name: "RoundImplies", CodePoints: []int{10608}, Characters: []byte{0xe2, 0xa5, 0xb0}}, + "Rrightarrow": {Name: "Rrightarrow", CodePoints: []int{8667}, Characters: []byte{0xe2, 0x87, 0x9b}}, + "Rscr": {Name: "Rscr", CodePoints: []int{8475}, Characters: []byte{0xe2, 0x84, 0x9b}}, + "Rsh": {Name: "Rsh", CodePoints: []int{8625}, Characters: []byte{0xe2, 0x86, 0xb1}}, + "RuleDelayed": {Name: "RuleDelayed", CodePoints: []int{10740}, Characters: []byte{0xe2, 0xa7, 0xb4}}, + "SHCHcy": {Name: "SHCHcy", CodePoints: []int{1065}, Characters: []byte{0xd0, 0xa9}}, + "SHcy": {Name: "SHcy", CodePoints: []int{1064}, Characters: []byte{0xd0, 0xa8}}, + "SOFTcy": {Name: "SOFTcy", CodePoints: []int{1068}, Characters: []byte{0xd0, 0xac}}, + "Sacute": {Name: "Sacute", CodePoints: []int{346}, Characters: []byte{0xc5, 0x9a}}, + "Sc": {Name: "Sc", CodePoints: []int{10940}, Characters: []byte{0xe2, 0xaa, 0xbc}}, + "Scaron": {Name: "Scaron", CodePoints: []int{352}, Characters: []byte{0xc5, 0xa0}}, + "Scedil": {Name: "Scedil", CodePoints: []int{350}, Characters: []byte{0xc5, 0x9e}}, + "Scirc": {Name: "Scirc", CodePoints: []int{348}, Characters: []byte{0xc5, 0x9c}}, + "Scy": {Name: "Scy", CodePoints: []int{1057}, Characters: []byte{0xd0, 0xa1}}, + "Sfr": {Name: "Sfr", CodePoints: []int{120086}, Characters: []byte{0xf0, 0x9d, 0x94, 0x96}}, + "ShortDownArrow": {Name: "ShortDownArrow", CodePoints: []int{8595}, Characters: []byte{0xe2, 0x86, 0x93}}, + "ShortLeftArrow": {Name: "ShortLeftArrow", CodePoints: []int{8592}, Characters: []byte{0xe2, 0x86, 0x90}}, + "ShortRightArrow": {Name: "ShortRightArrow", CodePoints: []int{8594}, Characters: []byte{0xe2, 0x86, 0x92}}, + "ShortUpArrow": {Name: "ShortUpArrow", CodePoints: []int{8593}, Characters: []byte{0xe2, 0x86, 0x91}}, + "Sigma": {Name: "Sigma", CodePoints: []int{931}, Characters: []byte{0xce, 0xa3}}, + "SmallCircle": {Name: "SmallCircle", CodePoints: []int{8728}, Characters: []byte{0xe2, 0x88, 0x98}}, + "Sopf": {Name: "Sopf", CodePoints: []int{120138}, Characters: []byte{0xf0, 0x9d, 0x95, 0x8a}}, + "Sqrt": {Name: "Sqrt", CodePoints: []int{8730}, Characters: []byte{0xe2, 0x88, 0x9a}}, + "Square": {Name: "Square", CodePoints: []int{9633}, Characters: []byte{0xe2, 0x96, 0xa1}}, + "SquareIntersection": {Name: "SquareIntersection", CodePoints: []int{8851}, Characters: []byte{0xe2, 0x8a, 0x93}}, + "SquareSubset": {Name: "SquareSubset", CodePoints: []int{8847}, Characters: []byte{0xe2, 0x8a, 0x8f}}, + "SquareSubsetEqual": {Name: "SquareSubsetEqual", CodePoints: []int{8849}, Characters: []byte{0xe2, 0x8a, 0x91}}, + "SquareSuperset": {Name: "SquareSuperset", CodePoints: []int{8848}, Characters: []byte{0xe2, 0x8a, 0x90}}, + "SquareSupersetEqual": {Name: "SquareSupersetEqual", CodePoints: []int{8850}, Characters: []byte{0xe2, 0x8a, 0x92}}, + "SquareUnion": {Name: "SquareUnion", CodePoints: []int{8852}, Characters: []byte{0xe2, 0x8a, 0x94}}, + "Sscr": {Name: "Sscr", CodePoints: []int{119982}, Characters: []byte{0xf0, 0x9d, 0x92, 0xae}}, + "Star": {Name: "Star", CodePoints: []int{8902}, Characters: []byte{0xe2, 0x8b, 0x86}}, + "Sub": {Name: "Sub", CodePoints: []int{8912}, Characters: []byte{0xe2, 0x8b, 0x90}}, + "Subset": {Name: "Subset", CodePoints: []int{8912}, Characters: []byte{0xe2, 0x8b, 0x90}}, + "SubsetEqual": {Name: "SubsetEqual", CodePoints: []int{8838}, Characters: []byte{0xe2, 0x8a, 0x86}}, + "Succeeds": {Name: "Succeeds", CodePoints: []int{8827}, Characters: []byte{0xe2, 0x89, 0xbb}}, + "SucceedsEqual": {Name: "SucceedsEqual", CodePoints: []int{10928}, Characters: []byte{0xe2, 0xaa, 0xb0}}, + "SucceedsSlantEqual": {Name: "SucceedsSlantEqual", CodePoints: []int{8829}, Characters: []byte{0xe2, 0x89, 0xbd}}, + "SucceedsTilde": {Name: "SucceedsTilde", CodePoints: []int{8831}, Characters: []byte{0xe2, 0x89, 0xbf}}, + "SuchThat": {Name: "SuchThat", CodePoints: []int{8715}, Characters: []byte{0xe2, 0x88, 0x8b}}, + "Sum": {Name: "Sum", CodePoints: []int{8721}, Characters: []byte{0xe2, 0x88, 0x91}}, + "Sup": {Name: "Sup", CodePoints: []int{8913}, Characters: []byte{0xe2, 0x8b, 0x91}}, + "Superset": {Name: "Superset", CodePoints: []int{8835}, Characters: []byte{0xe2, 0x8a, 0x83}}, + "SupersetEqual": {Name: "SupersetEqual", CodePoints: []int{8839}, Characters: []byte{0xe2, 0x8a, 0x87}}, + "Supset": {Name: "Supset", CodePoints: []int{8913}, Characters: []byte{0xe2, 0x8b, 0x91}}, + "THORN": {Name: "THORN", CodePoints: []int{222}, Characters: []byte{0xc3, 0x9e}}, + "TRADE": {Name: "TRADE", CodePoints: []int{8482}, Characters: []byte{0xe2, 0x84, 0xa2}}, + "TSHcy": {Name: "TSHcy", CodePoints: []int{1035}, Characters: []byte{0xd0, 0x8b}}, + "TScy": {Name: "TScy", CodePoints: []int{1062}, Characters: []byte{0xd0, 0xa6}}, + "Tab": {Name: "Tab", CodePoints: []int{9}, Characters: []byte{0x9}}, + "Tau": {Name: "Tau", CodePoints: []int{932}, Characters: []byte{0xce, 0xa4}}, + "Tcaron": {Name: "Tcaron", CodePoints: []int{356}, Characters: []byte{0xc5, 0xa4}}, + "Tcedil": {Name: "Tcedil", CodePoints: []int{354}, Characters: []byte{0xc5, 0xa2}}, + "Tcy": {Name: "Tcy", CodePoints: []int{1058}, Characters: []byte{0xd0, 0xa2}}, + "Tfr": {Name: "Tfr", CodePoints: []int{120087}, Characters: []byte{0xf0, 0x9d, 0x94, 0x97}}, + "Therefore": {Name: "Therefore", CodePoints: []int{8756}, Characters: []byte{0xe2, 0x88, 0xb4}}, + "Theta": {Name: "Theta", CodePoints: []int{920}, Characters: []byte{0xce, 0x98}}, + "ThickSpace": {Name: "ThickSpace", CodePoints: []int{8287, 8202}, Characters: []byte{0xe2, 0x81, 0x9f, 0xe2, 0x80, 0x8a}}, + "ThinSpace": {Name: "ThinSpace", CodePoints: []int{8201}, Characters: []byte{0xe2, 0x80, 0x89}}, + "Tilde": {Name: "Tilde", CodePoints: []int{8764}, Characters: []byte{0xe2, 0x88, 0xbc}}, + "TildeEqual": {Name: "TildeEqual", CodePoints: []int{8771}, Characters: []byte{0xe2, 0x89, 0x83}}, + "TildeFullEqual": {Name: "TildeFullEqual", CodePoints: []int{8773}, Characters: []byte{0xe2, 0x89, 0x85}}, + "TildeTilde": {Name: "TildeTilde", CodePoints: []int{8776}, Characters: []byte{0xe2, 0x89, 0x88}}, + "Topf": {Name: "Topf", CodePoints: []int{120139}, Characters: []byte{0xf0, 0x9d, 0x95, 0x8b}}, + "TripleDot": {Name: "TripleDot", CodePoints: []int{8411}, Characters: []byte{0xe2, 0x83, 0x9b}}, + "Tscr": {Name: "Tscr", CodePoints: []int{119983}, Characters: []byte{0xf0, 0x9d, 0x92, 0xaf}}, + "Tstrok": {Name: "Tstrok", CodePoints: []int{358}, Characters: []byte{0xc5, 0xa6}}, + "Uacute": {Name: "Uacute", CodePoints: []int{218}, Characters: []byte{0xc3, 0x9a}}, + "Uarr": {Name: "Uarr", CodePoints: []int{8607}, Characters: []byte{0xe2, 0x86, 0x9f}}, + "Uarrocir": {Name: "Uarrocir", CodePoints: []int{10569}, Characters: []byte{0xe2, 0xa5, 0x89}}, + "Ubrcy": {Name: "Ubrcy", CodePoints: []int{1038}, Characters: []byte{0xd0, 0x8e}}, + "Ubreve": {Name: "Ubreve", CodePoints: []int{364}, Characters: []byte{0xc5, 0xac}}, + "Ucirc": {Name: "Ucirc", CodePoints: []int{219}, Characters: []byte{0xc3, 0x9b}}, + "Ucy": {Name: "Ucy", CodePoints: []int{1059}, Characters: []byte{0xd0, 0xa3}}, + "Udblac": {Name: "Udblac", CodePoints: []int{368}, Characters: []byte{0xc5, 0xb0}}, + "Ufr": {Name: "Ufr", CodePoints: []int{120088}, Characters: []byte{0xf0, 0x9d, 0x94, 0x98}}, + "Ugrave": {Name: "Ugrave", CodePoints: []int{217}, Characters: []byte{0xc3, 0x99}}, + "Umacr": {Name: "Umacr", CodePoints: []int{362}, Characters: []byte{0xc5, 0xaa}}, + "UnderBar": {Name: "UnderBar", CodePoints: []int{95}, Characters: []byte{0x5f}}, + "UnderBrace": {Name: "UnderBrace", CodePoints: []int{9183}, Characters: []byte{0xe2, 0x8f, 0x9f}}, + "UnderBracket": {Name: "UnderBracket", CodePoints: []int{9141}, Characters: []byte{0xe2, 0x8e, 0xb5}}, + "UnderParenthesis": {Name: "UnderParenthesis", CodePoints: []int{9181}, Characters: []byte{0xe2, 0x8f, 0x9d}}, + "Union": {Name: "Union", CodePoints: []int{8899}, Characters: []byte{0xe2, 0x8b, 0x83}}, + "UnionPlus": {Name: "UnionPlus", CodePoints: []int{8846}, Characters: []byte{0xe2, 0x8a, 0x8e}}, + "Uogon": {Name: "Uogon", CodePoints: []int{370}, Characters: []byte{0xc5, 0xb2}}, + "Uopf": {Name: "Uopf", CodePoints: []int{120140}, Characters: []byte{0xf0, 0x9d, 0x95, 0x8c}}, + "UpArrow": {Name: "UpArrow", CodePoints: []int{8593}, Characters: []byte{0xe2, 0x86, 0x91}}, + "UpArrowBar": {Name: "UpArrowBar", CodePoints: []int{10514}, Characters: []byte{0xe2, 0xa4, 0x92}}, + "UpArrowDownArrow": {Name: "UpArrowDownArrow", CodePoints: []int{8645}, Characters: []byte{0xe2, 0x87, 0x85}}, + "UpDownArrow": {Name: "UpDownArrow", CodePoints: []int{8597}, Characters: []byte{0xe2, 0x86, 0x95}}, + "UpEquilibrium": {Name: "UpEquilibrium", CodePoints: []int{10606}, Characters: []byte{0xe2, 0xa5, 0xae}}, + "UpTee": {Name: "UpTee", CodePoints: []int{8869}, Characters: []byte{0xe2, 0x8a, 0xa5}}, + "UpTeeArrow": {Name: "UpTeeArrow", CodePoints: []int{8613}, Characters: []byte{0xe2, 0x86, 0xa5}}, + "Uparrow": {Name: "Uparrow", CodePoints: []int{8657}, Characters: []byte{0xe2, 0x87, 0x91}}, + "Updownarrow": {Name: "Updownarrow", CodePoints: []int{8661}, Characters: []byte{0xe2, 0x87, 0x95}}, + "UpperLeftArrow": {Name: "UpperLeftArrow", CodePoints: []int{8598}, Characters: []byte{0xe2, 0x86, 0x96}}, + "UpperRightArrow": {Name: "UpperRightArrow", CodePoints: []int{8599}, Characters: []byte{0xe2, 0x86, 0x97}}, + "Upsi": {Name: "Upsi", CodePoints: []int{978}, Characters: []byte{0xcf, 0x92}}, + "Upsilon": {Name: "Upsilon", CodePoints: []int{933}, Characters: []byte{0xce, 0xa5}}, + "Uring": {Name: "Uring", CodePoints: []int{366}, Characters: []byte{0xc5, 0xae}}, + "Uscr": {Name: "Uscr", CodePoints: []int{119984}, Characters: []byte{0xf0, 0x9d, 0x92, 0xb0}}, + "Utilde": {Name: "Utilde", CodePoints: []int{360}, Characters: []byte{0xc5, 0xa8}}, + "Uuml": {Name: "Uuml", CodePoints: []int{220}, Characters: []byte{0xc3, 0x9c}}, + "VDash": {Name: "VDash", CodePoints: []int{8875}, Characters: []byte{0xe2, 0x8a, 0xab}}, + "Vbar": {Name: "Vbar", CodePoints: []int{10987}, Characters: []byte{0xe2, 0xab, 0xab}}, + "Vcy": {Name: "Vcy", CodePoints: []int{1042}, Characters: []byte{0xd0, 0x92}}, + "Vdash": {Name: "Vdash", CodePoints: []int{8873}, Characters: []byte{0xe2, 0x8a, 0xa9}}, + "Vdashl": {Name: "Vdashl", CodePoints: []int{10982}, Characters: []byte{0xe2, 0xab, 0xa6}}, + "Vee": {Name: "Vee", CodePoints: []int{8897}, Characters: []byte{0xe2, 0x8b, 0x81}}, + "Verbar": {Name: "Verbar", CodePoints: []int{8214}, Characters: []byte{0xe2, 0x80, 0x96}}, + "Vert": {Name: "Vert", CodePoints: []int{8214}, Characters: []byte{0xe2, 0x80, 0x96}}, + "VerticalBar": {Name: "VerticalBar", CodePoints: []int{8739}, Characters: []byte{0xe2, 0x88, 0xa3}}, + "VerticalLine": {Name: "VerticalLine", CodePoints: []int{124}, Characters: []byte{0x7c}}, + "VerticalSeparator": {Name: "VerticalSeparator", CodePoints: []int{10072}, Characters: []byte{0xe2, 0x9d, 0x98}}, + "VerticalTilde": {Name: "VerticalTilde", CodePoints: []int{8768}, Characters: []byte{0xe2, 0x89, 0x80}}, + "VeryThinSpace": {Name: "VeryThinSpace", CodePoints: []int{8202}, Characters: []byte{0xe2, 0x80, 0x8a}}, + "Vfr": {Name: "Vfr", CodePoints: []int{120089}, Characters: []byte{0xf0, 0x9d, 0x94, 0x99}}, + "Vopf": {Name: "Vopf", CodePoints: []int{120141}, Characters: []byte{0xf0, 0x9d, 0x95, 0x8d}}, + "Vscr": {Name: "Vscr", CodePoints: []int{119985}, Characters: []byte{0xf0, 0x9d, 0x92, 0xb1}}, + "Vvdash": {Name: "Vvdash", CodePoints: []int{8874}, Characters: []byte{0xe2, 0x8a, 0xaa}}, + "Wcirc": {Name: "Wcirc", CodePoints: []int{372}, Characters: []byte{0xc5, 0xb4}}, + "Wedge": {Name: "Wedge", CodePoints: []int{8896}, Characters: []byte{0xe2, 0x8b, 0x80}}, + "Wfr": {Name: "Wfr", CodePoints: []int{120090}, Characters: []byte{0xf0, 0x9d, 0x94, 0x9a}}, + "Wopf": {Name: "Wopf", CodePoints: []int{120142}, Characters: []byte{0xf0, 0x9d, 0x95, 0x8e}}, + "Wscr": {Name: "Wscr", CodePoints: []int{119986}, Characters: []byte{0xf0, 0x9d, 0x92, 0xb2}}, + "Xfr": {Name: "Xfr", CodePoints: []int{120091}, Characters: []byte{0xf0, 0x9d, 0x94, 0x9b}}, + "Xi": {Name: "Xi", CodePoints: []int{926}, Characters: []byte{0xce, 0x9e}}, + "Xopf": {Name: "Xopf", CodePoints: []int{120143}, Characters: []byte{0xf0, 0x9d, 0x95, 0x8f}}, + "Xscr": {Name: "Xscr", CodePoints: []int{119987}, Characters: []byte{0xf0, 0x9d, 0x92, 0xb3}}, + "YAcy": {Name: "YAcy", CodePoints: []int{1071}, Characters: []byte{0xd0, 0xaf}}, + "YIcy": {Name: "YIcy", CodePoints: []int{1031}, Characters: []byte{0xd0, 0x87}}, + "YUcy": {Name: "YUcy", CodePoints: []int{1070}, Characters: []byte{0xd0, 0xae}}, + "Yacute": {Name: "Yacute", CodePoints: []int{221}, Characters: []byte{0xc3, 0x9d}}, + "Ycirc": {Name: "Ycirc", CodePoints: []int{374}, Characters: []byte{0xc5, 0xb6}}, + "Ycy": {Name: "Ycy", CodePoints: []int{1067}, Characters: []byte{0xd0, 0xab}}, + "Yfr": {Name: "Yfr", CodePoints: []int{120092}, Characters: []byte{0xf0, 0x9d, 0x94, 0x9c}}, + "Yopf": {Name: "Yopf", CodePoints: []int{120144}, Characters: []byte{0xf0, 0x9d, 0x95, 0x90}}, + "Yscr": {Name: "Yscr", CodePoints: []int{119988}, Characters: []byte{0xf0, 0x9d, 0x92, 0xb4}}, + "Yuml": {Name: "Yuml", CodePoints: []int{376}, Characters: []byte{0xc5, 0xb8}}, + "ZHcy": {Name: "ZHcy", CodePoints: []int{1046}, Characters: []byte{0xd0, 0x96}}, + "Zacute": {Name: "Zacute", CodePoints: []int{377}, Characters: []byte{0xc5, 0xb9}}, + "Zcaron": {Name: "Zcaron", CodePoints: []int{381}, Characters: []byte{0xc5, 0xbd}}, + "Zcy": {Name: "Zcy", CodePoints: []int{1047}, Characters: []byte{0xd0, 0x97}}, + "Zdot": {Name: "Zdot", CodePoints: []int{379}, Characters: []byte{0xc5, 0xbb}}, + "ZeroWidthSpace": {Name: "ZeroWidthSpace", CodePoints: []int{8203}, Characters: []byte{0xe2, 0x80, 0x8b}}, + "Zeta": {Name: "Zeta", CodePoints: []int{918}, Characters: []byte{0xce, 0x96}}, + "Zfr": {Name: "Zfr", CodePoints: []int{8488}, Characters: []byte{0xe2, 0x84, 0xa8}}, + "Zopf": {Name: "Zopf", CodePoints: []int{8484}, Characters: []byte{0xe2, 0x84, 0xa4}}, + "Zscr": {Name: "Zscr", CodePoints: []int{119989}, Characters: []byte{0xf0, 0x9d, 0x92, 0xb5}}, + "aacute": {Name: "aacute", CodePoints: []int{225}, Characters: []byte{0xc3, 0xa1}}, + "abreve": {Name: "abreve", CodePoints: []int{259}, Characters: []byte{0xc4, 0x83}}, + "ac": {Name: "ac", CodePoints: []int{8766}, Characters: []byte{0xe2, 0x88, 0xbe}}, + "acE": {Name: "acE", CodePoints: []int{8766, 819}, Characters: []byte{0xe2, 0x88, 0xbe, 0xcc, 0xb3}}, + "acd": {Name: "acd", CodePoints: []int{8767}, Characters: []byte{0xe2, 0x88, 0xbf}}, + "acirc": {Name: "acirc", CodePoints: []int{226}, Characters: []byte{0xc3, 0xa2}}, + "acute": {Name: "acute", CodePoints: []int{180}, Characters: []byte{0xc2, 0xb4}}, + "acy": {Name: "acy", CodePoints: []int{1072}, Characters: []byte{0xd0, 0xb0}}, + "aelig": {Name: "aelig", CodePoints: []int{230}, Characters: []byte{0xc3, 0xa6}}, + "af": {Name: "af", CodePoints: []int{8289}, Characters: []byte{0xe2, 0x81, 0xa1}}, + "afr": {Name: "afr", CodePoints: []int{120094}, Characters: []byte{0xf0, 0x9d, 0x94, 0x9e}}, + "agrave": {Name: "agrave", CodePoints: []int{224}, Characters: []byte{0xc3, 0xa0}}, + "alefsym": {Name: "alefsym", CodePoints: []int{8501}, Characters: []byte{0xe2, 0x84, 0xb5}}, + "aleph": {Name: "aleph", CodePoints: []int{8501}, Characters: []byte{0xe2, 0x84, 0xb5}}, + "alpha": {Name: "alpha", CodePoints: []int{945}, Characters: []byte{0xce, 0xb1}}, + "amacr": {Name: "amacr", CodePoints: []int{257}, Characters: []byte{0xc4, 0x81}}, + "amalg": {Name: "amalg", CodePoints: []int{10815}, Characters: []byte{0xe2, 0xa8, 0xbf}}, + "amp": {Name: "amp", CodePoints: []int{38}, Characters: []byte{0x26}}, + "and": {Name: "and", CodePoints: []int{8743}, Characters: []byte{0xe2, 0x88, 0xa7}}, + "andand": {Name: "andand", CodePoints: []int{10837}, Characters: []byte{0xe2, 0xa9, 0x95}}, + "andd": {Name: "andd", CodePoints: []int{10844}, Characters: []byte{0xe2, 0xa9, 0x9c}}, + "andslope": {Name: "andslope", CodePoints: []int{10840}, Characters: []byte{0xe2, 0xa9, 0x98}}, + "andv": {Name: "andv", CodePoints: []int{10842}, Characters: []byte{0xe2, 0xa9, 0x9a}}, + "ang": {Name: "ang", CodePoints: []int{8736}, Characters: []byte{0xe2, 0x88, 0xa0}}, + "ange": {Name: "ange", CodePoints: []int{10660}, Characters: []byte{0xe2, 0xa6, 0xa4}}, + "angle": {Name: "angle", CodePoints: []int{8736}, Characters: []byte{0xe2, 0x88, 0xa0}}, + "angmsd": {Name: "angmsd", CodePoints: []int{8737}, Characters: []byte{0xe2, 0x88, 0xa1}}, + "angmsdaa": {Name: "angmsdaa", CodePoints: []int{10664}, Characters: []byte{0xe2, 0xa6, 0xa8}}, + "angmsdab": {Name: "angmsdab", CodePoints: []int{10665}, Characters: []byte{0xe2, 0xa6, 0xa9}}, + "angmsdac": {Name: "angmsdac", CodePoints: []int{10666}, Characters: []byte{0xe2, 0xa6, 0xaa}}, + "angmsdad": {Name: "angmsdad", CodePoints: []int{10667}, Characters: []byte{0xe2, 0xa6, 0xab}}, + "angmsdae": {Name: "angmsdae", CodePoints: []int{10668}, Characters: []byte{0xe2, 0xa6, 0xac}}, + "angmsdaf": {Name: "angmsdaf", CodePoints: []int{10669}, Characters: []byte{0xe2, 0xa6, 0xad}}, + "angmsdag": {Name: "angmsdag", CodePoints: []int{10670}, Characters: []byte{0xe2, 0xa6, 0xae}}, + "angmsdah": {Name: "angmsdah", CodePoints: []int{10671}, Characters: []byte{0xe2, 0xa6, 0xaf}}, + "angrt": {Name: "angrt", CodePoints: []int{8735}, Characters: []byte{0xe2, 0x88, 0x9f}}, + "angrtvb": {Name: "angrtvb", CodePoints: []int{8894}, Characters: []byte{0xe2, 0x8a, 0xbe}}, + "angrtvbd": {Name: "angrtvbd", CodePoints: []int{10653}, Characters: []byte{0xe2, 0xa6, 0x9d}}, + "angsph": {Name: "angsph", CodePoints: []int{8738}, Characters: []byte{0xe2, 0x88, 0xa2}}, + "angst": {Name: "angst", CodePoints: []int{197}, Characters: []byte{0xc3, 0x85}}, + "angzarr": {Name: "angzarr", CodePoints: []int{9084}, Characters: []byte{0xe2, 0x8d, 0xbc}}, + "aogon": {Name: "aogon", CodePoints: []int{261}, Characters: []byte{0xc4, 0x85}}, + "aopf": {Name: "aopf", CodePoints: []int{120146}, Characters: []byte{0xf0, 0x9d, 0x95, 0x92}}, + "ap": {Name: "ap", CodePoints: []int{8776}, Characters: []byte{0xe2, 0x89, 0x88}}, + "apE": {Name: "apE", CodePoints: []int{10864}, Characters: []byte{0xe2, 0xa9, 0xb0}}, + "apacir": {Name: "apacir", CodePoints: []int{10863}, Characters: []byte{0xe2, 0xa9, 0xaf}}, + "ape": {Name: "ape", CodePoints: []int{8778}, Characters: []byte{0xe2, 0x89, 0x8a}}, + "apid": {Name: "apid", CodePoints: []int{8779}, Characters: []byte{0xe2, 0x89, 0x8b}}, + "apos": {Name: "apos", CodePoints: []int{39}, Characters: []byte{0x27}}, + "approx": {Name: "approx", CodePoints: []int{8776}, Characters: []byte{0xe2, 0x89, 0x88}}, + "approxeq": {Name: "approxeq", CodePoints: []int{8778}, Characters: []byte{0xe2, 0x89, 0x8a}}, + "aring": {Name: "aring", CodePoints: []int{229}, Characters: []byte{0xc3, 0xa5}}, + "ascr": {Name: "ascr", CodePoints: []int{119990}, Characters: []byte{0xf0, 0x9d, 0x92, 0xb6}}, + "ast": {Name: "ast", CodePoints: []int{42}, Characters: []byte{0x2a}}, + "asymp": {Name: "asymp", CodePoints: []int{8776}, Characters: []byte{0xe2, 0x89, 0x88}}, + "asympeq": {Name: "asympeq", CodePoints: []int{8781}, Characters: []byte{0xe2, 0x89, 0x8d}}, + "atilde": {Name: "atilde", CodePoints: []int{227}, Characters: []byte{0xc3, 0xa3}}, + "auml": {Name: "auml", CodePoints: []int{228}, Characters: []byte{0xc3, 0xa4}}, + "awconint": {Name: "awconint", CodePoints: []int{8755}, Characters: []byte{0xe2, 0x88, 0xb3}}, + "awint": {Name: "awint", CodePoints: []int{10769}, Characters: []byte{0xe2, 0xa8, 0x91}}, + "bNot": {Name: "bNot", CodePoints: []int{10989}, Characters: []byte{0xe2, 0xab, 0xad}}, + "backcong": {Name: "backcong", CodePoints: []int{8780}, Characters: []byte{0xe2, 0x89, 0x8c}}, + "backepsilon": {Name: "backepsilon", CodePoints: []int{1014}, Characters: []byte{0xcf, 0xb6}}, + "backprime": {Name: "backprime", CodePoints: []int{8245}, Characters: []byte{0xe2, 0x80, 0xb5}}, + "backsim": {Name: "backsim", CodePoints: []int{8765}, Characters: []byte{0xe2, 0x88, 0xbd}}, + "backsimeq": {Name: "backsimeq", CodePoints: []int{8909}, Characters: []byte{0xe2, 0x8b, 0x8d}}, + "barvee": {Name: "barvee", CodePoints: []int{8893}, Characters: []byte{0xe2, 0x8a, 0xbd}}, + "barwed": {Name: "barwed", CodePoints: []int{8965}, Characters: []byte{0xe2, 0x8c, 0x85}}, + "barwedge": {Name: "barwedge", CodePoints: []int{8965}, Characters: []byte{0xe2, 0x8c, 0x85}}, + "bbrk": {Name: "bbrk", CodePoints: []int{9141}, Characters: []byte{0xe2, 0x8e, 0xb5}}, + "bbrktbrk": {Name: "bbrktbrk", CodePoints: []int{9142}, Characters: []byte{0xe2, 0x8e, 0xb6}}, + "bcong": {Name: "bcong", CodePoints: []int{8780}, Characters: []byte{0xe2, 0x89, 0x8c}}, + "bcy": {Name: "bcy", CodePoints: []int{1073}, Characters: []byte{0xd0, 0xb1}}, + "bdquo": {Name: "bdquo", CodePoints: []int{8222}, Characters: []byte{0xe2, 0x80, 0x9e}}, + "becaus": {Name: "becaus", CodePoints: []int{8757}, Characters: []byte{0xe2, 0x88, 0xb5}}, + "because": {Name: "because", CodePoints: []int{8757}, Characters: []byte{0xe2, 0x88, 0xb5}}, + "bemptyv": {Name: "bemptyv", CodePoints: []int{10672}, Characters: []byte{0xe2, 0xa6, 0xb0}}, + "bepsi": {Name: "bepsi", CodePoints: []int{1014}, Characters: []byte{0xcf, 0xb6}}, + "bernou": {Name: "bernou", CodePoints: []int{8492}, Characters: []byte{0xe2, 0x84, 0xac}}, + "beta": {Name: "beta", CodePoints: []int{946}, Characters: []byte{0xce, 0xb2}}, + "beth": {Name: "beth", CodePoints: []int{8502}, Characters: []byte{0xe2, 0x84, 0xb6}}, + "between": {Name: "between", CodePoints: []int{8812}, Characters: []byte{0xe2, 0x89, 0xac}}, + "bfr": {Name: "bfr", CodePoints: []int{120095}, Characters: []byte{0xf0, 0x9d, 0x94, 0x9f}}, + "bigcap": {Name: "bigcap", CodePoints: []int{8898}, Characters: []byte{0xe2, 0x8b, 0x82}}, + "bigcirc": {Name: "bigcirc", CodePoints: []int{9711}, Characters: []byte{0xe2, 0x97, 0xaf}}, + "bigcup": {Name: "bigcup", CodePoints: []int{8899}, Characters: []byte{0xe2, 0x8b, 0x83}}, + "bigodot": {Name: "bigodot", CodePoints: []int{10752}, Characters: []byte{0xe2, 0xa8, 0x80}}, + "bigoplus": {Name: "bigoplus", CodePoints: []int{10753}, Characters: []byte{0xe2, 0xa8, 0x81}}, + "bigotimes": {Name: "bigotimes", CodePoints: []int{10754}, Characters: []byte{0xe2, 0xa8, 0x82}}, + "bigsqcup": {Name: "bigsqcup", CodePoints: []int{10758}, Characters: []byte{0xe2, 0xa8, 0x86}}, + "bigstar": {Name: "bigstar", CodePoints: []int{9733}, Characters: []byte{0xe2, 0x98, 0x85}}, + "bigtriangledown": {Name: "bigtriangledown", CodePoints: []int{9661}, Characters: []byte{0xe2, 0x96, 0xbd}}, + "bigtriangleup": {Name: "bigtriangleup", CodePoints: []int{9651}, Characters: []byte{0xe2, 0x96, 0xb3}}, + "biguplus": {Name: "biguplus", CodePoints: []int{10756}, Characters: []byte{0xe2, 0xa8, 0x84}}, + "bigvee": {Name: "bigvee", CodePoints: []int{8897}, Characters: []byte{0xe2, 0x8b, 0x81}}, + "bigwedge": {Name: "bigwedge", CodePoints: []int{8896}, Characters: []byte{0xe2, 0x8b, 0x80}}, + "bkarow": {Name: "bkarow", CodePoints: []int{10509}, Characters: []byte{0xe2, 0xa4, 0x8d}}, + "blacklozenge": {Name: "blacklozenge", CodePoints: []int{10731}, Characters: []byte{0xe2, 0xa7, 0xab}}, + "blacksquare": {Name: "blacksquare", CodePoints: []int{9642}, Characters: []byte{0xe2, 0x96, 0xaa}}, + "blacktriangle": {Name: "blacktriangle", CodePoints: []int{9652}, Characters: []byte{0xe2, 0x96, 0xb4}}, + "blacktriangledown": {Name: "blacktriangledown", CodePoints: []int{9662}, Characters: []byte{0xe2, 0x96, 0xbe}}, + "blacktriangleleft": {Name: "blacktriangleleft", CodePoints: []int{9666}, Characters: []byte{0xe2, 0x97, 0x82}}, + "blacktriangleright": {Name: "blacktriangleright", CodePoints: []int{9656}, Characters: []byte{0xe2, 0x96, 0xb8}}, + "blank": {Name: "blank", CodePoints: []int{9251}, Characters: []byte{0xe2, 0x90, 0xa3}}, + "blk12": {Name: "blk12", CodePoints: []int{9618}, Characters: []byte{0xe2, 0x96, 0x92}}, + "blk14": {Name: "blk14", CodePoints: []int{9617}, Characters: []byte{0xe2, 0x96, 0x91}}, + "blk34": {Name: "blk34", CodePoints: []int{9619}, Characters: []byte{0xe2, 0x96, 0x93}}, + "block": {Name: "block", CodePoints: []int{9608}, Characters: []byte{0xe2, 0x96, 0x88}}, + "bne": {Name: "bne", CodePoints: []int{61, 8421}, Characters: []byte{0x3d, 0xe2, 0x83, 0xa5}}, + "bnequiv": {Name: "bnequiv", CodePoints: []int{8801, 8421}, Characters: []byte{0xe2, 0x89, 0xa1, 0xe2, 0x83, 0xa5}}, + "bnot": {Name: "bnot", CodePoints: []int{8976}, Characters: []byte{0xe2, 0x8c, 0x90}}, + "bopf": {Name: "bopf", CodePoints: []int{120147}, Characters: []byte{0xf0, 0x9d, 0x95, 0x93}}, + "bot": {Name: "bot", CodePoints: []int{8869}, Characters: []byte{0xe2, 0x8a, 0xa5}}, + "bottom": {Name: "bottom", CodePoints: []int{8869}, Characters: []byte{0xe2, 0x8a, 0xa5}}, + "bowtie": {Name: "bowtie", CodePoints: []int{8904}, Characters: []byte{0xe2, 0x8b, 0x88}}, + "boxDL": {Name: "boxDL", CodePoints: []int{9559}, Characters: []byte{0xe2, 0x95, 0x97}}, + "boxDR": {Name: "boxDR", CodePoints: []int{9556}, Characters: []byte{0xe2, 0x95, 0x94}}, + "boxDl": {Name: "boxDl", CodePoints: []int{9558}, Characters: []byte{0xe2, 0x95, 0x96}}, + "boxDr": {Name: "boxDr", CodePoints: []int{9555}, Characters: []byte{0xe2, 0x95, 0x93}}, + "boxH": {Name: "boxH", CodePoints: []int{9552}, Characters: []byte{0xe2, 0x95, 0x90}}, + "boxHD": {Name: "boxHD", CodePoints: []int{9574}, Characters: []byte{0xe2, 0x95, 0xa6}}, + "boxHU": {Name: "boxHU", CodePoints: []int{9577}, Characters: []byte{0xe2, 0x95, 0xa9}}, + "boxHd": {Name: "boxHd", CodePoints: []int{9572}, Characters: []byte{0xe2, 0x95, 0xa4}}, + "boxHu": {Name: "boxHu", CodePoints: []int{9575}, Characters: []byte{0xe2, 0x95, 0xa7}}, + "boxUL": {Name: "boxUL", CodePoints: []int{9565}, Characters: []byte{0xe2, 0x95, 0x9d}}, + "boxUR": {Name: "boxUR", CodePoints: []int{9562}, Characters: []byte{0xe2, 0x95, 0x9a}}, + "boxUl": {Name: "boxUl", CodePoints: []int{9564}, Characters: []byte{0xe2, 0x95, 0x9c}}, + "boxUr": {Name: "boxUr", CodePoints: []int{9561}, Characters: []byte{0xe2, 0x95, 0x99}}, + "boxV": {Name: "boxV", CodePoints: []int{9553}, Characters: []byte{0xe2, 0x95, 0x91}}, + "boxVH": {Name: "boxVH", CodePoints: []int{9580}, Characters: []byte{0xe2, 0x95, 0xac}}, + "boxVL": {Name: "boxVL", CodePoints: []int{9571}, Characters: []byte{0xe2, 0x95, 0xa3}}, + "boxVR": {Name: "boxVR", CodePoints: []int{9568}, Characters: []byte{0xe2, 0x95, 0xa0}}, + "boxVh": {Name: "boxVh", CodePoints: []int{9579}, Characters: []byte{0xe2, 0x95, 0xab}}, + "boxVl": {Name: "boxVl", CodePoints: []int{9570}, Characters: []byte{0xe2, 0x95, 0xa2}}, + "boxVr": {Name: "boxVr", CodePoints: []int{9567}, Characters: []byte{0xe2, 0x95, 0x9f}}, + "boxbox": {Name: "boxbox", CodePoints: []int{10697}, Characters: []byte{0xe2, 0xa7, 0x89}}, + "boxdL": {Name: "boxdL", CodePoints: []int{9557}, Characters: []byte{0xe2, 0x95, 0x95}}, + "boxdR": {Name: "boxdR", CodePoints: []int{9554}, Characters: []byte{0xe2, 0x95, 0x92}}, + "boxdl": {Name: "boxdl", CodePoints: []int{9488}, Characters: []byte{0xe2, 0x94, 0x90}}, + "boxdr": {Name: "boxdr", CodePoints: []int{9484}, Characters: []byte{0xe2, 0x94, 0x8c}}, + "boxh": {Name: "boxh", CodePoints: []int{9472}, Characters: []byte{0xe2, 0x94, 0x80}}, + "boxhD": {Name: "boxhD", CodePoints: []int{9573}, Characters: []byte{0xe2, 0x95, 0xa5}}, + "boxhU": {Name: "boxhU", CodePoints: []int{9576}, Characters: []byte{0xe2, 0x95, 0xa8}}, + "boxhd": {Name: "boxhd", CodePoints: []int{9516}, Characters: []byte{0xe2, 0x94, 0xac}}, + "boxhu": {Name: "boxhu", CodePoints: []int{9524}, Characters: []byte{0xe2, 0x94, 0xb4}}, + "boxminus": {Name: "boxminus", CodePoints: []int{8863}, Characters: []byte{0xe2, 0x8a, 0x9f}}, + "boxplus": {Name: "boxplus", CodePoints: []int{8862}, Characters: []byte{0xe2, 0x8a, 0x9e}}, + "boxtimes": {Name: "boxtimes", CodePoints: []int{8864}, Characters: []byte{0xe2, 0x8a, 0xa0}}, + "boxuL": {Name: "boxuL", CodePoints: []int{9563}, Characters: []byte{0xe2, 0x95, 0x9b}}, + "boxuR": {Name: "boxuR", CodePoints: []int{9560}, Characters: []byte{0xe2, 0x95, 0x98}}, + "boxul": {Name: "boxul", CodePoints: []int{9496}, Characters: []byte{0xe2, 0x94, 0x98}}, + "boxur": {Name: "boxur", CodePoints: []int{9492}, Characters: []byte{0xe2, 0x94, 0x94}}, + "boxv": {Name: "boxv", CodePoints: []int{9474}, Characters: []byte{0xe2, 0x94, 0x82}}, + "boxvH": {Name: "boxvH", CodePoints: []int{9578}, Characters: []byte{0xe2, 0x95, 0xaa}}, + "boxvL": {Name: "boxvL", CodePoints: []int{9569}, Characters: []byte{0xe2, 0x95, 0xa1}}, + "boxvR": {Name: "boxvR", CodePoints: []int{9566}, Characters: []byte{0xe2, 0x95, 0x9e}}, + "boxvh": {Name: "boxvh", CodePoints: []int{9532}, Characters: []byte{0xe2, 0x94, 0xbc}}, + "boxvl": {Name: "boxvl", CodePoints: []int{9508}, Characters: []byte{0xe2, 0x94, 0xa4}}, + "boxvr": {Name: "boxvr", CodePoints: []int{9500}, Characters: []byte{0xe2, 0x94, 0x9c}}, + "bprime": {Name: "bprime", CodePoints: []int{8245}, Characters: []byte{0xe2, 0x80, 0xb5}}, + "breve": {Name: "breve", CodePoints: []int{728}, Characters: []byte{0xcb, 0x98}}, + "brvbar": {Name: "brvbar", CodePoints: []int{166}, Characters: []byte{0xc2, 0xa6}}, + "bscr": {Name: "bscr", CodePoints: []int{119991}, Characters: []byte{0xf0, 0x9d, 0x92, 0xb7}}, + "bsemi": {Name: "bsemi", CodePoints: []int{8271}, Characters: []byte{0xe2, 0x81, 0x8f}}, + "bsim": {Name: "bsim", CodePoints: []int{8765}, Characters: []byte{0xe2, 0x88, 0xbd}}, + "bsime": {Name: "bsime", CodePoints: []int{8909}, Characters: []byte{0xe2, 0x8b, 0x8d}}, + "bsol": {Name: "bsol", CodePoints: []int{92}, Characters: []byte{0x5c}}, + "bsolb": {Name: "bsolb", CodePoints: []int{10693}, Characters: []byte{0xe2, 0xa7, 0x85}}, + "bsolhsub": {Name: "bsolhsub", CodePoints: []int{10184}, Characters: []byte{0xe2, 0x9f, 0x88}}, + "bull": {Name: "bull", CodePoints: []int{8226}, Characters: []byte{0xe2, 0x80, 0xa2}}, + "bullet": {Name: "bullet", CodePoints: []int{8226}, Characters: []byte{0xe2, 0x80, 0xa2}}, + "bump": {Name: "bump", CodePoints: []int{8782}, Characters: []byte{0xe2, 0x89, 0x8e}}, + "bumpE": {Name: "bumpE", CodePoints: []int{10926}, Characters: []byte{0xe2, 0xaa, 0xae}}, + "bumpe": {Name: "bumpe", CodePoints: []int{8783}, Characters: []byte{0xe2, 0x89, 0x8f}}, + "bumpeq": {Name: "bumpeq", CodePoints: []int{8783}, Characters: []byte{0xe2, 0x89, 0x8f}}, + "cacute": {Name: "cacute", CodePoints: []int{263}, Characters: []byte{0xc4, 0x87}}, + "cap": {Name: "cap", CodePoints: []int{8745}, Characters: []byte{0xe2, 0x88, 0xa9}}, + "capand": {Name: "capand", CodePoints: []int{10820}, Characters: []byte{0xe2, 0xa9, 0x84}}, + "capbrcup": {Name: "capbrcup", CodePoints: []int{10825}, Characters: []byte{0xe2, 0xa9, 0x89}}, + "capcap": {Name: "capcap", CodePoints: []int{10827}, Characters: []byte{0xe2, 0xa9, 0x8b}}, + "capcup": {Name: "capcup", CodePoints: []int{10823}, Characters: []byte{0xe2, 0xa9, 0x87}}, + "capdot": {Name: "capdot", CodePoints: []int{10816}, Characters: []byte{0xe2, 0xa9, 0x80}}, + "caps": {Name: "caps", CodePoints: []int{8745, 65024}, Characters: []byte{0xe2, 0x88, 0xa9, 0xef, 0xb8, 0x80}}, + "caret": {Name: "caret", CodePoints: []int{8257}, Characters: []byte{0xe2, 0x81, 0x81}}, + "caron": {Name: "caron", CodePoints: []int{711}, Characters: []byte{0xcb, 0x87}}, + "ccaps": {Name: "ccaps", CodePoints: []int{10829}, Characters: []byte{0xe2, 0xa9, 0x8d}}, + "ccaron": {Name: "ccaron", CodePoints: []int{269}, Characters: []byte{0xc4, 0x8d}}, + "ccedil": {Name: "ccedil", CodePoints: []int{231}, Characters: []byte{0xc3, 0xa7}}, + "ccirc": {Name: "ccirc", CodePoints: []int{265}, Characters: []byte{0xc4, 0x89}}, + "ccups": {Name: "ccups", CodePoints: []int{10828}, Characters: []byte{0xe2, 0xa9, 0x8c}}, + "ccupssm": {Name: "ccupssm", CodePoints: []int{10832}, Characters: []byte{0xe2, 0xa9, 0x90}}, + "cdot": {Name: "cdot", CodePoints: []int{267}, Characters: []byte{0xc4, 0x8b}}, + "cedil": {Name: "cedil", CodePoints: []int{184}, Characters: []byte{0xc2, 0xb8}}, + "cemptyv": {Name: "cemptyv", CodePoints: []int{10674}, Characters: []byte{0xe2, 0xa6, 0xb2}}, + "cent": {Name: "cent", CodePoints: []int{162}, Characters: []byte{0xc2, 0xa2}}, + "centerdot": {Name: "centerdot", CodePoints: []int{183}, Characters: []byte{0xc2, 0xb7}}, + "cfr": {Name: "cfr", CodePoints: []int{120096}, Characters: []byte{0xf0, 0x9d, 0x94, 0xa0}}, + "chcy": {Name: "chcy", CodePoints: []int{1095}, Characters: []byte{0xd1, 0x87}}, + "check": {Name: "check", CodePoints: []int{10003}, Characters: []byte{0xe2, 0x9c, 0x93}}, + "checkmark": {Name: "checkmark", CodePoints: []int{10003}, Characters: []byte{0xe2, 0x9c, 0x93}}, + "chi": {Name: "chi", CodePoints: []int{967}, Characters: []byte{0xcf, 0x87}}, + "cir": {Name: "cir", CodePoints: []int{9675}, Characters: []byte{0xe2, 0x97, 0x8b}}, + "cirE": {Name: "cirE", CodePoints: []int{10691}, Characters: []byte{0xe2, 0xa7, 0x83}}, + "circ": {Name: "circ", CodePoints: []int{710}, Characters: []byte{0xcb, 0x86}}, + "circeq": {Name: "circeq", CodePoints: []int{8791}, Characters: []byte{0xe2, 0x89, 0x97}}, + "circlearrowleft": {Name: "circlearrowleft", CodePoints: []int{8634}, Characters: []byte{0xe2, 0x86, 0xba}}, + "circlearrowright": {Name: "circlearrowright", CodePoints: []int{8635}, Characters: []byte{0xe2, 0x86, 0xbb}}, + "circledR": {Name: "circledR", CodePoints: []int{174}, Characters: []byte{0xc2, 0xae}}, + "circledS": {Name: "circledS", CodePoints: []int{9416}, Characters: []byte{0xe2, 0x93, 0x88}}, + "circledast": {Name: "circledast", CodePoints: []int{8859}, Characters: []byte{0xe2, 0x8a, 0x9b}}, + "circledcirc": {Name: "circledcirc", CodePoints: []int{8858}, Characters: []byte{0xe2, 0x8a, 0x9a}}, + "circleddash": {Name: "circleddash", CodePoints: []int{8861}, Characters: []byte{0xe2, 0x8a, 0x9d}}, + "cire": {Name: "cire", CodePoints: []int{8791}, Characters: []byte{0xe2, 0x89, 0x97}}, + "cirfnint": {Name: "cirfnint", CodePoints: []int{10768}, Characters: []byte{0xe2, 0xa8, 0x90}}, + "cirmid": {Name: "cirmid", CodePoints: []int{10991}, Characters: []byte{0xe2, 0xab, 0xaf}}, + "cirscir": {Name: "cirscir", CodePoints: []int{10690}, Characters: []byte{0xe2, 0xa7, 0x82}}, + "clubs": {Name: "clubs", CodePoints: []int{9827}, Characters: []byte{0xe2, 0x99, 0xa3}}, + "clubsuit": {Name: "clubsuit", CodePoints: []int{9827}, Characters: []byte{0xe2, 0x99, 0xa3}}, + "colon": {Name: "colon", CodePoints: []int{58}, Characters: []byte{0x3a}}, + "colone": {Name: "colone", CodePoints: []int{8788}, Characters: []byte{0xe2, 0x89, 0x94}}, + "coloneq": {Name: "coloneq", CodePoints: []int{8788}, Characters: []byte{0xe2, 0x89, 0x94}}, + "comma": {Name: "comma", CodePoints: []int{44}, Characters: []byte{0x2c}}, + "commat": {Name: "commat", CodePoints: []int{64}, Characters: []byte{0x40}}, + "comp": {Name: "comp", CodePoints: []int{8705}, Characters: []byte{0xe2, 0x88, 0x81}}, + "compfn": {Name: "compfn", CodePoints: []int{8728}, Characters: []byte{0xe2, 0x88, 0x98}}, + "complement": {Name: "complement", CodePoints: []int{8705}, Characters: []byte{0xe2, 0x88, 0x81}}, + "complexes": {Name: "complexes", CodePoints: []int{8450}, Characters: []byte{0xe2, 0x84, 0x82}}, + "cong": {Name: "cong", CodePoints: []int{8773}, Characters: []byte{0xe2, 0x89, 0x85}}, + "congdot": {Name: "congdot", CodePoints: []int{10861}, Characters: []byte{0xe2, 0xa9, 0xad}}, + "conint": {Name: "conint", CodePoints: []int{8750}, Characters: []byte{0xe2, 0x88, 0xae}}, + "copf": {Name: "copf", CodePoints: []int{120148}, Characters: []byte{0xf0, 0x9d, 0x95, 0x94}}, + "coprod": {Name: "coprod", CodePoints: []int{8720}, Characters: []byte{0xe2, 0x88, 0x90}}, + "copy": {Name: "copy", CodePoints: []int{169}, Characters: []byte{0xc2, 0xa9}}, + "copysr": {Name: "copysr", CodePoints: []int{8471}, Characters: []byte{0xe2, 0x84, 0x97}}, + "crarr": {Name: "crarr", CodePoints: []int{8629}, Characters: []byte{0xe2, 0x86, 0xb5}}, + "cross": {Name: "cross", CodePoints: []int{10007}, Characters: []byte{0xe2, 0x9c, 0x97}}, + "cscr": {Name: "cscr", CodePoints: []int{119992}, Characters: []byte{0xf0, 0x9d, 0x92, 0xb8}}, + "csub": {Name: "csub", CodePoints: []int{10959}, Characters: []byte{0xe2, 0xab, 0x8f}}, + "csube": {Name: "csube", CodePoints: []int{10961}, Characters: []byte{0xe2, 0xab, 0x91}}, + "csup": {Name: "csup", CodePoints: []int{10960}, Characters: []byte{0xe2, 0xab, 0x90}}, + "csupe": {Name: "csupe", CodePoints: []int{10962}, Characters: []byte{0xe2, 0xab, 0x92}}, + "ctdot": {Name: "ctdot", CodePoints: []int{8943}, Characters: []byte{0xe2, 0x8b, 0xaf}}, + "cudarrl": {Name: "cudarrl", CodePoints: []int{10552}, Characters: []byte{0xe2, 0xa4, 0xb8}}, + "cudarrr": {Name: "cudarrr", CodePoints: []int{10549}, Characters: []byte{0xe2, 0xa4, 0xb5}}, + "cuepr": {Name: "cuepr", CodePoints: []int{8926}, Characters: []byte{0xe2, 0x8b, 0x9e}}, + "cuesc": {Name: "cuesc", CodePoints: []int{8927}, Characters: []byte{0xe2, 0x8b, 0x9f}}, + "cularr": {Name: "cularr", CodePoints: []int{8630}, Characters: []byte{0xe2, 0x86, 0xb6}}, + "cularrp": {Name: "cularrp", CodePoints: []int{10557}, Characters: []byte{0xe2, 0xa4, 0xbd}}, + "cup": {Name: "cup", CodePoints: []int{8746}, Characters: []byte{0xe2, 0x88, 0xaa}}, + "cupbrcap": {Name: "cupbrcap", CodePoints: []int{10824}, Characters: []byte{0xe2, 0xa9, 0x88}}, + "cupcap": {Name: "cupcap", CodePoints: []int{10822}, Characters: []byte{0xe2, 0xa9, 0x86}}, + "cupcup": {Name: "cupcup", CodePoints: []int{10826}, Characters: []byte{0xe2, 0xa9, 0x8a}}, + "cupdot": {Name: "cupdot", CodePoints: []int{8845}, Characters: []byte{0xe2, 0x8a, 0x8d}}, + "cupor": {Name: "cupor", CodePoints: []int{10821}, Characters: []byte{0xe2, 0xa9, 0x85}}, + "cups": {Name: "cups", CodePoints: []int{8746, 65024}, Characters: []byte{0xe2, 0x88, 0xaa, 0xef, 0xb8, 0x80}}, + "curarr": {Name: "curarr", CodePoints: []int{8631}, Characters: []byte{0xe2, 0x86, 0xb7}}, + "curarrm": {Name: "curarrm", CodePoints: []int{10556}, Characters: []byte{0xe2, 0xa4, 0xbc}}, + "curlyeqprec": {Name: "curlyeqprec", CodePoints: []int{8926}, Characters: []byte{0xe2, 0x8b, 0x9e}}, + "curlyeqsucc": {Name: "curlyeqsucc", CodePoints: []int{8927}, Characters: []byte{0xe2, 0x8b, 0x9f}}, + "curlyvee": {Name: "curlyvee", CodePoints: []int{8910}, Characters: []byte{0xe2, 0x8b, 0x8e}}, + "curlywedge": {Name: "curlywedge", CodePoints: []int{8911}, Characters: []byte{0xe2, 0x8b, 0x8f}}, + "curren": {Name: "curren", CodePoints: []int{164}, Characters: []byte{0xc2, 0xa4}}, + "curvearrowleft": {Name: "curvearrowleft", CodePoints: []int{8630}, Characters: []byte{0xe2, 0x86, 0xb6}}, + "curvearrowright": {Name: "curvearrowright", CodePoints: []int{8631}, Characters: []byte{0xe2, 0x86, 0xb7}}, + "cuvee": {Name: "cuvee", CodePoints: []int{8910}, Characters: []byte{0xe2, 0x8b, 0x8e}}, + "cuwed": {Name: "cuwed", CodePoints: []int{8911}, Characters: []byte{0xe2, 0x8b, 0x8f}}, + "cwconint": {Name: "cwconint", CodePoints: []int{8754}, Characters: []byte{0xe2, 0x88, 0xb2}}, + "cwint": {Name: "cwint", CodePoints: []int{8753}, Characters: []byte{0xe2, 0x88, 0xb1}}, + "cylcty": {Name: "cylcty", CodePoints: []int{9005}, Characters: []byte{0xe2, 0x8c, 0xad}}, + "dArr": {Name: "dArr", CodePoints: []int{8659}, Characters: []byte{0xe2, 0x87, 0x93}}, + "dHar": {Name: "dHar", CodePoints: []int{10597}, Characters: []byte{0xe2, 0xa5, 0xa5}}, + "dagger": {Name: "dagger", CodePoints: []int{8224}, Characters: []byte{0xe2, 0x80, 0xa0}}, + "daleth": {Name: "daleth", CodePoints: []int{8504}, Characters: []byte{0xe2, 0x84, 0xb8}}, + "darr": {Name: "darr", CodePoints: []int{8595}, Characters: []byte{0xe2, 0x86, 0x93}}, + "dash": {Name: "dash", CodePoints: []int{8208}, Characters: []byte{0xe2, 0x80, 0x90}}, + "dashv": {Name: "dashv", CodePoints: []int{8867}, Characters: []byte{0xe2, 0x8a, 0xa3}}, + "dbkarow": {Name: "dbkarow", CodePoints: []int{10511}, Characters: []byte{0xe2, 0xa4, 0x8f}}, + "dblac": {Name: "dblac", CodePoints: []int{733}, Characters: []byte{0xcb, 0x9d}}, + "dcaron": {Name: "dcaron", CodePoints: []int{271}, Characters: []byte{0xc4, 0x8f}}, + "dcy": {Name: "dcy", CodePoints: []int{1076}, Characters: []byte{0xd0, 0xb4}}, + "dd": {Name: "dd", CodePoints: []int{8518}, Characters: []byte{0xe2, 0x85, 0x86}}, + "ddagger": {Name: "ddagger", CodePoints: []int{8225}, Characters: []byte{0xe2, 0x80, 0xa1}}, + "ddarr": {Name: "ddarr", CodePoints: []int{8650}, Characters: []byte{0xe2, 0x87, 0x8a}}, + "ddotseq": {Name: "ddotseq", CodePoints: []int{10871}, Characters: []byte{0xe2, 0xa9, 0xb7}}, + "deg": {Name: "deg", CodePoints: []int{176}, Characters: []byte{0xc2, 0xb0}}, + "delta": {Name: "delta", CodePoints: []int{948}, Characters: []byte{0xce, 0xb4}}, + "demptyv": {Name: "demptyv", CodePoints: []int{10673}, Characters: []byte{0xe2, 0xa6, 0xb1}}, + "dfisht": {Name: "dfisht", CodePoints: []int{10623}, Characters: []byte{0xe2, 0xa5, 0xbf}}, + "dfr": {Name: "dfr", CodePoints: []int{120097}, Characters: []byte{0xf0, 0x9d, 0x94, 0xa1}}, + "dharl": {Name: "dharl", CodePoints: []int{8643}, Characters: []byte{0xe2, 0x87, 0x83}}, + "dharr": {Name: "dharr", CodePoints: []int{8642}, Characters: []byte{0xe2, 0x87, 0x82}}, + "diam": {Name: "diam", CodePoints: []int{8900}, Characters: []byte{0xe2, 0x8b, 0x84}}, + "diamond": {Name: "diamond", CodePoints: []int{8900}, Characters: []byte{0xe2, 0x8b, 0x84}}, + "diamondsuit": {Name: "diamondsuit", CodePoints: []int{9830}, Characters: []byte{0xe2, 0x99, 0xa6}}, + "diams": {Name: "diams", CodePoints: []int{9830}, Characters: []byte{0xe2, 0x99, 0xa6}}, + "die": {Name: "die", CodePoints: []int{168}, Characters: []byte{0xc2, 0xa8}}, + "digamma": {Name: "digamma", CodePoints: []int{989}, Characters: []byte{0xcf, 0x9d}}, + "disin": {Name: "disin", CodePoints: []int{8946}, Characters: []byte{0xe2, 0x8b, 0xb2}}, + "div": {Name: "div", CodePoints: []int{247}, Characters: []byte{0xc3, 0xb7}}, + "divide": {Name: "divide", CodePoints: []int{247}, Characters: []byte{0xc3, 0xb7}}, + "divideontimes": {Name: "divideontimes", CodePoints: []int{8903}, Characters: []byte{0xe2, 0x8b, 0x87}}, + "divonx": {Name: "divonx", CodePoints: []int{8903}, Characters: []byte{0xe2, 0x8b, 0x87}}, + "djcy": {Name: "djcy", CodePoints: []int{1106}, Characters: []byte{0xd1, 0x92}}, + "dlcorn": {Name: "dlcorn", CodePoints: []int{8990}, Characters: []byte{0xe2, 0x8c, 0x9e}}, + "dlcrop": {Name: "dlcrop", CodePoints: []int{8973}, Characters: []byte{0xe2, 0x8c, 0x8d}}, + "dollar": {Name: "dollar", CodePoints: []int{36}, Characters: []byte{0x24}}, + "dopf": {Name: "dopf", CodePoints: []int{120149}, Characters: []byte{0xf0, 0x9d, 0x95, 0x95}}, + "dot": {Name: "dot", CodePoints: []int{729}, Characters: []byte{0xcb, 0x99}}, + "doteq": {Name: "doteq", CodePoints: []int{8784}, Characters: []byte{0xe2, 0x89, 0x90}}, + "doteqdot": {Name: "doteqdot", CodePoints: []int{8785}, Characters: []byte{0xe2, 0x89, 0x91}}, + "dotminus": {Name: "dotminus", CodePoints: []int{8760}, Characters: []byte{0xe2, 0x88, 0xb8}}, + "dotplus": {Name: "dotplus", CodePoints: []int{8724}, Characters: []byte{0xe2, 0x88, 0x94}}, + "dotsquare": {Name: "dotsquare", CodePoints: []int{8865}, Characters: []byte{0xe2, 0x8a, 0xa1}}, + "doublebarwedge": {Name: "doublebarwedge", CodePoints: []int{8966}, Characters: []byte{0xe2, 0x8c, 0x86}}, + "downarrow": {Name: "downarrow", CodePoints: []int{8595}, Characters: []byte{0xe2, 0x86, 0x93}}, + "downdownarrows": {Name: "downdownarrows", CodePoints: []int{8650}, Characters: []byte{0xe2, 0x87, 0x8a}}, + "downharpoonleft": {Name: "downharpoonleft", CodePoints: []int{8643}, Characters: []byte{0xe2, 0x87, 0x83}}, + "downharpoonright": {Name: "downharpoonright", CodePoints: []int{8642}, Characters: []byte{0xe2, 0x87, 0x82}}, + "drbkarow": {Name: "drbkarow", CodePoints: []int{10512}, Characters: []byte{0xe2, 0xa4, 0x90}}, + "drcorn": {Name: "drcorn", CodePoints: []int{8991}, Characters: []byte{0xe2, 0x8c, 0x9f}}, + "drcrop": {Name: "drcrop", CodePoints: []int{8972}, Characters: []byte{0xe2, 0x8c, 0x8c}}, + "dscr": {Name: "dscr", CodePoints: []int{119993}, Characters: []byte{0xf0, 0x9d, 0x92, 0xb9}}, + "dscy": {Name: "dscy", CodePoints: []int{1109}, Characters: []byte{0xd1, 0x95}}, + "dsol": {Name: "dsol", CodePoints: []int{10742}, Characters: []byte{0xe2, 0xa7, 0xb6}}, + "dstrok": {Name: "dstrok", CodePoints: []int{273}, Characters: []byte{0xc4, 0x91}}, + "dtdot": {Name: "dtdot", CodePoints: []int{8945}, Characters: []byte{0xe2, 0x8b, 0xb1}}, + "dtri": {Name: "dtri", CodePoints: []int{9663}, Characters: []byte{0xe2, 0x96, 0xbf}}, + "dtrif": {Name: "dtrif", CodePoints: []int{9662}, Characters: []byte{0xe2, 0x96, 0xbe}}, + "duarr": {Name: "duarr", CodePoints: []int{8693}, Characters: []byte{0xe2, 0x87, 0xb5}}, + "duhar": {Name: "duhar", CodePoints: []int{10607}, Characters: []byte{0xe2, 0xa5, 0xaf}}, + "dwangle": {Name: "dwangle", CodePoints: []int{10662}, Characters: []byte{0xe2, 0xa6, 0xa6}}, + "dzcy": {Name: "dzcy", CodePoints: []int{1119}, Characters: []byte{0xd1, 0x9f}}, + "dzigrarr": {Name: "dzigrarr", CodePoints: []int{10239}, Characters: []byte{0xe2, 0x9f, 0xbf}}, + "eDDot": {Name: "eDDot", CodePoints: []int{10871}, Characters: []byte{0xe2, 0xa9, 0xb7}}, + "eDot": {Name: "eDot", CodePoints: []int{8785}, Characters: []byte{0xe2, 0x89, 0x91}}, + "eacute": {Name: "eacute", CodePoints: []int{233}, Characters: []byte{0xc3, 0xa9}}, + "easter": {Name: "easter", CodePoints: []int{10862}, Characters: []byte{0xe2, 0xa9, 0xae}}, + "ecaron": {Name: "ecaron", CodePoints: []int{283}, Characters: []byte{0xc4, 0x9b}}, + "ecir": {Name: "ecir", CodePoints: []int{8790}, Characters: []byte{0xe2, 0x89, 0x96}}, + "ecirc": {Name: "ecirc", CodePoints: []int{234}, Characters: []byte{0xc3, 0xaa}}, + "ecolon": {Name: "ecolon", CodePoints: []int{8789}, Characters: []byte{0xe2, 0x89, 0x95}}, + "ecy": {Name: "ecy", CodePoints: []int{1101}, Characters: []byte{0xd1, 0x8d}}, + "edot": {Name: "edot", CodePoints: []int{279}, Characters: []byte{0xc4, 0x97}}, + "ee": {Name: "ee", CodePoints: []int{8519}, Characters: []byte{0xe2, 0x85, 0x87}}, + "efDot": {Name: "efDot", CodePoints: []int{8786}, Characters: []byte{0xe2, 0x89, 0x92}}, + "efr": {Name: "efr", CodePoints: []int{120098}, Characters: []byte{0xf0, 0x9d, 0x94, 0xa2}}, + "eg": {Name: "eg", CodePoints: []int{10906}, Characters: []byte{0xe2, 0xaa, 0x9a}}, + "egrave": {Name: "egrave", CodePoints: []int{232}, Characters: []byte{0xc3, 0xa8}}, + "egs": {Name: "egs", CodePoints: []int{10902}, Characters: []byte{0xe2, 0xaa, 0x96}}, + "egsdot": {Name: "egsdot", CodePoints: []int{10904}, Characters: []byte{0xe2, 0xaa, 0x98}}, + "el": {Name: "el", CodePoints: []int{10905}, Characters: []byte{0xe2, 0xaa, 0x99}}, + "elinters": {Name: "elinters", CodePoints: []int{9191}, Characters: []byte{0xe2, 0x8f, 0xa7}}, + "ell": {Name: "ell", CodePoints: []int{8467}, Characters: []byte{0xe2, 0x84, 0x93}}, + "els": {Name: "els", CodePoints: []int{10901}, Characters: []byte{0xe2, 0xaa, 0x95}}, + "elsdot": {Name: "elsdot", CodePoints: []int{10903}, Characters: []byte{0xe2, 0xaa, 0x97}}, + "emacr": {Name: "emacr", CodePoints: []int{275}, Characters: []byte{0xc4, 0x93}}, + "empty": {Name: "empty", CodePoints: []int{8709}, Characters: []byte{0xe2, 0x88, 0x85}}, + "emptyset": {Name: "emptyset", CodePoints: []int{8709}, Characters: []byte{0xe2, 0x88, 0x85}}, + "emptyv": {Name: "emptyv", CodePoints: []int{8709}, Characters: []byte{0xe2, 0x88, 0x85}}, + "emsp": {Name: "emsp", CodePoints: []int{8195}, Characters: []byte{0xe2, 0x80, 0x83}}, + "emsp13": {Name: "emsp13", CodePoints: []int{8196}, Characters: []byte{0xe2, 0x80, 0x84}}, + "emsp14": {Name: "emsp14", CodePoints: []int{8197}, Characters: []byte{0xe2, 0x80, 0x85}}, + "eng": {Name: "eng", CodePoints: []int{331}, Characters: []byte{0xc5, 0x8b}}, + "ensp": {Name: "ensp", CodePoints: []int{8194}, Characters: []byte{0xe2, 0x80, 0x82}}, + "eogon": {Name: "eogon", CodePoints: []int{281}, Characters: []byte{0xc4, 0x99}}, + "eopf": {Name: "eopf", CodePoints: []int{120150}, Characters: []byte{0xf0, 0x9d, 0x95, 0x96}}, + "epar": {Name: "epar", CodePoints: []int{8917}, Characters: []byte{0xe2, 0x8b, 0x95}}, + "eparsl": {Name: "eparsl", CodePoints: []int{10723}, Characters: []byte{0xe2, 0xa7, 0xa3}}, + "eplus": {Name: "eplus", CodePoints: []int{10865}, Characters: []byte{0xe2, 0xa9, 0xb1}}, + "epsi": {Name: "epsi", CodePoints: []int{949}, Characters: []byte{0xce, 0xb5}}, + "epsilon": {Name: "epsilon", CodePoints: []int{949}, Characters: []byte{0xce, 0xb5}}, + "epsiv": {Name: "epsiv", CodePoints: []int{1013}, Characters: []byte{0xcf, 0xb5}}, + "eqcirc": {Name: "eqcirc", CodePoints: []int{8790}, Characters: []byte{0xe2, 0x89, 0x96}}, + "eqcolon": {Name: "eqcolon", CodePoints: []int{8789}, Characters: []byte{0xe2, 0x89, 0x95}}, + "eqsim": {Name: "eqsim", CodePoints: []int{8770}, Characters: []byte{0xe2, 0x89, 0x82}}, + "eqslantgtr": {Name: "eqslantgtr", CodePoints: []int{10902}, Characters: []byte{0xe2, 0xaa, 0x96}}, + "eqslantless": {Name: "eqslantless", CodePoints: []int{10901}, Characters: []byte{0xe2, 0xaa, 0x95}}, + "equals": {Name: "equals", CodePoints: []int{61}, Characters: []byte{0x3d}}, + "equest": {Name: "equest", CodePoints: []int{8799}, Characters: []byte{0xe2, 0x89, 0x9f}}, + "equiv": {Name: "equiv", CodePoints: []int{8801}, Characters: []byte{0xe2, 0x89, 0xa1}}, + "equivDD": {Name: "equivDD", CodePoints: []int{10872}, Characters: []byte{0xe2, 0xa9, 0xb8}}, + "eqvparsl": {Name: "eqvparsl", CodePoints: []int{10725}, Characters: []byte{0xe2, 0xa7, 0xa5}}, + "erDot": {Name: "erDot", CodePoints: []int{8787}, Characters: []byte{0xe2, 0x89, 0x93}}, + "erarr": {Name: "erarr", CodePoints: []int{10609}, Characters: []byte{0xe2, 0xa5, 0xb1}}, + "escr": {Name: "escr", CodePoints: []int{8495}, Characters: []byte{0xe2, 0x84, 0xaf}}, + "esdot": {Name: "esdot", CodePoints: []int{8784}, Characters: []byte{0xe2, 0x89, 0x90}}, + "esim": {Name: "esim", CodePoints: []int{8770}, Characters: []byte{0xe2, 0x89, 0x82}}, + "eta": {Name: "eta", CodePoints: []int{951}, Characters: []byte{0xce, 0xb7}}, + "eth": {Name: "eth", CodePoints: []int{240}, Characters: []byte{0xc3, 0xb0}}, + "euml": {Name: "euml", CodePoints: []int{235}, Characters: []byte{0xc3, 0xab}}, + "euro": {Name: "euro", CodePoints: []int{8364}, Characters: []byte{0xe2, 0x82, 0xac}}, + "excl": {Name: "excl", CodePoints: []int{33}, Characters: []byte{0x21}}, + "exist": {Name: "exist", CodePoints: []int{8707}, Characters: []byte{0xe2, 0x88, 0x83}}, + "expectation": {Name: "expectation", CodePoints: []int{8496}, Characters: []byte{0xe2, 0x84, 0xb0}}, + "exponentiale": {Name: "exponentiale", CodePoints: []int{8519}, Characters: []byte{0xe2, 0x85, 0x87}}, + "fallingdotseq": {Name: "fallingdotseq", CodePoints: []int{8786}, Characters: []byte{0xe2, 0x89, 0x92}}, + "fcy": {Name: "fcy", CodePoints: []int{1092}, Characters: []byte{0xd1, 0x84}}, + "female": {Name: "female", CodePoints: []int{9792}, Characters: []byte{0xe2, 0x99, 0x80}}, + "ffilig": {Name: "ffilig", CodePoints: []int{64259}, Characters: []byte{0xef, 0xac, 0x83}}, + "fflig": {Name: "fflig", CodePoints: []int{64256}, Characters: []byte{0xef, 0xac, 0x80}}, + "ffllig": {Name: "ffllig", CodePoints: []int{64260}, Characters: []byte{0xef, 0xac, 0x84}}, + "ffr": {Name: "ffr", CodePoints: []int{120099}, Characters: []byte{0xf0, 0x9d, 0x94, 0xa3}}, + "filig": {Name: "filig", CodePoints: []int{64257}, Characters: []byte{0xef, 0xac, 0x81}}, + "fjlig": {Name: "fjlig", CodePoints: []int{102, 106}, Characters: []byte{0x66, 0x6a}}, + "flat": {Name: "flat", CodePoints: []int{9837}, Characters: []byte{0xe2, 0x99, 0xad}}, + "fllig": {Name: "fllig", CodePoints: []int{64258}, Characters: []byte{0xef, 0xac, 0x82}}, + "fltns": {Name: "fltns", CodePoints: []int{9649}, Characters: []byte{0xe2, 0x96, 0xb1}}, + "fnof": {Name: "fnof", CodePoints: []int{402}, Characters: []byte{0xc6, 0x92}}, + "fopf": {Name: "fopf", CodePoints: []int{120151}, Characters: []byte{0xf0, 0x9d, 0x95, 0x97}}, + "forall": {Name: "forall", CodePoints: []int{8704}, Characters: []byte{0xe2, 0x88, 0x80}}, + "fork": {Name: "fork", CodePoints: []int{8916}, Characters: []byte{0xe2, 0x8b, 0x94}}, + "forkv": {Name: "forkv", CodePoints: []int{10969}, Characters: []byte{0xe2, 0xab, 0x99}}, + "fpartint": {Name: "fpartint", CodePoints: []int{10765}, Characters: []byte{0xe2, 0xa8, 0x8d}}, + "frac12": {Name: "frac12", CodePoints: []int{189}, Characters: []byte{0xc2, 0xbd}}, + "frac13": {Name: "frac13", CodePoints: []int{8531}, Characters: []byte{0xe2, 0x85, 0x93}}, + "frac14": {Name: "frac14", CodePoints: []int{188}, Characters: []byte{0xc2, 0xbc}}, + "frac15": {Name: "frac15", CodePoints: []int{8533}, Characters: []byte{0xe2, 0x85, 0x95}}, + "frac16": {Name: "frac16", CodePoints: []int{8537}, Characters: []byte{0xe2, 0x85, 0x99}}, + "frac18": {Name: "frac18", CodePoints: []int{8539}, Characters: []byte{0xe2, 0x85, 0x9b}}, + "frac23": {Name: "frac23", CodePoints: []int{8532}, Characters: []byte{0xe2, 0x85, 0x94}}, + "frac25": {Name: "frac25", CodePoints: []int{8534}, Characters: []byte{0xe2, 0x85, 0x96}}, + "frac34": {Name: "frac34", CodePoints: []int{190}, Characters: []byte{0xc2, 0xbe}}, + "frac35": {Name: "frac35", CodePoints: []int{8535}, Characters: []byte{0xe2, 0x85, 0x97}}, + "frac38": {Name: "frac38", CodePoints: []int{8540}, Characters: []byte{0xe2, 0x85, 0x9c}}, + "frac45": {Name: "frac45", CodePoints: []int{8536}, Characters: []byte{0xe2, 0x85, 0x98}}, + "frac56": {Name: "frac56", CodePoints: []int{8538}, Characters: []byte{0xe2, 0x85, 0x9a}}, + "frac58": {Name: "frac58", CodePoints: []int{8541}, Characters: []byte{0xe2, 0x85, 0x9d}}, + "frac78": {Name: "frac78", CodePoints: []int{8542}, Characters: []byte{0xe2, 0x85, 0x9e}}, + "frasl": {Name: "frasl", CodePoints: []int{8260}, Characters: []byte{0xe2, 0x81, 0x84}}, + "frown": {Name: "frown", CodePoints: []int{8994}, Characters: []byte{0xe2, 0x8c, 0xa2}}, + "fscr": {Name: "fscr", CodePoints: []int{119995}, Characters: []byte{0xf0, 0x9d, 0x92, 0xbb}}, + "gE": {Name: "gE", CodePoints: []int{8807}, Characters: []byte{0xe2, 0x89, 0xa7}}, + "gEl": {Name: "gEl", CodePoints: []int{10892}, Characters: []byte{0xe2, 0xaa, 0x8c}}, + "gacute": {Name: "gacute", CodePoints: []int{501}, Characters: []byte{0xc7, 0xb5}}, + "gamma": {Name: "gamma", CodePoints: []int{947}, Characters: []byte{0xce, 0xb3}}, + "gammad": {Name: "gammad", CodePoints: []int{989}, Characters: []byte{0xcf, 0x9d}}, + "gap": {Name: "gap", CodePoints: []int{10886}, Characters: []byte{0xe2, 0xaa, 0x86}}, + "gbreve": {Name: "gbreve", CodePoints: []int{287}, Characters: []byte{0xc4, 0x9f}}, + "gcirc": {Name: "gcirc", CodePoints: []int{285}, Characters: []byte{0xc4, 0x9d}}, + "gcy": {Name: "gcy", CodePoints: []int{1075}, Characters: []byte{0xd0, 0xb3}}, + "gdot": {Name: "gdot", CodePoints: []int{289}, Characters: []byte{0xc4, 0xa1}}, + "ge": {Name: "ge", CodePoints: []int{8805}, Characters: []byte{0xe2, 0x89, 0xa5}}, + "gel": {Name: "gel", CodePoints: []int{8923}, Characters: []byte{0xe2, 0x8b, 0x9b}}, + "geq": {Name: "geq", CodePoints: []int{8805}, Characters: []byte{0xe2, 0x89, 0xa5}}, + "geqq": {Name: "geqq", CodePoints: []int{8807}, Characters: []byte{0xe2, 0x89, 0xa7}}, + "geqslant": {Name: "geqslant", CodePoints: []int{10878}, Characters: []byte{0xe2, 0xa9, 0xbe}}, + "ges": {Name: "ges", CodePoints: []int{10878}, Characters: []byte{0xe2, 0xa9, 0xbe}}, + "gescc": {Name: "gescc", CodePoints: []int{10921}, Characters: []byte{0xe2, 0xaa, 0xa9}}, + "gesdot": {Name: "gesdot", CodePoints: []int{10880}, Characters: []byte{0xe2, 0xaa, 0x80}}, + "gesdoto": {Name: "gesdoto", CodePoints: []int{10882}, Characters: []byte{0xe2, 0xaa, 0x82}}, + "gesdotol": {Name: "gesdotol", CodePoints: []int{10884}, Characters: []byte{0xe2, 0xaa, 0x84}}, + "gesl": {Name: "gesl", CodePoints: []int{8923, 65024}, Characters: []byte{0xe2, 0x8b, 0x9b, 0xef, 0xb8, 0x80}}, + "gesles": {Name: "gesles", CodePoints: []int{10900}, Characters: []byte{0xe2, 0xaa, 0x94}}, + "gfr": {Name: "gfr", CodePoints: []int{120100}, Characters: []byte{0xf0, 0x9d, 0x94, 0xa4}}, + "gg": {Name: "gg", CodePoints: []int{8811}, Characters: []byte{0xe2, 0x89, 0xab}}, + "ggg": {Name: "ggg", CodePoints: []int{8921}, Characters: []byte{0xe2, 0x8b, 0x99}}, + "gimel": {Name: "gimel", CodePoints: []int{8503}, Characters: []byte{0xe2, 0x84, 0xb7}}, + "gjcy": {Name: "gjcy", CodePoints: []int{1107}, Characters: []byte{0xd1, 0x93}}, + "gl": {Name: "gl", CodePoints: []int{8823}, Characters: []byte{0xe2, 0x89, 0xb7}}, + "glE": {Name: "glE", CodePoints: []int{10898}, Characters: []byte{0xe2, 0xaa, 0x92}}, + "gla": {Name: "gla", CodePoints: []int{10917}, Characters: []byte{0xe2, 0xaa, 0xa5}}, + "glj": {Name: "glj", CodePoints: []int{10916}, Characters: []byte{0xe2, 0xaa, 0xa4}}, + "gnE": {Name: "gnE", CodePoints: []int{8809}, Characters: []byte{0xe2, 0x89, 0xa9}}, + "gnap": {Name: "gnap", CodePoints: []int{10890}, Characters: []byte{0xe2, 0xaa, 0x8a}}, + "gnapprox": {Name: "gnapprox", CodePoints: []int{10890}, Characters: []byte{0xe2, 0xaa, 0x8a}}, + "gne": {Name: "gne", CodePoints: []int{10888}, Characters: []byte{0xe2, 0xaa, 0x88}}, + "gneq": {Name: "gneq", CodePoints: []int{10888}, Characters: []byte{0xe2, 0xaa, 0x88}}, + "gneqq": {Name: "gneqq", CodePoints: []int{8809}, Characters: []byte{0xe2, 0x89, 0xa9}}, + "gnsim": {Name: "gnsim", CodePoints: []int{8935}, Characters: []byte{0xe2, 0x8b, 0xa7}}, + "gopf": {Name: "gopf", CodePoints: []int{120152}, Characters: []byte{0xf0, 0x9d, 0x95, 0x98}}, + "grave": {Name: "grave", CodePoints: []int{96}, Characters: []byte{0x60}}, + "gscr": {Name: "gscr", CodePoints: []int{8458}, Characters: []byte{0xe2, 0x84, 0x8a}}, + "gsim": {Name: "gsim", CodePoints: []int{8819}, Characters: []byte{0xe2, 0x89, 0xb3}}, + "gsime": {Name: "gsime", CodePoints: []int{10894}, Characters: []byte{0xe2, 0xaa, 0x8e}}, + "gsiml": {Name: "gsiml", CodePoints: []int{10896}, Characters: []byte{0xe2, 0xaa, 0x90}}, + "gt": {Name: "gt", CodePoints: []int{62}, Characters: []byte{0x3e}}, + "gtcc": {Name: "gtcc", CodePoints: []int{10919}, Characters: []byte{0xe2, 0xaa, 0xa7}}, + "gtcir": {Name: "gtcir", CodePoints: []int{10874}, Characters: []byte{0xe2, 0xa9, 0xba}}, + "gtdot": {Name: "gtdot", CodePoints: []int{8919}, Characters: []byte{0xe2, 0x8b, 0x97}}, + "gtlPar": {Name: "gtlPar", CodePoints: []int{10645}, Characters: []byte{0xe2, 0xa6, 0x95}}, + "gtquest": {Name: "gtquest", CodePoints: []int{10876}, Characters: []byte{0xe2, 0xa9, 0xbc}}, + "gtrapprox": {Name: "gtrapprox", CodePoints: []int{10886}, Characters: []byte{0xe2, 0xaa, 0x86}}, + "gtrarr": {Name: "gtrarr", CodePoints: []int{10616}, Characters: []byte{0xe2, 0xa5, 0xb8}}, + "gtrdot": {Name: "gtrdot", CodePoints: []int{8919}, Characters: []byte{0xe2, 0x8b, 0x97}}, + "gtreqless": {Name: "gtreqless", CodePoints: []int{8923}, Characters: []byte{0xe2, 0x8b, 0x9b}}, + "gtreqqless": {Name: "gtreqqless", CodePoints: []int{10892}, Characters: []byte{0xe2, 0xaa, 0x8c}}, + "gtrless": {Name: "gtrless", CodePoints: []int{8823}, Characters: []byte{0xe2, 0x89, 0xb7}}, + "gtrsim": {Name: "gtrsim", CodePoints: []int{8819}, Characters: []byte{0xe2, 0x89, 0xb3}}, + "gvertneqq": {Name: "gvertneqq", CodePoints: []int{8809, 65024}, Characters: []byte{0xe2, 0x89, 0xa9, 0xef, 0xb8, 0x80}}, + "gvnE": {Name: "gvnE", CodePoints: []int{8809, 65024}, Characters: []byte{0xe2, 0x89, 0xa9, 0xef, 0xb8, 0x80}}, + "hArr": {Name: "hArr", CodePoints: []int{8660}, Characters: []byte{0xe2, 0x87, 0x94}}, + "hairsp": {Name: "hairsp", CodePoints: []int{8202}, Characters: []byte{0xe2, 0x80, 0x8a}}, + "half": {Name: "half", CodePoints: []int{189}, Characters: []byte{0xc2, 0xbd}}, + "hamilt": {Name: "hamilt", CodePoints: []int{8459}, Characters: []byte{0xe2, 0x84, 0x8b}}, + "hardcy": {Name: "hardcy", CodePoints: []int{1098}, Characters: []byte{0xd1, 0x8a}}, + "harr": {Name: "harr", CodePoints: []int{8596}, Characters: []byte{0xe2, 0x86, 0x94}}, + "harrcir": {Name: "harrcir", CodePoints: []int{10568}, Characters: []byte{0xe2, 0xa5, 0x88}}, + "harrw": {Name: "harrw", CodePoints: []int{8621}, Characters: []byte{0xe2, 0x86, 0xad}}, + "hbar": {Name: "hbar", CodePoints: []int{8463}, Characters: []byte{0xe2, 0x84, 0x8f}}, + "hcirc": {Name: "hcirc", CodePoints: []int{293}, Characters: []byte{0xc4, 0xa5}}, + "hearts": {Name: "hearts", CodePoints: []int{9829}, Characters: []byte{0xe2, 0x99, 0xa5}}, + "heartsuit": {Name: "heartsuit", CodePoints: []int{9829}, Characters: []byte{0xe2, 0x99, 0xa5}}, + "hellip": {Name: "hellip", CodePoints: []int{8230}, Characters: []byte{0xe2, 0x80, 0xa6}}, + "hercon": {Name: "hercon", CodePoints: []int{8889}, Characters: []byte{0xe2, 0x8a, 0xb9}}, + "hfr": {Name: "hfr", CodePoints: []int{120101}, Characters: []byte{0xf0, 0x9d, 0x94, 0xa5}}, + "hksearow": {Name: "hksearow", CodePoints: []int{10533}, Characters: []byte{0xe2, 0xa4, 0xa5}}, + "hkswarow": {Name: "hkswarow", CodePoints: []int{10534}, Characters: []byte{0xe2, 0xa4, 0xa6}}, + "hoarr": {Name: "hoarr", CodePoints: []int{8703}, Characters: []byte{0xe2, 0x87, 0xbf}}, + "homtht": {Name: "homtht", CodePoints: []int{8763}, Characters: []byte{0xe2, 0x88, 0xbb}}, + "hookleftarrow": {Name: "hookleftarrow", CodePoints: []int{8617}, Characters: []byte{0xe2, 0x86, 0xa9}}, + "hookrightarrow": {Name: "hookrightarrow", CodePoints: []int{8618}, Characters: []byte{0xe2, 0x86, 0xaa}}, + "hopf": {Name: "hopf", CodePoints: []int{120153}, Characters: []byte{0xf0, 0x9d, 0x95, 0x99}}, + "horbar": {Name: "horbar", CodePoints: []int{8213}, Characters: []byte{0xe2, 0x80, 0x95}}, + "hscr": {Name: "hscr", CodePoints: []int{119997}, Characters: []byte{0xf0, 0x9d, 0x92, 0xbd}}, + "hslash": {Name: "hslash", CodePoints: []int{8463}, Characters: []byte{0xe2, 0x84, 0x8f}}, + "hstrok": {Name: "hstrok", CodePoints: []int{295}, Characters: []byte{0xc4, 0xa7}}, + "hybull": {Name: "hybull", CodePoints: []int{8259}, Characters: []byte{0xe2, 0x81, 0x83}}, + "hyphen": {Name: "hyphen", CodePoints: []int{8208}, Characters: []byte{0xe2, 0x80, 0x90}}, + "iacute": {Name: "iacute", CodePoints: []int{237}, Characters: []byte{0xc3, 0xad}}, + "ic": {Name: "ic", CodePoints: []int{8291}, Characters: []byte{0xe2, 0x81, 0xa3}}, + "icirc": {Name: "icirc", CodePoints: []int{238}, Characters: []byte{0xc3, 0xae}}, + "icy": {Name: "icy", CodePoints: []int{1080}, Characters: []byte{0xd0, 0xb8}}, + "iecy": {Name: "iecy", CodePoints: []int{1077}, Characters: []byte{0xd0, 0xb5}}, + "iexcl": {Name: "iexcl", CodePoints: []int{161}, Characters: []byte{0xc2, 0xa1}}, + "iff": {Name: "iff", CodePoints: []int{8660}, Characters: []byte{0xe2, 0x87, 0x94}}, + "ifr": {Name: "ifr", CodePoints: []int{120102}, Characters: []byte{0xf0, 0x9d, 0x94, 0xa6}}, + "igrave": {Name: "igrave", CodePoints: []int{236}, Characters: []byte{0xc3, 0xac}}, + "ii": {Name: "ii", CodePoints: []int{8520}, Characters: []byte{0xe2, 0x85, 0x88}}, + "iiiint": {Name: "iiiint", CodePoints: []int{10764}, Characters: []byte{0xe2, 0xa8, 0x8c}}, + "iiint": {Name: "iiint", CodePoints: []int{8749}, Characters: []byte{0xe2, 0x88, 0xad}}, + "iinfin": {Name: "iinfin", CodePoints: []int{10716}, Characters: []byte{0xe2, 0xa7, 0x9c}}, + "iiota": {Name: "iiota", CodePoints: []int{8489}, Characters: []byte{0xe2, 0x84, 0xa9}}, + "ijlig": {Name: "ijlig", CodePoints: []int{307}, Characters: []byte{0xc4, 0xb3}}, + "imacr": {Name: "imacr", CodePoints: []int{299}, Characters: []byte{0xc4, 0xab}}, + "image": {Name: "image", CodePoints: []int{8465}, Characters: []byte{0xe2, 0x84, 0x91}}, + "imagline": {Name: "imagline", CodePoints: []int{8464}, Characters: []byte{0xe2, 0x84, 0x90}}, + "imagpart": {Name: "imagpart", CodePoints: []int{8465}, Characters: []byte{0xe2, 0x84, 0x91}}, + "imath": {Name: "imath", CodePoints: []int{305}, Characters: []byte{0xc4, 0xb1}}, + "imof": {Name: "imof", CodePoints: []int{8887}, Characters: []byte{0xe2, 0x8a, 0xb7}}, + "imped": {Name: "imped", CodePoints: []int{437}, Characters: []byte{0xc6, 0xb5}}, + "in": {Name: "in", CodePoints: []int{8712}, Characters: []byte{0xe2, 0x88, 0x88}}, + "incare": {Name: "incare", CodePoints: []int{8453}, Characters: []byte{0xe2, 0x84, 0x85}}, + "infin": {Name: "infin", CodePoints: []int{8734}, Characters: []byte{0xe2, 0x88, 0x9e}}, + "infintie": {Name: "infintie", CodePoints: []int{10717}, Characters: []byte{0xe2, 0xa7, 0x9d}}, + "inodot": {Name: "inodot", CodePoints: []int{305}, Characters: []byte{0xc4, 0xb1}}, + "int": {Name: "int", CodePoints: []int{8747}, Characters: []byte{0xe2, 0x88, 0xab}}, + "intcal": {Name: "intcal", CodePoints: []int{8890}, Characters: []byte{0xe2, 0x8a, 0xba}}, + "integers": {Name: "integers", CodePoints: []int{8484}, Characters: []byte{0xe2, 0x84, 0xa4}}, + "intercal": {Name: "intercal", CodePoints: []int{8890}, Characters: []byte{0xe2, 0x8a, 0xba}}, + "intlarhk": {Name: "intlarhk", CodePoints: []int{10775}, Characters: []byte{0xe2, 0xa8, 0x97}}, + "intprod": {Name: "intprod", CodePoints: []int{10812}, Characters: []byte{0xe2, 0xa8, 0xbc}}, + "iocy": {Name: "iocy", CodePoints: []int{1105}, Characters: []byte{0xd1, 0x91}}, + "iogon": {Name: "iogon", CodePoints: []int{303}, Characters: []byte{0xc4, 0xaf}}, + "iopf": {Name: "iopf", CodePoints: []int{120154}, Characters: []byte{0xf0, 0x9d, 0x95, 0x9a}}, + "iota": {Name: "iota", CodePoints: []int{953}, Characters: []byte{0xce, 0xb9}}, + "iprod": {Name: "iprod", CodePoints: []int{10812}, Characters: []byte{0xe2, 0xa8, 0xbc}}, + "iquest": {Name: "iquest", CodePoints: []int{191}, Characters: []byte{0xc2, 0xbf}}, + "iscr": {Name: "iscr", CodePoints: []int{119998}, Characters: []byte{0xf0, 0x9d, 0x92, 0xbe}}, + "isin": {Name: "isin", CodePoints: []int{8712}, Characters: []byte{0xe2, 0x88, 0x88}}, + "isinE": {Name: "isinE", CodePoints: []int{8953}, Characters: []byte{0xe2, 0x8b, 0xb9}}, + "isindot": {Name: "isindot", CodePoints: []int{8949}, Characters: []byte{0xe2, 0x8b, 0xb5}}, + "isins": {Name: "isins", CodePoints: []int{8948}, Characters: []byte{0xe2, 0x8b, 0xb4}}, + "isinsv": {Name: "isinsv", CodePoints: []int{8947}, Characters: []byte{0xe2, 0x8b, 0xb3}}, + "isinv": {Name: "isinv", CodePoints: []int{8712}, Characters: []byte{0xe2, 0x88, 0x88}}, + "it": {Name: "it", CodePoints: []int{8290}, Characters: []byte{0xe2, 0x81, 0xa2}}, + "itilde": {Name: "itilde", CodePoints: []int{297}, Characters: []byte{0xc4, 0xa9}}, + "iukcy": {Name: "iukcy", CodePoints: []int{1110}, Characters: []byte{0xd1, 0x96}}, + "iuml": {Name: "iuml", CodePoints: []int{239}, Characters: []byte{0xc3, 0xaf}}, + "jcirc": {Name: "jcirc", CodePoints: []int{309}, Characters: []byte{0xc4, 0xb5}}, + "jcy": {Name: "jcy", CodePoints: []int{1081}, Characters: []byte{0xd0, 0xb9}}, + "jfr": {Name: "jfr", CodePoints: []int{120103}, Characters: []byte{0xf0, 0x9d, 0x94, 0xa7}}, + "jmath": {Name: "jmath", CodePoints: []int{567}, Characters: []byte{0xc8, 0xb7}}, + "jopf": {Name: "jopf", CodePoints: []int{120155}, Characters: []byte{0xf0, 0x9d, 0x95, 0x9b}}, + "jscr": {Name: "jscr", CodePoints: []int{119999}, Characters: []byte{0xf0, 0x9d, 0x92, 0xbf}}, + "jsercy": {Name: "jsercy", CodePoints: []int{1112}, Characters: []byte{0xd1, 0x98}}, + "jukcy": {Name: "jukcy", CodePoints: []int{1108}, Characters: []byte{0xd1, 0x94}}, + "kappa": {Name: "kappa", CodePoints: []int{954}, Characters: []byte{0xce, 0xba}}, + "kappav": {Name: "kappav", CodePoints: []int{1008}, Characters: []byte{0xcf, 0xb0}}, + "kcedil": {Name: "kcedil", CodePoints: []int{311}, Characters: []byte{0xc4, 0xb7}}, + "kcy": {Name: "kcy", CodePoints: []int{1082}, Characters: []byte{0xd0, 0xba}}, + "kfr": {Name: "kfr", CodePoints: []int{120104}, Characters: []byte{0xf0, 0x9d, 0x94, 0xa8}}, + "kgreen": {Name: "kgreen", CodePoints: []int{312}, Characters: []byte{0xc4, 0xb8}}, + "khcy": {Name: "khcy", CodePoints: []int{1093}, Characters: []byte{0xd1, 0x85}}, + "kjcy": {Name: "kjcy", CodePoints: []int{1116}, Characters: []byte{0xd1, 0x9c}}, + "kopf": {Name: "kopf", CodePoints: []int{120156}, Characters: []byte{0xf0, 0x9d, 0x95, 0x9c}}, + "kscr": {Name: "kscr", CodePoints: []int{120000}, Characters: []byte{0xf0, 0x9d, 0x93, 0x80}}, + "lAarr": {Name: "lAarr", CodePoints: []int{8666}, Characters: []byte{0xe2, 0x87, 0x9a}}, + "lArr": {Name: "lArr", CodePoints: []int{8656}, Characters: []byte{0xe2, 0x87, 0x90}}, + "lAtail": {Name: "lAtail", CodePoints: []int{10523}, Characters: []byte{0xe2, 0xa4, 0x9b}}, + "lBarr": {Name: "lBarr", CodePoints: []int{10510}, Characters: []byte{0xe2, 0xa4, 0x8e}}, + "lE": {Name: "lE", CodePoints: []int{8806}, Characters: []byte{0xe2, 0x89, 0xa6}}, + "lEg": {Name: "lEg", CodePoints: []int{10891}, Characters: []byte{0xe2, 0xaa, 0x8b}}, + "lHar": {Name: "lHar", CodePoints: []int{10594}, Characters: []byte{0xe2, 0xa5, 0xa2}}, + "lacute": {Name: "lacute", CodePoints: []int{314}, Characters: []byte{0xc4, 0xba}}, + "laemptyv": {Name: "laemptyv", CodePoints: []int{10676}, Characters: []byte{0xe2, 0xa6, 0xb4}}, + "lagran": {Name: "lagran", CodePoints: []int{8466}, Characters: []byte{0xe2, 0x84, 0x92}}, + "lambda": {Name: "lambda", CodePoints: []int{955}, Characters: []byte{0xce, 0xbb}}, + "lang": {Name: "lang", CodePoints: []int{10216}, Characters: []byte{0xe2, 0x9f, 0xa8}}, + "langd": {Name: "langd", CodePoints: []int{10641}, Characters: []byte{0xe2, 0xa6, 0x91}}, + "langle": {Name: "langle", CodePoints: []int{10216}, Characters: []byte{0xe2, 0x9f, 0xa8}}, + "lap": {Name: "lap", CodePoints: []int{10885}, Characters: []byte{0xe2, 0xaa, 0x85}}, + "laquo": {Name: "laquo", CodePoints: []int{171}, Characters: []byte{0xc2, 0xab}}, + "larr": {Name: "larr", CodePoints: []int{8592}, Characters: []byte{0xe2, 0x86, 0x90}}, + "larrb": {Name: "larrb", CodePoints: []int{8676}, Characters: []byte{0xe2, 0x87, 0xa4}}, + "larrbfs": {Name: "larrbfs", CodePoints: []int{10527}, Characters: []byte{0xe2, 0xa4, 0x9f}}, + "larrfs": {Name: "larrfs", CodePoints: []int{10525}, Characters: []byte{0xe2, 0xa4, 0x9d}}, + "larrhk": {Name: "larrhk", CodePoints: []int{8617}, Characters: []byte{0xe2, 0x86, 0xa9}}, + "larrlp": {Name: "larrlp", CodePoints: []int{8619}, Characters: []byte{0xe2, 0x86, 0xab}}, + "larrpl": {Name: "larrpl", CodePoints: []int{10553}, Characters: []byte{0xe2, 0xa4, 0xb9}}, + "larrsim": {Name: "larrsim", CodePoints: []int{10611}, Characters: []byte{0xe2, 0xa5, 0xb3}}, + "larrtl": {Name: "larrtl", CodePoints: []int{8610}, Characters: []byte{0xe2, 0x86, 0xa2}}, + "lat": {Name: "lat", CodePoints: []int{10923}, Characters: []byte{0xe2, 0xaa, 0xab}}, + "latail": {Name: "latail", CodePoints: []int{10521}, Characters: []byte{0xe2, 0xa4, 0x99}}, + "late": {Name: "late", CodePoints: []int{10925}, Characters: []byte{0xe2, 0xaa, 0xad}}, + "lates": {Name: "lates", CodePoints: []int{10925, 65024}, Characters: []byte{0xe2, 0xaa, 0xad, 0xef, 0xb8, 0x80}}, + "lbarr": {Name: "lbarr", CodePoints: []int{10508}, Characters: []byte{0xe2, 0xa4, 0x8c}}, + "lbbrk": {Name: "lbbrk", CodePoints: []int{10098}, Characters: []byte{0xe2, 0x9d, 0xb2}}, + "lbrace": {Name: "lbrace", CodePoints: []int{123}, Characters: []byte{0x7b}}, + "lbrack": {Name: "lbrack", CodePoints: []int{91}, Characters: []byte{0x5b}}, + "lbrke": {Name: "lbrke", CodePoints: []int{10635}, Characters: []byte{0xe2, 0xa6, 0x8b}}, + "lbrksld": {Name: "lbrksld", CodePoints: []int{10639}, Characters: []byte{0xe2, 0xa6, 0x8f}}, + "lbrkslu": {Name: "lbrkslu", CodePoints: []int{10637}, Characters: []byte{0xe2, 0xa6, 0x8d}}, + "lcaron": {Name: "lcaron", CodePoints: []int{318}, Characters: []byte{0xc4, 0xbe}}, + "lcedil": {Name: "lcedil", CodePoints: []int{316}, Characters: []byte{0xc4, 0xbc}}, + "lceil": {Name: "lceil", CodePoints: []int{8968}, Characters: []byte{0xe2, 0x8c, 0x88}}, + "lcub": {Name: "lcub", CodePoints: []int{123}, Characters: []byte{0x7b}}, + "lcy": {Name: "lcy", CodePoints: []int{1083}, Characters: []byte{0xd0, 0xbb}}, + "ldca": {Name: "ldca", CodePoints: []int{10550}, Characters: []byte{0xe2, 0xa4, 0xb6}}, + "ldquo": {Name: "ldquo", CodePoints: []int{8220}, Characters: []byte{0xe2, 0x80, 0x9c}}, + "ldquor": {Name: "ldquor", CodePoints: []int{8222}, Characters: []byte{0xe2, 0x80, 0x9e}}, + "ldrdhar": {Name: "ldrdhar", CodePoints: []int{10599}, Characters: []byte{0xe2, 0xa5, 0xa7}}, + "ldrushar": {Name: "ldrushar", CodePoints: []int{10571}, Characters: []byte{0xe2, 0xa5, 0x8b}}, + "ldsh": {Name: "ldsh", CodePoints: []int{8626}, Characters: []byte{0xe2, 0x86, 0xb2}}, + "le": {Name: "le", CodePoints: []int{8804}, Characters: []byte{0xe2, 0x89, 0xa4}}, + "leftarrow": {Name: "leftarrow", CodePoints: []int{8592}, Characters: []byte{0xe2, 0x86, 0x90}}, + "leftarrowtail": {Name: "leftarrowtail", CodePoints: []int{8610}, Characters: []byte{0xe2, 0x86, 0xa2}}, + "leftharpoondown": {Name: "leftharpoondown", CodePoints: []int{8637}, Characters: []byte{0xe2, 0x86, 0xbd}}, + "leftharpoonup": {Name: "leftharpoonup", CodePoints: []int{8636}, Characters: []byte{0xe2, 0x86, 0xbc}}, + "leftleftarrows": {Name: "leftleftarrows", CodePoints: []int{8647}, Characters: []byte{0xe2, 0x87, 0x87}}, + "leftrightarrow": {Name: "leftrightarrow", CodePoints: []int{8596}, Characters: []byte{0xe2, 0x86, 0x94}}, + "leftrightarrows": {Name: "leftrightarrows", CodePoints: []int{8646}, Characters: []byte{0xe2, 0x87, 0x86}}, + "leftrightharpoons": {Name: "leftrightharpoons", CodePoints: []int{8651}, Characters: []byte{0xe2, 0x87, 0x8b}}, + "leftrightsquigarrow": {Name: "leftrightsquigarrow", CodePoints: []int{8621}, Characters: []byte{0xe2, 0x86, 0xad}}, + "leftthreetimes": {Name: "leftthreetimes", CodePoints: []int{8907}, Characters: []byte{0xe2, 0x8b, 0x8b}}, + "leg": {Name: "leg", CodePoints: []int{8922}, Characters: []byte{0xe2, 0x8b, 0x9a}}, + "leq": {Name: "leq", CodePoints: []int{8804}, Characters: []byte{0xe2, 0x89, 0xa4}}, + "leqq": {Name: "leqq", CodePoints: []int{8806}, Characters: []byte{0xe2, 0x89, 0xa6}}, + "leqslant": {Name: "leqslant", CodePoints: []int{10877}, Characters: []byte{0xe2, 0xa9, 0xbd}}, + "les": {Name: "les", CodePoints: []int{10877}, Characters: []byte{0xe2, 0xa9, 0xbd}}, + "lescc": {Name: "lescc", CodePoints: []int{10920}, Characters: []byte{0xe2, 0xaa, 0xa8}}, + "lesdot": {Name: "lesdot", CodePoints: []int{10879}, Characters: []byte{0xe2, 0xa9, 0xbf}}, + "lesdoto": {Name: "lesdoto", CodePoints: []int{10881}, Characters: []byte{0xe2, 0xaa, 0x81}}, + "lesdotor": {Name: "lesdotor", CodePoints: []int{10883}, Characters: []byte{0xe2, 0xaa, 0x83}}, + "lesg": {Name: "lesg", CodePoints: []int{8922, 65024}, Characters: []byte{0xe2, 0x8b, 0x9a, 0xef, 0xb8, 0x80}}, + "lesges": {Name: "lesges", CodePoints: []int{10899}, Characters: []byte{0xe2, 0xaa, 0x93}}, + "lessapprox": {Name: "lessapprox", CodePoints: []int{10885}, Characters: []byte{0xe2, 0xaa, 0x85}}, + "lessdot": {Name: "lessdot", CodePoints: []int{8918}, Characters: []byte{0xe2, 0x8b, 0x96}}, + "lesseqgtr": {Name: "lesseqgtr", CodePoints: []int{8922}, Characters: []byte{0xe2, 0x8b, 0x9a}}, + "lesseqqgtr": {Name: "lesseqqgtr", CodePoints: []int{10891}, Characters: []byte{0xe2, 0xaa, 0x8b}}, + "lessgtr": {Name: "lessgtr", CodePoints: []int{8822}, Characters: []byte{0xe2, 0x89, 0xb6}}, + "lesssim": {Name: "lesssim", CodePoints: []int{8818}, Characters: []byte{0xe2, 0x89, 0xb2}}, + "lfisht": {Name: "lfisht", CodePoints: []int{10620}, Characters: []byte{0xe2, 0xa5, 0xbc}}, + "lfloor": {Name: "lfloor", CodePoints: []int{8970}, Characters: []byte{0xe2, 0x8c, 0x8a}}, + "lfr": {Name: "lfr", CodePoints: []int{120105}, Characters: []byte{0xf0, 0x9d, 0x94, 0xa9}}, + "lg": {Name: "lg", CodePoints: []int{8822}, Characters: []byte{0xe2, 0x89, 0xb6}}, + "lgE": {Name: "lgE", CodePoints: []int{10897}, Characters: []byte{0xe2, 0xaa, 0x91}}, + "lhard": {Name: "lhard", CodePoints: []int{8637}, Characters: []byte{0xe2, 0x86, 0xbd}}, + "lharu": {Name: "lharu", CodePoints: []int{8636}, Characters: []byte{0xe2, 0x86, 0xbc}}, + "lharul": {Name: "lharul", CodePoints: []int{10602}, Characters: []byte{0xe2, 0xa5, 0xaa}}, + "lhblk": {Name: "lhblk", CodePoints: []int{9604}, Characters: []byte{0xe2, 0x96, 0x84}}, + "ljcy": {Name: "ljcy", CodePoints: []int{1113}, Characters: []byte{0xd1, 0x99}}, + "ll": {Name: "ll", CodePoints: []int{8810}, Characters: []byte{0xe2, 0x89, 0xaa}}, + "llarr": {Name: "llarr", CodePoints: []int{8647}, Characters: []byte{0xe2, 0x87, 0x87}}, + "llcorner": {Name: "llcorner", CodePoints: []int{8990}, Characters: []byte{0xe2, 0x8c, 0x9e}}, + "llhard": {Name: "llhard", CodePoints: []int{10603}, Characters: []byte{0xe2, 0xa5, 0xab}}, + "lltri": {Name: "lltri", CodePoints: []int{9722}, Characters: []byte{0xe2, 0x97, 0xba}}, + "lmidot": {Name: "lmidot", CodePoints: []int{320}, Characters: []byte{0xc5, 0x80}}, + "lmoust": {Name: "lmoust", CodePoints: []int{9136}, Characters: []byte{0xe2, 0x8e, 0xb0}}, + "lmoustache": {Name: "lmoustache", CodePoints: []int{9136}, Characters: []byte{0xe2, 0x8e, 0xb0}}, + "lnE": {Name: "lnE", CodePoints: []int{8808}, Characters: []byte{0xe2, 0x89, 0xa8}}, + "lnap": {Name: "lnap", CodePoints: []int{10889}, Characters: []byte{0xe2, 0xaa, 0x89}}, + "lnapprox": {Name: "lnapprox", CodePoints: []int{10889}, Characters: []byte{0xe2, 0xaa, 0x89}}, + "lne": {Name: "lne", CodePoints: []int{10887}, Characters: []byte{0xe2, 0xaa, 0x87}}, + "lneq": {Name: "lneq", CodePoints: []int{10887}, Characters: []byte{0xe2, 0xaa, 0x87}}, + "lneqq": {Name: "lneqq", CodePoints: []int{8808}, Characters: []byte{0xe2, 0x89, 0xa8}}, + "lnsim": {Name: "lnsim", CodePoints: []int{8934}, Characters: []byte{0xe2, 0x8b, 0xa6}}, + "loang": {Name: "loang", CodePoints: []int{10220}, Characters: []byte{0xe2, 0x9f, 0xac}}, + "loarr": {Name: "loarr", CodePoints: []int{8701}, Characters: []byte{0xe2, 0x87, 0xbd}}, + "lobrk": {Name: "lobrk", CodePoints: []int{10214}, Characters: []byte{0xe2, 0x9f, 0xa6}}, + "longleftarrow": {Name: "longleftarrow", CodePoints: []int{10229}, Characters: []byte{0xe2, 0x9f, 0xb5}}, + "longleftrightarrow": {Name: "longleftrightarrow", CodePoints: []int{10231}, Characters: []byte{0xe2, 0x9f, 0xb7}}, + "longmapsto": {Name: "longmapsto", CodePoints: []int{10236}, Characters: []byte{0xe2, 0x9f, 0xbc}}, + "longrightarrow": {Name: "longrightarrow", CodePoints: []int{10230}, Characters: []byte{0xe2, 0x9f, 0xb6}}, + "looparrowleft": {Name: "looparrowleft", CodePoints: []int{8619}, Characters: []byte{0xe2, 0x86, 0xab}}, + "looparrowright": {Name: "looparrowright", CodePoints: []int{8620}, Characters: []byte{0xe2, 0x86, 0xac}}, + "lopar": {Name: "lopar", CodePoints: []int{10629}, Characters: []byte{0xe2, 0xa6, 0x85}}, + "lopf": {Name: "lopf", CodePoints: []int{120157}, Characters: []byte{0xf0, 0x9d, 0x95, 0x9d}}, + "loplus": {Name: "loplus", CodePoints: []int{10797}, Characters: []byte{0xe2, 0xa8, 0xad}}, + "lotimes": {Name: "lotimes", CodePoints: []int{10804}, Characters: []byte{0xe2, 0xa8, 0xb4}}, + "lowast": {Name: "lowast", CodePoints: []int{8727}, Characters: []byte{0xe2, 0x88, 0x97}}, + "lowbar": {Name: "lowbar", CodePoints: []int{95}, Characters: []byte{0x5f}}, + "loz": {Name: "loz", CodePoints: []int{9674}, Characters: []byte{0xe2, 0x97, 0x8a}}, + "lozenge": {Name: "lozenge", CodePoints: []int{9674}, Characters: []byte{0xe2, 0x97, 0x8a}}, + "lozf": {Name: "lozf", CodePoints: []int{10731}, Characters: []byte{0xe2, 0xa7, 0xab}}, + "lpar": {Name: "lpar", CodePoints: []int{40}, Characters: []byte{0x28}}, + "lparlt": {Name: "lparlt", CodePoints: []int{10643}, Characters: []byte{0xe2, 0xa6, 0x93}}, + "lrarr": {Name: "lrarr", CodePoints: []int{8646}, Characters: []byte{0xe2, 0x87, 0x86}}, + "lrcorner": {Name: "lrcorner", CodePoints: []int{8991}, Characters: []byte{0xe2, 0x8c, 0x9f}}, + "lrhar": {Name: "lrhar", CodePoints: []int{8651}, Characters: []byte{0xe2, 0x87, 0x8b}}, + "lrhard": {Name: "lrhard", CodePoints: []int{10605}, Characters: []byte{0xe2, 0xa5, 0xad}}, + "lrm": {Name: "lrm", CodePoints: []int{8206}, Characters: []byte{0xe2, 0x80, 0x8e}}, + "lrtri": {Name: "lrtri", CodePoints: []int{8895}, Characters: []byte{0xe2, 0x8a, 0xbf}}, + "lsaquo": {Name: "lsaquo", CodePoints: []int{8249}, Characters: []byte{0xe2, 0x80, 0xb9}}, + "lscr": {Name: "lscr", CodePoints: []int{120001}, Characters: []byte{0xf0, 0x9d, 0x93, 0x81}}, + "lsh": {Name: "lsh", CodePoints: []int{8624}, Characters: []byte{0xe2, 0x86, 0xb0}}, + "lsim": {Name: "lsim", CodePoints: []int{8818}, Characters: []byte{0xe2, 0x89, 0xb2}}, + "lsime": {Name: "lsime", CodePoints: []int{10893}, Characters: []byte{0xe2, 0xaa, 0x8d}}, + "lsimg": {Name: "lsimg", CodePoints: []int{10895}, Characters: []byte{0xe2, 0xaa, 0x8f}}, + "lsqb": {Name: "lsqb", CodePoints: []int{91}, Characters: []byte{0x5b}}, + "lsquo": {Name: "lsquo", CodePoints: []int{8216}, Characters: []byte{0xe2, 0x80, 0x98}}, + "lsquor": {Name: "lsquor", CodePoints: []int{8218}, Characters: []byte{0xe2, 0x80, 0x9a}}, + "lstrok": {Name: "lstrok", CodePoints: []int{322}, Characters: []byte{0xc5, 0x82}}, + "lt": {Name: "lt", CodePoints: []int{60}, Characters: []byte{0x3c}}, + "ltcc": {Name: "ltcc", CodePoints: []int{10918}, Characters: []byte{0xe2, 0xaa, 0xa6}}, + "ltcir": {Name: "ltcir", CodePoints: []int{10873}, Characters: []byte{0xe2, 0xa9, 0xb9}}, + "ltdot": {Name: "ltdot", CodePoints: []int{8918}, Characters: []byte{0xe2, 0x8b, 0x96}}, + "lthree": {Name: "lthree", CodePoints: []int{8907}, Characters: []byte{0xe2, 0x8b, 0x8b}}, + "ltimes": {Name: "ltimes", CodePoints: []int{8905}, Characters: []byte{0xe2, 0x8b, 0x89}}, + "ltlarr": {Name: "ltlarr", CodePoints: []int{10614}, Characters: []byte{0xe2, 0xa5, 0xb6}}, + "ltquest": {Name: "ltquest", CodePoints: []int{10875}, Characters: []byte{0xe2, 0xa9, 0xbb}}, + "ltrPar": {Name: "ltrPar", CodePoints: []int{10646}, Characters: []byte{0xe2, 0xa6, 0x96}}, + "ltri": {Name: "ltri", CodePoints: []int{9667}, Characters: []byte{0xe2, 0x97, 0x83}}, + "ltrie": {Name: "ltrie", CodePoints: []int{8884}, Characters: []byte{0xe2, 0x8a, 0xb4}}, + "ltrif": {Name: "ltrif", CodePoints: []int{9666}, Characters: []byte{0xe2, 0x97, 0x82}}, + "lurdshar": {Name: "lurdshar", CodePoints: []int{10570}, Characters: []byte{0xe2, 0xa5, 0x8a}}, + "luruhar": {Name: "luruhar", CodePoints: []int{10598}, Characters: []byte{0xe2, 0xa5, 0xa6}}, + "lvertneqq": {Name: "lvertneqq", CodePoints: []int{8808, 65024}, Characters: []byte{0xe2, 0x89, 0xa8, 0xef, 0xb8, 0x80}}, + "lvnE": {Name: "lvnE", CodePoints: []int{8808, 65024}, Characters: []byte{0xe2, 0x89, 0xa8, 0xef, 0xb8, 0x80}}, + "mDDot": {Name: "mDDot", CodePoints: []int{8762}, Characters: []byte{0xe2, 0x88, 0xba}}, + "macr": {Name: "macr", CodePoints: []int{175}, Characters: []byte{0xc2, 0xaf}}, + "male": {Name: "male", CodePoints: []int{9794}, Characters: []byte{0xe2, 0x99, 0x82}}, + "malt": {Name: "malt", CodePoints: []int{10016}, Characters: []byte{0xe2, 0x9c, 0xa0}}, + "maltese": {Name: "maltese", CodePoints: []int{10016}, Characters: []byte{0xe2, 0x9c, 0xa0}}, + "map": {Name: "map", CodePoints: []int{8614}, Characters: []byte{0xe2, 0x86, 0xa6}}, + "mapsto": {Name: "mapsto", CodePoints: []int{8614}, Characters: []byte{0xe2, 0x86, 0xa6}}, + "mapstodown": {Name: "mapstodown", CodePoints: []int{8615}, Characters: []byte{0xe2, 0x86, 0xa7}}, + "mapstoleft": {Name: "mapstoleft", CodePoints: []int{8612}, Characters: []byte{0xe2, 0x86, 0xa4}}, + "mapstoup": {Name: "mapstoup", CodePoints: []int{8613}, Characters: []byte{0xe2, 0x86, 0xa5}}, + "marker": {Name: "marker", CodePoints: []int{9646}, Characters: []byte{0xe2, 0x96, 0xae}}, + "mcomma": {Name: "mcomma", CodePoints: []int{10793}, Characters: []byte{0xe2, 0xa8, 0xa9}}, + "mcy": {Name: "mcy", CodePoints: []int{1084}, Characters: []byte{0xd0, 0xbc}}, + "mdash": {Name: "mdash", CodePoints: []int{8212}, Characters: []byte{0xe2, 0x80, 0x94}}, + "measuredangle": {Name: "measuredangle", CodePoints: []int{8737}, Characters: []byte{0xe2, 0x88, 0xa1}}, + "mfr": {Name: "mfr", CodePoints: []int{120106}, Characters: []byte{0xf0, 0x9d, 0x94, 0xaa}}, + "mho": {Name: "mho", CodePoints: []int{8487}, Characters: []byte{0xe2, 0x84, 0xa7}}, + "micro": {Name: "micro", CodePoints: []int{181}, Characters: []byte{0xc2, 0xb5}}, + "mid": {Name: "mid", CodePoints: []int{8739}, Characters: []byte{0xe2, 0x88, 0xa3}}, + "midast": {Name: "midast", CodePoints: []int{42}, Characters: []byte{0x2a}}, + "midcir": {Name: "midcir", CodePoints: []int{10992}, Characters: []byte{0xe2, 0xab, 0xb0}}, + "middot": {Name: "middot", CodePoints: []int{183}, Characters: []byte{0xc2, 0xb7}}, + "minus": {Name: "minus", CodePoints: []int{8722}, Characters: []byte{0xe2, 0x88, 0x92}}, + "minusb": {Name: "minusb", CodePoints: []int{8863}, Characters: []byte{0xe2, 0x8a, 0x9f}}, + "minusd": {Name: "minusd", CodePoints: []int{8760}, Characters: []byte{0xe2, 0x88, 0xb8}}, + "minusdu": {Name: "minusdu", CodePoints: []int{10794}, Characters: []byte{0xe2, 0xa8, 0xaa}}, + "mlcp": {Name: "mlcp", CodePoints: []int{10971}, Characters: []byte{0xe2, 0xab, 0x9b}}, + "mldr": {Name: "mldr", CodePoints: []int{8230}, Characters: []byte{0xe2, 0x80, 0xa6}}, + "mnplus": {Name: "mnplus", CodePoints: []int{8723}, Characters: []byte{0xe2, 0x88, 0x93}}, + "models": {Name: "models", CodePoints: []int{8871}, Characters: []byte{0xe2, 0x8a, 0xa7}}, + "mopf": {Name: "mopf", CodePoints: []int{120158}, Characters: []byte{0xf0, 0x9d, 0x95, 0x9e}}, + "mp": {Name: "mp", CodePoints: []int{8723}, Characters: []byte{0xe2, 0x88, 0x93}}, + "mscr": {Name: "mscr", CodePoints: []int{120002}, Characters: []byte{0xf0, 0x9d, 0x93, 0x82}}, + "mstpos": {Name: "mstpos", CodePoints: []int{8766}, Characters: []byte{0xe2, 0x88, 0xbe}}, + "mu": {Name: "mu", CodePoints: []int{956}, Characters: []byte{0xce, 0xbc}}, + "multimap": {Name: "multimap", CodePoints: []int{8888}, Characters: []byte{0xe2, 0x8a, 0xb8}}, + "mumap": {Name: "mumap", CodePoints: []int{8888}, Characters: []byte{0xe2, 0x8a, 0xb8}}, + "nGg": {Name: "nGg", CodePoints: []int{8921, 824}, Characters: []byte{0xe2, 0x8b, 0x99, 0xcc, 0xb8}}, + "nGt": {Name: "nGt", CodePoints: []int{8811, 8402}, Characters: []byte{0xe2, 0x89, 0xab, 0xe2, 0x83, 0x92}}, + "nGtv": {Name: "nGtv", CodePoints: []int{8811, 824}, Characters: []byte{0xe2, 0x89, 0xab, 0xcc, 0xb8}}, + "nLeftarrow": {Name: "nLeftarrow", CodePoints: []int{8653}, Characters: []byte{0xe2, 0x87, 0x8d}}, + "nLeftrightarrow": {Name: "nLeftrightarrow", CodePoints: []int{8654}, Characters: []byte{0xe2, 0x87, 0x8e}}, + "nLl": {Name: "nLl", CodePoints: []int{8920, 824}, Characters: []byte{0xe2, 0x8b, 0x98, 0xcc, 0xb8}}, + "nLt": {Name: "nLt", CodePoints: []int{8810, 8402}, Characters: []byte{0xe2, 0x89, 0xaa, 0xe2, 0x83, 0x92}}, + "nLtv": {Name: "nLtv", CodePoints: []int{8810, 824}, Characters: []byte{0xe2, 0x89, 0xaa, 0xcc, 0xb8}}, + "nRightarrow": {Name: "nRightarrow", CodePoints: []int{8655}, Characters: []byte{0xe2, 0x87, 0x8f}}, + "nVDash": {Name: "nVDash", CodePoints: []int{8879}, Characters: []byte{0xe2, 0x8a, 0xaf}}, + "nVdash": {Name: "nVdash", CodePoints: []int{8878}, Characters: []byte{0xe2, 0x8a, 0xae}}, + "nabla": {Name: "nabla", CodePoints: []int{8711}, Characters: []byte{0xe2, 0x88, 0x87}}, + "nacute": {Name: "nacute", CodePoints: []int{324}, Characters: []byte{0xc5, 0x84}}, + "nang": {Name: "nang", CodePoints: []int{8736, 8402}, Characters: []byte{0xe2, 0x88, 0xa0, 0xe2, 0x83, 0x92}}, + "nap": {Name: "nap", CodePoints: []int{8777}, Characters: []byte{0xe2, 0x89, 0x89}}, + "napE": {Name: "napE", CodePoints: []int{10864, 824}, Characters: []byte{0xe2, 0xa9, 0xb0, 0xcc, 0xb8}}, + "napid": {Name: "napid", CodePoints: []int{8779, 824}, Characters: []byte{0xe2, 0x89, 0x8b, 0xcc, 0xb8}}, + "napos": {Name: "napos", CodePoints: []int{329}, Characters: []byte{0xc5, 0x89}}, + "napprox": {Name: "napprox", CodePoints: []int{8777}, Characters: []byte{0xe2, 0x89, 0x89}}, + "natur": {Name: "natur", CodePoints: []int{9838}, Characters: []byte{0xe2, 0x99, 0xae}}, + "natural": {Name: "natural", CodePoints: []int{9838}, Characters: []byte{0xe2, 0x99, 0xae}}, + "naturals": {Name: "naturals", CodePoints: []int{8469}, Characters: []byte{0xe2, 0x84, 0x95}}, + "nbsp": {Name: "nbsp", CodePoints: []int{160}, Characters: []byte{0xc2, 0xa0}}, + "nbump": {Name: "nbump", CodePoints: []int{8782, 824}, Characters: []byte{0xe2, 0x89, 0x8e, 0xcc, 0xb8}}, + "nbumpe": {Name: "nbumpe", CodePoints: []int{8783, 824}, Characters: []byte{0xe2, 0x89, 0x8f, 0xcc, 0xb8}}, + "ncap": {Name: "ncap", CodePoints: []int{10819}, Characters: []byte{0xe2, 0xa9, 0x83}}, + "ncaron": {Name: "ncaron", CodePoints: []int{328}, Characters: []byte{0xc5, 0x88}}, + "ncedil": {Name: "ncedil", CodePoints: []int{326}, Characters: []byte{0xc5, 0x86}}, + "ncong": {Name: "ncong", CodePoints: []int{8775}, Characters: []byte{0xe2, 0x89, 0x87}}, + "ncongdot": {Name: "ncongdot", CodePoints: []int{10861, 824}, Characters: []byte{0xe2, 0xa9, 0xad, 0xcc, 0xb8}}, + "ncup": {Name: "ncup", CodePoints: []int{10818}, Characters: []byte{0xe2, 0xa9, 0x82}}, + "ncy": {Name: "ncy", CodePoints: []int{1085}, Characters: []byte{0xd0, 0xbd}}, + "ndash": {Name: "ndash", CodePoints: []int{8211}, Characters: []byte{0xe2, 0x80, 0x93}}, + "ne": {Name: "ne", CodePoints: []int{8800}, Characters: []byte{0xe2, 0x89, 0xa0}}, + "neArr": {Name: "neArr", CodePoints: []int{8663}, Characters: []byte{0xe2, 0x87, 0x97}}, + "nearhk": {Name: "nearhk", CodePoints: []int{10532}, Characters: []byte{0xe2, 0xa4, 0xa4}}, + "nearr": {Name: "nearr", CodePoints: []int{8599}, Characters: []byte{0xe2, 0x86, 0x97}}, + "nearrow": {Name: "nearrow", CodePoints: []int{8599}, Characters: []byte{0xe2, 0x86, 0x97}}, + "nedot": {Name: "nedot", CodePoints: []int{8784, 824}, Characters: []byte{0xe2, 0x89, 0x90, 0xcc, 0xb8}}, + "nequiv": {Name: "nequiv", CodePoints: []int{8802}, Characters: []byte{0xe2, 0x89, 0xa2}}, + "nesear": {Name: "nesear", CodePoints: []int{10536}, Characters: []byte{0xe2, 0xa4, 0xa8}}, + "nesim": {Name: "nesim", CodePoints: []int{8770, 824}, Characters: []byte{0xe2, 0x89, 0x82, 0xcc, 0xb8}}, + "nexist": {Name: "nexist", CodePoints: []int{8708}, Characters: []byte{0xe2, 0x88, 0x84}}, + "nexists": {Name: "nexists", CodePoints: []int{8708}, Characters: []byte{0xe2, 0x88, 0x84}}, + "nfr": {Name: "nfr", CodePoints: []int{120107}, Characters: []byte{0xf0, 0x9d, 0x94, 0xab}}, + "ngE": {Name: "ngE", CodePoints: []int{8807, 824}, Characters: []byte{0xe2, 0x89, 0xa7, 0xcc, 0xb8}}, + "nge": {Name: "nge", CodePoints: []int{8817}, Characters: []byte{0xe2, 0x89, 0xb1}}, + "ngeq": {Name: "ngeq", CodePoints: []int{8817}, Characters: []byte{0xe2, 0x89, 0xb1}}, + "ngeqq": {Name: "ngeqq", CodePoints: []int{8807, 824}, Characters: []byte{0xe2, 0x89, 0xa7, 0xcc, 0xb8}}, + "ngeqslant": {Name: "ngeqslant", CodePoints: []int{10878, 824}, Characters: []byte{0xe2, 0xa9, 0xbe, 0xcc, 0xb8}}, + "nges": {Name: "nges", CodePoints: []int{10878, 824}, Characters: []byte{0xe2, 0xa9, 0xbe, 0xcc, 0xb8}}, + "ngsim": {Name: "ngsim", CodePoints: []int{8821}, Characters: []byte{0xe2, 0x89, 0xb5}}, + "ngt": {Name: "ngt", CodePoints: []int{8815}, Characters: []byte{0xe2, 0x89, 0xaf}}, + "ngtr": {Name: "ngtr", CodePoints: []int{8815}, Characters: []byte{0xe2, 0x89, 0xaf}}, + "nhArr": {Name: "nhArr", CodePoints: []int{8654}, Characters: []byte{0xe2, 0x87, 0x8e}}, + "nharr": {Name: "nharr", CodePoints: []int{8622}, Characters: []byte{0xe2, 0x86, 0xae}}, + "nhpar": {Name: "nhpar", CodePoints: []int{10994}, Characters: []byte{0xe2, 0xab, 0xb2}}, + "ni": {Name: "ni", CodePoints: []int{8715}, Characters: []byte{0xe2, 0x88, 0x8b}}, + "nis": {Name: "nis", CodePoints: []int{8956}, Characters: []byte{0xe2, 0x8b, 0xbc}}, + "nisd": {Name: "nisd", CodePoints: []int{8954}, Characters: []byte{0xe2, 0x8b, 0xba}}, + "niv": {Name: "niv", CodePoints: []int{8715}, Characters: []byte{0xe2, 0x88, 0x8b}}, + "njcy": {Name: "njcy", CodePoints: []int{1114}, Characters: []byte{0xd1, 0x9a}}, + "nlArr": {Name: "nlArr", CodePoints: []int{8653}, Characters: []byte{0xe2, 0x87, 0x8d}}, + "nlE": {Name: "nlE", CodePoints: []int{8806, 824}, Characters: []byte{0xe2, 0x89, 0xa6, 0xcc, 0xb8}}, + "nlarr": {Name: "nlarr", CodePoints: []int{8602}, Characters: []byte{0xe2, 0x86, 0x9a}}, + "nldr": {Name: "nldr", CodePoints: []int{8229}, Characters: []byte{0xe2, 0x80, 0xa5}}, + "nle": {Name: "nle", CodePoints: []int{8816}, Characters: []byte{0xe2, 0x89, 0xb0}}, + "nleftarrow": {Name: "nleftarrow", CodePoints: []int{8602}, Characters: []byte{0xe2, 0x86, 0x9a}}, + "nleftrightarrow": {Name: "nleftrightarrow", CodePoints: []int{8622}, Characters: []byte{0xe2, 0x86, 0xae}}, + "nleq": {Name: "nleq", CodePoints: []int{8816}, Characters: []byte{0xe2, 0x89, 0xb0}}, + "nleqq": {Name: "nleqq", CodePoints: []int{8806, 824}, Characters: []byte{0xe2, 0x89, 0xa6, 0xcc, 0xb8}}, + "nleqslant": {Name: "nleqslant", CodePoints: []int{10877, 824}, Characters: []byte{0xe2, 0xa9, 0xbd, 0xcc, 0xb8}}, + "nles": {Name: "nles", CodePoints: []int{10877, 824}, Characters: []byte{0xe2, 0xa9, 0xbd, 0xcc, 0xb8}}, + "nless": {Name: "nless", CodePoints: []int{8814}, Characters: []byte{0xe2, 0x89, 0xae}}, + "nlsim": {Name: "nlsim", CodePoints: []int{8820}, Characters: []byte{0xe2, 0x89, 0xb4}}, + "nlt": {Name: "nlt", CodePoints: []int{8814}, Characters: []byte{0xe2, 0x89, 0xae}}, + "nltri": {Name: "nltri", CodePoints: []int{8938}, Characters: []byte{0xe2, 0x8b, 0xaa}}, + "nltrie": {Name: "nltrie", CodePoints: []int{8940}, Characters: []byte{0xe2, 0x8b, 0xac}}, + "nmid": {Name: "nmid", CodePoints: []int{8740}, Characters: []byte{0xe2, 0x88, 0xa4}}, + "nopf": {Name: "nopf", CodePoints: []int{120159}, Characters: []byte{0xf0, 0x9d, 0x95, 0x9f}}, + "not": {Name: "not", CodePoints: []int{172}, Characters: []byte{0xc2, 0xac}}, + "notin": {Name: "notin", CodePoints: []int{8713}, Characters: []byte{0xe2, 0x88, 0x89}}, + "notinE": {Name: "notinE", CodePoints: []int{8953, 824}, Characters: []byte{0xe2, 0x8b, 0xb9, 0xcc, 0xb8}}, + "notindot": {Name: "notindot", CodePoints: []int{8949, 824}, Characters: []byte{0xe2, 0x8b, 0xb5, 0xcc, 0xb8}}, + "notinva": {Name: "notinva", CodePoints: []int{8713}, Characters: []byte{0xe2, 0x88, 0x89}}, + "notinvb": {Name: "notinvb", CodePoints: []int{8951}, Characters: []byte{0xe2, 0x8b, 0xb7}}, + "notinvc": {Name: "notinvc", CodePoints: []int{8950}, Characters: []byte{0xe2, 0x8b, 0xb6}}, + "notni": {Name: "notni", CodePoints: []int{8716}, Characters: []byte{0xe2, 0x88, 0x8c}}, + "notniva": {Name: "notniva", CodePoints: []int{8716}, Characters: []byte{0xe2, 0x88, 0x8c}}, + "notnivb": {Name: "notnivb", CodePoints: []int{8958}, Characters: []byte{0xe2, 0x8b, 0xbe}}, + "notnivc": {Name: "notnivc", CodePoints: []int{8957}, Characters: []byte{0xe2, 0x8b, 0xbd}}, + "npar": {Name: "npar", CodePoints: []int{8742}, Characters: []byte{0xe2, 0x88, 0xa6}}, + "nparallel": {Name: "nparallel", CodePoints: []int{8742}, Characters: []byte{0xe2, 0x88, 0xa6}}, + "nparsl": {Name: "nparsl", CodePoints: []int{11005, 8421}, Characters: []byte{0xe2, 0xab, 0xbd, 0xe2, 0x83, 0xa5}}, + "npart": {Name: "npart", CodePoints: []int{8706, 824}, Characters: []byte{0xe2, 0x88, 0x82, 0xcc, 0xb8}}, + "npolint": {Name: "npolint", CodePoints: []int{10772}, Characters: []byte{0xe2, 0xa8, 0x94}}, + "npr": {Name: "npr", CodePoints: []int{8832}, Characters: []byte{0xe2, 0x8a, 0x80}}, + "nprcue": {Name: "nprcue", CodePoints: []int{8928}, Characters: []byte{0xe2, 0x8b, 0xa0}}, + "npre": {Name: "npre", CodePoints: []int{10927, 824}, Characters: []byte{0xe2, 0xaa, 0xaf, 0xcc, 0xb8}}, + "nprec": {Name: "nprec", CodePoints: []int{8832}, Characters: []byte{0xe2, 0x8a, 0x80}}, + "npreceq": {Name: "npreceq", CodePoints: []int{10927, 824}, Characters: []byte{0xe2, 0xaa, 0xaf, 0xcc, 0xb8}}, + "nrArr": {Name: "nrArr", CodePoints: []int{8655}, Characters: []byte{0xe2, 0x87, 0x8f}}, + "nrarr": {Name: "nrarr", CodePoints: []int{8603}, Characters: []byte{0xe2, 0x86, 0x9b}}, + "nrarrc": {Name: "nrarrc", CodePoints: []int{10547, 824}, Characters: []byte{0xe2, 0xa4, 0xb3, 0xcc, 0xb8}}, + "nrarrw": {Name: "nrarrw", CodePoints: []int{8605, 824}, Characters: []byte{0xe2, 0x86, 0x9d, 0xcc, 0xb8}}, + "nrightarrow": {Name: "nrightarrow", CodePoints: []int{8603}, Characters: []byte{0xe2, 0x86, 0x9b}}, + "nrtri": {Name: "nrtri", CodePoints: []int{8939}, Characters: []byte{0xe2, 0x8b, 0xab}}, + "nrtrie": {Name: "nrtrie", CodePoints: []int{8941}, Characters: []byte{0xe2, 0x8b, 0xad}}, + "nsc": {Name: "nsc", CodePoints: []int{8833}, Characters: []byte{0xe2, 0x8a, 0x81}}, + "nsccue": {Name: "nsccue", CodePoints: []int{8929}, Characters: []byte{0xe2, 0x8b, 0xa1}}, + "nsce": {Name: "nsce", CodePoints: []int{10928, 824}, Characters: []byte{0xe2, 0xaa, 0xb0, 0xcc, 0xb8}}, + "nscr": {Name: "nscr", CodePoints: []int{120003}, Characters: []byte{0xf0, 0x9d, 0x93, 0x83}}, + "nshortmid": {Name: "nshortmid", CodePoints: []int{8740}, Characters: []byte{0xe2, 0x88, 0xa4}}, + "nshortparallel": {Name: "nshortparallel", CodePoints: []int{8742}, Characters: []byte{0xe2, 0x88, 0xa6}}, + "nsim": {Name: "nsim", CodePoints: []int{8769}, Characters: []byte{0xe2, 0x89, 0x81}}, + "nsime": {Name: "nsime", CodePoints: []int{8772}, Characters: []byte{0xe2, 0x89, 0x84}}, + "nsimeq": {Name: "nsimeq", CodePoints: []int{8772}, Characters: []byte{0xe2, 0x89, 0x84}}, + "nsmid": {Name: "nsmid", CodePoints: []int{8740}, Characters: []byte{0xe2, 0x88, 0xa4}}, + "nspar": {Name: "nspar", CodePoints: []int{8742}, Characters: []byte{0xe2, 0x88, 0xa6}}, + "nsqsube": {Name: "nsqsube", CodePoints: []int{8930}, Characters: []byte{0xe2, 0x8b, 0xa2}}, + "nsqsupe": {Name: "nsqsupe", CodePoints: []int{8931}, Characters: []byte{0xe2, 0x8b, 0xa3}}, + "nsub": {Name: "nsub", CodePoints: []int{8836}, Characters: []byte{0xe2, 0x8a, 0x84}}, + "nsubE": {Name: "nsubE", CodePoints: []int{10949, 824}, Characters: []byte{0xe2, 0xab, 0x85, 0xcc, 0xb8}}, + "nsube": {Name: "nsube", CodePoints: []int{8840}, Characters: []byte{0xe2, 0x8a, 0x88}}, + "nsubset": {Name: "nsubset", CodePoints: []int{8834, 8402}, Characters: []byte{0xe2, 0x8a, 0x82, 0xe2, 0x83, 0x92}}, + "nsubseteq": {Name: "nsubseteq", CodePoints: []int{8840}, Characters: []byte{0xe2, 0x8a, 0x88}}, + "nsubseteqq": {Name: "nsubseteqq", CodePoints: []int{10949, 824}, Characters: []byte{0xe2, 0xab, 0x85, 0xcc, 0xb8}}, + "nsucc": {Name: "nsucc", CodePoints: []int{8833}, Characters: []byte{0xe2, 0x8a, 0x81}}, + "nsucceq": {Name: "nsucceq", CodePoints: []int{10928, 824}, Characters: []byte{0xe2, 0xaa, 0xb0, 0xcc, 0xb8}}, + "nsup": {Name: "nsup", CodePoints: []int{8837}, Characters: []byte{0xe2, 0x8a, 0x85}}, + "nsupE": {Name: "nsupE", CodePoints: []int{10950, 824}, Characters: []byte{0xe2, 0xab, 0x86, 0xcc, 0xb8}}, + "nsupe": {Name: "nsupe", CodePoints: []int{8841}, Characters: []byte{0xe2, 0x8a, 0x89}}, + "nsupset": {Name: "nsupset", CodePoints: []int{8835, 8402}, Characters: []byte{0xe2, 0x8a, 0x83, 0xe2, 0x83, 0x92}}, + "nsupseteq": {Name: "nsupseteq", CodePoints: []int{8841}, Characters: []byte{0xe2, 0x8a, 0x89}}, + "nsupseteqq": {Name: "nsupseteqq", CodePoints: []int{10950, 824}, Characters: []byte{0xe2, 0xab, 0x86, 0xcc, 0xb8}}, + "ntgl": {Name: "ntgl", CodePoints: []int{8825}, Characters: []byte{0xe2, 0x89, 0xb9}}, + "ntilde": {Name: "ntilde", CodePoints: []int{241}, Characters: []byte{0xc3, 0xb1}}, + "ntlg": {Name: "ntlg", CodePoints: []int{8824}, Characters: []byte{0xe2, 0x89, 0xb8}}, + "ntriangleleft": {Name: "ntriangleleft", CodePoints: []int{8938}, Characters: []byte{0xe2, 0x8b, 0xaa}}, + "ntrianglelefteq": {Name: "ntrianglelefteq", CodePoints: []int{8940}, Characters: []byte{0xe2, 0x8b, 0xac}}, + "ntriangleright": {Name: "ntriangleright", CodePoints: []int{8939}, Characters: []byte{0xe2, 0x8b, 0xab}}, + "ntrianglerighteq": {Name: "ntrianglerighteq", CodePoints: []int{8941}, Characters: []byte{0xe2, 0x8b, 0xad}}, + "nu": {Name: "nu", CodePoints: []int{957}, Characters: []byte{0xce, 0xbd}}, + "num": {Name: "num", CodePoints: []int{35}, Characters: []byte{0x23}}, + "numero": {Name: "numero", CodePoints: []int{8470}, Characters: []byte{0xe2, 0x84, 0x96}}, + "numsp": {Name: "numsp", CodePoints: []int{8199}, Characters: []byte{0xe2, 0x80, 0x87}}, + "nvDash": {Name: "nvDash", CodePoints: []int{8877}, Characters: []byte{0xe2, 0x8a, 0xad}}, + "nvHarr": {Name: "nvHarr", CodePoints: []int{10500}, Characters: []byte{0xe2, 0xa4, 0x84}}, + "nvap": {Name: "nvap", CodePoints: []int{8781, 8402}, Characters: []byte{0xe2, 0x89, 0x8d, 0xe2, 0x83, 0x92}}, + "nvdash": {Name: "nvdash", CodePoints: []int{8876}, Characters: []byte{0xe2, 0x8a, 0xac}}, + "nvge": {Name: "nvge", CodePoints: []int{8805, 8402}, Characters: []byte{0xe2, 0x89, 0xa5, 0xe2, 0x83, 0x92}}, + "nvgt": {Name: "nvgt", CodePoints: []int{62, 8402}, Characters: []byte{0x3e, 0xe2, 0x83, 0x92}}, + "nvinfin": {Name: "nvinfin", CodePoints: []int{10718}, Characters: []byte{0xe2, 0xa7, 0x9e}}, + "nvlArr": {Name: "nvlArr", CodePoints: []int{10498}, Characters: []byte{0xe2, 0xa4, 0x82}}, + "nvle": {Name: "nvle", CodePoints: []int{8804, 8402}, Characters: []byte{0xe2, 0x89, 0xa4, 0xe2, 0x83, 0x92}}, + "nvlt": {Name: "nvlt", CodePoints: []int{60, 8402}, Characters: []byte{0x3c, 0xe2, 0x83, 0x92}}, + "nvltrie": {Name: "nvltrie", CodePoints: []int{8884, 8402}, Characters: []byte{0xe2, 0x8a, 0xb4, 0xe2, 0x83, 0x92}}, + "nvrArr": {Name: "nvrArr", CodePoints: []int{10499}, Characters: []byte{0xe2, 0xa4, 0x83}}, + "nvrtrie": {Name: "nvrtrie", CodePoints: []int{8885, 8402}, Characters: []byte{0xe2, 0x8a, 0xb5, 0xe2, 0x83, 0x92}}, + "nvsim": {Name: "nvsim", CodePoints: []int{8764, 8402}, Characters: []byte{0xe2, 0x88, 0xbc, 0xe2, 0x83, 0x92}}, + "nwArr": {Name: "nwArr", CodePoints: []int{8662}, Characters: []byte{0xe2, 0x87, 0x96}}, + "nwarhk": {Name: "nwarhk", CodePoints: []int{10531}, Characters: []byte{0xe2, 0xa4, 0xa3}}, + "nwarr": {Name: "nwarr", CodePoints: []int{8598}, Characters: []byte{0xe2, 0x86, 0x96}}, + "nwarrow": {Name: "nwarrow", CodePoints: []int{8598}, Characters: []byte{0xe2, 0x86, 0x96}}, + "nwnear": {Name: "nwnear", CodePoints: []int{10535}, Characters: []byte{0xe2, 0xa4, 0xa7}}, + "oS": {Name: "oS", CodePoints: []int{9416}, Characters: []byte{0xe2, 0x93, 0x88}}, + "oacute": {Name: "oacute", CodePoints: []int{243}, Characters: []byte{0xc3, 0xb3}}, + "oast": {Name: "oast", CodePoints: []int{8859}, Characters: []byte{0xe2, 0x8a, 0x9b}}, + "ocir": {Name: "ocir", CodePoints: []int{8858}, Characters: []byte{0xe2, 0x8a, 0x9a}}, + "ocirc": {Name: "ocirc", CodePoints: []int{244}, Characters: []byte{0xc3, 0xb4}}, + "ocy": {Name: "ocy", CodePoints: []int{1086}, Characters: []byte{0xd0, 0xbe}}, + "odash": {Name: "odash", CodePoints: []int{8861}, Characters: []byte{0xe2, 0x8a, 0x9d}}, + "odblac": {Name: "odblac", CodePoints: []int{337}, Characters: []byte{0xc5, 0x91}}, + "odiv": {Name: "odiv", CodePoints: []int{10808}, Characters: []byte{0xe2, 0xa8, 0xb8}}, + "odot": {Name: "odot", CodePoints: []int{8857}, Characters: []byte{0xe2, 0x8a, 0x99}}, + "odsold": {Name: "odsold", CodePoints: []int{10684}, Characters: []byte{0xe2, 0xa6, 0xbc}}, + "oelig": {Name: "oelig", CodePoints: []int{339}, Characters: []byte{0xc5, 0x93}}, + "ofcir": {Name: "ofcir", CodePoints: []int{10687}, Characters: []byte{0xe2, 0xa6, 0xbf}}, + "ofr": {Name: "ofr", CodePoints: []int{120108}, Characters: []byte{0xf0, 0x9d, 0x94, 0xac}}, + "ogon": {Name: "ogon", CodePoints: []int{731}, Characters: []byte{0xcb, 0x9b}}, + "ograve": {Name: "ograve", CodePoints: []int{242}, Characters: []byte{0xc3, 0xb2}}, + "ogt": {Name: "ogt", CodePoints: []int{10689}, Characters: []byte{0xe2, 0xa7, 0x81}}, + "ohbar": {Name: "ohbar", CodePoints: []int{10677}, Characters: []byte{0xe2, 0xa6, 0xb5}}, + "ohm": {Name: "ohm", CodePoints: []int{937}, Characters: []byte{0xce, 0xa9}}, + "oint": {Name: "oint", CodePoints: []int{8750}, Characters: []byte{0xe2, 0x88, 0xae}}, + "olarr": {Name: "olarr", CodePoints: []int{8634}, Characters: []byte{0xe2, 0x86, 0xba}}, + "olcir": {Name: "olcir", CodePoints: []int{10686}, Characters: []byte{0xe2, 0xa6, 0xbe}}, + "olcross": {Name: "olcross", CodePoints: []int{10683}, Characters: []byte{0xe2, 0xa6, 0xbb}}, + "oline": {Name: "oline", CodePoints: []int{8254}, Characters: []byte{0xe2, 0x80, 0xbe}}, + "olt": {Name: "olt", CodePoints: []int{10688}, Characters: []byte{0xe2, 0xa7, 0x80}}, + "omacr": {Name: "omacr", CodePoints: []int{333}, Characters: []byte{0xc5, 0x8d}}, + "omega": {Name: "omega", CodePoints: []int{969}, Characters: []byte{0xcf, 0x89}}, + "omicron": {Name: "omicron", CodePoints: []int{959}, Characters: []byte{0xce, 0xbf}}, + "omid": {Name: "omid", CodePoints: []int{10678}, Characters: []byte{0xe2, 0xa6, 0xb6}}, + "ominus": {Name: "ominus", CodePoints: []int{8854}, Characters: []byte{0xe2, 0x8a, 0x96}}, + "oopf": {Name: "oopf", CodePoints: []int{120160}, Characters: []byte{0xf0, 0x9d, 0x95, 0xa0}}, + "opar": {Name: "opar", CodePoints: []int{10679}, Characters: []byte{0xe2, 0xa6, 0xb7}}, + "operp": {Name: "operp", CodePoints: []int{10681}, Characters: []byte{0xe2, 0xa6, 0xb9}}, + "oplus": {Name: "oplus", CodePoints: []int{8853}, Characters: []byte{0xe2, 0x8a, 0x95}}, + "or": {Name: "or", CodePoints: []int{8744}, Characters: []byte{0xe2, 0x88, 0xa8}}, + "orarr": {Name: "orarr", CodePoints: []int{8635}, Characters: []byte{0xe2, 0x86, 0xbb}}, + "ord": {Name: "ord", CodePoints: []int{10845}, Characters: []byte{0xe2, 0xa9, 0x9d}}, + "order": {Name: "order", CodePoints: []int{8500}, Characters: []byte{0xe2, 0x84, 0xb4}}, + "orderof": {Name: "orderof", CodePoints: []int{8500}, Characters: []byte{0xe2, 0x84, 0xb4}}, + "ordf": {Name: "ordf", CodePoints: []int{170}, Characters: []byte{0xc2, 0xaa}}, + "ordm": {Name: "ordm", CodePoints: []int{186}, Characters: []byte{0xc2, 0xba}}, + "origof": {Name: "origof", CodePoints: []int{8886}, Characters: []byte{0xe2, 0x8a, 0xb6}}, + "oror": {Name: "oror", CodePoints: []int{10838}, Characters: []byte{0xe2, 0xa9, 0x96}}, + "orslope": {Name: "orslope", CodePoints: []int{10839}, Characters: []byte{0xe2, 0xa9, 0x97}}, + "orv": {Name: "orv", CodePoints: []int{10843}, Characters: []byte{0xe2, 0xa9, 0x9b}}, + "oscr": {Name: "oscr", CodePoints: []int{8500}, Characters: []byte{0xe2, 0x84, 0xb4}}, + "oslash": {Name: "oslash", CodePoints: []int{248}, Characters: []byte{0xc3, 0xb8}}, + "osol": {Name: "osol", CodePoints: []int{8856}, Characters: []byte{0xe2, 0x8a, 0x98}}, + "otilde": {Name: "otilde", CodePoints: []int{245}, Characters: []byte{0xc3, 0xb5}}, + "otimes": {Name: "otimes", CodePoints: []int{8855}, Characters: []byte{0xe2, 0x8a, 0x97}}, + "otimesas": {Name: "otimesas", CodePoints: []int{10806}, Characters: []byte{0xe2, 0xa8, 0xb6}}, + "ouml": {Name: "ouml", CodePoints: []int{246}, Characters: []byte{0xc3, 0xb6}}, + "ovbar": {Name: "ovbar", CodePoints: []int{9021}, Characters: []byte{0xe2, 0x8c, 0xbd}}, + "par": {Name: "par", CodePoints: []int{8741}, Characters: []byte{0xe2, 0x88, 0xa5}}, + "para": {Name: "para", CodePoints: []int{182}, Characters: []byte{0xc2, 0xb6}}, + "parallel": {Name: "parallel", CodePoints: []int{8741}, Characters: []byte{0xe2, 0x88, 0xa5}}, + "parsim": {Name: "parsim", CodePoints: []int{10995}, Characters: []byte{0xe2, 0xab, 0xb3}}, + "parsl": {Name: "parsl", CodePoints: []int{11005}, Characters: []byte{0xe2, 0xab, 0xbd}}, + "part": {Name: "part", CodePoints: []int{8706}, Characters: []byte{0xe2, 0x88, 0x82}}, + "pcy": {Name: "pcy", CodePoints: []int{1087}, Characters: []byte{0xd0, 0xbf}}, + "percnt": {Name: "percnt", CodePoints: []int{37}, Characters: []byte{0x25}}, + "period": {Name: "period", CodePoints: []int{46}, Characters: []byte{0x2e}}, + "permil": {Name: "permil", CodePoints: []int{8240}, Characters: []byte{0xe2, 0x80, 0xb0}}, + "perp": {Name: "perp", CodePoints: []int{8869}, Characters: []byte{0xe2, 0x8a, 0xa5}}, + "pertenk": {Name: "pertenk", CodePoints: []int{8241}, Characters: []byte{0xe2, 0x80, 0xb1}}, + "pfr": {Name: "pfr", CodePoints: []int{120109}, Characters: []byte{0xf0, 0x9d, 0x94, 0xad}}, + "phi": {Name: "phi", CodePoints: []int{966}, Characters: []byte{0xcf, 0x86}}, + "phiv": {Name: "phiv", CodePoints: []int{981}, Characters: []byte{0xcf, 0x95}}, + "phmmat": {Name: "phmmat", CodePoints: []int{8499}, Characters: []byte{0xe2, 0x84, 0xb3}}, + "phone": {Name: "phone", CodePoints: []int{9742}, Characters: []byte{0xe2, 0x98, 0x8e}}, + "pi": {Name: "pi", CodePoints: []int{960}, Characters: []byte{0xcf, 0x80}}, + "pitchfork": {Name: "pitchfork", CodePoints: []int{8916}, Characters: []byte{0xe2, 0x8b, 0x94}}, + "piv": {Name: "piv", CodePoints: []int{982}, Characters: []byte{0xcf, 0x96}}, + "planck": {Name: "planck", CodePoints: []int{8463}, Characters: []byte{0xe2, 0x84, 0x8f}}, + "planckh": {Name: "planckh", CodePoints: []int{8462}, Characters: []byte{0xe2, 0x84, 0x8e}}, + "plankv": {Name: "plankv", CodePoints: []int{8463}, Characters: []byte{0xe2, 0x84, 0x8f}}, + "plus": {Name: "plus", CodePoints: []int{43}, Characters: []byte{0x2b}}, + "plusacir": {Name: "plusacir", CodePoints: []int{10787}, Characters: []byte{0xe2, 0xa8, 0xa3}}, + "plusb": {Name: "plusb", CodePoints: []int{8862}, Characters: []byte{0xe2, 0x8a, 0x9e}}, + "pluscir": {Name: "pluscir", CodePoints: []int{10786}, Characters: []byte{0xe2, 0xa8, 0xa2}}, + "plusdo": {Name: "plusdo", CodePoints: []int{8724}, Characters: []byte{0xe2, 0x88, 0x94}}, + "plusdu": {Name: "plusdu", CodePoints: []int{10789}, Characters: []byte{0xe2, 0xa8, 0xa5}}, + "pluse": {Name: "pluse", CodePoints: []int{10866}, Characters: []byte{0xe2, 0xa9, 0xb2}}, + "plusmn": {Name: "plusmn", CodePoints: []int{177}, Characters: []byte{0xc2, 0xb1}}, + "plussim": {Name: "plussim", CodePoints: []int{10790}, Characters: []byte{0xe2, 0xa8, 0xa6}}, + "plustwo": {Name: "plustwo", CodePoints: []int{10791}, Characters: []byte{0xe2, 0xa8, 0xa7}}, + "pm": {Name: "pm", CodePoints: []int{177}, Characters: []byte{0xc2, 0xb1}}, + "pointint": {Name: "pointint", CodePoints: []int{10773}, Characters: []byte{0xe2, 0xa8, 0x95}}, + "popf": {Name: "popf", CodePoints: []int{120161}, Characters: []byte{0xf0, 0x9d, 0x95, 0xa1}}, + "pound": {Name: "pound", CodePoints: []int{163}, Characters: []byte{0xc2, 0xa3}}, + "pr": {Name: "pr", CodePoints: []int{8826}, Characters: []byte{0xe2, 0x89, 0xba}}, + "prE": {Name: "prE", CodePoints: []int{10931}, Characters: []byte{0xe2, 0xaa, 0xb3}}, + "prap": {Name: "prap", CodePoints: []int{10935}, Characters: []byte{0xe2, 0xaa, 0xb7}}, + "prcue": {Name: "prcue", CodePoints: []int{8828}, Characters: []byte{0xe2, 0x89, 0xbc}}, + "pre": {Name: "pre", CodePoints: []int{10927}, Characters: []byte{0xe2, 0xaa, 0xaf}}, + "prec": {Name: "prec", CodePoints: []int{8826}, Characters: []byte{0xe2, 0x89, 0xba}}, + "precapprox": {Name: "precapprox", CodePoints: []int{10935}, Characters: []byte{0xe2, 0xaa, 0xb7}}, + "preccurlyeq": {Name: "preccurlyeq", CodePoints: []int{8828}, Characters: []byte{0xe2, 0x89, 0xbc}}, + "preceq": {Name: "preceq", CodePoints: []int{10927}, Characters: []byte{0xe2, 0xaa, 0xaf}}, + "precnapprox": {Name: "precnapprox", CodePoints: []int{10937}, Characters: []byte{0xe2, 0xaa, 0xb9}}, + "precneqq": {Name: "precneqq", CodePoints: []int{10933}, Characters: []byte{0xe2, 0xaa, 0xb5}}, + "precnsim": {Name: "precnsim", CodePoints: []int{8936}, Characters: []byte{0xe2, 0x8b, 0xa8}}, + "precsim": {Name: "precsim", CodePoints: []int{8830}, Characters: []byte{0xe2, 0x89, 0xbe}}, + "prime": {Name: "prime", CodePoints: []int{8242}, Characters: []byte{0xe2, 0x80, 0xb2}}, + "primes": {Name: "primes", CodePoints: []int{8473}, Characters: []byte{0xe2, 0x84, 0x99}}, + "prnE": {Name: "prnE", CodePoints: []int{10933}, Characters: []byte{0xe2, 0xaa, 0xb5}}, + "prnap": {Name: "prnap", CodePoints: []int{10937}, Characters: []byte{0xe2, 0xaa, 0xb9}}, + "prnsim": {Name: "prnsim", CodePoints: []int{8936}, Characters: []byte{0xe2, 0x8b, 0xa8}}, + "prod": {Name: "prod", CodePoints: []int{8719}, Characters: []byte{0xe2, 0x88, 0x8f}}, + "profalar": {Name: "profalar", CodePoints: []int{9006}, Characters: []byte{0xe2, 0x8c, 0xae}}, + "profline": {Name: "profline", CodePoints: []int{8978}, Characters: []byte{0xe2, 0x8c, 0x92}}, + "profsurf": {Name: "profsurf", CodePoints: []int{8979}, Characters: []byte{0xe2, 0x8c, 0x93}}, + "prop": {Name: "prop", CodePoints: []int{8733}, Characters: []byte{0xe2, 0x88, 0x9d}}, + "propto": {Name: "propto", CodePoints: []int{8733}, Characters: []byte{0xe2, 0x88, 0x9d}}, + "prsim": {Name: "prsim", CodePoints: []int{8830}, Characters: []byte{0xe2, 0x89, 0xbe}}, + "prurel": {Name: "prurel", CodePoints: []int{8880}, Characters: []byte{0xe2, 0x8a, 0xb0}}, + "pscr": {Name: "pscr", CodePoints: []int{120005}, Characters: []byte{0xf0, 0x9d, 0x93, 0x85}}, + "psi": {Name: "psi", CodePoints: []int{968}, Characters: []byte{0xcf, 0x88}}, + "puncsp": {Name: "puncsp", CodePoints: []int{8200}, Characters: []byte{0xe2, 0x80, 0x88}}, + "qfr": {Name: "qfr", CodePoints: []int{120110}, Characters: []byte{0xf0, 0x9d, 0x94, 0xae}}, + "qint": {Name: "qint", CodePoints: []int{10764}, Characters: []byte{0xe2, 0xa8, 0x8c}}, + "qopf": {Name: "qopf", CodePoints: []int{120162}, Characters: []byte{0xf0, 0x9d, 0x95, 0xa2}}, + "qprime": {Name: "qprime", CodePoints: []int{8279}, Characters: []byte{0xe2, 0x81, 0x97}}, + "qscr": {Name: "qscr", CodePoints: []int{120006}, Characters: []byte{0xf0, 0x9d, 0x93, 0x86}}, + "quaternions": {Name: "quaternions", CodePoints: []int{8461}, Characters: []byte{0xe2, 0x84, 0x8d}}, + "quatint": {Name: "quatint", CodePoints: []int{10774}, Characters: []byte{0xe2, 0xa8, 0x96}}, + "quest": {Name: "quest", CodePoints: []int{63}, Characters: []byte{0x3f}}, + "questeq": {Name: "questeq", CodePoints: []int{8799}, Characters: []byte{0xe2, 0x89, 0x9f}}, + "quot": {Name: "quot", CodePoints: []int{34}, Characters: []byte{0x22}}, + "rAarr": {Name: "rAarr", CodePoints: []int{8667}, Characters: []byte{0xe2, 0x87, 0x9b}}, + "rArr": {Name: "rArr", CodePoints: []int{8658}, Characters: []byte{0xe2, 0x87, 0x92}}, + "rAtail": {Name: "rAtail", CodePoints: []int{10524}, Characters: []byte{0xe2, 0xa4, 0x9c}}, + "rBarr": {Name: "rBarr", CodePoints: []int{10511}, Characters: []byte{0xe2, 0xa4, 0x8f}}, + "rHar": {Name: "rHar", CodePoints: []int{10596}, Characters: []byte{0xe2, 0xa5, 0xa4}}, + "race": {Name: "race", CodePoints: []int{8765, 817}, Characters: []byte{0xe2, 0x88, 0xbd, 0xcc, 0xb1}}, + "racute": {Name: "racute", CodePoints: []int{341}, Characters: []byte{0xc5, 0x95}}, + "radic": {Name: "radic", CodePoints: []int{8730}, Characters: []byte{0xe2, 0x88, 0x9a}}, + "raemptyv": {Name: "raemptyv", CodePoints: []int{10675}, Characters: []byte{0xe2, 0xa6, 0xb3}}, + "rang": {Name: "rang", CodePoints: []int{10217}, Characters: []byte{0xe2, 0x9f, 0xa9}}, + "rangd": {Name: "rangd", CodePoints: []int{10642}, Characters: []byte{0xe2, 0xa6, 0x92}}, + "range": {Name: "range", CodePoints: []int{10661}, Characters: []byte{0xe2, 0xa6, 0xa5}}, + "rangle": {Name: "rangle", CodePoints: []int{10217}, Characters: []byte{0xe2, 0x9f, 0xa9}}, + "raquo": {Name: "raquo", CodePoints: []int{187}, Characters: []byte{0xc2, 0xbb}}, + "rarr": {Name: "rarr", CodePoints: []int{8594}, Characters: []byte{0xe2, 0x86, 0x92}}, + "rarrap": {Name: "rarrap", CodePoints: []int{10613}, Characters: []byte{0xe2, 0xa5, 0xb5}}, + "rarrb": {Name: "rarrb", CodePoints: []int{8677}, Characters: []byte{0xe2, 0x87, 0xa5}}, + "rarrbfs": {Name: "rarrbfs", CodePoints: []int{10528}, Characters: []byte{0xe2, 0xa4, 0xa0}}, + "rarrc": {Name: "rarrc", CodePoints: []int{10547}, Characters: []byte{0xe2, 0xa4, 0xb3}}, + "rarrfs": {Name: "rarrfs", CodePoints: []int{10526}, Characters: []byte{0xe2, 0xa4, 0x9e}}, + "rarrhk": {Name: "rarrhk", CodePoints: []int{8618}, Characters: []byte{0xe2, 0x86, 0xaa}}, + "rarrlp": {Name: "rarrlp", CodePoints: []int{8620}, Characters: []byte{0xe2, 0x86, 0xac}}, + "rarrpl": {Name: "rarrpl", CodePoints: []int{10565}, Characters: []byte{0xe2, 0xa5, 0x85}}, + "rarrsim": {Name: "rarrsim", CodePoints: []int{10612}, Characters: []byte{0xe2, 0xa5, 0xb4}}, + "rarrtl": {Name: "rarrtl", CodePoints: []int{8611}, Characters: []byte{0xe2, 0x86, 0xa3}}, + "rarrw": {Name: "rarrw", CodePoints: []int{8605}, Characters: []byte{0xe2, 0x86, 0x9d}}, + "ratail": {Name: "ratail", CodePoints: []int{10522}, Characters: []byte{0xe2, 0xa4, 0x9a}}, + "ratio": {Name: "ratio", CodePoints: []int{8758}, Characters: []byte{0xe2, 0x88, 0xb6}}, + "rationals": {Name: "rationals", CodePoints: []int{8474}, Characters: []byte{0xe2, 0x84, 0x9a}}, + "rbarr": {Name: "rbarr", CodePoints: []int{10509}, Characters: []byte{0xe2, 0xa4, 0x8d}}, + "rbbrk": {Name: "rbbrk", CodePoints: []int{10099}, Characters: []byte{0xe2, 0x9d, 0xb3}}, + "rbrace": {Name: "rbrace", CodePoints: []int{125}, Characters: []byte{0x7d}}, + "rbrack": {Name: "rbrack", CodePoints: []int{93}, Characters: []byte{0x5d}}, + "rbrke": {Name: "rbrke", CodePoints: []int{10636}, Characters: []byte{0xe2, 0xa6, 0x8c}}, + "rbrksld": {Name: "rbrksld", CodePoints: []int{10638}, Characters: []byte{0xe2, 0xa6, 0x8e}}, + "rbrkslu": {Name: "rbrkslu", CodePoints: []int{10640}, Characters: []byte{0xe2, 0xa6, 0x90}}, + "rcaron": {Name: "rcaron", CodePoints: []int{345}, Characters: []byte{0xc5, 0x99}}, + "rcedil": {Name: "rcedil", CodePoints: []int{343}, Characters: []byte{0xc5, 0x97}}, + "rceil": {Name: "rceil", CodePoints: []int{8969}, Characters: []byte{0xe2, 0x8c, 0x89}}, + "rcub": {Name: "rcub", CodePoints: []int{125}, Characters: []byte{0x7d}}, + "rcy": {Name: "rcy", CodePoints: []int{1088}, Characters: []byte{0xd1, 0x80}}, + "rdca": {Name: "rdca", CodePoints: []int{10551}, Characters: []byte{0xe2, 0xa4, 0xb7}}, + "rdldhar": {Name: "rdldhar", CodePoints: []int{10601}, Characters: []byte{0xe2, 0xa5, 0xa9}}, + "rdquo": {Name: "rdquo", CodePoints: []int{8221}, Characters: []byte{0xe2, 0x80, 0x9d}}, + "rdquor": {Name: "rdquor", CodePoints: []int{8221}, Characters: []byte{0xe2, 0x80, 0x9d}}, + "rdsh": {Name: "rdsh", CodePoints: []int{8627}, Characters: []byte{0xe2, 0x86, 0xb3}}, + "real": {Name: "real", CodePoints: []int{8476}, Characters: []byte{0xe2, 0x84, 0x9c}}, + "realine": {Name: "realine", CodePoints: []int{8475}, Characters: []byte{0xe2, 0x84, 0x9b}}, + "realpart": {Name: "realpart", CodePoints: []int{8476}, Characters: []byte{0xe2, 0x84, 0x9c}}, + "reals": {Name: "reals", CodePoints: []int{8477}, Characters: []byte{0xe2, 0x84, 0x9d}}, + "rect": {Name: "rect", CodePoints: []int{9645}, Characters: []byte{0xe2, 0x96, 0xad}}, + "reg": {Name: "reg", CodePoints: []int{174}, Characters: []byte{0xc2, 0xae}}, + "rfisht": {Name: "rfisht", CodePoints: []int{10621}, Characters: []byte{0xe2, 0xa5, 0xbd}}, + "rfloor": {Name: "rfloor", CodePoints: []int{8971}, Characters: []byte{0xe2, 0x8c, 0x8b}}, + "rfr": {Name: "rfr", CodePoints: []int{120111}, Characters: []byte{0xf0, 0x9d, 0x94, 0xaf}}, + "rhard": {Name: "rhard", CodePoints: []int{8641}, Characters: []byte{0xe2, 0x87, 0x81}}, + "rharu": {Name: "rharu", CodePoints: []int{8640}, Characters: []byte{0xe2, 0x87, 0x80}}, + "rharul": {Name: "rharul", CodePoints: []int{10604}, Characters: []byte{0xe2, 0xa5, 0xac}}, + "rho": {Name: "rho", CodePoints: []int{961}, Characters: []byte{0xcf, 0x81}}, + "rhov": {Name: "rhov", CodePoints: []int{1009}, Characters: []byte{0xcf, 0xb1}}, + "rightarrow": {Name: "rightarrow", CodePoints: []int{8594}, Characters: []byte{0xe2, 0x86, 0x92}}, + "rightarrowtail": {Name: "rightarrowtail", CodePoints: []int{8611}, Characters: []byte{0xe2, 0x86, 0xa3}}, + "rightharpoondown": {Name: "rightharpoondown", CodePoints: []int{8641}, Characters: []byte{0xe2, 0x87, 0x81}}, + "rightharpoonup": {Name: "rightharpoonup", CodePoints: []int{8640}, Characters: []byte{0xe2, 0x87, 0x80}}, + "rightleftarrows": {Name: "rightleftarrows", CodePoints: []int{8644}, Characters: []byte{0xe2, 0x87, 0x84}}, + "rightleftharpoons": {Name: "rightleftharpoons", CodePoints: []int{8652}, Characters: []byte{0xe2, 0x87, 0x8c}}, + "rightrightarrows": {Name: "rightrightarrows", CodePoints: []int{8649}, Characters: []byte{0xe2, 0x87, 0x89}}, + "rightsquigarrow": {Name: "rightsquigarrow", CodePoints: []int{8605}, Characters: []byte{0xe2, 0x86, 0x9d}}, + "rightthreetimes": {Name: "rightthreetimes", CodePoints: []int{8908}, Characters: []byte{0xe2, 0x8b, 0x8c}}, + "ring": {Name: "ring", CodePoints: []int{730}, Characters: []byte{0xcb, 0x9a}}, + "risingdotseq": {Name: "risingdotseq", CodePoints: []int{8787}, Characters: []byte{0xe2, 0x89, 0x93}}, + "rlarr": {Name: "rlarr", CodePoints: []int{8644}, Characters: []byte{0xe2, 0x87, 0x84}}, + "rlhar": {Name: "rlhar", CodePoints: []int{8652}, Characters: []byte{0xe2, 0x87, 0x8c}}, + "rlm": {Name: "rlm", CodePoints: []int{8207}, Characters: []byte{0xe2, 0x80, 0x8f}}, + "rmoust": {Name: "rmoust", CodePoints: []int{9137}, Characters: []byte{0xe2, 0x8e, 0xb1}}, + "rmoustache": {Name: "rmoustache", CodePoints: []int{9137}, Characters: []byte{0xe2, 0x8e, 0xb1}}, + "rnmid": {Name: "rnmid", CodePoints: []int{10990}, Characters: []byte{0xe2, 0xab, 0xae}}, + "roang": {Name: "roang", CodePoints: []int{10221}, Characters: []byte{0xe2, 0x9f, 0xad}}, + "roarr": {Name: "roarr", CodePoints: []int{8702}, Characters: []byte{0xe2, 0x87, 0xbe}}, + "robrk": {Name: "robrk", CodePoints: []int{10215}, Characters: []byte{0xe2, 0x9f, 0xa7}}, + "ropar": {Name: "ropar", CodePoints: []int{10630}, Characters: []byte{0xe2, 0xa6, 0x86}}, + "ropf": {Name: "ropf", CodePoints: []int{120163}, Characters: []byte{0xf0, 0x9d, 0x95, 0xa3}}, + "roplus": {Name: "roplus", CodePoints: []int{10798}, Characters: []byte{0xe2, 0xa8, 0xae}}, + "rotimes": {Name: "rotimes", CodePoints: []int{10805}, Characters: []byte{0xe2, 0xa8, 0xb5}}, + "rpar": {Name: "rpar", CodePoints: []int{41}, Characters: []byte{0x29}}, + "rpargt": {Name: "rpargt", CodePoints: []int{10644}, Characters: []byte{0xe2, 0xa6, 0x94}}, + "rppolint": {Name: "rppolint", CodePoints: []int{10770}, Characters: []byte{0xe2, 0xa8, 0x92}}, + "rrarr": {Name: "rrarr", CodePoints: []int{8649}, Characters: []byte{0xe2, 0x87, 0x89}}, + "rsaquo": {Name: "rsaquo", CodePoints: []int{8250}, Characters: []byte{0xe2, 0x80, 0xba}}, + "rscr": {Name: "rscr", CodePoints: []int{120007}, Characters: []byte{0xf0, 0x9d, 0x93, 0x87}}, + "rsh": {Name: "rsh", CodePoints: []int{8625}, Characters: []byte{0xe2, 0x86, 0xb1}}, + "rsqb": {Name: "rsqb", CodePoints: []int{93}, Characters: []byte{0x5d}}, + "rsquo": {Name: "rsquo", CodePoints: []int{8217}, Characters: []byte{0xe2, 0x80, 0x99}}, + "rsquor": {Name: "rsquor", CodePoints: []int{8217}, Characters: []byte{0xe2, 0x80, 0x99}}, + "rthree": {Name: "rthree", CodePoints: []int{8908}, Characters: []byte{0xe2, 0x8b, 0x8c}}, + "rtimes": {Name: "rtimes", CodePoints: []int{8906}, Characters: []byte{0xe2, 0x8b, 0x8a}}, + "rtri": {Name: "rtri", CodePoints: []int{9657}, Characters: []byte{0xe2, 0x96, 0xb9}}, + "rtrie": {Name: "rtrie", CodePoints: []int{8885}, Characters: []byte{0xe2, 0x8a, 0xb5}}, + "rtrif": {Name: "rtrif", CodePoints: []int{9656}, Characters: []byte{0xe2, 0x96, 0xb8}}, + "rtriltri": {Name: "rtriltri", CodePoints: []int{10702}, Characters: []byte{0xe2, 0xa7, 0x8e}}, + "ruluhar": {Name: "ruluhar", CodePoints: []int{10600}, Characters: []byte{0xe2, 0xa5, 0xa8}}, + "rx": {Name: "rx", CodePoints: []int{8478}, Characters: []byte{0xe2, 0x84, 0x9e}}, + "sacute": {Name: "sacute", CodePoints: []int{347}, Characters: []byte{0xc5, 0x9b}}, + "sbquo": {Name: "sbquo", CodePoints: []int{8218}, Characters: []byte{0xe2, 0x80, 0x9a}}, + "sc": {Name: "sc", CodePoints: []int{8827}, Characters: []byte{0xe2, 0x89, 0xbb}}, + "scE": {Name: "scE", CodePoints: []int{10932}, Characters: []byte{0xe2, 0xaa, 0xb4}}, + "scap": {Name: "scap", CodePoints: []int{10936}, Characters: []byte{0xe2, 0xaa, 0xb8}}, + "scaron": {Name: "scaron", CodePoints: []int{353}, Characters: []byte{0xc5, 0xa1}}, + "sccue": {Name: "sccue", CodePoints: []int{8829}, Characters: []byte{0xe2, 0x89, 0xbd}}, + "sce": {Name: "sce", CodePoints: []int{10928}, Characters: []byte{0xe2, 0xaa, 0xb0}}, + "scedil": {Name: "scedil", CodePoints: []int{351}, Characters: []byte{0xc5, 0x9f}}, + "scirc": {Name: "scirc", CodePoints: []int{349}, Characters: []byte{0xc5, 0x9d}}, + "scnE": {Name: "scnE", CodePoints: []int{10934}, Characters: []byte{0xe2, 0xaa, 0xb6}}, + "scnap": {Name: "scnap", CodePoints: []int{10938}, Characters: []byte{0xe2, 0xaa, 0xba}}, + "scnsim": {Name: "scnsim", CodePoints: []int{8937}, Characters: []byte{0xe2, 0x8b, 0xa9}}, + "scpolint": {Name: "scpolint", CodePoints: []int{10771}, Characters: []byte{0xe2, 0xa8, 0x93}}, + "scsim": {Name: "scsim", CodePoints: []int{8831}, Characters: []byte{0xe2, 0x89, 0xbf}}, + "scy": {Name: "scy", CodePoints: []int{1089}, Characters: []byte{0xd1, 0x81}}, + "sdot": {Name: "sdot", CodePoints: []int{8901}, Characters: []byte{0xe2, 0x8b, 0x85}}, + "sdotb": {Name: "sdotb", CodePoints: []int{8865}, Characters: []byte{0xe2, 0x8a, 0xa1}}, + "sdote": {Name: "sdote", CodePoints: []int{10854}, Characters: []byte{0xe2, 0xa9, 0xa6}}, + "seArr": {Name: "seArr", CodePoints: []int{8664}, Characters: []byte{0xe2, 0x87, 0x98}}, + "searhk": {Name: "searhk", CodePoints: []int{10533}, Characters: []byte{0xe2, 0xa4, 0xa5}}, + "searr": {Name: "searr", CodePoints: []int{8600}, Characters: []byte{0xe2, 0x86, 0x98}}, + "searrow": {Name: "searrow", CodePoints: []int{8600}, Characters: []byte{0xe2, 0x86, 0x98}}, + "sect": {Name: "sect", CodePoints: []int{167}, Characters: []byte{0xc2, 0xa7}}, + "semi": {Name: "semi", CodePoints: []int{59}, Characters: []byte{0x3b}}, + "seswar": {Name: "seswar", CodePoints: []int{10537}, Characters: []byte{0xe2, 0xa4, 0xa9}}, + "setminus": {Name: "setminus", CodePoints: []int{8726}, Characters: []byte{0xe2, 0x88, 0x96}}, + "setmn": {Name: "setmn", CodePoints: []int{8726}, Characters: []byte{0xe2, 0x88, 0x96}}, + "sext": {Name: "sext", CodePoints: []int{10038}, Characters: []byte{0xe2, 0x9c, 0xb6}}, + "sfr": {Name: "sfr", CodePoints: []int{120112}, Characters: []byte{0xf0, 0x9d, 0x94, 0xb0}}, + "sfrown": {Name: "sfrown", CodePoints: []int{8994}, Characters: []byte{0xe2, 0x8c, 0xa2}}, + "sharp": {Name: "sharp", CodePoints: []int{9839}, Characters: []byte{0xe2, 0x99, 0xaf}}, + "shchcy": {Name: "shchcy", CodePoints: []int{1097}, Characters: []byte{0xd1, 0x89}}, + "shcy": {Name: "shcy", CodePoints: []int{1096}, Characters: []byte{0xd1, 0x88}}, + "shortmid": {Name: "shortmid", CodePoints: []int{8739}, Characters: []byte{0xe2, 0x88, 0xa3}}, + "shortparallel": {Name: "shortparallel", CodePoints: []int{8741}, Characters: []byte{0xe2, 0x88, 0xa5}}, + "shy": {Name: "shy", CodePoints: []int{173}, Characters: []byte{0xc2, 0xad}}, + "sigma": {Name: "sigma", CodePoints: []int{963}, Characters: []byte{0xcf, 0x83}}, + "sigmaf": {Name: "sigmaf", CodePoints: []int{962}, Characters: []byte{0xcf, 0x82}}, + "sigmav": {Name: "sigmav", CodePoints: []int{962}, Characters: []byte{0xcf, 0x82}}, + "sim": {Name: "sim", CodePoints: []int{8764}, Characters: []byte{0xe2, 0x88, 0xbc}}, + "simdot": {Name: "simdot", CodePoints: []int{10858}, Characters: []byte{0xe2, 0xa9, 0xaa}}, + "sime": {Name: "sime", CodePoints: []int{8771}, Characters: []byte{0xe2, 0x89, 0x83}}, + "simeq": {Name: "simeq", CodePoints: []int{8771}, Characters: []byte{0xe2, 0x89, 0x83}}, + "simg": {Name: "simg", CodePoints: []int{10910}, Characters: []byte{0xe2, 0xaa, 0x9e}}, + "simgE": {Name: "simgE", CodePoints: []int{10912}, Characters: []byte{0xe2, 0xaa, 0xa0}}, + "siml": {Name: "siml", CodePoints: []int{10909}, Characters: []byte{0xe2, 0xaa, 0x9d}}, + "simlE": {Name: "simlE", CodePoints: []int{10911}, Characters: []byte{0xe2, 0xaa, 0x9f}}, + "simne": {Name: "simne", CodePoints: []int{8774}, Characters: []byte{0xe2, 0x89, 0x86}}, + "simplus": {Name: "simplus", CodePoints: []int{10788}, Characters: []byte{0xe2, 0xa8, 0xa4}}, + "simrarr": {Name: "simrarr", CodePoints: []int{10610}, Characters: []byte{0xe2, 0xa5, 0xb2}}, + "slarr": {Name: "slarr", CodePoints: []int{8592}, Characters: []byte{0xe2, 0x86, 0x90}}, + "smallsetminus": {Name: "smallsetminus", CodePoints: []int{8726}, Characters: []byte{0xe2, 0x88, 0x96}}, + "smashp": {Name: "smashp", CodePoints: []int{10803}, Characters: []byte{0xe2, 0xa8, 0xb3}}, + "smeparsl": {Name: "smeparsl", CodePoints: []int{10724}, Characters: []byte{0xe2, 0xa7, 0xa4}}, + "smid": {Name: "smid", CodePoints: []int{8739}, Characters: []byte{0xe2, 0x88, 0xa3}}, + "smile": {Name: "smile", CodePoints: []int{8995}, Characters: []byte{0xe2, 0x8c, 0xa3}}, + "smt": {Name: "smt", CodePoints: []int{10922}, Characters: []byte{0xe2, 0xaa, 0xaa}}, + "smte": {Name: "smte", CodePoints: []int{10924}, Characters: []byte{0xe2, 0xaa, 0xac}}, + "smtes": {Name: "smtes", CodePoints: []int{10924, 65024}, Characters: []byte{0xe2, 0xaa, 0xac, 0xef, 0xb8, 0x80}}, + "softcy": {Name: "softcy", CodePoints: []int{1100}, Characters: []byte{0xd1, 0x8c}}, + "sol": {Name: "sol", CodePoints: []int{47}, Characters: []byte{0x2f}}, + "solb": {Name: "solb", CodePoints: []int{10692}, Characters: []byte{0xe2, 0xa7, 0x84}}, + "solbar": {Name: "solbar", CodePoints: []int{9023}, Characters: []byte{0xe2, 0x8c, 0xbf}}, + "sopf": {Name: "sopf", CodePoints: []int{120164}, Characters: []byte{0xf0, 0x9d, 0x95, 0xa4}}, + "spades": {Name: "spades", CodePoints: []int{9824}, Characters: []byte{0xe2, 0x99, 0xa0}}, + "spadesuit": {Name: "spadesuit", CodePoints: []int{9824}, Characters: []byte{0xe2, 0x99, 0xa0}}, + "spar": {Name: "spar", CodePoints: []int{8741}, Characters: []byte{0xe2, 0x88, 0xa5}}, + "sqcap": {Name: "sqcap", CodePoints: []int{8851}, Characters: []byte{0xe2, 0x8a, 0x93}}, + "sqcaps": {Name: "sqcaps", CodePoints: []int{8851, 65024}, Characters: []byte{0xe2, 0x8a, 0x93, 0xef, 0xb8, 0x80}}, + "sqcup": {Name: "sqcup", CodePoints: []int{8852}, Characters: []byte{0xe2, 0x8a, 0x94}}, + "sqcups": {Name: "sqcups", CodePoints: []int{8852, 65024}, Characters: []byte{0xe2, 0x8a, 0x94, 0xef, 0xb8, 0x80}}, + "sqsub": {Name: "sqsub", CodePoints: []int{8847}, Characters: []byte{0xe2, 0x8a, 0x8f}}, + "sqsube": {Name: "sqsube", CodePoints: []int{8849}, Characters: []byte{0xe2, 0x8a, 0x91}}, + "sqsubset": {Name: "sqsubset", CodePoints: []int{8847}, Characters: []byte{0xe2, 0x8a, 0x8f}}, + "sqsubseteq": {Name: "sqsubseteq", CodePoints: []int{8849}, Characters: []byte{0xe2, 0x8a, 0x91}}, + "sqsup": {Name: "sqsup", CodePoints: []int{8848}, Characters: []byte{0xe2, 0x8a, 0x90}}, + "sqsupe": {Name: "sqsupe", CodePoints: []int{8850}, Characters: []byte{0xe2, 0x8a, 0x92}}, + "sqsupset": {Name: "sqsupset", CodePoints: []int{8848}, Characters: []byte{0xe2, 0x8a, 0x90}}, + "sqsupseteq": {Name: "sqsupseteq", CodePoints: []int{8850}, Characters: []byte{0xe2, 0x8a, 0x92}}, + "squ": {Name: "squ", CodePoints: []int{9633}, Characters: []byte{0xe2, 0x96, 0xa1}}, + "square": {Name: "square", CodePoints: []int{9633}, Characters: []byte{0xe2, 0x96, 0xa1}}, + "squarf": {Name: "squarf", CodePoints: []int{9642}, Characters: []byte{0xe2, 0x96, 0xaa}}, + "squf": {Name: "squf", CodePoints: []int{9642}, Characters: []byte{0xe2, 0x96, 0xaa}}, + "srarr": {Name: "srarr", CodePoints: []int{8594}, Characters: []byte{0xe2, 0x86, 0x92}}, + "sscr": {Name: "sscr", CodePoints: []int{120008}, Characters: []byte{0xf0, 0x9d, 0x93, 0x88}}, + "ssetmn": {Name: "ssetmn", CodePoints: []int{8726}, Characters: []byte{0xe2, 0x88, 0x96}}, + "ssmile": {Name: "ssmile", CodePoints: []int{8995}, Characters: []byte{0xe2, 0x8c, 0xa3}}, + "sstarf": {Name: "sstarf", CodePoints: []int{8902}, Characters: []byte{0xe2, 0x8b, 0x86}}, + "star": {Name: "star", CodePoints: []int{9734}, Characters: []byte{0xe2, 0x98, 0x86}}, + "starf": {Name: "starf", CodePoints: []int{9733}, Characters: []byte{0xe2, 0x98, 0x85}}, + "straightepsilon": {Name: "straightepsilon", CodePoints: []int{1013}, Characters: []byte{0xcf, 0xb5}}, + "straightphi": {Name: "straightphi", CodePoints: []int{981}, Characters: []byte{0xcf, 0x95}}, + "strns": {Name: "strns", CodePoints: []int{175}, Characters: []byte{0xc2, 0xaf}}, + "sub": {Name: "sub", CodePoints: []int{8834}, Characters: []byte{0xe2, 0x8a, 0x82}}, + "subE": {Name: "subE", CodePoints: []int{10949}, Characters: []byte{0xe2, 0xab, 0x85}}, + "subdot": {Name: "subdot", CodePoints: []int{10941}, Characters: []byte{0xe2, 0xaa, 0xbd}}, + "sube": {Name: "sube", CodePoints: []int{8838}, Characters: []byte{0xe2, 0x8a, 0x86}}, + "subedot": {Name: "subedot", CodePoints: []int{10947}, Characters: []byte{0xe2, 0xab, 0x83}}, + "submult": {Name: "submult", CodePoints: []int{10945}, Characters: []byte{0xe2, 0xab, 0x81}}, + "subnE": {Name: "subnE", CodePoints: []int{10955}, Characters: []byte{0xe2, 0xab, 0x8b}}, + "subne": {Name: "subne", CodePoints: []int{8842}, Characters: []byte{0xe2, 0x8a, 0x8a}}, + "subplus": {Name: "subplus", CodePoints: []int{10943}, Characters: []byte{0xe2, 0xaa, 0xbf}}, + "subrarr": {Name: "subrarr", CodePoints: []int{10617}, Characters: []byte{0xe2, 0xa5, 0xb9}}, + "subset": {Name: "subset", CodePoints: []int{8834}, Characters: []byte{0xe2, 0x8a, 0x82}}, + "subseteq": {Name: "subseteq", CodePoints: []int{8838}, Characters: []byte{0xe2, 0x8a, 0x86}}, + "subseteqq": {Name: "subseteqq", CodePoints: []int{10949}, Characters: []byte{0xe2, 0xab, 0x85}}, + "subsetneq": {Name: "subsetneq", CodePoints: []int{8842}, Characters: []byte{0xe2, 0x8a, 0x8a}}, + "subsetneqq": {Name: "subsetneqq", CodePoints: []int{10955}, Characters: []byte{0xe2, 0xab, 0x8b}}, + "subsim": {Name: "subsim", CodePoints: []int{10951}, Characters: []byte{0xe2, 0xab, 0x87}}, + "subsub": {Name: "subsub", CodePoints: []int{10965}, Characters: []byte{0xe2, 0xab, 0x95}}, + "subsup": {Name: "subsup", CodePoints: []int{10963}, Characters: []byte{0xe2, 0xab, 0x93}}, + "succ": {Name: "succ", CodePoints: []int{8827}, Characters: []byte{0xe2, 0x89, 0xbb}}, + "succapprox": {Name: "succapprox", CodePoints: []int{10936}, Characters: []byte{0xe2, 0xaa, 0xb8}}, + "succcurlyeq": {Name: "succcurlyeq", CodePoints: []int{8829}, Characters: []byte{0xe2, 0x89, 0xbd}}, + "succeq": {Name: "succeq", CodePoints: []int{10928}, Characters: []byte{0xe2, 0xaa, 0xb0}}, + "succnapprox": {Name: "succnapprox", CodePoints: []int{10938}, Characters: []byte{0xe2, 0xaa, 0xba}}, + "succneqq": {Name: "succneqq", CodePoints: []int{10934}, Characters: []byte{0xe2, 0xaa, 0xb6}}, + "succnsim": {Name: "succnsim", CodePoints: []int{8937}, Characters: []byte{0xe2, 0x8b, 0xa9}}, + "succsim": {Name: "succsim", CodePoints: []int{8831}, Characters: []byte{0xe2, 0x89, 0xbf}}, + "sum": {Name: "sum", CodePoints: []int{8721}, Characters: []byte{0xe2, 0x88, 0x91}}, + "sung": {Name: "sung", CodePoints: []int{9834}, Characters: []byte{0xe2, 0x99, 0xaa}}, + "sup": {Name: "sup", CodePoints: []int{8835}, Characters: []byte{0xe2, 0x8a, 0x83}}, + "sup1": {Name: "sup1", CodePoints: []int{185}, Characters: []byte{0xc2, 0xb9}}, + "sup2": {Name: "sup2", CodePoints: []int{178}, Characters: []byte{0xc2, 0xb2}}, + "sup3": {Name: "sup3", CodePoints: []int{179}, Characters: []byte{0xc2, 0xb3}}, + "supE": {Name: "supE", CodePoints: []int{10950}, Characters: []byte{0xe2, 0xab, 0x86}}, + "supdot": {Name: "supdot", CodePoints: []int{10942}, Characters: []byte{0xe2, 0xaa, 0xbe}}, + "supdsub": {Name: "supdsub", CodePoints: []int{10968}, Characters: []byte{0xe2, 0xab, 0x98}}, + "supe": {Name: "supe", CodePoints: []int{8839}, Characters: []byte{0xe2, 0x8a, 0x87}}, + "supedot": {Name: "supedot", CodePoints: []int{10948}, Characters: []byte{0xe2, 0xab, 0x84}}, + "suphsol": {Name: "suphsol", CodePoints: []int{10185}, Characters: []byte{0xe2, 0x9f, 0x89}}, + "suphsub": {Name: "suphsub", CodePoints: []int{10967}, Characters: []byte{0xe2, 0xab, 0x97}}, + "suplarr": {Name: "suplarr", CodePoints: []int{10619}, Characters: []byte{0xe2, 0xa5, 0xbb}}, + "supmult": {Name: "supmult", CodePoints: []int{10946}, Characters: []byte{0xe2, 0xab, 0x82}}, + "supnE": {Name: "supnE", CodePoints: []int{10956}, Characters: []byte{0xe2, 0xab, 0x8c}}, + "supne": {Name: "supne", CodePoints: []int{8843}, Characters: []byte{0xe2, 0x8a, 0x8b}}, + "supplus": {Name: "supplus", CodePoints: []int{10944}, Characters: []byte{0xe2, 0xab, 0x80}}, + "supset": {Name: "supset", CodePoints: []int{8835}, Characters: []byte{0xe2, 0x8a, 0x83}}, + "supseteq": {Name: "supseteq", CodePoints: []int{8839}, Characters: []byte{0xe2, 0x8a, 0x87}}, + "supseteqq": {Name: "supseteqq", CodePoints: []int{10950}, Characters: []byte{0xe2, 0xab, 0x86}}, + "supsetneq": {Name: "supsetneq", CodePoints: []int{8843}, Characters: []byte{0xe2, 0x8a, 0x8b}}, + "supsetneqq": {Name: "supsetneqq", CodePoints: []int{10956}, Characters: []byte{0xe2, 0xab, 0x8c}}, + "supsim": {Name: "supsim", CodePoints: []int{10952}, Characters: []byte{0xe2, 0xab, 0x88}}, + "supsub": {Name: "supsub", CodePoints: []int{10964}, Characters: []byte{0xe2, 0xab, 0x94}}, + "supsup": {Name: "supsup", CodePoints: []int{10966}, Characters: []byte{0xe2, 0xab, 0x96}}, + "swArr": {Name: "swArr", CodePoints: []int{8665}, Characters: []byte{0xe2, 0x87, 0x99}}, + "swarhk": {Name: "swarhk", CodePoints: []int{10534}, Characters: []byte{0xe2, 0xa4, 0xa6}}, + "swarr": {Name: "swarr", CodePoints: []int{8601}, Characters: []byte{0xe2, 0x86, 0x99}}, + "swarrow": {Name: "swarrow", CodePoints: []int{8601}, Characters: []byte{0xe2, 0x86, 0x99}}, + "swnwar": {Name: "swnwar", CodePoints: []int{10538}, Characters: []byte{0xe2, 0xa4, 0xaa}}, + "szlig": {Name: "szlig", CodePoints: []int{223}, Characters: []byte{0xc3, 0x9f}}, + "target": {Name: "target", CodePoints: []int{8982}, Characters: []byte{0xe2, 0x8c, 0x96}}, + "tau": {Name: "tau", CodePoints: []int{964}, Characters: []byte{0xcf, 0x84}}, + "tbrk": {Name: "tbrk", CodePoints: []int{9140}, Characters: []byte{0xe2, 0x8e, 0xb4}}, + "tcaron": {Name: "tcaron", CodePoints: []int{357}, Characters: []byte{0xc5, 0xa5}}, + "tcedil": {Name: "tcedil", CodePoints: []int{355}, Characters: []byte{0xc5, 0xa3}}, + "tcy": {Name: "tcy", CodePoints: []int{1090}, Characters: []byte{0xd1, 0x82}}, + "tdot": {Name: "tdot", CodePoints: []int{8411}, Characters: []byte{0xe2, 0x83, 0x9b}}, + "telrec": {Name: "telrec", CodePoints: []int{8981}, Characters: []byte{0xe2, 0x8c, 0x95}}, + "tfr": {Name: "tfr", CodePoints: []int{120113}, Characters: []byte{0xf0, 0x9d, 0x94, 0xb1}}, + "there4": {Name: "there4", CodePoints: []int{8756}, Characters: []byte{0xe2, 0x88, 0xb4}}, + "therefore": {Name: "therefore", CodePoints: []int{8756}, Characters: []byte{0xe2, 0x88, 0xb4}}, + "theta": {Name: "theta", CodePoints: []int{952}, Characters: []byte{0xce, 0xb8}}, + "thetasym": {Name: "thetasym", CodePoints: []int{977}, Characters: []byte{0xcf, 0x91}}, + "thetav": {Name: "thetav", CodePoints: []int{977}, Characters: []byte{0xcf, 0x91}}, + "thickapprox": {Name: "thickapprox", CodePoints: []int{8776}, Characters: []byte{0xe2, 0x89, 0x88}}, + "thicksim": {Name: "thicksim", CodePoints: []int{8764}, Characters: []byte{0xe2, 0x88, 0xbc}}, + "thinsp": {Name: "thinsp", CodePoints: []int{8201}, Characters: []byte{0xe2, 0x80, 0x89}}, + "thkap": {Name: "thkap", CodePoints: []int{8776}, Characters: []byte{0xe2, 0x89, 0x88}}, + "thksim": {Name: "thksim", CodePoints: []int{8764}, Characters: []byte{0xe2, 0x88, 0xbc}}, + "thorn": {Name: "thorn", CodePoints: []int{254}, Characters: []byte{0xc3, 0xbe}}, + "tilde": {Name: "tilde", CodePoints: []int{732}, Characters: []byte{0xcb, 0x9c}}, + "times": {Name: "times", CodePoints: []int{215}, Characters: []byte{0xc3, 0x97}}, + "timesb": {Name: "timesb", CodePoints: []int{8864}, Characters: []byte{0xe2, 0x8a, 0xa0}}, + "timesbar": {Name: "timesbar", CodePoints: []int{10801}, Characters: []byte{0xe2, 0xa8, 0xb1}}, + "timesd": {Name: "timesd", CodePoints: []int{10800}, Characters: []byte{0xe2, 0xa8, 0xb0}}, + "tint": {Name: "tint", CodePoints: []int{8749}, Characters: []byte{0xe2, 0x88, 0xad}}, + "toea": {Name: "toea", CodePoints: []int{10536}, Characters: []byte{0xe2, 0xa4, 0xa8}}, + "top": {Name: "top", CodePoints: []int{8868}, Characters: []byte{0xe2, 0x8a, 0xa4}}, + "topbot": {Name: "topbot", CodePoints: []int{9014}, Characters: []byte{0xe2, 0x8c, 0xb6}}, + "topcir": {Name: "topcir", CodePoints: []int{10993}, Characters: []byte{0xe2, 0xab, 0xb1}}, + "topf": {Name: "topf", CodePoints: []int{120165}, Characters: []byte{0xf0, 0x9d, 0x95, 0xa5}}, + "topfork": {Name: "topfork", CodePoints: []int{10970}, Characters: []byte{0xe2, 0xab, 0x9a}}, + "tosa": {Name: "tosa", CodePoints: []int{10537}, Characters: []byte{0xe2, 0xa4, 0xa9}}, + "tprime": {Name: "tprime", CodePoints: []int{8244}, Characters: []byte{0xe2, 0x80, 0xb4}}, + "trade": {Name: "trade", CodePoints: []int{8482}, Characters: []byte{0xe2, 0x84, 0xa2}}, + "triangle": {Name: "triangle", CodePoints: []int{9653}, Characters: []byte{0xe2, 0x96, 0xb5}}, + "triangledown": {Name: "triangledown", CodePoints: []int{9663}, Characters: []byte{0xe2, 0x96, 0xbf}}, + "triangleleft": {Name: "triangleleft", CodePoints: []int{9667}, Characters: []byte{0xe2, 0x97, 0x83}}, + "trianglelefteq": {Name: "trianglelefteq", CodePoints: []int{8884}, Characters: []byte{0xe2, 0x8a, 0xb4}}, + "triangleq": {Name: "triangleq", CodePoints: []int{8796}, Characters: []byte{0xe2, 0x89, 0x9c}}, + "triangleright": {Name: "triangleright", CodePoints: []int{9657}, Characters: []byte{0xe2, 0x96, 0xb9}}, + "trianglerighteq": {Name: "trianglerighteq", CodePoints: []int{8885}, Characters: []byte{0xe2, 0x8a, 0xb5}}, + "tridot": {Name: "tridot", CodePoints: []int{9708}, Characters: []byte{0xe2, 0x97, 0xac}}, + "trie": {Name: "trie", CodePoints: []int{8796}, Characters: []byte{0xe2, 0x89, 0x9c}}, + "triminus": {Name: "triminus", CodePoints: []int{10810}, Characters: []byte{0xe2, 0xa8, 0xba}}, + "triplus": {Name: "triplus", CodePoints: []int{10809}, Characters: []byte{0xe2, 0xa8, 0xb9}}, + "trisb": {Name: "trisb", CodePoints: []int{10701}, Characters: []byte{0xe2, 0xa7, 0x8d}}, + "tritime": {Name: "tritime", CodePoints: []int{10811}, Characters: []byte{0xe2, 0xa8, 0xbb}}, + "trpezium": {Name: "trpezium", CodePoints: []int{9186}, Characters: []byte{0xe2, 0x8f, 0xa2}}, + "tscr": {Name: "tscr", CodePoints: []int{120009}, Characters: []byte{0xf0, 0x9d, 0x93, 0x89}}, + "tscy": {Name: "tscy", CodePoints: []int{1094}, Characters: []byte{0xd1, 0x86}}, + "tshcy": {Name: "tshcy", CodePoints: []int{1115}, Characters: []byte{0xd1, 0x9b}}, + "tstrok": {Name: "tstrok", CodePoints: []int{359}, Characters: []byte{0xc5, 0xa7}}, + "twixt": {Name: "twixt", CodePoints: []int{8812}, Characters: []byte{0xe2, 0x89, 0xac}}, + "twoheadleftarrow": {Name: "twoheadleftarrow", CodePoints: []int{8606}, Characters: []byte{0xe2, 0x86, 0x9e}}, + "twoheadrightarrow": {Name: "twoheadrightarrow", CodePoints: []int{8608}, Characters: []byte{0xe2, 0x86, 0xa0}}, + "uArr": {Name: "uArr", CodePoints: []int{8657}, Characters: []byte{0xe2, 0x87, 0x91}}, + "uHar": {Name: "uHar", CodePoints: []int{10595}, Characters: []byte{0xe2, 0xa5, 0xa3}}, + "uacute": {Name: "uacute", CodePoints: []int{250}, Characters: []byte{0xc3, 0xba}}, + "uarr": {Name: "uarr", CodePoints: []int{8593}, Characters: []byte{0xe2, 0x86, 0x91}}, + "ubrcy": {Name: "ubrcy", CodePoints: []int{1118}, Characters: []byte{0xd1, 0x9e}}, + "ubreve": {Name: "ubreve", CodePoints: []int{365}, Characters: []byte{0xc5, 0xad}}, + "ucirc": {Name: "ucirc", CodePoints: []int{251}, Characters: []byte{0xc3, 0xbb}}, + "ucy": {Name: "ucy", CodePoints: []int{1091}, Characters: []byte{0xd1, 0x83}}, + "udarr": {Name: "udarr", CodePoints: []int{8645}, Characters: []byte{0xe2, 0x87, 0x85}}, + "udblac": {Name: "udblac", CodePoints: []int{369}, Characters: []byte{0xc5, 0xb1}}, + "udhar": {Name: "udhar", CodePoints: []int{10606}, Characters: []byte{0xe2, 0xa5, 0xae}}, + "ufisht": {Name: "ufisht", CodePoints: []int{10622}, Characters: []byte{0xe2, 0xa5, 0xbe}}, + "ufr": {Name: "ufr", CodePoints: []int{120114}, Characters: []byte{0xf0, 0x9d, 0x94, 0xb2}}, + "ugrave": {Name: "ugrave", CodePoints: []int{249}, Characters: []byte{0xc3, 0xb9}}, + "uharl": {Name: "uharl", CodePoints: []int{8639}, Characters: []byte{0xe2, 0x86, 0xbf}}, + "uharr": {Name: "uharr", CodePoints: []int{8638}, Characters: []byte{0xe2, 0x86, 0xbe}}, + "uhblk": {Name: "uhblk", CodePoints: []int{9600}, Characters: []byte{0xe2, 0x96, 0x80}}, + "ulcorn": {Name: "ulcorn", CodePoints: []int{8988}, Characters: []byte{0xe2, 0x8c, 0x9c}}, + "ulcorner": {Name: "ulcorner", CodePoints: []int{8988}, Characters: []byte{0xe2, 0x8c, 0x9c}}, + "ulcrop": {Name: "ulcrop", CodePoints: []int{8975}, Characters: []byte{0xe2, 0x8c, 0x8f}}, + "ultri": {Name: "ultri", CodePoints: []int{9720}, Characters: []byte{0xe2, 0x97, 0xb8}}, + "umacr": {Name: "umacr", CodePoints: []int{363}, Characters: []byte{0xc5, 0xab}}, + "uml": {Name: "uml", CodePoints: []int{168}, Characters: []byte{0xc2, 0xa8}}, + "uogon": {Name: "uogon", CodePoints: []int{371}, Characters: []byte{0xc5, 0xb3}}, + "uopf": {Name: "uopf", CodePoints: []int{120166}, Characters: []byte{0xf0, 0x9d, 0x95, 0xa6}}, + "uparrow": {Name: "uparrow", CodePoints: []int{8593}, Characters: []byte{0xe2, 0x86, 0x91}}, + "updownarrow": {Name: "updownarrow", CodePoints: []int{8597}, Characters: []byte{0xe2, 0x86, 0x95}}, + "upharpoonleft": {Name: "upharpoonleft", CodePoints: []int{8639}, Characters: []byte{0xe2, 0x86, 0xbf}}, + "upharpoonright": {Name: "upharpoonright", CodePoints: []int{8638}, Characters: []byte{0xe2, 0x86, 0xbe}}, + "uplus": {Name: "uplus", CodePoints: []int{8846}, Characters: []byte{0xe2, 0x8a, 0x8e}}, + "upsi": {Name: "upsi", CodePoints: []int{965}, Characters: []byte{0xcf, 0x85}}, + "upsih": {Name: "upsih", CodePoints: []int{978}, Characters: []byte{0xcf, 0x92}}, + "upsilon": {Name: "upsilon", CodePoints: []int{965}, Characters: []byte{0xcf, 0x85}}, + "upuparrows": {Name: "upuparrows", CodePoints: []int{8648}, Characters: []byte{0xe2, 0x87, 0x88}}, + "urcorn": {Name: "urcorn", CodePoints: []int{8989}, Characters: []byte{0xe2, 0x8c, 0x9d}}, + "urcorner": {Name: "urcorner", CodePoints: []int{8989}, Characters: []byte{0xe2, 0x8c, 0x9d}}, + "urcrop": {Name: "urcrop", CodePoints: []int{8974}, Characters: []byte{0xe2, 0x8c, 0x8e}}, + "uring": {Name: "uring", CodePoints: []int{367}, Characters: []byte{0xc5, 0xaf}}, + "urtri": {Name: "urtri", CodePoints: []int{9721}, Characters: []byte{0xe2, 0x97, 0xb9}}, + "uscr": {Name: "uscr", CodePoints: []int{120010}, Characters: []byte{0xf0, 0x9d, 0x93, 0x8a}}, + "utdot": {Name: "utdot", CodePoints: []int{8944}, Characters: []byte{0xe2, 0x8b, 0xb0}}, + "utilde": {Name: "utilde", CodePoints: []int{361}, Characters: []byte{0xc5, 0xa9}}, + "utri": {Name: "utri", CodePoints: []int{9653}, Characters: []byte{0xe2, 0x96, 0xb5}}, + "utrif": {Name: "utrif", CodePoints: []int{9652}, Characters: []byte{0xe2, 0x96, 0xb4}}, + "uuarr": {Name: "uuarr", CodePoints: []int{8648}, Characters: []byte{0xe2, 0x87, 0x88}}, + "uuml": {Name: "uuml", CodePoints: []int{252}, Characters: []byte{0xc3, 0xbc}}, + "uwangle": {Name: "uwangle", CodePoints: []int{10663}, Characters: []byte{0xe2, 0xa6, 0xa7}}, + "vArr": {Name: "vArr", CodePoints: []int{8661}, Characters: []byte{0xe2, 0x87, 0x95}}, + "vBar": {Name: "vBar", CodePoints: []int{10984}, Characters: []byte{0xe2, 0xab, 0xa8}}, + "vBarv": {Name: "vBarv", CodePoints: []int{10985}, Characters: []byte{0xe2, 0xab, 0xa9}}, + "vDash": {Name: "vDash", CodePoints: []int{8872}, Characters: []byte{0xe2, 0x8a, 0xa8}}, + "vangrt": {Name: "vangrt", CodePoints: []int{10652}, Characters: []byte{0xe2, 0xa6, 0x9c}}, + "varepsilon": {Name: "varepsilon", CodePoints: []int{1013}, Characters: []byte{0xcf, 0xb5}}, + "varkappa": {Name: "varkappa", CodePoints: []int{1008}, Characters: []byte{0xcf, 0xb0}}, + "varnothing": {Name: "varnothing", CodePoints: []int{8709}, Characters: []byte{0xe2, 0x88, 0x85}}, + "varphi": {Name: "varphi", CodePoints: []int{981}, Characters: []byte{0xcf, 0x95}}, + "varpi": {Name: "varpi", CodePoints: []int{982}, Characters: []byte{0xcf, 0x96}}, + "varpropto": {Name: "varpropto", CodePoints: []int{8733}, Characters: []byte{0xe2, 0x88, 0x9d}}, + "varr": {Name: "varr", CodePoints: []int{8597}, Characters: []byte{0xe2, 0x86, 0x95}}, + "varrho": {Name: "varrho", CodePoints: []int{1009}, Characters: []byte{0xcf, 0xb1}}, + "varsigma": {Name: "varsigma", CodePoints: []int{962}, Characters: []byte{0xcf, 0x82}}, + "varsubsetneq": {Name: "varsubsetneq", CodePoints: []int{8842, 65024}, Characters: []byte{0xe2, 0x8a, 0x8a, 0xef, 0xb8, 0x80}}, + "varsubsetneqq": {Name: "varsubsetneqq", CodePoints: []int{10955, 65024}, Characters: []byte{0xe2, 0xab, 0x8b, 0xef, 0xb8, 0x80}}, + "varsupsetneq": {Name: "varsupsetneq", CodePoints: []int{8843, 65024}, Characters: []byte{0xe2, 0x8a, 0x8b, 0xef, 0xb8, 0x80}}, + "varsupsetneqq": {Name: "varsupsetneqq", CodePoints: []int{10956, 65024}, Characters: []byte{0xe2, 0xab, 0x8c, 0xef, 0xb8, 0x80}}, + "vartheta": {Name: "vartheta", CodePoints: []int{977}, Characters: []byte{0xcf, 0x91}}, + "vartriangleleft": {Name: "vartriangleleft", CodePoints: []int{8882}, Characters: []byte{0xe2, 0x8a, 0xb2}}, + "vartriangleright": {Name: "vartriangleright", CodePoints: []int{8883}, Characters: []byte{0xe2, 0x8a, 0xb3}}, + "vcy": {Name: "vcy", CodePoints: []int{1074}, Characters: []byte{0xd0, 0xb2}}, + "vdash": {Name: "vdash", CodePoints: []int{8866}, Characters: []byte{0xe2, 0x8a, 0xa2}}, + "vee": {Name: "vee", CodePoints: []int{8744}, Characters: []byte{0xe2, 0x88, 0xa8}}, + "veebar": {Name: "veebar", CodePoints: []int{8891}, Characters: []byte{0xe2, 0x8a, 0xbb}}, + "veeeq": {Name: "veeeq", CodePoints: []int{8794}, Characters: []byte{0xe2, 0x89, 0x9a}}, + "vellip": {Name: "vellip", CodePoints: []int{8942}, Characters: []byte{0xe2, 0x8b, 0xae}}, + "verbar": {Name: "verbar", CodePoints: []int{124}, Characters: []byte{0x7c}}, + "vert": {Name: "vert", CodePoints: []int{124}, Characters: []byte{0x7c}}, + "vfr": {Name: "vfr", CodePoints: []int{120115}, Characters: []byte{0xf0, 0x9d, 0x94, 0xb3}}, + "vltri": {Name: "vltri", CodePoints: []int{8882}, Characters: []byte{0xe2, 0x8a, 0xb2}}, + "vnsub": {Name: "vnsub", CodePoints: []int{8834, 8402}, Characters: []byte{0xe2, 0x8a, 0x82, 0xe2, 0x83, 0x92}}, + "vnsup": {Name: "vnsup", CodePoints: []int{8835, 8402}, Characters: []byte{0xe2, 0x8a, 0x83, 0xe2, 0x83, 0x92}}, + "vopf": {Name: "vopf", CodePoints: []int{120167}, Characters: []byte{0xf0, 0x9d, 0x95, 0xa7}}, + "vprop": {Name: "vprop", CodePoints: []int{8733}, Characters: []byte{0xe2, 0x88, 0x9d}}, + "vrtri": {Name: "vrtri", CodePoints: []int{8883}, Characters: []byte{0xe2, 0x8a, 0xb3}}, + "vscr": {Name: "vscr", CodePoints: []int{120011}, Characters: []byte{0xf0, 0x9d, 0x93, 0x8b}}, + "vsubnE": {Name: "vsubnE", CodePoints: []int{10955, 65024}, Characters: []byte{0xe2, 0xab, 0x8b, 0xef, 0xb8, 0x80}}, + "vsubne": {Name: "vsubne", CodePoints: []int{8842, 65024}, Characters: []byte{0xe2, 0x8a, 0x8a, 0xef, 0xb8, 0x80}}, + "vsupnE": {Name: "vsupnE", CodePoints: []int{10956, 65024}, Characters: []byte{0xe2, 0xab, 0x8c, 0xef, 0xb8, 0x80}}, + "vsupne": {Name: "vsupne", CodePoints: []int{8843, 65024}, Characters: []byte{0xe2, 0x8a, 0x8b, 0xef, 0xb8, 0x80}}, + "vzigzag": {Name: "vzigzag", CodePoints: []int{10650}, Characters: []byte{0xe2, 0xa6, 0x9a}}, + "wcirc": {Name: "wcirc", CodePoints: []int{373}, Characters: []byte{0xc5, 0xb5}}, + "wedbar": {Name: "wedbar", CodePoints: []int{10847}, Characters: []byte{0xe2, 0xa9, 0x9f}}, + "wedge": {Name: "wedge", CodePoints: []int{8743}, Characters: []byte{0xe2, 0x88, 0xa7}}, + "wedgeq": {Name: "wedgeq", CodePoints: []int{8793}, Characters: []byte{0xe2, 0x89, 0x99}}, + "weierp": {Name: "weierp", CodePoints: []int{8472}, Characters: []byte{0xe2, 0x84, 0x98}}, + "wfr": {Name: "wfr", CodePoints: []int{120116}, Characters: []byte{0xf0, 0x9d, 0x94, 0xb4}}, + "wopf": {Name: "wopf", CodePoints: []int{120168}, Characters: []byte{0xf0, 0x9d, 0x95, 0xa8}}, + "wp": {Name: "wp", CodePoints: []int{8472}, Characters: []byte{0xe2, 0x84, 0x98}}, + "wr": {Name: "wr", CodePoints: []int{8768}, Characters: []byte{0xe2, 0x89, 0x80}}, + "wreath": {Name: "wreath", CodePoints: []int{8768}, Characters: []byte{0xe2, 0x89, 0x80}}, + "wscr": {Name: "wscr", CodePoints: []int{120012}, Characters: []byte{0xf0, 0x9d, 0x93, 0x8c}}, + "xcap": {Name: "xcap", CodePoints: []int{8898}, Characters: []byte{0xe2, 0x8b, 0x82}}, + "xcirc": {Name: "xcirc", CodePoints: []int{9711}, Characters: []byte{0xe2, 0x97, 0xaf}}, + "xcup": {Name: "xcup", CodePoints: []int{8899}, Characters: []byte{0xe2, 0x8b, 0x83}}, + "xdtri": {Name: "xdtri", CodePoints: []int{9661}, Characters: []byte{0xe2, 0x96, 0xbd}}, + "xfr": {Name: "xfr", CodePoints: []int{120117}, Characters: []byte{0xf0, 0x9d, 0x94, 0xb5}}, + "xhArr": {Name: "xhArr", CodePoints: []int{10234}, Characters: []byte{0xe2, 0x9f, 0xba}}, + "xharr": {Name: "xharr", CodePoints: []int{10231}, Characters: []byte{0xe2, 0x9f, 0xb7}}, + "xi": {Name: "xi", CodePoints: []int{958}, Characters: []byte{0xce, 0xbe}}, + "xlArr": {Name: "xlArr", CodePoints: []int{10232}, Characters: []byte{0xe2, 0x9f, 0xb8}}, + "xlarr": {Name: "xlarr", CodePoints: []int{10229}, Characters: []byte{0xe2, 0x9f, 0xb5}}, + "xmap": {Name: "xmap", CodePoints: []int{10236}, Characters: []byte{0xe2, 0x9f, 0xbc}}, + "xnis": {Name: "xnis", CodePoints: []int{8955}, Characters: []byte{0xe2, 0x8b, 0xbb}}, + "xodot": {Name: "xodot", CodePoints: []int{10752}, Characters: []byte{0xe2, 0xa8, 0x80}}, + "xopf": {Name: "xopf", CodePoints: []int{120169}, Characters: []byte{0xf0, 0x9d, 0x95, 0xa9}}, + "xoplus": {Name: "xoplus", CodePoints: []int{10753}, Characters: []byte{0xe2, 0xa8, 0x81}}, + "xotime": {Name: "xotime", CodePoints: []int{10754}, Characters: []byte{0xe2, 0xa8, 0x82}}, + "xrArr": {Name: "xrArr", CodePoints: []int{10233}, Characters: []byte{0xe2, 0x9f, 0xb9}}, + "xrarr": {Name: "xrarr", CodePoints: []int{10230}, Characters: []byte{0xe2, 0x9f, 0xb6}}, + "xscr": {Name: "xscr", CodePoints: []int{120013}, Characters: []byte{0xf0, 0x9d, 0x93, 0x8d}}, + "xsqcup": {Name: "xsqcup", CodePoints: []int{10758}, Characters: []byte{0xe2, 0xa8, 0x86}}, + "xuplus": {Name: "xuplus", CodePoints: []int{10756}, Characters: []byte{0xe2, 0xa8, 0x84}}, + "xutri": {Name: "xutri", CodePoints: []int{9651}, Characters: []byte{0xe2, 0x96, 0xb3}}, + "xvee": {Name: "xvee", CodePoints: []int{8897}, Characters: []byte{0xe2, 0x8b, 0x81}}, + "xwedge": {Name: "xwedge", CodePoints: []int{8896}, Characters: []byte{0xe2, 0x8b, 0x80}}, + "yacute": {Name: "yacute", CodePoints: []int{253}, Characters: []byte{0xc3, 0xbd}}, + "yacy": {Name: "yacy", CodePoints: []int{1103}, Characters: []byte{0xd1, 0x8f}}, + "ycirc": {Name: "ycirc", CodePoints: []int{375}, Characters: []byte{0xc5, 0xb7}}, + "ycy": {Name: "ycy", CodePoints: []int{1099}, Characters: []byte{0xd1, 0x8b}}, + "yen": {Name: "yen", CodePoints: []int{165}, Characters: []byte{0xc2, 0xa5}}, + "yfr": {Name: "yfr", CodePoints: []int{120118}, Characters: []byte{0xf0, 0x9d, 0x94, 0xb6}}, + "yicy": {Name: "yicy", CodePoints: []int{1111}, Characters: []byte{0xd1, 0x97}}, + "yopf": {Name: "yopf", CodePoints: []int{120170}, Characters: []byte{0xf0, 0x9d, 0x95, 0xaa}}, + "yscr": {Name: "yscr", CodePoints: []int{120014}, Characters: []byte{0xf0, 0x9d, 0x93, 0x8e}}, + "yucy": {Name: "yucy", CodePoints: []int{1102}, Characters: []byte{0xd1, 0x8e}}, + "yuml": {Name: "yuml", CodePoints: []int{255}, Characters: []byte{0xc3, 0xbf}}, + "zacute": {Name: "zacute", CodePoints: []int{378}, Characters: []byte{0xc5, 0xba}}, + "zcaron": {Name: "zcaron", CodePoints: []int{382}, Characters: []byte{0xc5, 0xbe}}, + "zcy": {Name: "zcy", CodePoints: []int{1079}, Characters: []byte{0xd0, 0xb7}}, + "zdot": {Name: "zdot", CodePoints: []int{380}, Characters: []byte{0xc5, 0xbc}}, + "zeetrf": {Name: "zeetrf", CodePoints: []int{8488}, Characters: []byte{0xe2, 0x84, 0xa8}}, + "zeta": {Name: "zeta", CodePoints: []int{950}, Characters: []byte{0xce, 0xb6}}, + "zfr": {Name: "zfr", CodePoints: []int{120119}, Characters: []byte{0xf0, 0x9d, 0x94, 0xb7}}, + "zhcy": {Name: "zhcy", CodePoints: []int{1078}, Characters: []byte{0xd0, 0xb6}}, + "zigrarr": {Name: "zigrarr", CodePoints: []int{8669}, Characters: []byte{0xe2, 0x87, 0x9d}}, + "zopf": {Name: "zopf", CodePoints: []int{120171}, Characters: []byte{0xf0, 0x9d, 0x95, 0xab}}, + "zscr": {Name: "zscr", CodePoints: []int{120015}, Characters: []byte{0xf0, 0x9d, 0x93, 0x8f}}, + "zwj": {Name: "zwj", CodePoints: []int{8205}, Characters: []byte{0xe2, 0x80, 0x8d}}, + "zwnj": {Name: "zwnj", CodePoints: []int{8204}, Characters: []byte{0xe2, 0x80, 0x8c}}, +} diff --git a/vendor/github.com/yuin/goldmark/util/unicode_case_folding.go b/vendor/github.com/yuin/goldmark/util/unicode_case_folding.go new file mode 100644 index 0000000..ab93ba4 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/util/unicode_case_folding.go @@ -0,0 +1,1535 @@ +//nolint:all +package util + +var unicodeCaseFoldings = map[rune][]rune{ + 0x41: []int32{97}, + 0x42: []int32{98}, + 0x43: []int32{99}, + 0x44: []int32{100}, + 0x45: []int32{101}, + 0x46: []int32{102}, + 0x47: []int32{103}, + 0x48: []int32{104}, + 0x49: []int32{105}, + 0x4a: []int32{106}, + 0x4b: []int32{107}, + 0x4c: []int32{108}, + 0x4d: []int32{109}, + 0x4e: []int32{110}, + 0x4f: []int32{111}, + 0x50: []int32{112}, + 0x51: []int32{113}, + 0x52: []int32{114}, + 0x53: []int32{115}, + 0x54: []int32{116}, + 0x55: []int32{117}, + 0x56: []int32{118}, + 0x57: []int32{119}, + 0x58: []int32{120}, + 0x59: []int32{121}, + 0x5a: []int32{122}, + 0xb5: []int32{956}, + 0xc0: []int32{224}, + 0xc1: []int32{225}, + 0xc2: []int32{226}, + 0xc3: []int32{227}, + 0xc4: []int32{228}, + 0xc5: []int32{229}, + 0xc6: []int32{230}, + 0xc7: []int32{231}, + 0xc8: []int32{232}, + 0xc9: []int32{233}, + 0xca: []int32{234}, + 0xcb: []int32{235}, + 0xcc: []int32{236}, + 0xcd: []int32{237}, + 0xce: []int32{238}, + 0xcf: []int32{239}, + 0xd0: []int32{240}, + 0xd1: []int32{241}, + 0xd2: []int32{242}, + 0xd3: []int32{243}, + 0xd4: []int32{244}, + 0xd5: []int32{245}, + 0xd6: []int32{246}, + 0xd8: []int32{248}, + 0xd9: []int32{249}, + 0xda: []int32{250}, + 0xdb: []int32{251}, + 0xdc: []int32{252}, + 0xdd: []int32{253}, + 0xde: []int32{254}, + 0xdf: []int32{115, 115}, + 0x100: []int32{257}, + 0x102: []int32{259}, + 0x104: []int32{261}, + 0x106: []int32{263}, + 0x108: []int32{265}, + 0x10a: []int32{267}, + 0x10c: []int32{269}, + 0x10e: []int32{271}, + 0x110: []int32{273}, + 0x112: []int32{275}, + 0x114: []int32{277}, + 0x116: []int32{279}, + 0x118: []int32{281}, + 0x11a: []int32{283}, + 0x11c: []int32{285}, + 0x11e: []int32{287}, + 0x120: []int32{289}, + 0x122: []int32{291}, + 0x124: []int32{293}, + 0x126: []int32{295}, + 0x128: []int32{297}, + 0x12a: []int32{299}, + 0x12c: []int32{301}, + 0x12e: []int32{303}, + 0x130: []int32{105, 775}, + 0x132: []int32{307}, + 0x134: []int32{309}, + 0x136: []int32{311}, + 0x139: []int32{314}, + 0x13b: []int32{316}, + 0x13d: []int32{318}, + 0x13f: []int32{320}, + 0x141: []int32{322}, + 0x143: []int32{324}, + 0x145: []int32{326}, + 0x147: []int32{328}, + 0x149: []int32{700, 110}, + 0x14a: []int32{331}, + 0x14c: []int32{333}, + 0x14e: []int32{335}, + 0x150: []int32{337}, + 0x152: []int32{339}, + 0x154: []int32{341}, + 0x156: []int32{343}, + 0x158: []int32{345}, + 0x15a: []int32{347}, + 0x15c: []int32{349}, + 0x15e: []int32{351}, + 0x160: []int32{353}, + 0x162: []int32{355}, + 0x164: []int32{357}, + 0x166: []int32{359}, + 0x168: []int32{361}, + 0x16a: []int32{363}, + 0x16c: []int32{365}, + 0x16e: []int32{367}, + 0x170: []int32{369}, + 0x172: []int32{371}, + 0x174: []int32{373}, + 0x176: []int32{375}, + 0x178: []int32{255}, + 0x179: []int32{378}, + 0x17b: []int32{380}, + 0x17d: []int32{382}, + 0x17f: []int32{115}, + 0x181: []int32{595}, + 0x182: []int32{387}, + 0x184: []int32{389}, + 0x186: []int32{596}, + 0x187: []int32{392}, + 0x189: []int32{598}, + 0x18a: []int32{599}, + 0x18b: []int32{396}, + 0x18e: []int32{477}, + 0x18f: []int32{601}, + 0x190: []int32{603}, + 0x191: []int32{402}, + 0x193: []int32{608}, + 0x194: []int32{611}, + 0x196: []int32{617}, + 0x197: []int32{616}, + 0x198: []int32{409}, + 0x19c: []int32{623}, + 0x19d: []int32{626}, + 0x19f: []int32{629}, + 0x1a0: []int32{417}, + 0x1a2: []int32{419}, + 0x1a4: []int32{421}, + 0x1a6: []int32{640}, + 0x1a7: []int32{424}, + 0x1a9: []int32{643}, + 0x1ac: []int32{429}, + 0x1ae: []int32{648}, + 0x1af: []int32{432}, + 0x1b1: []int32{650}, + 0x1b2: []int32{651}, + 0x1b3: []int32{436}, + 0x1b5: []int32{438}, + 0x1b7: []int32{658}, + 0x1b8: []int32{441}, + 0x1bc: []int32{445}, + 0x1c4: []int32{454}, + 0x1c5: []int32{454}, + 0x1c7: []int32{457}, + 0x1c8: []int32{457}, + 0x1ca: []int32{460}, + 0x1cb: []int32{460}, + 0x1cd: []int32{462}, + 0x1cf: []int32{464}, + 0x1d1: []int32{466}, + 0x1d3: []int32{468}, + 0x1d5: []int32{470}, + 0x1d7: []int32{472}, + 0x1d9: []int32{474}, + 0x1db: []int32{476}, + 0x1de: []int32{479}, + 0x1e0: []int32{481}, + 0x1e2: []int32{483}, + 0x1e4: []int32{485}, + 0x1e6: []int32{487}, + 0x1e8: []int32{489}, + 0x1ea: []int32{491}, + 0x1ec: []int32{493}, + 0x1ee: []int32{495}, + 0x1f0: []int32{106, 780}, + 0x1f1: []int32{499}, + 0x1f2: []int32{499}, + 0x1f4: []int32{501}, + 0x1f6: []int32{405}, + 0x1f7: []int32{447}, + 0x1f8: []int32{505}, + 0x1fa: []int32{507}, + 0x1fc: []int32{509}, + 0x1fe: []int32{511}, + 0x200: []int32{513}, + 0x202: []int32{515}, + 0x204: []int32{517}, + 0x206: []int32{519}, + 0x208: []int32{521}, + 0x20a: []int32{523}, + 0x20c: []int32{525}, + 0x20e: []int32{527}, + 0x210: []int32{529}, + 0x212: []int32{531}, + 0x214: []int32{533}, + 0x216: []int32{535}, + 0x218: []int32{537}, + 0x21a: []int32{539}, + 0x21c: []int32{541}, + 0x21e: []int32{543}, + 0x220: []int32{414}, + 0x222: []int32{547}, + 0x224: []int32{549}, + 0x226: []int32{551}, + 0x228: []int32{553}, + 0x22a: []int32{555}, + 0x22c: []int32{557}, + 0x22e: []int32{559}, + 0x230: []int32{561}, + 0x232: []int32{563}, + 0x23a: []int32{11365}, + 0x23b: []int32{572}, + 0x23d: []int32{410}, + 0x23e: []int32{11366}, + 0x241: []int32{578}, + 0x243: []int32{384}, + 0x244: []int32{649}, + 0x245: []int32{652}, + 0x246: []int32{583}, + 0x248: []int32{585}, + 0x24a: []int32{587}, + 0x24c: []int32{589}, + 0x24e: []int32{591}, + 0x345: []int32{953}, + 0x370: []int32{881}, + 0x372: []int32{883}, + 0x376: []int32{887}, + 0x37f: []int32{1011}, + 0x386: []int32{940}, + 0x388: []int32{941}, + 0x389: []int32{942}, + 0x38a: []int32{943}, + 0x38c: []int32{972}, + 0x38e: []int32{973}, + 0x38f: []int32{974}, + 0x390: []int32{953, 776, 769}, + 0x391: []int32{945}, + 0x392: []int32{946}, + 0x393: []int32{947}, + 0x394: []int32{948}, + 0x395: []int32{949}, + 0x396: []int32{950}, + 0x397: []int32{951}, + 0x398: []int32{952}, + 0x399: []int32{953}, + 0x39a: []int32{954}, + 0x39b: []int32{955}, + 0x39c: []int32{956}, + 0x39d: []int32{957}, + 0x39e: []int32{958}, + 0x39f: []int32{959}, + 0x3a0: []int32{960}, + 0x3a1: []int32{961}, + 0x3a3: []int32{963}, + 0x3a4: []int32{964}, + 0x3a5: []int32{965}, + 0x3a6: []int32{966}, + 0x3a7: []int32{967}, + 0x3a8: []int32{968}, + 0x3a9: []int32{969}, + 0x3aa: []int32{970}, + 0x3ab: []int32{971}, + 0x3b0: []int32{965, 776, 769}, + 0x3c2: []int32{963}, + 0x3cf: []int32{983}, + 0x3d0: []int32{946}, + 0x3d1: []int32{952}, + 0x3d5: []int32{966}, + 0x3d6: []int32{960}, + 0x3d8: []int32{985}, + 0x3da: []int32{987}, + 0x3dc: []int32{989}, + 0x3de: []int32{991}, + 0x3e0: []int32{993}, + 0x3e2: []int32{995}, + 0x3e4: []int32{997}, + 0x3e6: []int32{999}, + 0x3e8: []int32{1001}, + 0x3ea: []int32{1003}, + 0x3ec: []int32{1005}, + 0x3ee: []int32{1007}, + 0x3f0: []int32{954}, + 0x3f1: []int32{961}, + 0x3f4: []int32{952}, + 0x3f5: []int32{949}, + 0x3f7: []int32{1016}, + 0x3f9: []int32{1010}, + 0x3fa: []int32{1019}, + 0x3fd: []int32{891}, + 0x3fe: []int32{892}, + 0x3ff: []int32{893}, + 0x400: []int32{1104}, + 0x401: []int32{1105}, + 0x402: []int32{1106}, + 0x403: []int32{1107}, + 0x404: []int32{1108}, + 0x405: []int32{1109}, + 0x406: []int32{1110}, + 0x407: []int32{1111}, + 0x408: []int32{1112}, + 0x409: []int32{1113}, + 0x40a: []int32{1114}, + 0x40b: []int32{1115}, + 0x40c: []int32{1116}, + 0x40d: []int32{1117}, + 0x40e: []int32{1118}, + 0x40f: []int32{1119}, + 0x410: []int32{1072}, + 0x411: []int32{1073}, + 0x412: []int32{1074}, + 0x413: []int32{1075}, + 0x414: []int32{1076}, + 0x415: []int32{1077}, + 0x416: []int32{1078}, + 0x417: []int32{1079}, + 0x418: []int32{1080}, + 0x419: []int32{1081}, + 0x41a: []int32{1082}, + 0x41b: []int32{1083}, + 0x41c: []int32{1084}, + 0x41d: []int32{1085}, + 0x41e: []int32{1086}, + 0x41f: []int32{1087}, + 0x420: []int32{1088}, + 0x421: []int32{1089}, + 0x422: []int32{1090}, + 0x423: []int32{1091}, + 0x424: []int32{1092}, + 0x425: []int32{1093}, + 0x426: []int32{1094}, + 0x427: []int32{1095}, + 0x428: []int32{1096}, + 0x429: []int32{1097}, + 0x42a: []int32{1098}, + 0x42b: []int32{1099}, + 0x42c: []int32{1100}, + 0x42d: []int32{1101}, + 0x42e: []int32{1102}, + 0x42f: []int32{1103}, + 0x460: []int32{1121}, + 0x462: []int32{1123}, + 0x464: []int32{1125}, + 0x466: []int32{1127}, + 0x468: []int32{1129}, + 0x46a: []int32{1131}, + 0x46c: []int32{1133}, + 0x46e: []int32{1135}, + 0x470: []int32{1137}, + 0x472: []int32{1139}, + 0x474: []int32{1141}, + 0x476: []int32{1143}, + 0x478: []int32{1145}, + 0x47a: []int32{1147}, + 0x47c: []int32{1149}, + 0x47e: []int32{1151}, + 0x480: []int32{1153}, + 0x48a: []int32{1163}, + 0x48c: []int32{1165}, + 0x48e: []int32{1167}, + 0x490: []int32{1169}, + 0x492: []int32{1171}, + 0x494: []int32{1173}, + 0x496: []int32{1175}, + 0x498: []int32{1177}, + 0x49a: []int32{1179}, + 0x49c: []int32{1181}, + 0x49e: []int32{1183}, + 0x4a0: []int32{1185}, + 0x4a2: []int32{1187}, + 0x4a4: []int32{1189}, + 0x4a6: []int32{1191}, + 0x4a8: []int32{1193}, + 0x4aa: []int32{1195}, + 0x4ac: []int32{1197}, + 0x4ae: []int32{1199}, + 0x4b0: []int32{1201}, + 0x4b2: []int32{1203}, + 0x4b4: []int32{1205}, + 0x4b6: []int32{1207}, + 0x4b8: []int32{1209}, + 0x4ba: []int32{1211}, + 0x4bc: []int32{1213}, + 0x4be: []int32{1215}, + 0x4c0: []int32{1231}, + 0x4c1: []int32{1218}, + 0x4c3: []int32{1220}, + 0x4c5: []int32{1222}, + 0x4c7: []int32{1224}, + 0x4c9: []int32{1226}, + 0x4cb: []int32{1228}, + 0x4cd: []int32{1230}, + 0x4d0: []int32{1233}, + 0x4d2: []int32{1235}, + 0x4d4: []int32{1237}, + 0x4d6: []int32{1239}, + 0x4d8: []int32{1241}, + 0x4da: []int32{1243}, + 0x4dc: []int32{1245}, + 0x4de: []int32{1247}, + 0x4e0: []int32{1249}, + 0x4e2: []int32{1251}, + 0x4e4: []int32{1253}, + 0x4e6: []int32{1255}, + 0x4e8: []int32{1257}, + 0x4ea: []int32{1259}, + 0x4ec: []int32{1261}, + 0x4ee: []int32{1263}, + 0x4f0: []int32{1265}, + 0x4f2: []int32{1267}, + 0x4f4: []int32{1269}, + 0x4f6: []int32{1271}, + 0x4f8: []int32{1273}, + 0x4fa: []int32{1275}, + 0x4fc: []int32{1277}, + 0x4fe: []int32{1279}, + 0x500: []int32{1281}, + 0x502: []int32{1283}, + 0x504: []int32{1285}, + 0x506: []int32{1287}, + 0x508: []int32{1289}, + 0x50a: []int32{1291}, + 0x50c: []int32{1293}, + 0x50e: []int32{1295}, + 0x510: []int32{1297}, + 0x512: []int32{1299}, + 0x514: []int32{1301}, + 0x516: []int32{1303}, + 0x518: []int32{1305}, + 0x51a: []int32{1307}, + 0x51c: []int32{1309}, + 0x51e: []int32{1311}, + 0x520: []int32{1313}, + 0x522: []int32{1315}, + 0x524: []int32{1317}, + 0x526: []int32{1319}, + 0x528: []int32{1321}, + 0x52a: []int32{1323}, + 0x52c: []int32{1325}, + 0x52e: []int32{1327}, + 0x531: []int32{1377}, + 0x532: []int32{1378}, + 0x533: []int32{1379}, + 0x534: []int32{1380}, + 0x535: []int32{1381}, + 0x536: []int32{1382}, + 0x537: []int32{1383}, + 0x538: []int32{1384}, + 0x539: []int32{1385}, + 0x53a: []int32{1386}, + 0x53b: []int32{1387}, + 0x53c: []int32{1388}, + 0x53d: []int32{1389}, + 0x53e: []int32{1390}, + 0x53f: []int32{1391}, + 0x540: []int32{1392}, + 0x541: []int32{1393}, + 0x542: []int32{1394}, + 0x543: []int32{1395}, + 0x544: []int32{1396}, + 0x545: []int32{1397}, + 0x546: []int32{1398}, + 0x547: []int32{1399}, + 0x548: []int32{1400}, + 0x549: []int32{1401}, + 0x54a: []int32{1402}, + 0x54b: []int32{1403}, + 0x54c: []int32{1404}, + 0x54d: []int32{1405}, + 0x54e: []int32{1406}, + 0x54f: []int32{1407}, + 0x550: []int32{1408}, + 0x551: []int32{1409}, + 0x552: []int32{1410}, + 0x553: []int32{1411}, + 0x554: []int32{1412}, + 0x555: []int32{1413}, + 0x556: []int32{1414}, + 0x587: []int32{1381, 1410}, + 0x10a0: []int32{11520}, + 0x10a1: []int32{11521}, + 0x10a2: []int32{11522}, + 0x10a3: []int32{11523}, + 0x10a4: []int32{11524}, + 0x10a5: []int32{11525}, + 0x10a6: []int32{11526}, + 0x10a7: []int32{11527}, + 0x10a8: []int32{11528}, + 0x10a9: []int32{11529}, + 0x10aa: []int32{11530}, + 0x10ab: []int32{11531}, + 0x10ac: []int32{11532}, + 0x10ad: []int32{11533}, + 0x10ae: []int32{11534}, + 0x10af: []int32{11535}, + 0x10b0: []int32{11536}, + 0x10b1: []int32{11537}, + 0x10b2: []int32{11538}, + 0x10b3: []int32{11539}, + 0x10b4: []int32{11540}, + 0x10b5: []int32{11541}, + 0x10b6: []int32{11542}, + 0x10b7: []int32{11543}, + 0x10b8: []int32{11544}, + 0x10b9: []int32{11545}, + 0x10ba: []int32{11546}, + 0x10bb: []int32{11547}, + 0x10bc: []int32{11548}, + 0x10bd: []int32{11549}, + 0x10be: []int32{11550}, + 0x10bf: []int32{11551}, + 0x10c0: []int32{11552}, + 0x10c1: []int32{11553}, + 0x10c2: []int32{11554}, + 0x10c3: []int32{11555}, + 0x10c4: []int32{11556}, + 0x10c5: []int32{11557}, + 0x10c7: []int32{11559}, + 0x10cd: []int32{11565}, + 0x13f8: []int32{5104}, + 0x13f9: []int32{5105}, + 0x13fa: []int32{5106}, + 0x13fb: []int32{5107}, + 0x13fc: []int32{5108}, + 0x13fd: []int32{5109}, + 0x1c80: []int32{1074}, + 0x1c81: []int32{1076}, + 0x1c82: []int32{1086}, + 0x1c83: []int32{1089}, + 0x1c84: []int32{1090}, + 0x1c85: []int32{1090}, + 0x1c86: []int32{1098}, + 0x1c87: []int32{1123}, + 0x1c88: []int32{42571}, + 0x1c90: []int32{4304}, + 0x1c91: []int32{4305}, + 0x1c92: []int32{4306}, + 0x1c93: []int32{4307}, + 0x1c94: []int32{4308}, + 0x1c95: []int32{4309}, + 0x1c96: []int32{4310}, + 0x1c97: []int32{4311}, + 0x1c98: []int32{4312}, + 0x1c99: []int32{4313}, + 0x1c9a: []int32{4314}, + 0x1c9b: []int32{4315}, + 0x1c9c: []int32{4316}, + 0x1c9d: []int32{4317}, + 0x1c9e: []int32{4318}, + 0x1c9f: []int32{4319}, + 0x1ca0: []int32{4320}, + 0x1ca1: []int32{4321}, + 0x1ca2: []int32{4322}, + 0x1ca3: []int32{4323}, + 0x1ca4: []int32{4324}, + 0x1ca5: []int32{4325}, + 0x1ca6: []int32{4326}, + 0x1ca7: []int32{4327}, + 0x1ca8: []int32{4328}, + 0x1ca9: []int32{4329}, + 0x1caa: []int32{4330}, + 0x1cab: []int32{4331}, + 0x1cac: []int32{4332}, + 0x1cad: []int32{4333}, + 0x1cae: []int32{4334}, + 0x1caf: []int32{4335}, + 0x1cb0: []int32{4336}, + 0x1cb1: []int32{4337}, + 0x1cb2: []int32{4338}, + 0x1cb3: []int32{4339}, + 0x1cb4: []int32{4340}, + 0x1cb5: []int32{4341}, + 0x1cb6: []int32{4342}, + 0x1cb7: []int32{4343}, + 0x1cb8: []int32{4344}, + 0x1cb9: []int32{4345}, + 0x1cba: []int32{4346}, + 0x1cbd: []int32{4349}, + 0x1cbe: []int32{4350}, + 0x1cbf: []int32{4351}, + 0x1e00: []int32{7681}, + 0x1e02: []int32{7683}, + 0x1e04: []int32{7685}, + 0x1e06: []int32{7687}, + 0x1e08: []int32{7689}, + 0x1e0a: []int32{7691}, + 0x1e0c: []int32{7693}, + 0x1e0e: []int32{7695}, + 0x1e10: []int32{7697}, + 0x1e12: []int32{7699}, + 0x1e14: []int32{7701}, + 0x1e16: []int32{7703}, + 0x1e18: []int32{7705}, + 0x1e1a: []int32{7707}, + 0x1e1c: []int32{7709}, + 0x1e1e: []int32{7711}, + 0x1e20: []int32{7713}, + 0x1e22: []int32{7715}, + 0x1e24: []int32{7717}, + 0x1e26: []int32{7719}, + 0x1e28: []int32{7721}, + 0x1e2a: []int32{7723}, + 0x1e2c: []int32{7725}, + 0x1e2e: []int32{7727}, + 0x1e30: []int32{7729}, + 0x1e32: []int32{7731}, + 0x1e34: []int32{7733}, + 0x1e36: []int32{7735}, + 0x1e38: []int32{7737}, + 0x1e3a: []int32{7739}, + 0x1e3c: []int32{7741}, + 0x1e3e: []int32{7743}, + 0x1e40: []int32{7745}, + 0x1e42: []int32{7747}, + 0x1e44: []int32{7749}, + 0x1e46: []int32{7751}, + 0x1e48: []int32{7753}, + 0x1e4a: []int32{7755}, + 0x1e4c: []int32{7757}, + 0x1e4e: []int32{7759}, + 0x1e50: []int32{7761}, + 0x1e52: []int32{7763}, + 0x1e54: []int32{7765}, + 0x1e56: []int32{7767}, + 0x1e58: []int32{7769}, + 0x1e5a: []int32{7771}, + 0x1e5c: []int32{7773}, + 0x1e5e: []int32{7775}, + 0x1e60: []int32{7777}, + 0x1e62: []int32{7779}, + 0x1e64: []int32{7781}, + 0x1e66: []int32{7783}, + 0x1e68: []int32{7785}, + 0x1e6a: []int32{7787}, + 0x1e6c: []int32{7789}, + 0x1e6e: []int32{7791}, + 0x1e70: []int32{7793}, + 0x1e72: []int32{7795}, + 0x1e74: []int32{7797}, + 0x1e76: []int32{7799}, + 0x1e78: []int32{7801}, + 0x1e7a: []int32{7803}, + 0x1e7c: []int32{7805}, + 0x1e7e: []int32{7807}, + 0x1e80: []int32{7809}, + 0x1e82: []int32{7811}, + 0x1e84: []int32{7813}, + 0x1e86: []int32{7815}, + 0x1e88: []int32{7817}, + 0x1e8a: []int32{7819}, + 0x1e8c: []int32{7821}, + 0x1e8e: []int32{7823}, + 0x1e90: []int32{7825}, + 0x1e92: []int32{7827}, + 0x1e94: []int32{7829}, + 0x1e96: []int32{104, 817}, + 0x1e97: []int32{116, 776}, + 0x1e98: []int32{119, 778}, + 0x1e99: []int32{121, 778}, + 0x1e9a: []int32{97, 702}, + 0x1e9b: []int32{7777}, + 0x1e9e: []int32{115, 115}, + 0x1ea0: []int32{7841}, + 0x1ea2: []int32{7843}, + 0x1ea4: []int32{7845}, + 0x1ea6: []int32{7847}, + 0x1ea8: []int32{7849}, + 0x1eaa: []int32{7851}, + 0x1eac: []int32{7853}, + 0x1eae: []int32{7855}, + 0x1eb0: []int32{7857}, + 0x1eb2: []int32{7859}, + 0x1eb4: []int32{7861}, + 0x1eb6: []int32{7863}, + 0x1eb8: []int32{7865}, + 0x1eba: []int32{7867}, + 0x1ebc: []int32{7869}, + 0x1ebe: []int32{7871}, + 0x1ec0: []int32{7873}, + 0x1ec2: []int32{7875}, + 0x1ec4: []int32{7877}, + 0x1ec6: []int32{7879}, + 0x1ec8: []int32{7881}, + 0x1eca: []int32{7883}, + 0x1ecc: []int32{7885}, + 0x1ece: []int32{7887}, + 0x1ed0: []int32{7889}, + 0x1ed2: []int32{7891}, + 0x1ed4: []int32{7893}, + 0x1ed6: []int32{7895}, + 0x1ed8: []int32{7897}, + 0x1eda: []int32{7899}, + 0x1edc: []int32{7901}, + 0x1ede: []int32{7903}, + 0x1ee0: []int32{7905}, + 0x1ee2: []int32{7907}, + 0x1ee4: []int32{7909}, + 0x1ee6: []int32{7911}, + 0x1ee8: []int32{7913}, + 0x1eea: []int32{7915}, + 0x1eec: []int32{7917}, + 0x1eee: []int32{7919}, + 0x1ef0: []int32{7921}, + 0x1ef2: []int32{7923}, + 0x1ef4: []int32{7925}, + 0x1ef6: []int32{7927}, + 0x1ef8: []int32{7929}, + 0x1efa: []int32{7931}, + 0x1efc: []int32{7933}, + 0x1efe: []int32{7935}, + 0x1f08: []int32{7936}, + 0x1f09: []int32{7937}, + 0x1f0a: []int32{7938}, + 0x1f0b: []int32{7939}, + 0x1f0c: []int32{7940}, + 0x1f0d: []int32{7941}, + 0x1f0e: []int32{7942}, + 0x1f0f: []int32{7943}, + 0x1f18: []int32{7952}, + 0x1f19: []int32{7953}, + 0x1f1a: []int32{7954}, + 0x1f1b: []int32{7955}, + 0x1f1c: []int32{7956}, + 0x1f1d: []int32{7957}, + 0x1f28: []int32{7968}, + 0x1f29: []int32{7969}, + 0x1f2a: []int32{7970}, + 0x1f2b: []int32{7971}, + 0x1f2c: []int32{7972}, + 0x1f2d: []int32{7973}, + 0x1f2e: []int32{7974}, + 0x1f2f: []int32{7975}, + 0x1f38: []int32{7984}, + 0x1f39: []int32{7985}, + 0x1f3a: []int32{7986}, + 0x1f3b: []int32{7987}, + 0x1f3c: []int32{7988}, + 0x1f3d: []int32{7989}, + 0x1f3e: []int32{7990}, + 0x1f3f: []int32{7991}, + 0x1f48: []int32{8000}, + 0x1f49: []int32{8001}, + 0x1f4a: []int32{8002}, + 0x1f4b: []int32{8003}, + 0x1f4c: []int32{8004}, + 0x1f4d: []int32{8005}, + 0x1f50: []int32{965, 787}, + 0x1f52: []int32{965, 787, 768}, + 0x1f54: []int32{965, 787, 769}, + 0x1f56: []int32{965, 787, 834}, + 0x1f59: []int32{8017}, + 0x1f5b: []int32{8019}, + 0x1f5d: []int32{8021}, + 0x1f5f: []int32{8023}, + 0x1f68: []int32{8032}, + 0x1f69: []int32{8033}, + 0x1f6a: []int32{8034}, + 0x1f6b: []int32{8035}, + 0x1f6c: []int32{8036}, + 0x1f6d: []int32{8037}, + 0x1f6e: []int32{8038}, + 0x1f6f: []int32{8039}, + 0x1f80: []int32{7936, 953}, + 0x1f81: []int32{7937, 953}, + 0x1f82: []int32{7938, 953}, + 0x1f83: []int32{7939, 953}, + 0x1f84: []int32{7940, 953}, + 0x1f85: []int32{7941, 953}, + 0x1f86: []int32{7942, 953}, + 0x1f87: []int32{7943, 953}, + 0x1f88: []int32{7936, 953}, + 0x1f89: []int32{7937, 953}, + 0x1f8a: []int32{7938, 953}, + 0x1f8b: []int32{7939, 953}, + 0x1f8c: []int32{7940, 953}, + 0x1f8d: []int32{7941, 953}, + 0x1f8e: []int32{7942, 953}, + 0x1f8f: []int32{7943, 953}, + 0x1f90: []int32{7968, 953}, + 0x1f91: []int32{7969, 953}, + 0x1f92: []int32{7970, 953}, + 0x1f93: []int32{7971, 953}, + 0x1f94: []int32{7972, 953}, + 0x1f95: []int32{7973, 953}, + 0x1f96: []int32{7974, 953}, + 0x1f97: []int32{7975, 953}, + 0x1f98: []int32{7968, 953}, + 0x1f99: []int32{7969, 953}, + 0x1f9a: []int32{7970, 953}, + 0x1f9b: []int32{7971, 953}, + 0x1f9c: []int32{7972, 953}, + 0x1f9d: []int32{7973, 953}, + 0x1f9e: []int32{7974, 953}, + 0x1f9f: []int32{7975, 953}, + 0x1fa0: []int32{8032, 953}, + 0x1fa1: []int32{8033, 953}, + 0x1fa2: []int32{8034, 953}, + 0x1fa3: []int32{8035, 953}, + 0x1fa4: []int32{8036, 953}, + 0x1fa5: []int32{8037, 953}, + 0x1fa6: []int32{8038, 953}, + 0x1fa7: []int32{8039, 953}, + 0x1fa8: []int32{8032, 953}, + 0x1fa9: []int32{8033, 953}, + 0x1faa: []int32{8034, 953}, + 0x1fab: []int32{8035, 953}, + 0x1fac: []int32{8036, 953}, + 0x1fad: []int32{8037, 953}, + 0x1fae: []int32{8038, 953}, + 0x1faf: []int32{8039, 953}, + 0x1fb2: []int32{8048, 953}, + 0x1fb3: []int32{945, 953}, + 0x1fb4: []int32{940, 953}, + 0x1fb6: []int32{945, 834}, + 0x1fb7: []int32{945, 834, 953}, + 0x1fb8: []int32{8112}, + 0x1fb9: []int32{8113}, + 0x1fba: []int32{8048}, + 0x1fbb: []int32{8049}, + 0x1fbc: []int32{945, 953}, + 0x1fbe: []int32{953}, + 0x1fc2: []int32{8052, 953}, + 0x1fc3: []int32{951, 953}, + 0x1fc4: []int32{942, 953}, + 0x1fc6: []int32{951, 834}, + 0x1fc7: []int32{951, 834, 953}, + 0x1fc8: []int32{8050}, + 0x1fc9: []int32{8051}, + 0x1fca: []int32{8052}, + 0x1fcb: []int32{8053}, + 0x1fcc: []int32{951, 953}, + 0x1fd2: []int32{953, 776, 768}, + 0x1fd3: []int32{953, 776, 769}, + 0x1fd6: []int32{953, 834}, + 0x1fd7: []int32{953, 776, 834}, + 0x1fd8: []int32{8144}, + 0x1fd9: []int32{8145}, + 0x1fda: []int32{8054}, + 0x1fdb: []int32{8055}, + 0x1fe2: []int32{965, 776, 768}, + 0x1fe3: []int32{965, 776, 769}, + 0x1fe4: []int32{961, 787}, + 0x1fe6: []int32{965, 834}, + 0x1fe7: []int32{965, 776, 834}, + 0x1fe8: []int32{8160}, + 0x1fe9: []int32{8161}, + 0x1fea: []int32{8058}, + 0x1feb: []int32{8059}, + 0x1fec: []int32{8165}, + 0x1ff2: []int32{8060, 953}, + 0x1ff3: []int32{969, 953}, + 0x1ff4: []int32{974, 953}, + 0x1ff6: []int32{969, 834}, + 0x1ff7: []int32{969, 834, 953}, + 0x1ff8: []int32{8056}, + 0x1ff9: []int32{8057}, + 0x1ffa: []int32{8060}, + 0x1ffb: []int32{8061}, + 0x1ffc: []int32{969, 953}, + 0x2126: []int32{969}, + 0x212a: []int32{107}, + 0x212b: []int32{229}, + 0x2132: []int32{8526}, + 0x2160: []int32{8560}, + 0x2161: []int32{8561}, + 0x2162: []int32{8562}, + 0x2163: []int32{8563}, + 0x2164: []int32{8564}, + 0x2165: []int32{8565}, + 0x2166: []int32{8566}, + 0x2167: []int32{8567}, + 0x2168: []int32{8568}, + 0x2169: []int32{8569}, + 0x216a: []int32{8570}, + 0x216b: []int32{8571}, + 0x216c: []int32{8572}, + 0x216d: []int32{8573}, + 0x216e: []int32{8574}, + 0x216f: []int32{8575}, + 0x2183: []int32{8580}, + 0x24b6: []int32{9424}, + 0x24b7: []int32{9425}, + 0x24b8: []int32{9426}, + 0x24b9: []int32{9427}, + 0x24ba: []int32{9428}, + 0x24bb: []int32{9429}, + 0x24bc: []int32{9430}, + 0x24bd: []int32{9431}, + 0x24be: []int32{9432}, + 0x24bf: []int32{9433}, + 0x24c0: []int32{9434}, + 0x24c1: []int32{9435}, + 0x24c2: []int32{9436}, + 0x24c3: []int32{9437}, + 0x24c4: []int32{9438}, + 0x24c5: []int32{9439}, + 0x24c6: []int32{9440}, + 0x24c7: []int32{9441}, + 0x24c8: []int32{9442}, + 0x24c9: []int32{9443}, + 0x24ca: []int32{9444}, + 0x24cb: []int32{9445}, + 0x24cc: []int32{9446}, + 0x24cd: []int32{9447}, + 0x24ce: []int32{9448}, + 0x24cf: []int32{9449}, + 0x2c00: []int32{11312}, + 0x2c01: []int32{11313}, + 0x2c02: []int32{11314}, + 0x2c03: []int32{11315}, + 0x2c04: []int32{11316}, + 0x2c05: []int32{11317}, + 0x2c06: []int32{11318}, + 0x2c07: []int32{11319}, + 0x2c08: []int32{11320}, + 0x2c09: []int32{11321}, + 0x2c0a: []int32{11322}, + 0x2c0b: []int32{11323}, + 0x2c0c: []int32{11324}, + 0x2c0d: []int32{11325}, + 0x2c0e: []int32{11326}, + 0x2c0f: []int32{11327}, + 0x2c10: []int32{11328}, + 0x2c11: []int32{11329}, + 0x2c12: []int32{11330}, + 0x2c13: []int32{11331}, + 0x2c14: []int32{11332}, + 0x2c15: []int32{11333}, + 0x2c16: []int32{11334}, + 0x2c17: []int32{11335}, + 0x2c18: []int32{11336}, + 0x2c19: []int32{11337}, + 0x2c1a: []int32{11338}, + 0x2c1b: []int32{11339}, + 0x2c1c: []int32{11340}, + 0x2c1d: []int32{11341}, + 0x2c1e: []int32{11342}, + 0x2c1f: []int32{11343}, + 0x2c20: []int32{11344}, + 0x2c21: []int32{11345}, + 0x2c22: []int32{11346}, + 0x2c23: []int32{11347}, + 0x2c24: []int32{11348}, + 0x2c25: []int32{11349}, + 0x2c26: []int32{11350}, + 0x2c27: []int32{11351}, + 0x2c28: []int32{11352}, + 0x2c29: []int32{11353}, + 0x2c2a: []int32{11354}, + 0x2c2b: []int32{11355}, + 0x2c2c: []int32{11356}, + 0x2c2d: []int32{11357}, + 0x2c2e: []int32{11358}, + 0x2c2f: []int32{11359}, + 0x2c60: []int32{11361}, + 0x2c62: []int32{619}, + 0x2c63: []int32{7549}, + 0x2c64: []int32{637}, + 0x2c67: []int32{11368}, + 0x2c69: []int32{11370}, + 0x2c6b: []int32{11372}, + 0x2c6d: []int32{593}, + 0x2c6e: []int32{625}, + 0x2c6f: []int32{592}, + 0x2c70: []int32{594}, + 0x2c72: []int32{11379}, + 0x2c75: []int32{11382}, + 0x2c7e: []int32{575}, + 0x2c7f: []int32{576}, + 0x2c80: []int32{11393}, + 0x2c82: []int32{11395}, + 0x2c84: []int32{11397}, + 0x2c86: []int32{11399}, + 0x2c88: []int32{11401}, + 0x2c8a: []int32{11403}, + 0x2c8c: []int32{11405}, + 0x2c8e: []int32{11407}, + 0x2c90: []int32{11409}, + 0x2c92: []int32{11411}, + 0x2c94: []int32{11413}, + 0x2c96: []int32{11415}, + 0x2c98: []int32{11417}, + 0x2c9a: []int32{11419}, + 0x2c9c: []int32{11421}, + 0x2c9e: []int32{11423}, + 0x2ca0: []int32{11425}, + 0x2ca2: []int32{11427}, + 0x2ca4: []int32{11429}, + 0x2ca6: []int32{11431}, + 0x2ca8: []int32{11433}, + 0x2caa: []int32{11435}, + 0x2cac: []int32{11437}, + 0x2cae: []int32{11439}, + 0x2cb0: []int32{11441}, + 0x2cb2: []int32{11443}, + 0x2cb4: []int32{11445}, + 0x2cb6: []int32{11447}, + 0x2cb8: []int32{11449}, + 0x2cba: []int32{11451}, + 0x2cbc: []int32{11453}, + 0x2cbe: []int32{11455}, + 0x2cc0: []int32{11457}, + 0x2cc2: []int32{11459}, + 0x2cc4: []int32{11461}, + 0x2cc6: []int32{11463}, + 0x2cc8: []int32{11465}, + 0x2cca: []int32{11467}, + 0x2ccc: []int32{11469}, + 0x2cce: []int32{11471}, + 0x2cd0: []int32{11473}, + 0x2cd2: []int32{11475}, + 0x2cd4: []int32{11477}, + 0x2cd6: []int32{11479}, + 0x2cd8: []int32{11481}, + 0x2cda: []int32{11483}, + 0x2cdc: []int32{11485}, + 0x2cde: []int32{11487}, + 0x2ce0: []int32{11489}, + 0x2ce2: []int32{11491}, + 0x2ceb: []int32{11500}, + 0x2ced: []int32{11502}, + 0x2cf2: []int32{11507}, + 0xa640: []int32{42561}, + 0xa642: []int32{42563}, + 0xa644: []int32{42565}, + 0xa646: []int32{42567}, + 0xa648: []int32{42569}, + 0xa64a: []int32{42571}, + 0xa64c: []int32{42573}, + 0xa64e: []int32{42575}, + 0xa650: []int32{42577}, + 0xa652: []int32{42579}, + 0xa654: []int32{42581}, + 0xa656: []int32{42583}, + 0xa658: []int32{42585}, + 0xa65a: []int32{42587}, + 0xa65c: []int32{42589}, + 0xa65e: []int32{42591}, + 0xa660: []int32{42593}, + 0xa662: []int32{42595}, + 0xa664: []int32{42597}, + 0xa666: []int32{42599}, + 0xa668: []int32{42601}, + 0xa66a: []int32{42603}, + 0xa66c: []int32{42605}, + 0xa680: []int32{42625}, + 0xa682: []int32{42627}, + 0xa684: []int32{42629}, + 0xa686: []int32{42631}, + 0xa688: []int32{42633}, + 0xa68a: []int32{42635}, + 0xa68c: []int32{42637}, + 0xa68e: []int32{42639}, + 0xa690: []int32{42641}, + 0xa692: []int32{42643}, + 0xa694: []int32{42645}, + 0xa696: []int32{42647}, + 0xa698: []int32{42649}, + 0xa69a: []int32{42651}, + 0xa722: []int32{42787}, + 0xa724: []int32{42789}, + 0xa726: []int32{42791}, + 0xa728: []int32{42793}, + 0xa72a: []int32{42795}, + 0xa72c: []int32{42797}, + 0xa72e: []int32{42799}, + 0xa732: []int32{42803}, + 0xa734: []int32{42805}, + 0xa736: []int32{42807}, + 0xa738: []int32{42809}, + 0xa73a: []int32{42811}, + 0xa73c: []int32{42813}, + 0xa73e: []int32{42815}, + 0xa740: []int32{42817}, + 0xa742: []int32{42819}, + 0xa744: []int32{42821}, + 0xa746: []int32{42823}, + 0xa748: []int32{42825}, + 0xa74a: []int32{42827}, + 0xa74c: []int32{42829}, + 0xa74e: []int32{42831}, + 0xa750: []int32{42833}, + 0xa752: []int32{42835}, + 0xa754: []int32{42837}, + 0xa756: []int32{42839}, + 0xa758: []int32{42841}, + 0xa75a: []int32{42843}, + 0xa75c: []int32{42845}, + 0xa75e: []int32{42847}, + 0xa760: []int32{42849}, + 0xa762: []int32{42851}, + 0xa764: []int32{42853}, + 0xa766: []int32{42855}, + 0xa768: []int32{42857}, + 0xa76a: []int32{42859}, + 0xa76c: []int32{42861}, + 0xa76e: []int32{42863}, + 0xa779: []int32{42874}, + 0xa77b: []int32{42876}, + 0xa77d: []int32{7545}, + 0xa77e: []int32{42879}, + 0xa780: []int32{42881}, + 0xa782: []int32{42883}, + 0xa784: []int32{42885}, + 0xa786: []int32{42887}, + 0xa78b: []int32{42892}, + 0xa78d: []int32{613}, + 0xa790: []int32{42897}, + 0xa792: []int32{42899}, + 0xa796: []int32{42903}, + 0xa798: []int32{42905}, + 0xa79a: []int32{42907}, + 0xa79c: []int32{42909}, + 0xa79e: []int32{42911}, + 0xa7a0: []int32{42913}, + 0xa7a2: []int32{42915}, + 0xa7a4: []int32{42917}, + 0xa7a6: []int32{42919}, + 0xa7a8: []int32{42921}, + 0xa7aa: []int32{614}, + 0xa7ab: []int32{604}, + 0xa7ac: []int32{609}, + 0xa7ad: []int32{620}, + 0xa7ae: []int32{618}, + 0xa7b0: []int32{670}, + 0xa7b1: []int32{647}, + 0xa7b2: []int32{669}, + 0xa7b3: []int32{43859}, + 0xa7b4: []int32{42933}, + 0xa7b6: []int32{42935}, + 0xa7b8: []int32{42937}, + 0xa7ba: []int32{42939}, + 0xa7bc: []int32{42941}, + 0xa7be: []int32{42943}, + 0xa7c0: []int32{42945}, + 0xa7c2: []int32{42947}, + 0xa7c4: []int32{42900}, + 0xa7c5: []int32{642}, + 0xa7c6: []int32{7566}, + 0xa7c7: []int32{42952}, + 0xa7c9: []int32{42954}, + 0xa7d0: []int32{42961}, + 0xa7d6: []int32{42967}, + 0xa7d8: []int32{42969}, + 0xa7f5: []int32{42998}, + 0xab70: []int32{5024}, + 0xab71: []int32{5025}, + 0xab72: []int32{5026}, + 0xab73: []int32{5027}, + 0xab74: []int32{5028}, + 0xab75: []int32{5029}, + 0xab76: []int32{5030}, + 0xab77: []int32{5031}, + 0xab78: []int32{5032}, + 0xab79: []int32{5033}, + 0xab7a: []int32{5034}, + 0xab7b: []int32{5035}, + 0xab7c: []int32{5036}, + 0xab7d: []int32{5037}, + 0xab7e: []int32{5038}, + 0xab7f: []int32{5039}, + 0xab80: []int32{5040}, + 0xab81: []int32{5041}, + 0xab82: []int32{5042}, + 0xab83: []int32{5043}, + 0xab84: []int32{5044}, + 0xab85: []int32{5045}, + 0xab86: []int32{5046}, + 0xab87: []int32{5047}, + 0xab88: []int32{5048}, + 0xab89: []int32{5049}, + 0xab8a: []int32{5050}, + 0xab8b: []int32{5051}, + 0xab8c: []int32{5052}, + 0xab8d: []int32{5053}, + 0xab8e: []int32{5054}, + 0xab8f: []int32{5055}, + 0xab90: []int32{5056}, + 0xab91: []int32{5057}, + 0xab92: []int32{5058}, + 0xab93: []int32{5059}, + 0xab94: []int32{5060}, + 0xab95: []int32{5061}, + 0xab96: []int32{5062}, + 0xab97: []int32{5063}, + 0xab98: []int32{5064}, + 0xab99: []int32{5065}, + 0xab9a: []int32{5066}, + 0xab9b: []int32{5067}, + 0xab9c: []int32{5068}, + 0xab9d: []int32{5069}, + 0xab9e: []int32{5070}, + 0xab9f: []int32{5071}, + 0xaba0: []int32{5072}, + 0xaba1: []int32{5073}, + 0xaba2: []int32{5074}, + 0xaba3: []int32{5075}, + 0xaba4: []int32{5076}, + 0xaba5: []int32{5077}, + 0xaba6: []int32{5078}, + 0xaba7: []int32{5079}, + 0xaba8: []int32{5080}, + 0xaba9: []int32{5081}, + 0xabaa: []int32{5082}, + 0xabab: []int32{5083}, + 0xabac: []int32{5084}, + 0xabad: []int32{5085}, + 0xabae: []int32{5086}, + 0xabaf: []int32{5087}, + 0xabb0: []int32{5088}, + 0xabb1: []int32{5089}, + 0xabb2: []int32{5090}, + 0xabb3: []int32{5091}, + 0xabb4: []int32{5092}, + 0xabb5: []int32{5093}, + 0xabb6: []int32{5094}, + 0xabb7: []int32{5095}, + 0xabb8: []int32{5096}, + 0xabb9: []int32{5097}, + 0xabba: []int32{5098}, + 0xabbb: []int32{5099}, + 0xabbc: []int32{5100}, + 0xabbd: []int32{5101}, + 0xabbe: []int32{5102}, + 0xabbf: []int32{5103}, + 0xfb00: []int32{102, 102}, + 0xfb01: []int32{102, 105}, + 0xfb02: []int32{102, 108}, + 0xfb03: []int32{102, 102, 105}, + 0xfb04: []int32{102, 102, 108}, + 0xfb05: []int32{115, 116}, + 0xfb06: []int32{115, 116}, + 0xfb13: []int32{1396, 1398}, + 0xfb14: []int32{1396, 1381}, + 0xfb15: []int32{1396, 1387}, + 0xfb16: []int32{1406, 1398}, + 0xfb17: []int32{1396, 1389}, + 0xff21: []int32{65345}, + 0xff22: []int32{65346}, + 0xff23: []int32{65347}, + 0xff24: []int32{65348}, + 0xff25: []int32{65349}, + 0xff26: []int32{65350}, + 0xff27: []int32{65351}, + 0xff28: []int32{65352}, + 0xff29: []int32{65353}, + 0xff2a: []int32{65354}, + 0xff2b: []int32{65355}, + 0xff2c: []int32{65356}, + 0xff2d: []int32{65357}, + 0xff2e: []int32{65358}, + 0xff2f: []int32{65359}, + 0xff30: []int32{65360}, + 0xff31: []int32{65361}, + 0xff32: []int32{65362}, + 0xff33: []int32{65363}, + 0xff34: []int32{65364}, + 0xff35: []int32{65365}, + 0xff36: []int32{65366}, + 0xff37: []int32{65367}, + 0xff38: []int32{65368}, + 0xff39: []int32{65369}, + 0xff3a: []int32{65370}, + 0x10400: []int32{66600}, + 0x10401: []int32{66601}, + 0x10402: []int32{66602}, + 0x10403: []int32{66603}, + 0x10404: []int32{66604}, + 0x10405: []int32{66605}, + 0x10406: []int32{66606}, + 0x10407: []int32{66607}, + 0x10408: []int32{66608}, + 0x10409: []int32{66609}, + 0x1040a: []int32{66610}, + 0x1040b: []int32{66611}, + 0x1040c: []int32{66612}, + 0x1040d: []int32{66613}, + 0x1040e: []int32{66614}, + 0x1040f: []int32{66615}, + 0x10410: []int32{66616}, + 0x10411: []int32{66617}, + 0x10412: []int32{66618}, + 0x10413: []int32{66619}, + 0x10414: []int32{66620}, + 0x10415: []int32{66621}, + 0x10416: []int32{66622}, + 0x10417: []int32{66623}, + 0x10418: []int32{66624}, + 0x10419: []int32{66625}, + 0x1041a: []int32{66626}, + 0x1041b: []int32{66627}, + 0x1041c: []int32{66628}, + 0x1041d: []int32{66629}, + 0x1041e: []int32{66630}, + 0x1041f: []int32{66631}, + 0x10420: []int32{66632}, + 0x10421: []int32{66633}, + 0x10422: []int32{66634}, + 0x10423: []int32{66635}, + 0x10424: []int32{66636}, + 0x10425: []int32{66637}, + 0x10426: []int32{66638}, + 0x10427: []int32{66639}, + 0x104b0: []int32{66776}, + 0x104b1: []int32{66777}, + 0x104b2: []int32{66778}, + 0x104b3: []int32{66779}, + 0x104b4: []int32{66780}, + 0x104b5: []int32{66781}, + 0x104b6: []int32{66782}, + 0x104b7: []int32{66783}, + 0x104b8: []int32{66784}, + 0x104b9: []int32{66785}, + 0x104ba: []int32{66786}, + 0x104bb: []int32{66787}, + 0x104bc: []int32{66788}, + 0x104bd: []int32{66789}, + 0x104be: []int32{66790}, + 0x104bf: []int32{66791}, + 0x104c0: []int32{66792}, + 0x104c1: []int32{66793}, + 0x104c2: []int32{66794}, + 0x104c3: []int32{66795}, + 0x104c4: []int32{66796}, + 0x104c5: []int32{66797}, + 0x104c6: []int32{66798}, + 0x104c7: []int32{66799}, + 0x104c8: []int32{66800}, + 0x104c9: []int32{66801}, + 0x104ca: []int32{66802}, + 0x104cb: []int32{66803}, + 0x104cc: []int32{66804}, + 0x104cd: []int32{66805}, + 0x104ce: []int32{66806}, + 0x104cf: []int32{66807}, + 0x104d0: []int32{66808}, + 0x104d1: []int32{66809}, + 0x104d2: []int32{66810}, + 0x104d3: []int32{66811}, + 0x10570: []int32{66967}, + 0x10571: []int32{66968}, + 0x10572: []int32{66969}, + 0x10573: []int32{66970}, + 0x10574: []int32{66971}, + 0x10575: []int32{66972}, + 0x10576: []int32{66973}, + 0x10577: []int32{66974}, + 0x10578: []int32{66975}, + 0x10579: []int32{66976}, + 0x1057a: []int32{66977}, + 0x1057c: []int32{66979}, + 0x1057d: []int32{66980}, + 0x1057e: []int32{66981}, + 0x1057f: []int32{66982}, + 0x10580: []int32{66983}, + 0x10581: []int32{66984}, + 0x10582: []int32{66985}, + 0x10583: []int32{66986}, + 0x10584: []int32{66987}, + 0x10585: []int32{66988}, + 0x10586: []int32{66989}, + 0x10587: []int32{66990}, + 0x10588: []int32{66991}, + 0x10589: []int32{66992}, + 0x1058a: []int32{66993}, + 0x1058c: []int32{66995}, + 0x1058d: []int32{66996}, + 0x1058e: []int32{66997}, + 0x1058f: []int32{66998}, + 0x10590: []int32{66999}, + 0x10591: []int32{67000}, + 0x10592: []int32{67001}, + 0x10594: []int32{67003}, + 0x10595: []int32{67004}, + 0x10c80: []int32{68800}, + 0x10c81: []int32{68801}, + 0x10c82: []int32{68802}, + 0x10c83: []int32{68803}, + 0x10c84: []int32{68804}, + 0x10c85: []int32{68805}, + 0x10c86: []int32{68806}, + 0x10c87: []int32{68807}, + 0x10c88: []int32{68808}, + 0x10c89: []int32{68809}, + 0x10c8a: []int32{68810}, + 0x10c8b: []int32{68811}, + 0x10c8c: []int32{68812}, + 0x10c8d: []int32{68813}, + 0x10c8e: []int32{68814}, + 0x10c8f: []int32{68815}, + 0x10c90: []int32{68816}, + 0x10c91: []int32{68817}, + 0x10c92: []int32{68818}, + 0x10c93: []int32{68819}, + 0x10c94: []int32{68820}, + 0x10c95: []int32{68821}, + 0x10c96: []int32{68822}, + 0x10c97: []int32{68823}, + 0x10c98: []int32{68824}, + 0x10c99: []int32{68825}, + 0x10c9a: []int32{68826}, + 0x10c9b: []int32{68827}, + 0x10c9c: []int32{68828}, + 0x10c9d: []int32{68829}, + 0x10c9e: []int32{68830}, + 0x10c9f: []int32{68831}, + 0x10ca0: []int32{68832}, + 0x10ca1: []int32{68833}, + 0x10ca2: []int32{68834}, + 0x10ca3: []int32{68835}, + 0x10ca4: []int32{68836}, + 0x10ca5: []int32{68837}, + 0x10ca6: []int32{68838}, + 0x10ca7: []int32{68839}, + 0x10ca8: []int32{68840}, + 0x10ca9: []int32{68841}, + 0x10caa: []int32{68842}, + 0x10cab: []int32{68843}, + 0x10cac: []int32{68844}, + 0x10cad: []int32{68845}, + 0x10cae: []int32{68846}, + 0x10caf: []int32{68847}, + 0x10cb0: []int32{68848}, + 0x10cb1: []int32{68849}, + 0x10cb2: []int32{68850}, + 0x118a0: []int32{71872}, + 0x118a1: []int32{71873}, + 0x118a2: []int32{71874}, + 0x118a3: []int32{71875}, + 0x118a4: []int32{71876}, + 0x118a5: []int32{71877}, + 0x118a6: []int32{71878}, + 0x118a7: []int32{71879}, + 0x118a8: []int32{71880}, + 0x118a9: []int32{71881}, + 0x118aa: []int32{71882}, + 0x118ab: []int32{71883}, + 0x118ac: []int32{71884}, + 0x118ad: []int32{71885}, + 0x118ae: []int32{71886}, + 0x118af: []int32{71887}, + 0x118b0: []int32{71888}, + 0x118b1: []int32{71889}, + 0x118b2: []int32{71890}, + 0x118b3: []int32{71891}, + 0x118b4: []int32{71892}, + 0x118b5: []int32{71893}, + 0x118b6: []int32{71894}, + 0x118b7: []int32{71895}, + 0x118b8: []int32{71896}, + 0x118b9: []int32{71897}, + 0x118ba: []int32{71898}, + 0x118bb: []int32{71899}, + 0x118bc: []int32{71900}, + 0x118bd: []int32{71901}, + 0x118be: []int32{71902}, + 0x118bf: []int32{71903}, + 0x16e40: []int32{93792}, + 0x16e41: []int32{93793}, + 0x16e42: []int32{93794}, + 0x16e43: []int32{93795}, + 0x16e44: []int32{93796}, + 0x16e45: []int32{93797}, + 0x16e46: []int32{93798}, + 0x16e47: []int32{93799}, + 0x16e48: []int32{93800}, + 0x16e49: []int32{93801}, + 0x16e4a: []int32{93802}, + 0x16e4b: []int32{93803}, + 0x16e4c: []int32{93804}, + 0x16e4d: []int32{93805}, + 0x16e4e: []int32{93806}, + 0x16e4f: []int32{93807}, + 0x16e50: []int32{93808}, + 0x16e51: []int32{93809}, + 0x16e52: []int32{93810}, + 0x16e53: []int32{93811}, + 0x16e54: []int32{93812}, + 0x16e55: []int32{93813}, + 0x16e56: []int32{93814}, + 0x16e57: []int32{93815}, + 0x16e58: []int32{93816}, + 0x16e59: []int32{93817}, + 0x16e5a: []int32{93818}, + 0x16e5b: []int32{93819}, + 0x16e5c: []int32{93820}, + 0x16e5d: []int32{93821}, + 0x16e5e: []int32{93822}, + 0x16e5f: []int32{93823}, + 0x1e900: []int32{125218}, + 0x1e901: []int32{125219}, + 0x1e902: []int32{125220}, + 0x1e903: []int32{125221}, + 0x1e904: []int32{125222}, + 0x1e905: []int32{125223}, + 0x1e906: []int32{125224}, + 0x1e907: []int32{125225}, + 0x1e908: []int32{125226}, + 0x1e909: []int32{125227}, + 0x1e90a: []int32{125228}, + 0x1e90b: []int32{125229}, + 0x1e90c: []int32{125230}, + 0x1e90d: []int32{125231}, + 0x1e90e: []int32{125232}, + 0x1e90f: []int32{125233}, + 0x1e910: []int32{125234}, + 0x1e911: []int32{125235}, + 0x1e912: []int32{125236}, + 0x1e913: []int32{125237}, + 0x1e914: []int32{125238}, + 0x1e915: []int32{125239}, + 0x1e916: []int32{125240}, + 0x1e917: []int32{125241}, + 0x1e918: []int32{125242}, + 0x1e919: []int32{125243}, + 0x1e91a: []int32{125244}, + 0x1e91b: []int32{125245}, + 0x1e91c: []int32{125246}, + 0x1e91d: []int32{125247}, + 0x1e91e: []int32{125248}, + 0x1e91f: []int32{125249}, + 0x1e920: []int32{125250}, + 0x1e921: []int32{125251}, +} diff --git a/vendor/github.com/yuin/goldmark/util/util.go b/vendor/github.com/yuin/goldmark/util/util.go new file mode 100644 index 0000000..9bf09ad --- /dev/null +++ b/vendor/github.com/yuin/goldmark/util/util.go @@ -0,0 +1,982 @@ +// Package util provides utility functions for the goldmark. +package util + +import ( + "bytes" + "io" + "net/url" + "regexp" + "sort" + "strconv" + "unicode" + "unicode/utf8" +) + +// A CopyOnWriteBuffer is a byte buffer that copies buffer when +// it need to be changed. +type CopyOnWriteBuffer struct { + buffer []byte + copied bool +} + +// NewCopyOnWriteBuffer returns a new CopyOnWriteBuffer. +func NewCopyOnWriteBuffer(buffer []byte) CopyOnWriteBuffer { + return CopyOnWriteBuffer{ + buffer: buffer, + copied: false, + } +} + +// Write writes given bytes to the buffer. +// Write allocate new buffer and clears it at the first time. +func (b *CopyOnWriteBuffer) Write(value []byte) { + if !b.copied { + b.buffer = make([]byte, 0, len(b.buffer)+20) + b.copied = true + } + b.buffer = append(b.buffer, value...) +} + +// WriteString writes given string to the buffer. +// WriteString allocate new buffer and clears it at the first time. +func (b *CopyOnWriteBuffer) WriteString(value string) { + b.Write(StringToReadOnlyBytes(value)) +} + +// Append appends given bytes to the buffer. +// Append copy buffer at the first time. +func (b *CopyOnWriteBuffer) Append(value []byte) { + if !b.copied { + tmp := make([]byte, len(b.buffer), len(b.buffer)+20) + copy(tmp, b.buffer) + b.buffer = tmp + b.copied = true + } + b.buffer = append(b.buffer, value...) +} + +// AppendString appends given string to the buffer. +// AppendString copy buffer at the first time. +func (b *CopyOnWriteBuffer) AppendString(value string) { + b.Append(StringToReadOnlyBytes(value)) +} + +// WriteByte writes the given byte to the buffer. +// WriteByte allocate new buffer and clears it at the first time. +func (b *CopyOnWriteBuffer) WriteByte(c byte) error { + if !b.copied { + b.buffer = make([]byte, 0, len(b.buffer)+20) + b.copied = true + } + b.buffer = append(b.buffer, c) + return nil +} + +// AppendByte appends given bytes to the buffer. +// AppendByte copy buffer at the first time. +func (b *CopyOnWriteBuffer) AppendByte(c byte) { + if !b.copied { + tmp := make([]byte, len(b.buffer), len(b.buffer)+20) + copy(tmp, b.buffer) + b.buffer = tmp + b.copied = true + } + b.buffer = append(b.buffer, c) +} + +// Bytes returns bytes of this buffer. +func (b *CopyOnWriteBuffer) Bytes() []byte { + return b.buffer +} + +// IsCopied returns true if buffer has been copied, otherwise false. +func (b *CopyOnWriteBuffer) IsCopied() bool { + return b.copied +} + +// IsEscapedPunctuation returns true if character at a given index i +// is an escaped punctuation, otherwise false. +func IsEscapedPunctuation(source []byte, i int) bool { + return source[i] == '\\' && i < len(source)-1 && IsPunct(source[i+1]) +} + +// ReadWhile read the given source while pred is true. +func ReadWhile(source []byte, index [2]int, pred func(byte) bool) (int, bool) { + j := index[0] + ok := false + for ; j < index[1]; j++ { + c1 := source[j] + if pred(c1) { + ok = true + continue + } + break + } + return j, ok +} + +// IsBlank returns true if the given string is all space characters. +func IsBlank(bs []byte) bool { + for _, b := range bs { + if !IsSpace(b) { + return false + } + } + return true +} + +// VisualizeSpaces visualize invisible space characters. +func VisualizeSpaces(bs []byte) []byte { + bs = bytes.Replace(bs, []byte(" "), []byte("[SPACE]"), -1) + bs = bytes.Replace(bs, []byte("\t"), []byte("[TAB]"), -1) + bs = bytes.Replace(bs, []byte("\n"), []byte("[NEWLINE]\n"), -1) + bs = bytes.Replace(bs, []byte("\r"), []byte("[CR]"), -1) + bs = bytes.Replace(bs, []byte("\v"), []byte("[VTAB]"), -1) + bs = bytes.Replace(bs, []byte("\x00"), []byte("[NUL]"), -1) + bs = bytes.Replace(bs, []byte("\ufffd"), []byte("[U+FFFD]"), -1) + return bs +} + +// TabWidth calculates actual width of a tab at the given position. +func TabWidth(currentPos int) int { + return 4 - currentPos%4 +} + +// IndentPosition searches an indent position with the given width for the given line. +// If the line contains tab characters, paddings may be not zero. +// currentPos==0 and width==2: +// +// position: 0 1 +// [TAB]aaaa +// width: 1234 5678 +// +// width=2 is in the tab character. In this case, IndentPosition returns +// (pos=1, padding=2). +func IndentPosition(bs []byte, currentPos, width int) (pos, padding int) { + return IndentPositionPadding(bs, currentPos, 0, width) +} + +// IndentPositionPadding searches an indent position with the given width for the given line. +// This function is mostly same as IndentPosition except this function +// takes account into additional paddings. +func IndentPositionPadding(bs []byte, currentPos, paddingv, width int) (pos, padding int) { + if width == 0 { + return 0, paddingv + } + w := 0 + i := 0 + l := len(bs) + for ; i < l; i++ { + if bs[i] == '\t' && w < width { + w += TabWidth(currentPos + w) + } else if bs[i] == ' ' && w < width { + w++ + } else { + break + } + } + if w >= width { + return i - paddingv, w - width + } + return -1, -1 +} + +// DedentPosition dedents lines by the given width. +// +// Deprecated: This function has bugs. Use util.IndentPositionPadding and util.FirstNonSpacePosition. +func DedentPosition(bs []byte, currentPos, width int) (pos, padding int) { + if width == 0 { + return 0, 0 + } + w := 0 + l := len(bs) + i := 0 + for ; i < l; i++ { + if bs[i] == '\t' { + w += TabWidth(currentPos + w) + } else if bs[i] == ' ' { + w++ + } else { + break + } + } + if w >= width { + return i, w - width + } + return i, 0 +} + +// DedentPositionPadding dedents lines by the given width. +// This function is mostly same as DedentPosition except this function +// takes account into additional paddings. +// +// Deprecated: This function has bugs. Use util.IndentPositionPadding and util.FirstNonSpacePosition. +func DedentPositionPadding(bs []byte, currentPos, paddingv, width int) (pos, padding int) { + if width == 0 { + return 0, paddingv + } + + w := 0 + i := 0 + l := len(bs) + for ; i < l; i++ { + if bs[i] == '\t' { + w += TabWidth(currentPos + w) + } else if bs[i] == ' ' { + w++ + } else { + break + } + } + if w >= width { + return i - paddingv, w - width + } + return i - paddingv, 0 +} + +// IndentWidth calculate an indent width for the given line. +func IndentWidth(bs []byte, currentPos int) (width, pos int) { + l := len(bs) + for i := 0; i < l; i++ { + b := bs[i] + if b == ' ' { + width++ + pos++ + } else if b == '\t' { + width += TabWidth(currentPos + width) + pos++ + } else { + break + } + } + return +} + +// FirstNonSpacePosition returns a position line that is a first nonspace +// character. +func FirstNonSpacePosition(bs []byte) int { + i := 0 + for ; i < len(bs); i++ { + c := bs[i] + if c == ' ' || c == '\t' { + continue + } + if c == '\n' { + return -1 + } + return i + } + return -1 +} + +// FindClosure returns a position that closes the given opener. +// If codeSpan is set true, it ignores characters in code spans. +// If allowNesting is set true, closures correspond to nested opener will be +// ignored. +// +// Deprecated: This function can not handle newlines. Many elements +// can be existed over multiple lines(e.g. link labels). +// Use text.Reader.FindClosure. +func FindClosure(bs []byte, opener, closure byte, codeSpan, allowNesting bool) int { + i := 0 + opened := 1 + codeSpanOpener := 0 + for i < len(bs) { + c := bs[i] + if codeSpan && codeSpanOpener != 0 && c == '`' { + codeSpanCloser := 0 + for ; i < len(bs); i++ { + if bs[i] == '`' { + codeSpanCloser++ + } else { + i-- + break + } + } + if codeSpanCloser == codeSpanOpener { + codeSpanOpener = 0 + } + } else if codeSpanOpener == 0 && c == '\\' && i < len(bs)-1 && IsPunct(bs[i+1]) { + i += 2 + continue + } else if codeSpan && codeSpanOpener == 0 && c == '`' { + for ; i < len(bs); i++ { + if bs[i] == '`' { + codeSpanOpener++ + } else { + i-- + break + } + } + } else if (codeSpan && codeSpanOpener == 0) || !codeSpan { + if c == closure { + opened-- + if opened == 0 { + return i + } + } else if c == opener { + if !allowNesting { + return -1 + } + opened++ + } + } + i++ + } + return -1 +} + +// TrimLeft trims characters in the given s from head of the source. +// bytes.TrimLeft offers same functionalities, but bytes.TrimLeft +// allocates new buffer for the result. +func TrimLeft(source, b []byte) []byte { + i := 0 + for ; i < len(source); i++ { + c := source[i] + found := false + for j := 0; j < len(b); j++ { + if c == b[j] { + found = true + break + } + } + if !found { + break + } + } + return source[i:] +} + +// TrimRight trims characters in the given s from tail of the source. +func TrimRight(source, b []byte) []byte { + i := len(source) - 1 + for ; i >= 0; i-- { + c := source[i] + found := false + for j := 0; j < len(b); j++ { + if c == b[j] { + found = true + break + } + } + if !found { + break + } + } + return source[:i+1] +} + +// TrimLeftLength returns a length of leading specified characters. +func TrimLeftLength(source, s []byte) int { + return len(source) - len(TrimLeft(source, s)) +} + +// TrimRightLength returns a length of trailing specified characters. +func TrimRightLength(source, s []byte) int { + return len(source) - len(TrimRight(source, s)) +} + +// TrimLeftSpaceLength returns a length of leading space characters. +func TrimLeftSpaceLength(source []byte) int { + i := 0 + for ; i < len(source); i++ { + if !IsSpace(source[i]) { + break + } + } + return i +} + +// TrimRightSpaceLength returns a length of trailing space characters. +func TrimRightSpaceLength(source []byte) int { + l := len(source) + i := l - 1 + for ; i >= 0; i-- { + if !IsSpace(source[i]) { + break + } + } + if i < 0 { + return l + } + return l - 1 - i +} + +// TrimLeftSpace returns a subslice of the given string by slicing off all leading +// space characters. +func TrimLeftSpace(source []byte) []byte { + return TrimLeft(source, spaces) +} + +// TrimRightSpace returns a subslice of the given string by slicing off all trailing +// space characters. +func TrimRightSpace(source []byte) []byte { + return TrimRight(source, spaces) +} + +// DoFullUnicodeCaseFolding performs full unicode case folding to given bytes. +func DoFullUnicodeCaseFolding(v []byte) []byte { + var rbuf []byte + cob := NewCopyOnWriteBuffer(v) + n := 0 + for i := 0; i < len(v); i++ { + c := v[i] + if c < 0xb5 { + if c >= 0x41 && c <= 0x5a { + // A-Z to a-z + cob.Write(v[n:i]) + _ = cob.WriteByte(c + 32) + n = i + 1 + } + continue + } + + if !utf8.RuneStart(c) { + continue + } + r, length := utf8.DecodeRune(v[i:]) + if r == utf8.RuneError { + continue + } + folded, ok := unicodeCaseFoldings[r] + if !ok { + continue + } + + cob.Write(v[n:i]) + if rbuf == nil { + rbuf = make([]byte, 4) + } + for _, f := range folded { + l := utf8.EncodeRune(rbuf, f) + cob.Write(rbuf[:l]) + } + i += length - 1 + n = i + 1 + } + if cob.IsCopied() { + cob.Write(v[n:]) + } + return cob.Bytes() +} + +// ReplaceSpaces replaces sequence of spaces with the given repl. +func ReplaceSpaces(source []byte, repl byte) []byte { + var ret []byte + start := -1 + for i, c := range source { + iss := IsSpace(c) + if start < 0 && iss { + start = i + continue + } else if start >= 0 && iss { + continue + } else if start >= 0 { + if ret == nil { + ret = make([]byte, 0, len(source)) + ret = append(ret, source[:start]...) + } + ret = append(ret, repl) + start = -1 + } + if ret != nil { + ret = append(ret, c) + } + } + if start >= 0 && ret != nil { + ret = append(ret, repl) + } + if ret == nil { + return source + } + return ret +} + +// ToRune decode given bytes start at pos and returns a rune. +func ToRune(source []byte, pos int) rune { + i := pos + for ; i >= 0; i-- { + if utf8.RuneStart(source[i]) { + break + } + } + r, _ := utf8.DecodeRune(source[i:]) + return r +} + +// ToValidRune returns 0xFFFD if the given rune is invalid, otherwise v. +func ToValidRune(v rune) rune { + if v == 0 || !utf8.ValidRune(v) { + return rune(0xFFFD) + } + return v +} + +// ToLinkReference converts given bytes into a valid link reference string. +// ToLinkReference performs unicode case folding, trims leading and trailing spaces, converts into lower +// case and replace spaces with a single space character. +func ToLinkReference(v []byte) string { + v = TrimLeftSpace(v) + v = TrimRightSpace(v) + v = DoFullUnicodeCaseFolding(v) + return string(ReplaceSpaces(v, ' ')) +} + +var htmlEscapeTable = [256][]byte{nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []byte("""), nil, nil, nil, []byte("&"), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, []byte("<"), nil, []byte(">"), nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil} //nolint:golint,lll + +// EscapeHTMLByte returns HTML escaped bytes if the given byte should be escaped, +// otherwise nil. +func EscapeHTMLByte(b byte) []byte { + return htmlEscapeTable[b] +} + +// EscapeHTML escapes characters that should be escaped in HTML text. +func EscapeHTML(v []byte) []byte { + cob := NewCopyOnWriteBuffer(v) + n := 0 + for i := 0; i < len(v); i++ { + c := v[i] + escaped := htmlEscapeTable[c] + if escaped != nil { + cob.Write(v[n:i]) + cob.Write(escaped) + n = i + 1 + } + } + if cob.IsCopied() { + cob.Write(v[n:]) + } + return cob.Bytes() +} + +// UnescapePunctuations unescapes blackslash escaped punctuations. +func UnescapePunctuations(source []byte) []byte { + cob := NewCopyOnWriteBuffer(source) + limit := len(source) + n := 0 + for i := 0; i < limit; { + c := source[i] + if i < limit-1 && c == '\\' && IsPunct(source[i+1]) { + cob.Write(source[n:i]) + _ = cob.WriteByte(source[i+1]) + i += 2 + n = i + continue + } + i++ + } + if cob.IsCopied() { + cob.Write(source[n:]) + } + return cob.Bytes() +} + +// ResolveNumericReferences resolve numeric references like 'Ӓ" . +func ResolveNumericReferences(source []byte) []byte { + cob := NewCopyOnWriteBuffer(source) + buf := make([]byte, 6) + limit := len(source) + var ok bool + n := 0 + for i := 0; i < limit; i++ { + if source[i] == '&' { + pos := i + next := i + 1 + if next < limit && source[next] == '#' { + nnext := next + 1 + if nnext < limit { + nc := source[nnext] + // code point like #x22; + if nnext < limit && nc == 'x' || nc == 'X' { + start := nnext + 1 + i, ok = ReadWhile(source, [2]int{start, limit}, IsHexDecimal) + if ok && i < limit && source[i] == ';' { + v, _ := strconv.ParseUint(BytesToReadOnlyString(source[start:i]), 16, 32) + cob.Write(source[n:pos]) + n = i + 1 + runeSize := utf8.EncodeRune(buf, ToValidRune(rune(v))) + cob.Write(buf[:runeSize]) + continue + } + // code point like #1234; + } else if nc >= '0' && nc <= '9' { + start := nnext + i, ok = ReadWhile(source, [2]int{start, limit}, IsNumeric) + if ok && i < limit && i-start < 8 && source[i] == ';' { + v, _ := strconv.ParseUint(BytesToReadOnlyString(source[start:i]), 0, 32) + cob.Write(source[n:pos]) + n = i + 1 + runeSize := utf8.EncodeRune(buf, ToValidRune(rune(v))) + cob.Write(buf[:runeSize]) + continue + } + } + } + } + i = next - 1 + } + } + if cob.IsCopied() { + cob.Write(source[n:]) + } + return cob.Bytes() +} + +// ResolveEntityNames resolve entity references like 'ö" . +func ResolveEntityNames(source []byte) []byte { + cob := NewCopyOnWriteBuffer(source) + limit := len(source) + var ok bool + n := 0 + for i := 0; i < limit; i++ { + if source[i] == '&' { + pos := i + next := i + 1 + if !(next < limit && source[next] == '#') { + start := next + i, ok = ReadWhile(source, [2]int{start, limit}, IsAlphaNumeric) + if ok && i < limit && source[i] == ';' { + name := BytesToReadOnlyString(source[start:i]) + entity, ok := LookUpHTML5EntityByName(name) + if ok { + cob.Write(source[n:pos]) + n = i + 1 + cob.Write(entity.Characters) + continue + } + } + } + i = next - 1 + } + } + if cob.IsCopied() { + cob.Write(source[n:]) + } + return cob.Bytes() +} + +var htmlSpace = []byte("%20") + +// URLEscape escape the given URL. +// If resolveReference is set true: +// 1. unescape punctuations +// 2. resolve numeric references +// 3. resolve entity references +// +// URL encoded values (%xx) are kept as is. +func URLEscape(v []byte, resolveReference bool) []byte { + if resolveReference { + v = UnescapePunctuations(v) + v = ResolveNumericReferences(v) + v = ResolveEntityNames(v) + } + cob := NewCopyOnWriteBuffer(v) + limit := len(v) + n := 0 + + for i := 0; i < limit; { + c := v[i] + if urlEscapeTable[c] == 1 { + i++ + continue + } + if c == '%' && i+2 < limit && IsHexDecimal(v[i+1]) && IsHexDecimal(v[i+1]) { + i += 3 + continue + } + u8len := utf8lenTable[c] + if u8len == 99 { // invalid utf8 leading byte, skip it + i++ + continue + } + if c == ' ' { + cob.Write(v[n:i]) + cob.Write(htmlSpace) + i++ + n = i + continue + } + if int(u8len) > len(v) { + u8len = int8(len(v) - 1) + } + if u8len == 0 { + i++ + n = i + continue + } + cob.Write(v[n:i]) + stop := i + int(u8len) + if stop > len(v) { + i++ + n = i + continue + } + cob.Write(StringToReadOnlyBytes(url.QueryEscape(string(v[i:stop])))) + i += int(u8len) + n = i + } + if cob.IsCopied() && n < limit { + cob.Write(v[n:]) + } + return cob.Bytes() +} + +// FindURLIndex returns a stop index value if the given bytes seem an URL. +// This function is equivalent to [A-Za-z][A-Za-z0-9.+-]{1,31}:[^<>\x00-\x20]* . +func FindURLIndex(b []byte) int { + i := 0 + if !(len(b) > 0 && urlTable[b[i]]&7 == 7) { + return -1 + } + i++ + for ; i < len(b); i++ { + c := b[i] + if urlTable[c]&4 != 4 { + break + } + } + if i == 1 || i > 33 || i >= len(b) { + return -1 + } + if b[i] != ':' { + return -1 + } + i++ + for ; i < len(b); i++ { + c := b[i] + if urlTable[c]&1 != 1 { + break + } + } + return i +} + +var emailDomainRegexp = regexp.MustCompile(`^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*`) //nolint:golint,lll + +// FindEmailIndex returns a stop index value if the given bytes seem an email address. +func FindEmailIndex(b []byte) int { + // TODO: eliminate regexps + i := 0 + for ; i < len(b); i++ { + c := b[i] + if emailTable[c]&1 != 1 { + break + } + } + if i == 0 { + return -1 + } + if i >= len(b) || b[i] != '@' { + return -1 + } + i++ + if i >= len(b) { + return -1 + } + match := emailDomainRegexp.FindSubmatchIndex(b[i:]) + if match == nil { + return -1 + } + return i + match[1] +} + +var spaces = []byte(" \t\n\x0b\x0c\x0d") + +var spaceTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} //nolint:golint,lll + +var punctTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} //nolint:golint,lll + +// a-zA-Z0-9, ;/?:@&=+$,-_.!~*'()# + +var urlEscapeTable = [256]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} //nolint:golint,lll + +var utf8lenTable = [256]int8{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 99, 99, 99, 99, 99, 99, 99, 99} //nolint:golint,lll + +var urlTable = [256]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 5, 5, 1, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 0, 1, 0, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} //nolint:golint,lll + +var emailTable = [256]uint8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} //nolint:golint,lll + +// UTF8Len returns a byte length of the utf-8 character. +func UTF8Len(b byte) int8 { + return utf8lenTable[b] +} + +// IsPunct returns true if the given character is a punctuation, otherwise false. +func IsPunct(c byte) bool { + return punctTable[c] == 1 +} + +// IsPunctRune returns true if the given rune is a punctuation, otherwise false. +func IsPunctRune(r rune) bool { + return int32(r) <= 256 && IsPunct(byte(r)) || unicode.IsPunct(r) +} + +// IsSpace returns true if the given character is a space, otherwise false. +func IsSpace(c byte) bool { + return spaceTable[c] == 1 +} + +// IsSpaceRune returns true if the given rune is a space, otherwise false. +func IsSpaceRune(r rune) bool { + return int32(r) <= 256 && IsSpace(byte(r)) || unicode.IsSpace(r) +} + +// IsNumeric returns true if the given character is a numeric, otherwise false. +func IsNumeric(c byte) bool { + return c >= '0' && c <= '9' +} + +// IsHexDecimal returns true if the given character is a hexdecimal, otherwise false. +func IsHexDecimal(c byte) bool { + return c >= '0' && c <= '9' || c >= 'a' && c <= 'f' || c >= 'A' && c <= 'F' +} + +// IsAlphaNumeric returns true if the given character is a alphabet or a numeric, otherwise false. +func IsAlphaNumeric(c byte) bool { + return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' +} + +// A BufWriter is a subset of the bufio.Writer . +type BufWriter interface { + io.Writer + Available() int + Buffered() int + Flush() error + WriteByte(c byte) error + WriteRune(r rune) (size int, err error) + WriteString(s string) (int, error) +} + +// A PrioritizedValue struct holds pair of an arbitrary value and a priority. +type PrioritizedValue struct { + // Value is an arbitrary value that you want to prioritize. + Value interface{} + // Priority is a priority of the value. + Priority int +} + +// PrioritizedSlice is a slice of the PrioritizedValues. +type PrioritizedSlice []PrioritizedValue + +// Sort sorts the PrioritizedSlice in ascending order. +func (s PrioritizedSlice) Sort() { + sort.Slice(s, func(i, j int) bool { + return s[i].Priority < s[j].Priority + }) +} + +// Remove removes the given value from this slice. +func (s PrioritizedSlice) Remove(v interface{}) PrioritizedSlice { + i := 0 + found := false + for ; i < len(s); i++ { + if s[i].Value == v { + found = true + break + } + } + if !found { + return s + } + return append(s[:i], s[i+1:]...) +} + +// Prioritized returns a new PrioritizedValue. +func Prioritized(v interface{}, priority int) PrioritizedValue { + return PrioritizedValue{v, priority} +} + +func bytesHash(b []byte) uint64 { + var hash uint64 = 5381 + for _, c := range b { + hash = ((hash << 5) + hash) + uint64(c) + } + return hash +} + +// BytesFilter is a efficient data structure for checking whether bytes exist or not. +// BytesFilter is thread-safe. +type BytesFilter interface { + // Add adds given bytes to this set. + Add([]byte) + + // Contains return true if this set contains given bytes, otherwise false. + Contains([]byte) bool + + // Extend copies this filter and adds given bytes to new filter. + Extend(...[]byte) BytesFilter +} + +type bytesFilter struct { + chars [256]uint8 + threshold int + slots [][][]byte +} + +// NewBytesFilter returns a new BytesFilter. +func NewBytesFilter(elements ...[]byte) BytesFilter { + s := &bytesFilter{ + threshold: 3, + slots: make([][][]byte, 64), + } + for _, element := range elements { + s.Add(element) + } + return s +} + +func (s *bytesFilter) Add(b []byte) { + l := len(b) + m := s.threshold + if l < s.threshold { + m = l + } + for i := 0; i < m; i++ { + s.chars[b[i]] |= 1 << uint8(i) + } + h := bytesHash(b) % uint64(len(s.slots)) + slot := s.slots[h] + if slot == nil { + slot = [][]byte{} + } + s.slots[h] = append(slot, b) +} + +func (s *bytesFilter) Extend(bs ...[]byte) BytesFilter { + newFilter := NewBytesFilter().(*bytesFilter) + newFilter.chars = s.chars + newFilter.threshold = s.threshold + for k, v := range s.slots { + newSlot := make([][]byte, len(v)) + copy(newSlot, v) + newFilter.slots[k] = v + } + for _, b := range bs { + newFilter.Add(b) + } + return newFilter +} + +func (s *bytesFilter) Contains(b []byte) bool { + l := len(b) + m := s.threshold + if l < s.threshold { + m = l + } + for i := 0; i < m; i++ { + if (s.chars[b[i]] & (1 << uint8(i))) == 0 { + return false + } + } + h := bytesHash(b) % uint64(len(s.slots)) + slot := s.slots[h] + if len(slot) == 0 { + return false + } + for _, element := range slot { + if bytes.Equal(element, b) { + return true + } + } + return false +} diff --git a/vendor/github.com/yuin/goldmark/util/util_cjk.go b/vendor/github.com/yuin/goldmark/util/util_cjk.go new file mode 100644 index 0000000..d758107 --- /dev/null +++ b/vendor/github.com/yuin/goldmark/util/util_cjk.go @@ -0,0 +1,469 @@ +package util + +import "unicode" + +var cjkRadicalsSupplement = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x2E80, 0x2EFF, 1}, + }, +} + +var kangxiRadicals = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x2F00, 0x2FDF, 1}, + }, +} + +var ideographicDescriptionCharacters = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x2FF0, 0x2FFF, 1}, + }, +} + +var cjkSymbolsAndPunctuation = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x3000, 0x303F, 1}, + }, +} + +var hiragana = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x3040, 0x309F, 1}, + }, +} + +var katakana = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x30A0, 0x30FF, 1}, + }, +} + +var kanbun = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x3130, 0x318F, 1}, + {0x3190, 0x319F, 1}, + }, +} + +var cjkStrokes = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x31C0, 0x31EF, 1}, + }, +} + +var katakanaPhoneticExtensions = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x31F0, 0x31FF, 1}, + }, +} + +var cjkCompatibility = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x3300, 0x33FF, 1}, + }, +} + +var cjkUnifiedIdeographsExtensionA = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x3400, 0x4DBF, 1}, + }, +} + +var cjkUnifiedIdeographs = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0x4E00, 0x9FFF, 1}, + }, +} + +var yiSyllables = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0xA000, 0xA48F, 1}, + }, +} + +var yiRadicals = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0xA490, 0xA4CF, 1}, + }, +} + +var cjkCompatibilityIdeographs = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0xF900, 0xFAFF, 1}, + }, +} + +var verticalForms = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0xFE10, 0xFE1F, 1}, + }, +} + +var cjkCompatibilityForms = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0xFE30, 0xFE4F, 1}, + }, +} + +var smallFormVariants = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0xFE50, 0xFE6F, 1}, + }, +} + +var halfwidthAndFullwidthForms = &unicode.RangeTable{ + R16: []unicode.Range16{ + {0xFF00, 0xFFEF, 1}, + }, +} + +var kanaSupplement = &unicode.RangeTable{ + R32: []unicode.Range32{ + {0x1B000, 0x1B0FF, 1}, + }, +} + +var kanaExtendedA = &unicode.RangeTable{ + R32: []unicode.Range32{ + {0x1B100, 0x1B12F, 1}, + }, +} + +var smallKanaExtension = &unicode.RangeTable{ + R32: []unicode.Range32{ + {0x1B130, 0x1B16F, 1}, + }, +} + +var cjkUnifiedIdeographsExtensionB = &unicode.RangeTable{ + R32: []unicode.Range32{ + {0x20000, 0x2A6DF, 1}, + }, +} + +var cjkUnifiedIdeographsExtensionC = &unicode.RangeTable{ + R32: []unicode.Range32{ + {0x2A700, 0x2B73F, 1}, + }, +} + +var cjkUnifiedIdeographsExtensionD = &unicode.RangeTable{ + R32: []unicode.Range32{ + {0x2B740, 0x2B81F, 1}, + }, +} + +var cjkUnifiedIdeographsExtensionE = &unicode.RangeTable{ + R32: []unicode.Range32{ + {0x2B820, 0x2CEAF, 1}, + }, +} + +var cjkUnifiedIdeographsExtensionF = &unicode.RangeTable{ + R32: []unicode.Range32{ + {0x2CEB0, 0x2EBEF, 1}, + }, +} + +var cjkCompatibilityIdeographsSupplement = &unicode.RangeTable{ + R32: []unicode.Range32{ + {0x2F800, 0x2FA1F, 1}, + }, +} + +var cjkUnifiedIdeographsExtensionG = &unicode.RangeTable{ + R32: []unicode.Range32{ + {0x30000, 0x3134F, 1}, + }, +} + +// IsEastAsianWideRune returns trhe if the given rune is an east asian wide character, otherwise false. +func IsEastAsianWideRune(r rune) bool { + return unicode.Is(unicode.Hiragana, r) || + unicode.Is(unicode.Katakana, r) || + unicode.Is(unicode.Han, r) || + unicode.Is(unicode.Lm, r) || + unicode.Is(unicode.Hangul, r) || + unicode.Is(cjkSymbolsAndPunctuation, r) +} + +// IsSpaceDiscardingUnicodeRune returns true if the given rune is space-discarding unicode character, otherwise false. +// See https://www.w3.org/TR/2020/WD-css-text-3-20200429/#space-discard-set +func IsSpaceDiscardingUnicodeRune(r rune) bool { + return unicode.Is(cjkRadicalsSupplement, r) || + unicode.Is(kangxiRadicals, r) || + unicode.Is(ideographicDescriptionCharacters, r) || + unicode.Is(cjkSymbolsAndPunctuation, r) || + unicode.Is(hiragana, r) || + unicode.Is(katakana, r) || + unicode.Is(kanbun, r) || + unicode.Is(cjkStrokes, r) || + unicode.Is(katakanaPhoneticExtensions, r) || + unicode.Is(cjkCompatibility, r) || + unicode.Is(cjkUnifiedIdeographsExtensionA, r) || + unicode.Is(cjkUnifiedIdeographs, r) || + unicode.Is(yiSyllables, r) || + unicode.Is(yiRadicals, r) || + unicode.Is(cjkCompatibilityIdeographs, r) || + unicode.Is(verticalForms, r) || + unicode.Is(cjkCompatibilityForms, r) || + unicode.Is(smallFormVariants, r) || + unicode.Is(halfwidthAndFullwidthForms, r) || + unicode.Is(kanaSupplement, r) || + unicode.Is(kanaExtendedA, r) || + unicode.Is(smallKanaExtension, r) || + unicode.Is(cjkUnifiedIdeographsExtensionB, r) || + unicode.Is(cjkUnifiedIdeographsExtensionC, r) || + unicode.Is(cjkUnifiedIdeographsExtensionD, r) || + unicode.Is(cjkUnifiedIdeographsExtensionE, r) || + unicode.Is(cjkUnifiedIdeographsExtensionF, r) || + unicode.Is(cjkCompatibilityIdeographsSupplement, r) || + unicode.Is(cjkUnifiedIdeographsExtensionG, r) +} + +// EastAsianWidth returns the east asian width of the given rune. +// See https://www.unicode.org/reports/tr11/tr11-36.html +func EastAsianWidth(r rune) string { + switch { + case r == 0x3000, + (0xFF01 <= r && r <= 0xFF60), + (0xFFE0 <= r && r <= 0xFFE6): + return "F" + + case r == 0x20A9, + (0xFF61 <= r && r <= 0xFFBE), + (0xFFC2 <= r && r <= 0xFFC7), + (0xFFCA <= r && r <= 0xFFCF), + (0xFFD2 <= r && r <= 0xFFD7), + (0xFFDA <= r && r <= 0xFFDC), + (0xFFE8 <= r && r <= 0xFFEE): + return "H" + + case (0x1100 <= r && r <= 0x115F), + (0x11A3 <= r && r <= 0x11A7), + (0x11FA <= r && r <= 0x11FF), + (0x2329 <= r && r <= 0x232A), + (0x2E80 <= r && r <= 0x2E99), + (0x2E9B <= r && r <= 0x2EF3), + (0x2F00 <= r && r <= 0x2FD5), + (0x2FF0 <= r && r <= 0x2FFB), + (0x3001 <= r && r <= 0x303E), + (0x3041 <= r && r <= 0x3096), + (0x3099 <= r && r <= 0x30FF), + (0x3105 <= r && r <= 0x312D), + (0x3131 <= r && r <= 0x318E), + (0x3190 <= r && r <= 0x31BA), + (0x31C0 <= r && r <= 0x31E3), + (0x31F0 <= r && r <= 0x321E), + (0x3220 <= r && r <= 0x3247), + (0x3250 <= r && r <= 0x32FE), + (0x3300 <= r && r <= 0x4DBF), + (0x4E00 <= r && r <= 0xA48C), + (0xA490 <= r && r <= 0xA4C6), + (0xA960 <= r && r <= 0xA97C), + (0xAC00 <= r && r <= 0xD7A3), + (0xD7B0 <= r && r <= 0xD7C6), + (0xD7CB <= r && r <= 0xD7FB), + (0xF900 <= r && r <= 0xFAFF), + (0xFE10 <= r && r <= 0xFE19), + (0xFE30 <= r && r <= 0xFE52), + (0xFE54 <= r && r <= 0xFE66), + (0xFE68 <= r && r <= 0xFE6B), + (0x1B000 <= r && r <= 0x1B001), + (0x1F200 <= r && r <= 0x1F202), + (0x1F210 <= r && r <= 0x1F23A), + (0x1F240 <= r && r <= 0x1F248), + (0x1F250 <= r && r <= 0x1F251), + (0x20000 <= r && r <= 0x2F73F), + (0x2B740 <= r && r <= 0x2FFFD), + (0x30000 <= r && r <= 0x3FFFD): + return "W" + + case (0x0020 <= r && r <= 0x007E), + (0x00A2 <= r && r <= 0x00A3), + (0x00A5 <= r && r <= 0x00A6), + r == 0x00AC, + r == 0x00AF, + (0x27E6 <= r && r <= 0x27ED), + (0x2985 <= r && r <= 0x2986): + return "Na" + + case (0x00A1 == r), + (0x00A4 == r), + (0x00A7 <= r && r <= 0x00A8), + (0x00AA == r), + (0x00AD <= r && r <= 0x00AE), + (0x00B0 <= r && r <= 0x00B4), + (0x00B6 <= r && r <= 0x00BA), + (0x00BC <= r && r <= 0x00BF), + (0x00C6 == r), + (0x00D0 == r), + (0x00D7 <= r && r <= 0x00D8), + (0x00DE <= r && r <= 0x00E1), + (0x00E6 == r), + (0x00E8 <= r && r <= 0x00EA), + (0x00EC <= r && r <= 0x00ED), + (0x00F0 == r), + (0x00F2 <= r && r <= 0x00F3), + (0x00F7 <= r && r <= 0x00FA), + (0x00FC == r), + (0x00FE == r), + (0x0101 == r), + (0x0111 == r), + (0x0113 == r), + (0x011B == r), + (0x0126 <= r && r <= 0x0127), + (0x012B == r), + (0x0131 <= r && r <= 0x0133), + (0x0138 == r), + (0x013F <= r && r <= 0x0142), + (0x0144 == r), + (0x0148 <= r && r <= 0x014B), + (0x014D == r), + (0x0152 <= r && r <= 0x0153), + (0x0166 <= r && r <= 0x0167), + (0x016B == r), + (0x01CE == r), + (0x01D0 == r), + (0x01D2 == r), + (0x01D4 == r), + (0x01D6 == r), + (0x01D8 == r), + (0x01DA == r), + (0x01DC == r), + (0x0251 == r), + (0x0261 == r), + (0x02C4 == r), + (0x02C7 == r), + (0x02C9 <= r && r <= 0x02CB), + (0x02CD == r), + (0x02D0 == r), + (0x02D8 <= r && r <= 0x02DB), + (0x02DD == r), + (0x02DF == r), + (0x0300 <= r && r <= 0x036F), + (0x0391 <= r && r <= 0x03A1), + (0x03A3 <= r && r <= 0x03A9), + (0x03B1 <= r && r <= 0x03C1), + (0x03C3 <= r && r <= 0x03C9), + (0x0401 == r), + (0x0410 <= r && r <= 0x044F), + (0x0451 == r), + (0x2010 == r), + (0x2013 <= r && r <= 0x2016), + (0x2018 <= r && r <= 0x2019), + (0x201C <= r && r <= 0x201D), + (0x2020 <= r && r <= 0x2022), + (0x2024 <= r && r <= 0x2027), + (0x2030 == r), + (0x2032 <= r && r <= 0x2033), + (0x2035 == r), + (0x203B == r), + (0x203E == r), + (0x2074 == r), + (0x207F == r), + (0x2081 <= r && r <= 0x2084), + (0x20AC == r), + (0x2103 == r), + (0x2105 == r), + (0x2109 == r), + (0x2113 == r), + (0x2116 == r), + (0x2121 <= r && r <= 0x2122), + (0x2126 == r), + (0x212B == r), + (0x2153 <= r && r <= 0x2154), + (0x215B <= r && r <= 0x215E), + (0x2160 <= r && r <= 0x216B), + (0x2170 <= r && r <= 0x2179), + (0x2189 == r), + (0x2190 <= r && r <= 0x2199), + (0x21B8 <= r && r <= 0x21B9), + (0x21D2 == r), + (0x21D4 == r), + (0x21E7 == r), + (0x2200 == r), + (0x2202 <= r && r <= 0x2203), + (0x2207 <= r && r <= 0x2208), + (0x220B == r), + (0x220F == r), + (0x2211 == r), + (0x2215 == r), + (0x221A == r), + (0x221D <= r && r <= 0x2220), + (0x2223 == r), + (0x2225 == r), + (0x2227 <= r && r <= 0x222C), + (0x222E == r), + (0x2234 <= r && r <= 0x2237), + (0x223C <= r && r <= 0x223D), + (0x2248 == r), + (0x224C == r), + (0x2252 == r), + (0x2260 <= r && r <= 0x2261), + (0x2264 <= r && r <= 0x2267), + (0x226A <= r && r <= 0x226B), + (0x226E <= r && r <= 0x226F), + (0x2282 <= r && r <= 0x2283), + (0x2286 <= r && r <= 0x2287), + (0x2295 == r), + (0x2299 == r), + (0x22A5 == r), + (0x22BF == r), + (0x2312 == r), + (0x2460 <= r && r <= 0x24E9), + (0x24EB <= r && r <= 0x254B), + (0x2550 <= r && r <= 0x2573), + (0x2580 <= r && r <= 0x258F), + (0x2592 <= r && r <= 0x2595), + (0x25A0 <= r && r <= 0x25A1), + (0x25A3 <= r && r <= 0x25A9), + (0x25B2 <= r && r <= 0x25B3), + (0x25B6 <= r && r <= 0x25B7), + (0x25BC <= r && r <= 0x25BD), + (0x25C0 <= r && r <= 0x25C1), + (0x25C6 <= r && r <= 0x25C8), + (0x25CB == r), + (0x25CE <= r && r <= 0x25D1), + (0x25E2 <= r && r <= 0x25E5), + (0x25EF == r), + (0x2605 <= r && r <= 0x2606), + (0x2609 == r), + (0x260E <= r && r <= 0x260F), + (0x2614 <= r && r <= 0x2615), + (0x261C == r), + (0x261E == r), + (0x2640 == r), + (0x2642 == r), + (0x2660 <= r && r <= 0x2661), + (0x2663 <= r && r <= 0x2665), + (0x2667 <= r && r <= 0x266A), + (0x266C <= r && r <= 0x266D), + (0x266F == r), + (0x269E <= r && r <= 0x269F), + (0x26BE <= r && r <= 0x26BF), + (0x26C4 <= r && r <= 0x26CD), + (0x26CF <= r && r <= 0x26E1), + (0x26E3 == r), + (0x26E8 <= r && r <= 0x26FF), + (0x273D == r), + (0x2757 == r), + (0x2776 <= r && r <= 0x277F), + (0x2B55 <= r && r <= 0x2B59), + (0x3248 <= r && r <= 0x324F), + (0xE000 <= r && r <= 0xF8FF), + (0xFE00 <= r && r <= 0xFE0F), + (0xFFFD == r), + (0x1F100 <= r && r <= 0x1F10A), + (0x1F110 <= r && r <= 0x1F12D), + (0x1F130 <= r && r <= 0x1F169), + (0x1F170 <= r && r <= 0x1F19A), + (0xE0100 <= r && r <= 0xE01EF), + (0xF0000 <= r && r <= 0xFFFFD), + (0x100000 <= r && r <= 0x10FFFD): + return "A" + + default: + return "N" + } +} diff --git a/vendor/github.com/yuin/goldmark/util/util_safe.go b/vendor/github.com/yuin/goldmark/util/util_safe.go new file mode 100644 index 0000000..2f6a3fe --- /dev/null +++ b/vendor/github.com/yuin/goldmark/util/util_safe.go @@ -0,0 +1,14 @@ +//go:build appengine || js +// +build appengine js + +package util + +// BytesToReadOnlyString returns a string converted from given bytes. +func BytesToReadOnlyString(b []byte) string { + return string(b) +} + +// StringToReadOnlyBytes returns bytes converted from given string. +func StringToReadOnlyBytes(s string) []byte { + return []byte(s) +} diff --git a/vendor/github.com/yuin/goldmark/util/util_unsafe.go b/vendor/github.com/yuin/goldmark/util/util_unsafe.go new file mode 100644 index 0000000..840007a --- /dev/null +++ b/vendor/github.com/yuin/goldmark/util/util_unsafe.go @@ -0,0 +1,24 @@ +//go:build !appengine && !js +// +build !appengine,!js + +package util + +import ( + "reflect" + "unsafe" +) + +// BytesToReadOnlyString returns a string converted from given bytes. +func BytesToReadOnlyString(b []byte) string { + return *(*string)(unsafe.Pointer(&b)) +} + +// StringToReadOnlyBytes returns bytes converted from given string. +func StringToReadOnlyBytes(s string) (bs []byte) { + sh := (*reflect.StringHeader)(unsafe.Pointer(&s)) + bh := (*reflect.SliceHeader)(unsafe.Pointer(&bs)) + bh.Data = sh.Data + bh.Cap = sh.Len + bh.Len = sh.Len + return +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 6e3af04..13e6e0b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -20,6 +20,22 @@ github.com/valyala/bytebufferpool # github.com/valyala/quicktemplate v1.7.0 ## explicit; go 1.11 github.com/valyala/quicktemplate +# github.com/yuin/goldmark v1.6.0 +## explicit; go 1.18 +github.com/yuin/goldmark +github.com/yuin/goldmark/ast +github.com/yuin/goldmark/extension +github.com/yuin/goldmark/extension/ast +github.com/yuin/goldmark/parser +github.com/yuin/goldmark/renderer +github.com/yuin/goldmark/renderer/html +github.com/yuin/goldmark/text +github.com/yuin/goldmark/util +# github.com/yuin/goldmark-emoji v1.0.2 +## explicit; go 1.15 +github.com/yuin/goldmark-emoji +github.com/yuin/goldmark-emoji/ast +github.com/yuin/goldmark-emoji/definition # golang.org/x/text v0.14.0 ## explicit; go 1.18 golang.org/x/text/feature/plural