• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.circleci/H15-Jun-2021-3837

.github/H15-Jun-2021-3925

_tools/H15-Jun-2021-471394

bin/H15-Jun-2021-191137

cmd/H15-Jun-2021-699615

formatters/H15-Jun-2021-1,4421,149

lexers/H15-Jun-2021-54,82550,853

quick/H15-Jun-2021-6546

styles/H15-Jun-2021-2,0331,821

vendor/H03-May-2022-236,843193,654

.gitignoreH A D15-Jun-2021316 2014

.golangci.ymlH A D15-Jun-20211.8 KiB7771

.goreleaser.ymlH A D15-Jun-2021709 3635

COPYINGH A D15-Jun-20211 KiB2016

MakefileH A D15-Jun-2021508 2013

README.mdH A D15-Jun-202111.7 KiB287213

coalesce.goH A D15-Jun-2021780 3631

coalesce_test.goH A D15-Jun-2021388 2016

colour.goH A D15-Jun-20214.5 KiB165116

colour_test.goH A D15-Jun-20211.1 KiB4334

delegate.goH A D15-Jun-20213.2 KiB138114

delegate_test.goH A D15-Jun-20212.6 KiB112103

doc.goH A D15-Jun-2021326 81

formatter.goH A D15-Jun-20211 KiB4428

go.modH A D15-Jun-2021687 1916

go.sumH A D15-Jun-20213.2 KiB3534

iterator.goH A D15-Jun-20211.7 KiB7757

lexer.goH A D15-Jun-20212.8 KiB12965

lexer_test.goH A D15-Jun-20211.2 KiB5348

mutators.goH A D15-Jun-20213.3 KiB132100

mutators_test.goH A D15-Jun-20211.2 KiB5853

regexp.goH A D15-Jun-202114.9 KiB566420

regexp_test.goH A D15-Jun-20214.4 KiB187173

remap.goH A D15-Jun-20211.7 KiB8163

remap_test.goH A D15-Jun-2021739 3025

style.goH A D15-Jun-20217.9 KiB345277

style_test.goH A D15-Jun-20211.9 KiB6657

table.pyH A D15-Jun-2021916 3322

tokentype_string.goH A D15-Jun-20217.4 KiB214204

types.goH A D15-Jun-20217 KiB348276

README.md

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