diff options
Diffstat (limited to 'vendor/github.com/alecthomas/chroma/v2/README.md')
| -rw-r--r-- | vendor/github.com/alecthomas/chroma/v2/README.md | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/vendor/github.com/alecthomas/chroma/v2/README.md b/vendor/github.com/alecthomas/chroma/v2/README.md new file mode 100644 index 0000000..445fb96 --- /dev/null +++ b/vendor/github.com/alecthomas/chroma/v2/README.md | |||
| @@ -0,0 +1,285 @@ | |||
| 1 | # Chroma — A general purpose syntax highlighter in pure Go | ||
| 2 | [](https://godoc.org/github.com/alecthomas/chroma) [](https://github.com/alecthomas/chroma/actions/workflows/ci.yml) [](https://invite.slack.golangbridge.org/) | ||
| 3 | |||
| 4 | > **NOTE:** As Chroma has just been released, its API is still in flux. That said, the high-level interface should not change significantly. | ||
| 5 | |||
| 6 | Chroma takes source code and other structured text and converts it into syntax | ||
| 7 | highlighted HTML, ANSI-coloured text, etc. | ||
| 8 | |||
| 9 | Chroma is based heavily on [Pygments](http://pygments.org/), and includes | ||
| 10 | translators for Pygments lexers and styles. | ||
| 11 | |||
| 12 | <a id="markdown-table-of-contents" name="table-of-contents"></a> | ||
| 13 | ## Table of Contents | ||
| 14 | |||
| 15 | <!-- TOC --> | ||
| 16 | |||
| 17 | 1. [Table of Contents](#table-of-contents) | ||
| 18 | 2. [Supported languages](#supported-languages) | ||
| 19 | 3. [Try it](#try-it) | ||
| 20 | 4. [Using the library](#using-the-library) | ||
| 21 | 1. [Quick start](#quick-start) | ||
| 22 | 2. [Identifying the language](#identifying-the-language) | ||
| 23 | 3. [Formatting the output](#formatting-the-output) | ||
| 24 | 4. [The HTML formatter](#the-html-formatter) | ||
| 25 | 5. [More detail](#more-detail) | ||
| 26 | 1. [Lexers](#lexers) | ||
| 27 | 2. [Formatters](#formatters) | ||
| 28 | 3. [Styles](#styles) | ||
| 29 | 6. [Command-line interface](#command-line-interface) | ||
| 30 | 7. [What's missing compared to Pygments?](#whats-missing-compared-to-pygments) | ||
| 31 | |||
| 32 | <!-- /TOC --> | ||
| 33 | |||
| 34 | <a id="markdown-supported-languages" name="supported-languages"></a> | ||
| 35 | ## Supported languages | ||
| 36 | |||
| 37 | Prefix | Language | ||
| 38 | :----: | -------- | ||
| 39 | A | ABAP, ABNF, ActionScript, ActionScript 3, Ada, Angular2, ANTLR, ApacheConf, APL, AppleScript, Arduino, Awk | ||
| 40 | B | Ballerina, Base Makefile, Bash, Batchfile, BibTeX, Bicep, BlitzBasic, BNF, Brainfuck | ||
| 41 | C | C, C#, C++, Caddyfile, Caddyfile Directives, Cap'n Proto, Cassandra CQL, Ceylon, CFEngine3, cfstatement, ChaiScript, Cheetah, Clojure, CMake, COBOL, CoffeeScript, Common Lisp, Coq, Crystal, CSS, Cython | ||
| 42 | D | D, Dart, Diff, Django/Jinja, Docker, DTD, Dylan | ||
| 43 | E | EBNF, Elixir, Elm, EmacsLisp, Erlang | ||
| 44 | F | Factor, Fish, Forth, Fortran, FSharp | ||
| 45 | G | GAS, GDScript, Genshi, Genshi HTML, Genshi Text, Gherkin, GLSL, Gnuplot, Go, Go HTML Template, Go Text Template, GraphQL, Groff, Groovy | ||
| 46 | H | Handlebars, Haskell, Haxe, HCL, Hexdump, HLB, HTML, HTTP, Hy | ||
| 47 | I | Idris, Igor, INI, Io | ||
| 48 | J | J, Java, JavaScript, JSON, Julia, Jungle | ||
| 49 | K | Kotlin | ||
| 50 | L | Lighttpd configuration file, LLVM, Lua | ||
| 51 | M | Mako, markdown, Mason, Mathematica, Matlab, MiniZinc, MLIR, Modula-2, MonkeyC, MorrowindScript, Myghty, MySQL | ||
| 52 | N | NASM, Newspeak, Nginx configuration file, Nim, Nix | ||
| 53 | O | Objective-C, OCaml, Octave, OnesEnterprise, OpenEdge ABL, OpenSCAD, Org Mode | ||
| 54 | P | PacmanConf, Perl, PHP, PHTML, Pig, PkgConfig, PL/pgSQL, plaintext, Pony, PostgreSQL SQL dialect, PostScript, POVRay, PowerShell, Prolog, PromQL, Protocol Buffer, Puppet, Python 2, Python | ||
| 55 | Q | QBasic | ||
| 56 | R | R, Racket, Ragel, Raku, react, ReasonML, reg, reStructuredText, Rexx, Ruby, Rust | ||
| 57 | S | SAS, Sass, Scala, Scheme, Scilab, SCSS, Smalltalk, Smarty, Snobol, Solidity, SPARQL, SQL, SquidConf, Standard ML, Stylus, Svelte, Swift, SYSTEMD, systemverilog | ||
| 58 | T | TableGen, TASM, Tcl, Tcsh, Termcap, Terminfo, Terraform, TeX, Thrift, TOML, TradingView, Transact-SQL, Turing, Turtle, Twig, TypeScript, TypoScript, TypoScriptCssData, TypoScriptHtmlData | ||
| 59 | V | VB.net, verilog, VHDL, VimL, vue | ||
| 60 | W | WDTE | ||
| 61 | X | XML, Xorg | ||
| 62 | Y | YAML, YANG | ||
| 63 | Z | Zig | ||
| 64 | |||
| 65 | |||
| 66 | _I will attempt to keep this section up to date, but an authoritative list can be | ||
| 67 | displayed with `chroma --list`._ | ||
| 68 | |||
| 69 | <a id="markdown-try-it" name="try-it"></a> | ||
| 70 | ## Try it | ||
| 71 | |||
| 72 | Try out various languages and styles on the [Chroma Playground](https://swapoff.org/chroma/playground/). | ||
| 73 | |||
| 74 | <a id="markdown-using-the-library" name="using-the-library"></a> | ||
| 75 | ## Using the library | ||
| 76 | |||
| 77 | Chroma, like Pygments, has the concepts of | ||
| 78 | [lexers](https://github.com/alecthomas/chroma/tree/master/lexers), | ||
| 79 | [formatters](https://github.com/alecthomas/chroma/tree/master/formatters) and | ||
| 80 | [styles](https://github.com/alecthomas/chroma/tree/master/styles). | ||
| 81 | |||
| 82 | Lexers convert source text into a stream of tokens, styles specify how token | ||
| 83 | types are mapped to colours, and formatters convert tokens and styles into | ||
| 84 | formatted output. | ||
| 85 | |||
| 86 | A package exists for each of these, containing a global `Registry` variable | ||
| 87 | with all of the registered implementations. There are also helper functions | ||
| 88 | for using the registry in each package, such as looking up lexers by name or | ||
| 89 | matching filenames, etc. | ||
| 90 | |||
| 91 | In all cases, if a lexer, formatter or style can not be determined, `nil` will | ||
| 92 | be returned. In this situation you may want to default to the `Fallback` | ||
| 93 | value in each respective package, which provides sane defaults. | ||
| 94 | |||
| 95 | <a id="markdown-quick-start" name="quick-start"></a> | ||
| 96 | ### Quick start | ||
| 97 | |||
| 98 | A convenience function exists that can be used to simply format some source | ||
| 99 | text, without any effort: | ||
| 100 | |||
| 101 | ```go | ||
| 102 | err := quick.Highlight(os.Stdout, someSourceCode, "go", "html", "monokai") | ||
| 103 | ``` | ||
| 104 | |||
| 105 | <a id="markdown-identifying-the-language" name="identifying-the-language"></a> | ||
| 106 | ### Identifying the language | ||
| 107 | |||
| 108 | To highlight code, you'll first have to identify what language the code is | ||
| 109 | written in. There are three primary ways to do that: | ||
| 110 | |||
| 111 | 1. Detect the language from its filename. | ||
| 112 | |||
| 113 | ```go | ||
| 114 | lexer := lexers.Match("foo.go") | ||
| 115 | ``` | ||
| 116 | |||
| 117 | 3. Explicitly specify the language by its Chroma syntax ID (a full list is available from `lexers.Names()`). | ||
| 118 | |||
| 119 | ```go | ||
| 120 | lexer := lexers.Get("go") | ||
| 121 | ``` | ||
| 122 | |||
| 123 | 3. Detect the language from its content. | ||
| 124 | |||
| 125 | ```go | ||
| 126 | lexer := lexers.Analyse("package main\n\nfunc main()\n{\n}\n") | ||
| 127 | ``` | ||
| 128 | |||
| 129 | In all cases, `nil` will be returned if the language can not be identified. | ||
| 130 | |||
| 131 | ```go | ||
| 132 | if lexer == nil { | ||
| 133 | lexer = lexers.Fallback | ||
| 134 | } | ||
| 135 | ``` | ||
| 136 | |||
| 137 | At this point, it should be noted that some lexers can be extremely chatty. To | ||
| 138 | mitigate this, you can use the coalescing lexer to coalesce runs of identical | ||
| 139 | token types into a single token: | ||
| 140 | |||
| 141 | ```go | ||
| 142 | lexer = chroma.Coalesce(lexer) | ||
| 143 | ``` | ||
| 144 | |||
| 145 | <a id="markdown-formatting-the-output" name="formatting-the-output"></a> | ||
| 146 | ### Formatting the output | ||
| 147 | |||
| 148 | Once a language is identified you will need to pick a formatter and a style (theme). | ||
| 149 | |||
| 150 | ```go | ||
| 151 | style := styles.Get("swapoff") | ||
| 152 | if style == nil { | ||
| 153 | style = styles.Fallback | ||
| 154 | } | ||
| 155 | formatter := formatters.Get("html") | ||
| 156 | if formatter == nil { | ||
| 157 | formatter = formatters.Fallback | ||
| 158 | } | ||
| 159 | ``` | ||
| 160 | |||
| 161 | Then obtain an iterator over the tokens: | ||
| 162 | |||
| 163 | ```go | ||
| 164 | contents, err := ioutil.ReadAll(r) | ||
| 165 | iterator, err := lexer.Tokenise(nil, string(contents)) | ||
| 166 | ``` | ||
| 167 | |||
| 168 | And finally, format the tokens from the iterator: | ||
| 169 | |||
| 170 | ```go | ||
| 171 | err := formatter.Format(w, style, iterator) | ||
| 172 | ``` | ||
| 173 | |||
| 174 | <a id="markdown-the-html-formatter" name="the-html-formatter"></a> | ||
| 175 | ### The HTML formatter | ||
| 176 | |||
| 177 | By default the `html` registered formatter generates standalone HTML with | ||
| 178 | embedded CSS. More flexibility is available through the `formatters/html` package. | ||
| 179 | |||
| 180 | Firstly, the output generated by the formatter can be customised with the | ||
| 181 | following constructor options: | ||
| 182 | |||
| 183 | - `Standalone()` - generate standalone HTML with embedded CSS. | ||
| 184 | - `WithClasses()` - use classes rather than inlined style attributes. | ||
| 185 | - `ClassPrefix(prefix)` - prefix each generated CSS class. | ||
| 186 | - `TabWidth(width)` - Set the rendered tab width, in characters. | ||
| 187 | - `WithLineNumbers()` - Render line numbers (style with `LineNumbers`). | ||
| 188 | - `LinkableLineNumbers()` - Make the line numbers linkable and be a link to themselves. | ||
| 189 | - `HighlightLines(ranges)` - Highlight lines in these ranges (style with `LineHighlight`). | ||
| 190 | - `LineNumbersInTable()` - Use a table for formatting line numbers and code, rather than spans. | ||
| 191 | |||
| 192 | If `WithClasses()` is used, the corresponding CSS can be obtained from the formatter with: | ||
| 193 | |||
| 194 | ```go | ||
| 195 | formatter := html.New(html.WithClasses(true)) | ||
| 196 | err := formatter.WriteCSS(w, style) | ||
| 197 | ``` | ||
| 198 | |||
| 199 | <a id="markdown-more-detail" name="more-detail"></a> | ||
| 200 | ## More detail | ||
| 201 | |||
| 202 | <a id="markdown-lexers" name="lexers"></a> | ||
| 203 | ### Lexers | ||
| 204 | |||
| 205 | See the [Pygments documentation](http://pygments.org/docs/lexerdevelopment/) | ||
| 206 | for details on implementing lexers. Most concepts apply directly to Chroma, | ||
| 207 | but see existing lexer implementations for real examples. | ||
| 208 | |||
| 209 | In many cases lexers can be automatically converted directly from Pygments by | ||
| 210 | using the included Python 3 script `pygments2chroma.py`. I use something like | ||
| 211 | the following: | ||
| 212 | |||
| 213 | ```sh | ||
| 214 | python3 _tools/pygments2chroma.py \ | ||
| 215 | pygments.lexers.jvm.KotlinLexer \ | ||
| 216 | > lexers/k/kotlin.go \ | ||
| 217 | && gofmt -s -w lexers/k/kotlin.go | ||
| 218 | ``` | ||
| 219 | |||
| 220 | See notes in [pygments-lexers.txt](https://github.com/alecthomas/chroma/blob/master/pygments-lexers.txt) | ||
| 221 | for a list of lexers, and notes on some of the issues importing them. | ||
| 222 | |||
| 223 | <a id="markdown-formatters" name="formatters"></a> | ||
| 224 | ### Formatters | ||
| 225 | |||
| 226 | Chroma supports HTML output, as well as terminal output in 8 colour, 256 colour, and true-colour. | ||
| 227 | |||
| 228 | A `noop` formatter is included that outputs the token text only, and a `tokens` | ||
| 229 | formatter outputs raw tokens. The latter is useful for debugging lexers. | ||
| 230 | |||
| 231 | <a id="markdown-styles" name="styles"></a> | ||
| 232 | ### Styles | ||
| 233 | |||
| 234 | Chroma styles use the [same syntax](http://pygments.org/docs/styles/) as Pygments. | ||
| 235 | |||
| 236 | All Pygments styles have been converted to Chroma using the `_tools/style.py` script. | ||
| 237 | |||
| 238 | When you work with one of [Chroma's styles](https://github.com/alecthomas/chroma/tree/master/styles), know that the `chroma.Background` token type provides the default style for tokens. It does so by defining a foreground color and background color. | ||
| 239 | |||
| 240 | For example, this gives each token name not defined in the style a default color of `#f8f8f8` and uses `#000000` for the highlighted code block's background: | ||
| 241 | |||
| 242 | ~~~go | ||
| 243 | chroma.Background: "#f8f8f2 bg:#000000", | ||
| 244 | ~~~ | ||
| 245 | |||
| 246 | Also, token types in a style file are hierarchical. For instance, when `CommentSpecial` is not defined, Chroma uses the token style from `Comment`. So when several comment tokens use the same color, you'll only need to define `Comment` and override the one that has a different color. | ||
| 247 | |||
| 248 | For a quick overview of the available styles and how they look, check out the [Chroma Style Gallery](https://xyproto.github.io/splash/docs/). | ||
| 249 | |||
| 250 | <a id="markdown-command-line-interface" name="command-line-interface"></a> | ||
| 251 | ## Command-line interface | ||
| 252 | |||
| 253 | A command-line interface to Chroma is included. | ||
| 254 | |||
| 255 | Binaries are available to install from [the releases page](https://github.com/alecthomas/chroma/releases). | ||
| 256 | |||
| 257 | The CLI can be used as a preprocessor to colorise output of `less(1)`, | ||
| 258 | see documentation for the `LESSOPEN` environment variable. | ||
| 259 | |||
| 260 | The `--fail` flag can be used to suppress output and return with exit status | ||
| 261 | 1 to facilitate falling back to some other preprocessor in case chroma | ||
| 262 | does not resolve a specific lexer to use for the given file. For example: | ||
| 263 | |||
| 264 | ```shell | ||
| 265 | export LESSOPEN='| p() { chroma --fail "$1" || cat "$1"; }; p "%s"' | ||
| 266 | ``` | ||
| 267 | |||
| 268 | Replace `cat` with your favourite fallback preprocessor. | ||
| 269 | |||
| 270 | When invoked as `.lessfilter`, the `--fail` flag is automatically turned | ||
| 271 | on under the hood for easy integration with [lesspipe shipping with | ||
| 272 | Debian and derivatives](https://manpages.debian.org/lesspipe#USER_DEFINED_FILTERS); | ||
| 273 | for that setup the `chroma` executable can be just symlinked to `~/.lessfilter`. | ||
| 274 | |||
| 275 | <a id="markdown-whats-missing-compared-to-pygments" name="whats-missing-compared-to-pygments"></a> | ||
| 276 | ## What's missing compared to Pygments? | ||
| 277 | |||
| 278 | - Quite a few lexers, for various reasons (pull-requests welcome): | ||
| 279 | - Pygments lexers for complex languages often include custom code to | ||
| 280 | handle certain aspects, such as Raku's ability to nest code inside | ||
| 281 | regular expressions. These require time and effort to convert. | ||
| 282 | - I mostly only converted languages I had heard of, to reduce the porting cost. | ||
| 283 | - Some more esoteric features of Pygments are omitted for simplicity. | ||
| 284 | - Though the Chroma API supports content detection, very few languages support them. | ||
| 285 | I have plans to implement a statistical analyser at some point, but not enough time. | ||
