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 [![Golang Documentation](https://godoc.org/github.com/alecthomas/chroma?status.svg)](https://godoc.org/github.com/alecthomas/chroma) [![CI](https://github.com/alecthomas/chroma/actions/workflows/ci.yml/badge.svg)](https://github.com/alecthomas/chroma/actions/workflows/ci.yml) [![Slack chat](https://img.shields.io/static/v1?logo=slack&style=flat&label=slack&color=green&message=gophers)](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.