Mercurial > yakumo_izuru > aya
comparison vendor/github.com/alecthomas/chroma/v2/README.md @ 66:787b5ee0289d draft
Use vendored modules
Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
| author | yakumo.izuru |
|---|---|
| date | Sun, 23 Jul 2023 13:18:53 +0000 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 65:6d985efa0f7a | 66:787b5ee0289d |
|---|---|
| 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, Chapel, 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, Properties, 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. |
