Repository: tj/go-termd Branch: master Commit: 7f6aeb166380 Files: 13 Total size: 21.6 KB Directory structure: gitextract_09an3s_0/ ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE.yml │ └── PULL_REQUEST_TEMPLATE.md ├── .gitignore ├── LICENSE ├── Readme.md ├── go.mod ├── go.sum ├── highlight.go ├── termd.go ├── termd_test.go ├── testdata/ │ └── example.md └── theme.go ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/FUNDING.yml ================================================ github: tj ================================================ FILE: .github/ISSUE_TEMPLATE.yml ================================================ ## Prerequisites * [ ] I searched to see if the issue already exists. ## Description Describe the bug or feature. ## Steps to Reproduce Describe the steps required to reproduce the issue if applicable. ## Slack Join us on Slack https://chat.apex.sh/ ================================================ FILE: .github/PULL_REQUEST_TEMPLATE.md ================================================ Please open an issue and discuss changes before spending time on them, unless the change is trivial or an issue already exists. ================================================ FILE: .gitignore ================================================ .envrc ================================================ FILE: LICENSE ================================================ The MIT License Copyright (c) 2019 TJ Holowaychuk tj@tjholowaychuk.com 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. ================================================ FILE: Readme.md ================================================ # Termd Package termd provides terminal markdown rendering, with code block syntax highlighting support. ## Features - Code block syntax highlighting (JSON-friendly for loading from user config) - Word wrapping to the specified column width - Terminal specific styling (still looks like markdown but it's cleaned up for the term) ![](https://apex-software.imgix.net/github/tj/termd/screenshot.png) --- [![GoDoc](https://godoc.org/github.com/tj/go-termd?status.svg)](https://godoc.org/github.com/tj/go-termd) ![](https://img.shields.io/badge/license-MIT-blue.svg) ![](https://img.shields.io/badge/status-stable-green.svg) ## Sponsors This project is [sponsored](https://github.com/sponsors/tj) by [CTO.ai](https://cto.ai/), making it easy for development teams to create and share workflow automations without leaving the command line. [![](https://apex-software.imgix.net/github/sponsors/cto.png)](https://cto.ai/) ================================================ FILE: go.mod ================================================ module github.com/tj/go-termd go 1.13 require ( github.com/alecthomas/chroma v0.6.8 github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 github.com/kr/text v0.1.0 github.com/mitchellh/go-wordwrap v1.0.0 github.com/russross/blackfriday/v2 v2.0.1 github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect github.com/tj/go-css v0.0.0-20191108133013-220a796d1705 ) ================================================ FILE: go.sum ================================================ github.com/GeertJohan/go.incremental v1.0.0/go.mod h1:6fAjUhbVuX1KcMD3c8TEgVUqmo4seqhv0i0kdATSkM0= github.com/GeertJohan/go.rice v1.0.0/go.mod h1:eH6gbSOAUv07dQuZVnBmoDP8mgsM1rtixis4Tib9if0= github.com/akavel/rsrc v0.8.0/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U= github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38/go.mod h1:r7bzyVFMNntcxPZXK3/+KdruV1H5KSlyVY0gc+NgInI= github.com/alecthomas/chroma v0.6.8 h1:TW4JJaIdbAbMyUtGEd6BukFlOKYvVQz3vVhLBEUNwMU= github.com/alecthomas/chroma v0.6.8/go.mod h1:o9ohftueRi7H5be3+Q2cQCNa/YnLBFUNx40ZJfGVFKA= github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721 h1:JHZL0hZKJ1VENNfmXvHbgYlbUOvpzYzvy2aZU5gXVeo= github.com/alecthomas/colour v0.0.0-20160524082231-60882d9e2721/go.mod h1:QO9JBoKquHd+jz9nshCh40fOfO+JzsoXy8qTHF68zU0= github.com/alecthomas/kong v0.1.17-0.20190424132513-439c674f7ae0/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI= github.com/alecthomas/kong v0.2.1-0.20190708041108-0548c6b1afae/go.mod h1:+inYUSluD+p4L8KdviBSgzcqEjUQOfC5fQDRFuc36lI= github.com/alecthomas/kong-hcl v0.1.8-0.20190615233001-b21fea9723c8/go.mod h1:MRgZdU3vrFd05IQ89AxUZ0aYdF39BYoNFa324SodPCA= github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897 h1:p9Sln00KOTlrYkxI1zYWl1QLnEqAqEARBEYa8FQnQcY= github.com/alecthomas/repr v0.0.0-20180818092828-117648cd9897/go.mod h1:xTS7Pm1pD1mvyM075QCDSRqH6qRLXylzS24ZTpRiSzQ= github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59 h1:WWB576BN5zNSZc/M9d/10pqEx5VHNhaQ/yOVAkmj5Yo= github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I= github.com/daaku/go.zipexe v1.0.0/go.mod h1:z8IiR6TsVLEYKwXAoE/I+8ys/sDkgTzSL0CLnGVd57E= github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ= github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dlclark/regexp2 v1.1.6 h1:CqB4MjHw0MFCDj+PHHjiESmHX+N7t0tJzKvC6M97BRg= github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/gorilla/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI= github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.4 h1:bnP0vzxcAdeI1zdubAl5PjU6zsERjGZb7raWodagDYs= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/nkovacs/streamquote v0.0.0-20170412213628-49af9bddb229/go.mod h1:0aYXnNPJ8l7uZxf45rWW1a/uME32OF0rhiYGNQ2oF2E= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160 h1:NSWpaDaurcAJY7PkL8Xt0PhZE7qpvbZl5ljd8r6U0bI= github.com/tj/assert v0.0.0-20190920132354-ee03d75cd160/go.mod h1:mZ9/Rh9oLWpLLDRpvE+3b7gP/C2YyLFYxNmcLnPTMe0= github.com/tj/go-css v0.0.0-20191108133013-220a796d1705 h1:+UA89aFRjPMqdccHd9A0HLNCRDXIoElaDoW2C1V3TzA= github.com/tj/go-css v0.0.0-20191108133013-220a796d1705/go.mod h1:e+JPLQ9wyQCgRnPenX2bo7MJoLphBHz5c1WUqaANSeA= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35 h1:YAFjXN64LMvktoUZH9zgY4lGc/msGN7HQfoSuKCgaDU= golang.org/x/sys v0.0.0-20181128092732-4ed8d59d0b35/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= ================================================ FILE: highlight.go ================================================ package termd import ( "strings" "github.com/alecthomas/chroma" "github.com/alecthomas/chroma/lexers" ) // SyntaxHighlighter is the interface used to highlight blocks of code. type SyntaxHighlighter interface { Token(chroma.Token) string } // highlight returns highlighted code, or the input text on error. func highlight(source, lang string, highlight SyntaxHighlighter) string { l := lexers.Get(lang) if l == nil { return source } l = chroma.Coalesce(l) it, err := l.Tokenise(nil, source) if err != nil { return source } var w strings.Builder for _, t := range it.Tokens() { w.WriteString(highlight.Token(t)) } return w.String() } ================================================ FILE: termd.go ================================================ // Package termd provides terminal markdown rendering, // with code block syntax highlighting support. package termd import ( "fmt" "strings" "github.com/kr/text" "github.com/mitchellh/go-wordwrap" "github.com/russross/blackfriday/v2" ) // Compiler is the markdown to text compiler. The zero value can be used. type Compiler struct { // Columns is the number of columns to wrap text, defaulting to 90. Columns int // Markdown is an optional instance of a blackfriday markdown parser, // defaulting to one with CommonExtensions enabled. Markdown *blackfriday.Markdown // SyntaxHighlighter is an optional syntax highlighter for code blocks, // using the low-level SyntaxHighlighter interface, or SyntaxTheme map. SyntaxHighlighter inBlockQuote bool inList bool } // Compile returns a terminal-styled plain text representation of a markdown string. func (c *Compiler) Compile(s string) string { if c.Markdown == nil { c.Markdown = blackfriday.New(blackfriday.WithExtensions(blackfriday.CommonExtensions)) } if c.Columns == 0 { c.Columns = 90 } if c.SyntaxHighlighter == nil { c.SyntaxHighlighter = SyntaxTheme{} } n := c.Markdown.Parse([]byte(s)) return c.visit(n) } // visit returns a compiled node string. func (c *Compiler) visit(n *blackfriday.Node) (s string) { switch n.Type { case blackfriday.Document: s = c.visit(n.FirstChild) case blackfriday.BlockQuote: prev := c.inBlockQuote c.inBlockQuote = true s = c.visit(n.FirstChild) s = fmt.Sprintf("\033[38;5;102m%s\033[m", s) c.inBlockQuote = prev case blackfriday.List: prev := c.inList c.inList = true s = fmt.Sprintf("%s\n", c.visit(n.FirstChild)) c.inList = prev case blackfriday.Item: s = fmt.Sprintf(" - %s", c.visit(n.FirstChild)) case blackfriday.Paragraph: s = c.visit(n.FirstChild) if c.inList { s += "\n" } else { s = wordwrap.WrapString(s, uint(c.Columns)) s = text.Indent(s, " ") s += "\n\n" } case blackfriday.Heading: h := strings.Repeat("#", n.HeadingData.Level) t := c.visit(n.FirstChild) s = fmt.Sprintf("\033[1m%s %s\033[m\n\n", h, t) case blackfriday.HorizontalRule: s = fmt.Sprintf(" %s\n\n", strings.Repeat("─", c.Columns)) case blackfriday.Emph: s = c.visit(n.FirstChild) if !c.inBlockQuote { s = fmt.Sprintf("\033[3m%s\033[m", s) } case blackfriday.Strong: s = c.visit(n.FirstChild) if !c.inBlockQuote { s = fmt.Sprintf("\033[1m%s\033[m", s) } case blackfriday.Link: s = c.visit(n.FirstChild) d := string(n.LinkData.Destination) if s != d { s = fmt.Sprintf("%s (%s)", s, d) } case blackfriday.Image: s = string(n.LinkData.Destination) case blackfriday.Text: s = string(n.Literal) case blackfriday.CodeBlock: lang := string(n.CodeBlockData.Info) s = string(n.Literal) s = highlight(s, lang, c.SyntaxHighlighter) s = fmt.Sprintf("%s\n", text.Indent(s, " ")) case blackfriday.Code: s = fmt.Sprintf("\033[38;5;102m`%s`\033[m", string(n.Literal)) case blackfriday.HTMLSpan: // ignore default: s = fmt.Sprintf("", n) } if n.Next != nil { s += c.visit(n.Next) } return } ================================================ FILE: termd_test.go ================================================ package termd_test import ( "fmt" "io/ioutil" "github.com/tj/go-termd" ) func Example() { var c termd.Compiler c.SyntaxHighlighter = termd.SyntaxTheme{ "keyword": termd.Style{}, "comment": termd.Style{ Color: "#323232", }, "literal": termd.Style{ Color: "#555555", }, "name": termd.Style{ Color: "#777777", }, "name.function": termd.Style{ Color: "#444444", }, "literal.string": termd.Style{ Color: "#333333", }, } b, _ := ioutil.ReadFile("testdata/example.md") fmt.Printf("%s\n", c.Compile(string(b))) // Output: } ================================================ FILE: testdata/example.md ================================================ # Heading Lorem ipsum _dolor_ sit amet, consectetur **adipiscing** elit. Curabitur `convallis` aliquet diam ut pharetra. In et sapien dui. Pellentesque nec magna non diam volutpat commodo. Nam non lorem vitae justo facilisis varius eu at lorem. ## Sub Heading Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur convallis aliquet diam ut pharetra. In et sapien dui. Pellentesque nec magna non diam volutpat commodo. Nam non lorem vitae justo facilisis varius eu at lorem. Maecenas auctor, velit consectetur commodo pellentesque, nunc augue tristique justo, ac ullamcorper mi nisi a arcu. Cras lobortis lacus sed erat pellentesque malesuada. Integer iaculis commodo libero quis scelerisque. Integer tortor tortor, aliquet eu quam sed, viverra pellentesque augue. Sed suscipit nulla magna, at ultrices odio fermentum a. Praesent sodales nulla massa, eu imperdiet magna. Odio fermentum a. Praesent sodales nulla massa, eu imperdiet magna. Integer iaculis commodo libero quis scelerisque. Integer tortor tortor, aliquet eu quam sed, viverra pellentesque augue. Sed suscipit nulla magna, at ultrices odio fermentum a. Praesent sodales nulla massa, eu imperdiet magna. --- Integer iaculis commodo libero quis scelerisque. Integer tortor tortor, aliquet eu quam sed, viverra pellentesque augue. Sed suscipit nulla magna, at ultrices odio fermentum a. Praesent sodales nulla massa, eu imperdiet magna. ## Code Example Here's an example code block: ```js const foo = /something/ /** * isJSON returns true if the string looks like JSON. */ function isJSON(s = '') { s = s.trim() return s[0] == '{' && s[s.length - 1] == '}' } console.log('Testing some stuff') ``` ================================================ FILE: theme.go ================================================ package termd import ( "fmt" "github.com/alecthomas/chroma" "github.com/aybabtme/rgbterm" "github.com/tj/go-css/csshex" ) // Style is the configuration used to style a particular token. type Style struct { Color string `json:"color"` Background string `json:"background"` Bold bool `json:"bold"` Faint bool `json:"faint"` Italic bool `json:"italic"` Underline bool `json:"underline"` } // apply returns a string with the style applied. func (s Style) apply(v string) string { if s.Bold { v = escape(1, v) } if s.Faint { v = escape(2, v) } if s.Italic { v = escape(3, v) } if s.Underline { v = escape(4, v) } if s.Color != "" { v = foreground(v, s.Color) } if s.Background != "" { v = background(v, s.Background) } return v } // SyntaxTheme is a map of token names to style configurations. type SyntaxTheme map[string]Style // Token implementation. func (c SyntaxTheme) Token(t chroma.Token) string { // specific if s, ok := c.mapped(t.Type, t.Value); ok { return s } // sub-category if s, ok := c.mapped(t.Type.SubCategory(), t.Value); ok { return s } // category if s, ok := c.mapped(t.Type.Category(), t.Value); ok { return s } return t.Value } // mapped returns a string mapped to its style, or returns the input string as-is. func (c SyntaxTheme) mapped(t chroma.TokenType, v string) (string, bool) { // check if the key is valid k, ok := themeKeys[t] if !ok { return v, false } // check if the style is mapped s, ok := c[k] if !ok { return v, false } return s.apply(v), true } // escape returns an ansi escape sequence with the given code. func escape(code int, s string) string { return fmt.Sprintf("\033[%dm%s\033[m", code, s) } // foreground color. func foreground(s, color string) string { r, g, b, ok := csshex.Parse(color) if !ok { return s } return rgbterm.FgString(s, r, g, b) } // background color. func background(s, color string) string { r, g, b, ok := csshex.Parse(color) if !ok { return s } return rgbterm.BgString(s, r, g, b) } // themeKeys is the map of token types to names. var themeKeys = map[chroma.TokenType]string{ chroma.Keyword: "keyword", chroma.KeywordConstant: "keyword.constant", chroma.KeywordDeclaration: "keyword.declaration", chroma.KeywordNamespace: "keyword.namespace", chroma.KeywordPseudo: "keyword.pseudo", chroma.KeywordReserved: "keyword.reserved", chroma.KeywordType: "keyword.type", chroma.Name: "name", chroma.NameAttribute: "name.attribute", chroma.NameBuiltin: "name.builtin", chroma.NameBuiltinPseudo: "name.builtin.pseudo", chroma.NameClass: "name.class", chroma.NameConstant: "name.constant", chroma.NameDecorator: "name.decorator", chroma.NameEntity: "name.entity", chroma.NameException: "name.exception", chroma.NameFunction: "name.function", chroma.NameFunctionMagic: "name.function.magic", chroma.NameKeyword: "name.keyword", chroma.NameLabel: "name.label", chroma.NameNamespace: "name.namespace", chroma.NameOperator: "name.operator", chroma.NameOther: "name.other", chroma.NamePseudo: "name.pseudo", chroma.NameProperty: "name.property", chroma.NameTag: "name.tag", chroma.NameVariable: "name.variable", chroma.NameVariableAnonymous: "name.variable.anonymous", chroma.NameVariableClass: "name.variable.class", chroma.NameVariableGlobal: "name.variable.global", chroma.NameVariableInstance: "name.variable.instance", chroma.NameVariableMagic: "name.variable.magic", chroma.Literal: "literal", chroma.LiteralDate: "literal.date", chroma.LiteralOther: "literal.other", chroma.LiteralString: "literal.string", chroma.LiteralStringAffix: "literal.string.affix", chroma.LiteralStringAtom: "literal.string.atom", chroma.LiteralStringBacktick: "literal.string.backtick", chroma.LiteralStringBoolean: "literal.string.boolean", chroma.LiteralStringChar: "literal.string.char", chroma.LiteralStringDelimiter: "literal.string.delimiter", chroma.LiteralStringDoc: "literal.string.doc", chroma.LiteralStringDouble: "literal.string.double", chroma.LiteralStringEscape: "literal.string.escape", chroma.LiteralStringHeredoc: "literal.string.heredoc", chroma.LiteralStringInterpol: "literal.string.interpol", chroma.LiteralStringName: "literal.string.name", chroma.LiteralStringOther: "literal.string.other", chroma.LiteralStringRegex: "literal.string.regex", chroma.LiteralStringSingle: "literal.string.single", chroma.LiteralStringSymbol: "literal.string.symbol", chroma.LiteralNumber: "literal.number", chroma.LiteralNumberBin: "literal.number.bin", chroma.LiteralNumberFloat: "literal.number.float", chroma.LiteralNumberHex: "literal.number.hex", chroma.LiteralNumberInteger: "literal.number.integer", chroma.LiteralNumberIntegerLong: "literal.number.integer.long", chroma.LiteralNumberOct: "literal.number.oct", chroma.Operator: "operator", chroma.OperatorWord: "operator.word", chroma.Punctuation: "punctuation", chroma.Comment: "comment", chroma.CommentHashbang: "comment.hashbang", chroma.CommentMultiline: "comment.multiline", chroma.CommentSingle: "comment.single", chroma.CommentSpecial: "comment.special", chroma.CommentPreproc: "comment.preproc", chroma.CommentPreprocFile: "comment.preproc.file", chroma.Generic: "generic", chroma.GenericDeleted: "generic.deleted", chroma.GenericEmph: "generic.emph", chroma.GenericError: "generic.error", chroma.GenericHeading: "generic.heading", chroma.GenericInserted: "generic.inserted", chroma.GenericOutput: "generic.output", chroma.GenericPrompt: "generic.prompt", chroma.GenericStrong: "generic.strong", chroma.GenericSubheading: "generic.subheading", chroma.GenericTraceback: "generic.traceback", chroma.GenericUnderline: "generic.underline", chroma.Text: "text", chroma.TextWhitespace: "text.whitespace", chroma.TextSymbol: "text.symbol", chroma.TextPunctuation: "text.punctuation", }