"
labels: ["bug"]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the bug you encountered.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: Describe the bug
description: |
A clear and concise description of what the bug is. Screenshots are often helpful here.
Do *NOT* just paste a link to other issues on GitHub.
validations:
required: true
- type: textarea
attributes:
label: To Reproduce
description: |
1. Reproduce your issue in the [Chroma Playground](https://swapoff.org/chroma/playground/), then click the _copy_ icon to copy a shareable link for your issue. Consider using `[markdown links](URL)` to minimise the visual noise of the links.
2. Provide input text and a command-line invocation of `chroma` that reproduces your problem. eg. For Hugo this might be something like `chroma -s monokailight --html --html-lines --html-lines-table --html-inline-styles `
Do *NOT* provide configuration for another tool (eg. Hugo, Gitea). My time is limited and if you want me to fix your issue, help me help you.
validations:
required: true
chroma-2.20.0/.github/ISSUE_TEMPLATE/feature_request.yaml 0000664 0000000 0000000 00000001701 15044027432 0022656 0 ustar 00root root 0000000 0000000 name: Feature request
description: Suggest an idea for this project
title: ""
labels: ["feature request"]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the feature you're requesting.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: What problem does this feature solve?
description: |
Please check the Chroma [README](https://github.com/alecthomas/chroma) and command-line tool to ensure this isn't an already solved problem.
validations:
required: true
- type: textarea
attributes:
label: What feature do you propose?
description: |
The feature should describe a change to Chroma's code, not lexers.
For lexers, fill out the "Lexer request" form.
validations:
required: true
chroma-2.20.0/.github/ISSUE_TEMPLATE/lexer_request.yaml 0000664 0000000 0000000 00000002146 15044027432 0022346 0 ustar 00root root 0000000 0000000 name: Lexer request
description: Suggest the addition of a lexer
title: ""
labels: ["help wanted", "lexer missing"]
body:
- type: checkboxes
attributes:
label: Is there an existing issue for this?
description: Please search to see if an issue already exists for the lexer you're requesting.
options:
- label: I have searched the existing issues
required: true
- type: textarea
attributes:
label: What is the missing lexer?
description: |
Please note that lexers are contributed by the community. Your best option is to contribute this yourself.
Lexers are defined in XML (see the [existing lexers](https://github.com/alecthomas/chroma/tree/master/lexers/embedded) for examples).
You can test your lexer with the Chroma command-line, `chroma --lexer=my-lexer.xml example-file.lang`
validations:
required: true
- type: textarea
attributes:
label: Links to existing syntax definitions
description: |
Provide links to existing syntax definitions in Textmate, etc.
validations:
required: true
chroma-2.20.0/.github/workflows/ 0000775 0000000 0000000 00000000000 15044027432 0016442 5 ustar 00root root 0000000 0000000 chroma-2.20.0/.github/workflows/ci.yml 0000664 0000000 0000000 00000001076 15044027432 0017564 0 ustar 00root root 0000000 0000000 on:
push:
branches:
- master
pull_request:
name: CI
jobs:
test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: cashapp/activate-hermit@e49f5cb4dd64ff0b0b659d1d8df499595451155a # v1
- run: go test ./...
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
- uses: cashapp/activate-hermit@e49f5cb4dd64ff0b0b659d1d8df499595451155a # v1
- run: golangci-lint run
chroma-2.20.0/.github/workflows/release.yml 0000664 0000000 0000000 00000000564 15044027432 0020612 0 ustar 00root root 0000000 0000000 name: Release
on:
push:
tags:
- 'v*'
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4
with:
fetch-depth: 0
- run: ./bin/hermit env --raw >> $GITHUB_ENV
- run: goreleaser release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
chroma-2.20.0/.gitignore 0000664 0000000 0000000 00000000646 15044027432 0015043 0 ustar 00root root 0000000 0000000 # Binaries for programs and plugins
.git
.idea
.vscode
.hermit
*.exe
*.dll
*.so
*.dylib
/cmd/chroma/chroma
# Test binary, build with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
.glide/
_models/
_examples/
*.min.*
build/
cmd/chromad/static/chroma.wasm
cmd/chromad/static/wasm_exec.js
chroma-2.20.0/.golangci.yml 0000664 0000000 0000000 00000003747 15044027432 0015444 0 ustar 00root root 0000000 0000000 run:
tests: true
output:
print-issued-lines: false
linters:
enable-all: true
disable:
- lll
- gocyclo
- dupl
- gochecknoglobals
- funlen
- godox
- wsl
- gocognit
- nolintlint
- testpackage
- godot
- nestif
- paralleltest
- nlreturn
- cyclop
- gci
- gofumpt
- errorlint
- exhaustive
- wrapcheck
- stylecheck
- thelper
- nonamedreturns
- revive
- dupword
- exhaustruct
- varnamelen
- forcetypeassert
- ireturn
- maintidx
- govet
- testableexamples
- musttag
- depguard
- goconst
- perfsprint
- mnd
- predeclared
- recvcheck
- tenv
- err113
linters-settings:
gocyclo:
min-complexity: 10
dupl:
threshold: 100
goconst:
min-len: 8
min-occurrences: 3
forbidigo:
#forbid:
# - (Must)?NewLexer$
exclude_godoc_examples: false
issues:
exclude-dirs:
- _examples
max-per-linter: 0
max-same: 0
exclude-use-default: false
exclude:
# Captured by errcheck.
- '^(G104|G204):'
# Very commonly not checked.
- 'Error return value of .(.*\.Help|.*\.MarkFlagRequired|(os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked'
- 'exported method (.*\.MarshalJSON|.*\.UnmarshalJSON|.*\.EntityURN|.*\.GoString|.*\.Pos) should have comment or be unexported'
- 'composite literal uses unkeyed fields'
- 'declaration of "err" shadows declaration'
- 'should not use dot imports'
- 'Potential file inclusion via variable'
- 'should have comment or be unexported'
- 'comment on exported var .* should be of the form'
- 'at least one file in a package should have a package comment'
- 'string literal contains the Unicode'
- 'methods on the same type should have the same receiver name'
- '_TokenType_name should be _TokenTypeName'
- '`_TokenType_map` should be `_TokenTypeMap`'
- 'rewrite if-else to switch statement'
chroma-2.20.0/.goreleaser.yml 0000664 0000000 0000000 00000001342 15044027432 0015776 0 ustar 00root root 0000000 0000000 project_name: chroma
release:
github:
owner: alecthomas
name: chroma
brews:
- install: bin.install "chroma"
env:
- CGO_ENABLED=0
builds:
- goos:
- linux
- darwin
- windows
goarch:
- arm64
- amd64
- "386"
goarm:
- "6"
dir: ./cmd/chroma
main: .
ldflags: -s -w -X main.version={{.Version}} -X main.commit={{.Commit}} -X main.date={{.Date}}
binary: chroma
archives:
- format: tar.gz
name_template: "{{ .Binary }}-{{ .Version }}-{{ .Os }}-{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
files:
- COPYING
- README*
snapshot:
name_template: SNAPSHOT-{{ .Commit }}
checksum:
name_template: "{{ .ProjectName }}-{{ .Version }}-checksums.txt"
chroma-2.20.0/Bitfile 0000664 0000000 0000000 00000001262 15044027432 0014347 0 ustar 00root root 0000000 0000000 VERSION = %(git describe --tags --dirty --always)%
export CGOENABLED = 0
tokentype_enumer.go: types.go
build: go generate
# Regenerate the list of lexers in the README
README.md: lexers/*.go lexers/*/*.xml table.py
build: ./table.py
-clean
implicit %{1}%{2}.min.%{3}: **/*.{css,js}
build: esbuild --bundle %{IN} --minify --outfile=%{OUT}
implicit build/%{1}: cmd/*
cd cmd/%{1}
inputs: cmd/%{1}/**/* **/*.go
build: go build -ldflags="-X 'main.version=%{VERSION}'" -o ../../build/%{1} .
#upload: chromad
# build:
# scp chromad root@swapoff.org:
# ssh root@swapoff.org 'install -m755 ./chromad /srv/http/swapoff.org/bin && service chromad restart'
# touch upload
chroma-2.20.0/COPYING 0000664 0000000 0000000 00000002037 15044027432 0014102 0 ustar 00root root 0000000 0000000 Copyright (C) 2017 Alec Thomas
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.
chroma-2.20.0/Dockerfile 0000664 0000000 0000000 00000002764 15044027432 0015050 0 ustar 00root root 0000000 0000000 # Multi-stage Dockerfile for chromad Go application using Hermit-managed tools
# Build stage
FROM ubuntu:24.04 AS builder
# Install system dependencies
RUN apt-get update && apt-get install -y \
curl \
git \
make \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
# Set working directory
WORKDIR /app
# Copy the entire project (including bin directory with Hermit tools)
COPY . .
# Make Hermit tools executable and add to PATH
ENV PATH="/app/bin:${PATH}"
# Set Go environment variables for static compilation
ENV CGO_ENABLED=0
ENV GOOS=linux
ENV GOARCH=amd64
# Build the application using make
RUN make build/chromad
# Runtime stage
FROM alpine:3.22 AS runtime
# Install ca-certificates for HTTPS requests
RUN apk --no-cache add ca-certificates curl
# Create a non-root user
RUN addgroup -g 1001 chromad && \
adduser -D -s /bin/sh -u 1001 -G chromad chromad
# Set working directory
WORKDIR /app
# Copy the binary from build stage
COPY --from=builder /app/build/chromad /app/chromad
# Change ownership to non-root user
RUN chown chromad:chromad /app/chromad
# Switch to non-root user
USER chromad
# Expose port (default is 8080, but can be overridden via PORT env var)
EXPOSE 8080
# Set default environment variables
ENV PORT=8080
ENV CHROMA_CSRF_KEY="testtest"
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -fsSL http://127.0.0.1:8080/ > /dev/null
# Run the application
CMD ["sh", "-c", "./chromad --csrf-key=$CHROMA_CSRF_KEY --bind=0.0.0.0:$PORT"]
chroma-2.20.0/Makefile 0000664 0000000 0000000 00000002671 15044027432 0014513 0 ustar 00root root 0000000 0000000 .PHONY: chromad upload all
VERSION ?= $(shell git describe --tags --dirty --always)
export GOOS ?= linux
export GOARCH ?= amd64
all: README.md tokentype_string.go
README.md: lexers/*.go lexers/embedded/*.xml
GOOS= GOARCH= ./table.py
tokentype_string.go: types.go
go generate
.PHONY: format-js
format-js:
biome format --write cmd/chromad/static/{index.js,chroma.js}
.PHONY: chromad
chromad: build/chromad
build/chromad: $(shell find cmd/chromad -name '*.go' -o -name '*.html' -o -name '*.css' -o -name '*.js') \
cmd/chromad/static/wasm_exec.js \
cmd/chromad/static/chroma.wasm
rm -rf build
esbuild --platform=node --bundle cmd/chromad/static/index.js --minify --outfile=cmd/chromad/static/index.min.js
esbuild --bundle cmd/chromad/static/index.css --minify --outfile=cmd/chromad/static/index.min.css
(export CGOENABLED=0 ; go build -C cmd/chromad -ldflags="-X 'main.version=$(VERSION)'" -o ../../build/chromad .)
cmd/chromad/static/wasm_exec.js: $(shell tinygo env TINYGOROOT)/targets/wasm_exec.js
install -m644 $< $@
cmd/chromad/static/chroma.wasm: $(shell git ls-files | grep '\.go|\.xml')
if type tinygo > /dev/null; then \
tinygo build -no-debug -target wasm -o $@ cmd/libchromawasm/main.go; \
else \
GOOS=js GOARCH=wasm go build -o $@ cmd/libchromawasm/main.go; \
fi
upload: build/chromad
scp build/chromad root@swapoff.org: && \
ssh root@swapoff.org 'install -m755 ./chromad /srv/http/swapoff.org/bin && service chromad restart'
chroma-2.20.0/README.md 0000664 0000000 0000000 00000030777 15044027432 0014342 0 ustar 00root root 0000000 0000000 
# A general purpose syntax highlighter in pure Go
[](https://pkg.go.dev/github.com/alecthomas/chroma/v2) [](https://github.com/alecthomas/chroma/actions/workflows/ci.yml) [](https://invite.slack.golangbridge.org/)
Chroma takes source code and other structured text and converts it into syntax
highlighted HTML, ANSI-coloured text, etc.
Chroma is based heavily on [Pygments](http://pygments.org/), and includes
translators for Pygments lexers and styles.
## Table of Contents
1. [Supported languages](#supported-languages)
2. [Try it](#try-it)
3. [Using the library](#using-the-library)
1. [Quick start](#quick-start)
2. [Identifying the language](#identifying-the-language)
3. [Formatting the output](#formatting-the-output)
4. [The HTML formatter](#the-html-formatter)
4. [More detail](#more-detail)
1. [Lexers](#lexers)
2. [Formatters](#formatters)
3. [Styles](#styles)
5. [Command-line interface](#command-line-interface)
6. [Testing lexers](#testing-lexers)
7. [What's missing compared to Pygments?](#whats-missing-compared-to-pygments)
## Supported languages
| Prefix | Language
| :----: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| A | ABAP, ABNF, ActionScript, ActionScript 3, Ada, Agda, AL, Alloy, Angular2, ANTLR, ApacheConf, APL, AppleScript, ArangoDB AQL, Arduino, ArmAsm, ATL, AutoHotkey, AutoIt, Awk
| B | Ballerina, Bash, Bash Session, Batchfile, Beef, BibTeX, Bicep, BlitzBasic, BNF, BQN, Brainfuck
| 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, Core, Crystal, CSS, CSV, CUE, Cython
| D | D, Dart, Dax, Desktop file, Diff, Django/Jinja, dns, Docker, DTD, Dylan
| E | EBNF, Elixir, Elm, EmacsLisp, Erlang
| F | Factor, Fennel, Fish, Forth, Fortran, FortranFixed, FSharp
| G | GAS, GDScript, GDScript3, Gemtext, Genshi, Genshi HTML, Genshi Text, Gherkin, Gleam, GLSL, Gnuplot, Go, Go HTML Template, Go Template, Go Text Template, GraphQL, Groff, Groovy
| H | Handlebars, Hare, Haskell, Haxe, HCL, Hexdump, HLB, HLSL, HolyC, HTML, HTTP, Hy
| I | Idris, Igor, INI, Io, ISCdhcpd
| J | J, Janet, Java, JavaScript, JSON, JSONata, Jsonnet, Julia, Jungle
| K | Kotlin
| L | Lean4, Lighttpd configuration file, LLVM, lox, Lua
| M | Makefile, Mako, markdown, Mason, Materialize SQL dialect, Mathematica, Matlab, MCFunction, Meson, Metal, MiniZinc, MLIR, Modula-2, Mojo, MonkeyC, MoonScript, MorrowindScript, Myghty, MySQL
| N | NASM, Natural, NDISASM, Newspeak, Nginx configuration file, Nim, Nix, NSIS, Nu
| O | Objective-C, ObjectPascal, OCaml, Octave, Odin, OnesEnterprise, OpenEdge ABL, OpenSCAD, Org Mode
| P | PacmanConf, Perl, PHP, PHTML, Pig, PkgConfig, PL/pgSQL, plaintext, Plutus Core, Pony, PostgreSQL SQL dialect, PostScript, POVRay, PowerQuery, PowerShell, Prolog, Promela, PromQL, properties, Protocol Buffer, PRQL, PSL, Puppet, Python, Python 2
| Q | QBasic, QML
| R | R, Racket, Ragel, Raku, react, ReasonML, reg, Rego, reStructuredText, Rexx, RPGLE, RPMSpec, Ruby, Rust
| S | SAS, Sass, Scala, Scheme, Scilab, SCSS, Sed, Sieve, Smali, Smalltalk, Smarty, SNBT, Snobol, Solidity, SourcePawn, SPARQL, SQL, SquidConf, Standard ML, stas, Stylus, Svelte, Swift, SYSTEMD, systemverilog
| T | TableGen, Tal, TASM, Tcl, Tcsh, Termcap, Terminfo, Terraform, TeX, Thrift, TOML, TradingView, Transact-SQL, Turing, Turtle, Twig, TypeScript, TypoScript, TypoScriptCssData, TypoScriptHtmlData, Typst
| U | ucode
| V | V, V shell, Vala, VB.net, verilog, VHDL, VHS, VimL, vue
| W | WDTE, WebGPU Shading Language, WebVTT, Whiley
| X | XML, Xorg
| Y | YAML, YANG
| Z | Z80 Assembly, Zed, Zig
_I will attempt to keep this section up to date, but an authoritative list can be
displayed with `chroma --list`._
## Try it
Try out various languages and styles on the [Chroma Playground](https://swapoff.org/chroma/playground/).
## Using the library
This is version 2 of Chroma, use the import path:
```go
import "github.com/alecthomas/chroma/v2"
```
Chroma, like Pygments, has the concepts of
[lexers](https://github.com/alecthomas/chroma/tree/master/lexers),
[formatters](https://github.com/alecthomas/chroma/tree/master/formatters) and
[styles](https://github.com/alecthomas/chroma/tree/master/styles).
Lexers convert source text into a stream of tokens, styles specify how token
types are mapped to colours, and formatters convert tokens and styles into
formatted output.
A package exists for each of these, containing a global `Registry` variable
with all of the registered implementations. There are also helper functions
for using the registry in each package, such as looking up lexers by name or
matching filenames, etc.
In all cases, if a lexer, formatter or style can not be determined, `nil` will
be returned. In this situation you may want to default to the `Fallback`
value in each respective package, which provides sane defaults.
### Quick start
A convenience function exists that can be used to simply format some source
text, without any effort:
```go
err := quick.Highlight(os.Stdout, someSourceCode, "go", "html", "monokai")
```
### Identifying the language
To highlight code, you'll first have to identify what language the code is
written in. There are three primary ways to do that:
1. Detect the language from its filename.
```go
lexer := lexers.Match("foo.go")
```
2. Explicitly specify the language by its Chroma syntax ID (a full list is available from `lexers.Names()`).
```go
lexer := lexers.Get("go")
```
3. Detect the language from its content.
```go
lexer := lexers.Analyse("package main\n\nfunc main()\n{\n}\n")
```
In all cases, `nil` will be returned if the language can not be identified.
```go
if lexer == nil {
lexer = lexers.Fallback
}
```
At this point, it should be noted that some lexers can be extremely chatty. To
mitigate this, you can use the coalescing lexer to coalesce runs of identical
token types into a single token:
```go
lexer = chroma.Coalesce(lexer)
```
### Formatting the output
Once a language is identified you will need to pick a formatter and a style (theme).
```go
style := styles.Get("swapoff")
if style == nil {
style = styles.Fallback
}
formatter := formatters.Get("html")
if formatter == nil {
formatter = formatters.Fallback
}
```
Then obtain an iterator over the tokens:
```go
contents, err := ioutil.ReadAll(r)
iterator, err := lexer.Tokenise(nil, string(contents))
```
And finally, format the tokens from the iterator:
```go
err := formatter.Format(w, style, iterator)
```
### The HTML formatter
By default the `html` registered formatter generates standalone HTML with
embedded CSS. More flexibility is available through the `formatters/html` package.
Firstly, the output generated by the formatter can be customised with the
following constructor options:
- `Standalone()` - generate standalone HTML with embedded CSS.
- `WithClasses()` - use classes rather than inlined style attributes.
- `ClassPrefix(prefix)` - prefix each generated CSS class.
- `TabWidth(width)` - Set the rendered tab width, in characters.
- `WithLineNumbers()` - Render line numbers (style with `LineNumbers`).
- `WithLinkableLineNumbers()` - Make the line numbers linkable and be a link to themselves.
- `HighlightLines(ranges)` - Highlight lines in these ranges (style with `LineHighlight`).
- `LineNumbersInTable()` - Use a table for formatting line numbers and code, rather than spans.
If `WithClasses()` is used, the corresponding CSS can be obtained from the formatter with:
```go
formatter := html.New(html.WithClasses(true))
err := formatter.WriteCSS(w, style)
```
## More detail
### Lexers
See the [Pygments documentation](http://pygments.org/docs/lexerdevelopment/)
for details on implementing lexers. Most concepts apply directly to Chroma,
but see existing lexer implementations for real examples.
In many cases lexers can be automatically converted directly from Pygments by
using the included Python 3 script `pygments2chroma_xml.py`. I use something like
the following:
```sh
python3 _tools/pygments2chroma_xml.py \
pygments.lexers.jvm.KotlinLexer \
> lexers/embedded/kotlin.xml
```
A list of all lexers available in Pygments can be found in [pygments-lexers.txt](https://github.com/alecthomas/chroma/blob/master/pygments-lexers.txt).
### Formatters
Chroma supports HTML output, as well as terminal output in 8 colour, 256 colour, and true-colour.
A `noop` formatter is included that outputs the token text only, and a `tokens`
formatter outputs raw tokens. The latter is useful for debugging lexers.
### Styles
Chroma styles are defined in XML. The style entries use the
[same syntax](http://pygments.org/docs/styles/) as Pygments.
All Pygments styles have been converted to Chroma using the `_tools/style.py`
script.
When you work with one of [Chroma's styles](https://github.com/alecthomas/chroma/tree/master/styles),
know that the `Background` token type provides the default style for tokens. It does so
by defining a foreground color and background color.
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:
```xml
```
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.
For a quick overview of the available styles and how they look, check out the [Chroma Style Gallery](https://xyproto.github.io/splash/docs/).
## Command-line interface
A command-line interface to Chroma is included.
Binaries are available to install from [the releases page](https://github.com/alecthomas/chroma/releases).
The CLI can be used as a preprocessor to colorise output of `less(1)`,
see documentation for the `LESSOPEN` environment variable.
The `--fail` flag can be used to suppress output and return with exit status
1 to facilitate falling back to some other preprocessor in case chroma
does not resolve a specific lexer to use for the given file. For example:
```shell
export LESSOPEN='| p() { chroma --fail "$1" || cat "$1"; }; p "%s"'
```
Replace `cat` with your favourite fallback preprocessor.
When invoked as `.lessfilter`, the `--fail` flag is automatically turned
on under the hood for easy integration with [lesspipe shipping with
Debian and derivatives](https://manpages.debian.org/lesspipe#USER_DEFINED_FILTERS);
for that setup the `chroma` executable can be just symlinked to `~/.lessfilter`.
## Projects using Chroma
* [`moar`](https://github.com/walles/moar) is a full-blown pager that colorizes
its input using Chroma
* [Hugo](https://gohugo.io/) is a static site generator that [uses Chroma for syntax
highlighting code examples](https://gohugo.io/content-management/syntax-highlighting/)
## Testing lexers
If you edit some lexers and want to try it, open a shell in `cmd/chromad` and run:
```shell
go run . --csrf-key=securekey
```
A Link will be printed. Open it in your Browser. Now you can test on the Playground with your local changes.
If you want to run the tests and the lexers, open a shell in the root directory and run:
```shell
go test ./lexers
```
When updating or adding a lexer, please add tests. See [lexers/README.md](lexers/README.md) for more.
## What's missing compared to Pygments?
- Quite a few lexers, for various reasons (pull-requests welcome):
- Pygments lexers for complex languages often include custom code to
handle certain aspects, such as Raku's ability to nest code inside
regular expressions. These require time and effort to convert.
- I mostly only converted languages I had heard of, to reduce the porting cost.
- Some more esoteric features of Pygments are omitted for simplicity.
- Though the Chroma API supports content detection, very few languages support them.
I have plans to implement a statistical analyser at some point, but not enough time.
chroma-2.20.0/_tools/ 0000775 0000000 0000000 00000000000 15044027432 0014344 5 ustar 00root root 0000000 0000000 chroma-2.20.0/_tools/css2style/ 0000775 0000000 0000000 00000000000 15044027432 0016277 5 ustar 00root root 0000000 0000000 chroma-2.20.0/_tools/css2style/main.go 0000664 0000000 0000000 00000013303 15044027432 0017552 0 ustar 00root root 0000000 0000000 package main
import (
"io/ioutil"
"os"
"strings"
"text/template"
"github.com/aymerick/douceur/css"
"github.com/aymerick/douceur/parser"
"gopkg.in/alecthomas/kingpin.v3-unstable"
"github.com/alecthomas/chroma/v2"
)
const (
outputTemplate = `package styles
import (
"github.com/alecthomas/chroma/v2"
)
// {{.Name}} style.
var {{.Name}} = Register(chroma.MustNewStyle("{{.Name|Lower}}", chroma.StyleEntries{
{{- range .Rules}}
{{- if .Prelude|TokenType}}
chroma.{{.Prelude|TokenType}}: "{{.Declarations|TranslateDecls}}",
{{- end}}
{{- end}}
}))
`
)
var (
typeByClass = map[string]chroma.TokenType{
".hll": chroma.Background,
}
cssNamedColours = map[string]string{
"black": "#000000", "silver": "#c0c0c0", "gray": "#808080", "white": "#ffffff",
"maroon": "#800000", "red": "#ff0000", "purple": "#800080", "fuchsia": "#ff00ff",
"green": "#008000", "lime": "#00ff00", "olive": "#808000", "yellow": "#ffff00",
"navy": "#000080", "blue": "#0000ff", "teal": "#008080", "aqua": "#00ffff",
"orange": "#ffa500", "aliceblue": "#f0f8ff", "antiquewhite": "#faebd7", "aquamarine": "#7fffd4",
"azure": "#f0ffff", "beige": "#f5f5dc", "bisque": "#ffe4c4", "blanchedalmond": "#ffebcd",
"blueviolet": "#8a2be2", "brown": "#a52a2a", "burlywood": "#deb887", "cadetblue": "#5f9ea0",
"chartreuse": "#7fff00", "chocolate": "#d2691e", "coral": "#ff7f50", "cornflowerblue": "#6495ed",
"cornsilk": "#fff8dc", "crimson": "#dc143c", "cyan": "#00ffff", "darkblue": "#00008b",
"darkcyan": "#008b8b", "darkgoldenrod": "#b8860b", "darkgray": "#a9a9a9", "darkgreen": "#006400",
"darkgrey": "#a9a9a9", "darkkhaki": "#bdb76b", "darkmagenta": "#8b008b", "darkolivegreen": "#556b2f",
"darkorange": "#ff8c00", "darkorchid": "#9932cc", "darkred": "#8b0000", "darksalmon": "#e9967a",
"darkseagreen": "#8fbc8f", "darkslateblue": "#483d8b", "darkslategray": "#2f4f4f", "darkslategrey": "#2f4f4f",
"darkturquoise": "#00ced1", "darkviolet": "#9400d3", "deeppink": "#ff1493", "deepskyblue": "#00bfff",
"dimgray": "#696969", "dimgrey": "#696969", "dodgerblue": "#1e90ff", "firebrick": "#b22222",
"floralwhite": "#fffaf0", "forestgreen": "#228b22", "gainsboro": "#dcdcdc", "ghostwhite": "#f8f8ff",
"gold": "#ffd700", "goldenrod": "#daa520", "greenyellow": "#adff2f", "grey": "#808080",
"honeydew": "#f0fff0", "hotpink": "#ff69b4", "indianred": "#cd5c5c", "indigo": "#4b0082",
"ivory": "#fffff0", "khaki": "#f0e68c", "lavender": "#e6e6fa", "lavenderblush": "#fff0f5",
"lawngreen": "#7cfc00", "lemonchiffon": "#fffacd", "lightblue": "#add8e6", "lightcoral": "#f08080",
"lightcyan": "#e0ffff", "lightgoldenrodyellow": "#fafad2", "lightgray": "#d3d3d3", "lightgreen": "#90ee90",
"lightgrey": "#d3d3d3", "lightpink": "#ffb6c1", "lightsalmon": "#ffa07a", "lightseagreen": "#20b2aa",
"lightskyblue": "#87cefa", "lightslategray": "#778899", "lightslategrey": "#778899", "lightsteelblue": "#b0c4de",
"lightyellow": "#ffffe0", "limegreen": "#32cd32", "linen": "#faf0e6", "magenta": "#ff00ff",
"mediumaquamarine": "#66cdaa", "mediumblue": "#0000cd", "mediumorchid": "#ba55d3", "mediumpurple": "#9370db",
"mediumseagreen": "#3cb371", "mediumslateblue": "#7b68ee", "mediumspringgreen": "#00fa9a", "mediumturquoise": "#48d1cc",
"mediumvioletred": "#c71585", "midnightblue": "#191970", "mintcream": "#f5fffa", "mistyrose": "#ffe4e1",
"moccasin": "#ffe4b5", "navajowhite": "#ffdead", "oldlace": "#fdf5e6", "olivedrab": "#6b8e23",
"orangered": "#ff4500", "orchid": "#da70d6", "palegoldenrod": "#eee8aa", "palegreen": "#98fb98",
"paleturquoise": "#afeeee", "palevioletred": "#db7093", "papayawhip": "#ffefd5", "peachpuff": "#ffdab9",
"peru": "#cd853f", "pink": "#ffc0cb", "plum": "#dda0dd", "powderblue": "#b0e0e6",
"rosybrown": "#bc8f8f", "royalblue": "#4169e1", "saddlebrown": "#8b4513", "salmon": "#fa8072",
"sandybrown": "#f4a460", "seagreen": "#2e8b57", "seashell": "#fff5ee", "sienna": "#a0522d",
"skyblue": "#87ceeb", "slateblue": "#6a5acd", "slategray": "#708090", "slategrey": "#708090",
"snow": "#fffafa", "springgreen": "#00ff7f", "steelblue": "#4682b4", "tan": "#d2b48c",
"thistle": "#d8bfd8", "tomato": "#ff6347", "turquoise": "#40e0d0", "violet": "#ee82ee",
"wheat": "#f5deb3", "whitesmoke": "#f5f5f5", "yellowgreen": "#9acd32", "rebeccapurple": "#663399",
}
nameArg = kingpin.Arg("name", "Name of output style.").Required().String()
fileArg = kingpin.Arg("stylesheets", ".css file to import").Required().ExistingFile()
)
func init() {
for tt, str := range chroma.StandardTypes {
typeByClass["."+str] = tt
}
}
func translateDecls(decls []*css.Declaration) string {
out := []string{}
for _, decl := range decls {
switch decl.Property {
case "color":
clr := decl.Value
if c, ok := cssNamedColours[clr]; ok {
clr = c
}
out = append(out, clr)
case "background-color":
out = append(out, "bg:"+decl.Value)
case "font-style":
if strings.Contains(decl.Value, "italic") {
out = append(out, "italic")
}
case "font-weight":
if strings.Contains(decl.Value, "bold") {
out = append(out, "bold")
}
case "text-decoration":
if strings.Contains(decl.Value, "underline") {
out = append(out, "underline")
}
}
}
return strings.Join(out, " ")
}
func main() {
kingpin.Parse()
source, err := ioutil.ReadFile(*fileArg)
kingpin.FatalIfError(err, "")
css, err := parser.Parse(string(source))
kingpin.FatalIfError(err, "")
context := map[string]interface{}{
"Name": *nameArg,
"Rules": css.Rules,
}
tmpl := template.Must(template.New("style").Funcs(template.FuncMap{
"Lower": strings.ToLower,
"TranslateDecls": translateDecls,
"TokenType": func(s string) chroma.TokenType { return typeByClass[s] },
}).Parse(outputTemplate))
err = tmpl.Execute(os.Stdout, context)
kingpin.FatalIfError(err, "")
}
chroma-2.20.0/_tools/exercise/ 0000775 0000000 0000000 00000000000 15044027432 0016153 5 ustar 00root root 0000000 0000000 chroma-2.20.0/_tools/exercise/main.go 0000664 0000000 0000000 00000001771 15044027432 0017434 0 ustar 00root root 0000000 0000000 package main
import (
"fmt"
"io/ioutil"
"os"
"github.com/alecthomas/chroma/v2/formatters"
"github.com/alecthomas/chroma/v2/lexers"
"github.com/alecthomas/chroma/v2/styles"
"gopkg.in/alecthomas/kingpin.v3-unstable"
)
var (
filesArgs = kingpin.Arg("file", "Files to use to exercise lexers.").Required().ExistingFiles()
)
func main() {
kingpin.CommandLine.Help = "Exercise linters against a list of files."
kingpin.Parse()
for _, file := range *filesArgs {
lexer := lexers.Match(file)
if lexer == nil {
fmt.Printf("warning: could not find lexer for %q\n", file)
continue
}
fmt.Printf("%s: ", file)
os.Stdout.Sync()
text, err := ioutil.ReadFile(file)
kingpin.FatalIfError(err, "")
it, err := lexer.Tokenise(nil, string(text))
kingpin.FatalIfError(err, "%s failed to tokenise %q", lexer.Config().Name, file)
err = formatters.NoOp.Format(ioutil.Discard, styles.SwapOff, it)
kingpin.FatalIfError(err, "%s failed to format %q", lexer.Config().Name, file)
fmt.Printf("ok\n")
}
}
chroma-2.20.0/_tools/pygments2chroma.hlb 0000664 0000000 0000000 00000001360 15044027432 0020155 0 ustar 00root root 0000000 0000000 fs default() {
gofmt fs { chromaLexer "pygments.lexers.hlb.HlbLexer"; }
}
fs script() {
local "." with option {
includePatterns "pygments2chroma.py"
}
}
fs runChromaPython(string package) {
image "python:alpine" with option { resolve; }
run "apk add -U git"
run "pip install -U pystache"
run "pip install -U -e git+https://github.com/hinshun/pygments.git@hlb-lexer#egg=pygments"
run string { format "python pygments2chroma.py %s > /out/lexer.go" package; } with option {
dir "/chroma"
mount script "/chroma"
mount fs { scratch; } "/out" as chromaLexer
}
}
fs runGoFormat(fs goFiles) {
image "golang:alpine" with option { resolve; }
run "gofmt -s -w /gofmt/*.go" with option {
dir "/gofmt"
mount goFiles "/gofmt" as gofmt
}
}
chroma-2.20.0/_tools/pygments2chroma_xml.py 0000775 0000000 0000000 00000014027 15044027432 0020727 0 ustar 00root root 0000000 0000000 #!/usr/bin/env -S uv run --script
import functools
import importlib
import re
import sys
import types
import html
import pystache
from pygments import lexer as pygments_lexer
from pygments.token import _TokenType
TEMPLATE = r'''
{{name}}
{{#aliases}}
{{alias}}
{{/aliases}}
{{#filenames}}
{{filename}}
{{/filenames}}
{{#mimetypes}}
{{mimetype}}
{{/mimetypes}}
{{#re_ignorecase}}
true
{{/re_ignorecase}}
{{#re_dotall}}
true
{{/re_dotall}}
{{#re_not_multiline}}
true
{{/re_not_multiline}}
{{#tokens}}
{{#rules}}
{{{.}}}
{{/rules}}
{{/tokens}}
'''
def xml_regex(s):
return xml_string(s)
def xml_string(s):
s = html.escape(s)
return '"' + s + '"'
def to_camel_case(snake_str):
components = snake_str.split('_')
return ''.join(x.title() for x in components)
def warning(message):
print('warning: ' + message, file=sys.stderr)
def resolve_emitter(emitter):
if isinstance(emitter, types.FunctionType):
if repr(emitter).startswith('' % '" state="'.join(rule[2])
else:
raise ValueError('unsupported modifier %r' % (rule[2],))
out.append('{}{}'.format(regex, emitter, modifier))
elif isinstance(rule, pygments_lexer.include):
out.append(''.format(rule))
elif isinstance(rule, pygments_lexer.default):
process_state_action(rule.state)
out.append('{}'.format(''.join(process_state_action(rule.state))))
else:
raise ValueError('unsupported rule %r' % (rule,))
return out
class TemplateView(object):
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, key, value)
def re_not_multiline(self):
return not (self.regex_flags & re.MULTILINE)
def re_dotall(self):
return self.regex_flags & re.DOTALL
def re_ignorecase(self):
return self.regex_flags & re.IGNORECASE
def main():
package_name, symbol_name = sys.argv[1].rsplit(sep=".", maxsplit=1)
package = importlib.import_module(package_name)
lexer_cls = getattr(package, symbol_name)
assert issubclass(lexer_cls, pygments_lexer.RegexLexer), 'can only translate from RegexLexer'
print(pystache.render(TEMPLATE, TemplateView(
name=lexer_cls.name,
regex_flags=lexer_cls.flags,
aliases=[{'alias': alias} for alias in lexer_cls.aliases],
filenames=[{'filename': filename} for filename in lexer_cls.filenames],
mimetypes=[{'mimetype': mimetype} for mimetype in lexer_cls.mimetypes],
tokens=[{'state': state, 'rules': translate_rules(rules)} for (state, rules) in lexer_cls.get_tokendefs().items()],
)))
if __name__ == '__main__':
main()
chroma-2.20.0/_tools/pyproject.toml 0000664 0000000 0000000 00000000315 15044027432 0017257 0 ustar 00root root 0000000 0000000 [project]
name = "chromatools"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"pygments>=2.19.1",
"pystache>=0.6.8",
]
chroma-2.20.0/_tools/style.py 0000775 0000000 0000000 00000002565 15044027432 0016071 0 ustar 00root root 0000000 0000000 #!/usr/bin/env -S uv run --script
import importlib
import sys
import pystache
from pygments.style import Style
from pygments.token import Token
TEMPLATE = r'''
package styles
import (
"github.com/alecthomas/chroma/v2"
)
// {{upper_name}} style.
var {{upper_name}} = Register(chroma.MustNewStyle("{{name}}", chroma.StyleEntries{
{{#styles}}
chroma.{{type}}: "{{style}}",
{{/styles}}
}))
'''
def to_camel_case(snake_str):
components = snake_str.split('_')
return ''.join(x.title() for x in components)
def translate_token_type(t):
if t == Token:
t = Token.Background
return "".join(map(str, t))
def main():
name = sys.argv[1]
package_name, symbol_name = sys.argv[2].rsplit(sep=".", maxsplit=1)
package = importlib.import_module(package_name)
style_cls = getattr(package, symbol_name)
assert issubclass(style_cls, Style), 'can only translate from Style subclass'
styles = dict(style_cls.styles)
bg = "bg:" + style_cls.background_color
if Token in styles:
styles[Token] += " " + bg
else:
styles[Token] = bg
context = {
'upper_name': style_cls.__name__[:-5],
'name': name,
'styles': [{'type': translate_token_type(t), 'style': s}
for t, s in styles.items() if s],
}
print(pystache.render(TEMPLATE, context))
if __name__ == '__main__':
main()
chroma-2.20.0/_tools/uv.lock 0000664 0000000 0000000 00000003313 15044027432 0015650 0 ustar 00root root 0000000 0000000 version = 1
revision = 2
requires-python = ">=3.13"
[[package]]
name = "chromatools"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "pygments" },
{ name = "pystache" },
]
[package.metadata]
requires-dist = [
{ name = "pygments", specifier = ">=2.19.1" },
{ name = "pystache", specifier = ">=0.6.8" },
]
[[package]]
name = "pygments"
version = "2.19.1"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" },
]
[[package]]
name = "pystache"
version = "0.6.8"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/85/89/0a712ca22930b8c71bced8703e5bb45669c31690ea81afe15f6cb284550c/pystache-0.6.8.tar.gz", hash = "sha256:3707518e6a4d26dd189b07c10c669b1fc17df72684617c327bd3550e7075c72c", size = 101892, upload-time = "2025-03-18T11:54:47.595Z" }
wheels = [
{ url = "https://files.pythonhosted.org/packages/fa/78/ffd13a516219129cef6a754a11ba2a1c0d69f1e281af4f6bca9ed5327219/pystache-0.6.8-py3-none-any.whl", hash = "sha256:7211e000974a6e06bce2d4d5cad8df03bcfffefd367209117376e4527a1c3cb8", size = 82051, upload-time = "2025-03-18T11:54:45.813Z" },
]
chroma-2.20.0/bin/ 0000775 0000000 0000000 00000000000 15044027432 0013615 5 ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.binaryen-123.pkg 0000777 0000000 0000000 00000000000 15044027432 0017716 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.biome-2.1.3.pkg 0000777 0000000 0000000 00000000000 15044027432 0017336 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.bit-0.5.2.pkg 0000777 0000000 0000000 00000000000 15044027432 0017022 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.caddy-2.10.0.pkg 0000777 0000000 0000000 00000000000 15044027432 0017404 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.enumer-1.5.11.pkg 0000777 0000000 0000000 00000000000 15044027432 0017620 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.esbuild-0.25.8.pkg 0000777 0000000 0000000 00000000000 15044027432 0017763 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.go-1.24.5.pkg 0000777 0000000 0000000 00000000000 15044027432 0016736 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.golangci-lint-1.64.6.pkg 0000777 0000000 0000000 00000000000 15044027432 0021065 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.goreleaser-1.26.2.pkg 0000777 0000000 0000000 00000000000 15044027432 0020460 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.hlb-0.4.0.pkg 0000777 0000000 0000000 00000000000 15044027432 0017006 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.hyperfine-1.19.0.pkg 0000777 0000000 0000000 00000000000 15044027432 0020321 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.python3-3.13.2.pkg 0000777 0000000 0000000 00000000000 15044027432 0017732 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.reflex-0.3.1.pkg 0000777 0000000 0000000 00000000000 15044027432 0017526 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.svu-3.2.3.pkg 0000777 0000000 0000000 00000000000 15044027432 0017062 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.tinygo-0.38.0.pkg 0000777 0000000 0000000 00000000000 15044027432 0017641 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.typescript-7.0.0-dev.20250629.1.pkg 0000777 0000000 0000000 00000000000 15044027432 0022275 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.uv-0.8.4.pkg 0000777 0000000 0000000 00000000000 15044027432 0016703 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/.watchexec-2.3.2.pkg 0000777 0000000 0000000 00000000000 15044027432 0020217 2hermit ustar 00root root 0000000 0000000 chroma-2.20.0/bin/README.hermit.md 0000664 0000000 0000000 00000000416 15044027432 0016364 0 ustar 00root root 0000000 0000000 # Hermit environment
This is a [Hermit](https://github.com/cashapp/hermit) bin directory.
The symlinks in this directory are managed by Hermit and will automatically
download and install Hermit itself as well as packages. These packages are
local to this environment.
chroma-2.20.0/bin/activate-hermit 0000775 0000000 0000000 00000001062 15044027432 0016630 0 ustar 00root root 0000000 0000000 #!/bin/bash
# This file must be used with "source bin/activate-hermit" from bash or zsh.
# You cannot run it directly
if [ "${BASH_SOURCE-}" = "$0" ]; then
echo "You must source this script: \$ source $0" >&2
exit 33
fi
BIN_DIR="$(dirname "${BASH_SOURCE[0]:-${(%):-%x}}")"
if "${BIN_DIR}/hermit" noop > /dev/null; then
eval "$("${BIN_DIR}/hermit" activate "${BIN_DIR}/..")"
if [ -n "${BASH-}" ] || [ -n "${ZSH_VERSION-}" ]; then
hash -r 2>/dev/null
fi
echo "Hermit environment $("${HERMIT_ENV}"/bin/hermit env HERMIT_ENV) activated"
fi
chroma-2.20.0/bin/binaryen-unittests 0000777 0000000 0000000 00000000000 15044027432 0022275 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/biome 0000777 0000000 0000000 00000000000 15044027432 0017141 2.biome-2.1.3.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/bit 0000777 0000000 0000000 00000000000 15044027432 0016310 2.bit-0.5.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/caddy 0000777 0000000 0000000 00000000000 15044027432 0017200 2.caddy-2.10.0.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/chroma 0000775 0000000 0000000 00000000147 15044027432 0015016 0 ustar 00root root 0000000 0000000 #!/bin/bash
set -euo pipefail
go build -C cmd/chroma -o $TMPDIR/chroma . && exec $TMPDIR/chroma "$@"
chroma-2.20.0/bin/chromad 0000775 0000000 0000000 00000000152 15044027432 0015156 0 ustar 00root root 0000000 0000000 #!/bin/bash
set -euo pipefail
go build -C cmd/chromad -o $TMPDIR/chromad . && exec $TMPDIR/chromad "$@"
chroma-2.20.0/bin/enumer 0000777 0000000 0000000 00000000000 15044027432 0017623 2.enumer-1.5.11.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/esbuild 0000777 0000000 0000000 00000000000 15044027432 0020122 2.esbuild-0.25.8.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/go 0000777 0000000 0000000 00000000000 15044027432 0016053 2.go-1.24.5.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/gofmt 0000777 0000000 0000000 00000000000 15044027432 0016562 2.go-1.24.5.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/golangci-lint 0000777 0000000 0000000 00000000000 15044027432 0022324 2.golangci-lint-1.64.6.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/goreleaser 0000777 0000000 0000000 00000000000 15044027432 0021320 2.goreleaser-1.26.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/hermit 0000775 0000000 0000000 00000001361 15044027432 0015034 0 ustar 00root root 0000000 0000000 #!/bin/bash
set -eo pipefail
if [ -z "${HERMIT_STATE_DIR}" ]; then
case "$(uname -s)" in
Darwin)
export HERMIT_STATE_DIR="${HOME}/Library/Caches/hermit"
;;
Linux)
export HERMIT_STATE_DIR="${XDG_CACHE_HOME:-${HOME}/.cache}/hermit"
;;
esac
fi
export HERMIT_DIST_URL="${HERMIT_DIST_URL:-https://github.com/cashapp/hermit/releases/download/stable}"
HERMIT_CHANNEL="$(basename "${HERMIT_DIST_URL}")"
export HERMIT_CHANNEL
export HERMIT_EXE=${HERMIT_EXE:-${HERMIT_STATE_DIR}/pkg/hermit@${HERMIT_CHANNEL}/hermit}
if [ ! -x "${HERMIT_EXE}" ]; then
echo "Bootstrapping ${HERMIT_EXE} from ${HERMIT_DIST_URL}" 1>&2
curl -fsSL "${HERMIT_DIST_URL}/install.sh" | /bin/bash 1>&2
fi
exec "${HERMIT_EXE}" --level=fatal exec "$0" -- "$@"
chroma-2.20.0/bin/hermit.hcl 0000664 0000000 0000000 00000000000 15044027432 0015563 0 ustar 00root root 0000000 0000000 chroma-2.20.0/bin/hlb 0000777 0000000 0000000 00000000000 15044027432 0016263 2.hlb-0.4.0.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/hyperfine 0000777 0000000 0000000 00000000000 15044027432 0021022 2.hyperfine-1.19.0.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/pip 0000777 0000000 0000000 00000000000 15044027432 0017232 2.python3-3.13.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/pip3 0000777 0000000 0000000 00000000000 15044027432 0017315 2.python3-3.13.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/pip3.13 0000777 0000000 0000000 00000000000 15044027432 0017537 2.python3-3.13.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/pydoc3 0000777 0000000 0000000 00000000000 15044027432 0017643 2.python3-3.13.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/pydoc3.13 0000777 0000000 0000000 00000000000 15044027432 0020065 2.python3-3.13.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/python 0000777 0000000 0000000 00000000000 15044027432 0017763 2.python3-3.13.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/python3 0000777 0000000 0000000 00000000000 15044027432 0020046 2.python3-3.13.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/python3-config 0000777 0000000 0000000 00000000000 15044027432 0021311 2.python3-3.13.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/python3.13 0000777 0000000 0000000 00000000000 15044027432 0020270 2.python3-3.13.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/python3.13-config 0000777 0000000 0000000 00000000000 15044027432 0021533 2.python3-3.13.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/reflex 0000777 0000000 0000000 00000000000 15044027432 0017523 2.reflex-0.3.1.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/svu 0000777 0000000 0000000 00000000000 15044027432 0016407 2.svu-3.2.3.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/tinygo 0000777 0000000 0000000 00000000000 15044027432 0017662 2.tinygo-0.38.0.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/tsc 0000777 0000000 0000000 00000000000 15044027432 0021576 2.typescript-7.0.0-dev.20250629.1.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/uv 0000777 0000000 0000000 00000000000 15044027432 0016045 2.uv-0.8.4.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/uvx 0000777 0000000 0000000 00000000000 15044027432 0016235 2.uv-0.8.4.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-as 0000777 0000000 0000000 00000000000 15044027432 0017776 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-ctor-eval 0000777 0000000 0000000 00000000000 15044027432 0021267 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-dis 0000777 0000000 0000000 00000000000 15044027432 0020152 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-emscripten-finalize 0000777 0000000 0000000 00000000000 15044027432 0023343 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-fuzz-lattices 0000777 0000000 0000000 00000000000 15044027432 0022177 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-fuzz-types 0000777 0000000 0000000 00000000000 15044027432 0021533 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-merge 0000777 0000000 0000000 00000000000 15044027432 0020472 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-metadce 0000777 0000000 0000000 00000000000 15044027432 0020775 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-opt 0000777 0000000 0000000 00000000000 15044027432 0020175 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-reduce 0000777 0000000 0000000 00000000000 15044027432 0020642 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-shell 0000777 0000000 0000000 00000000000 15044027432 0020502 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm-split 0000777 0000000 0000000 00000000000 15044027432 0020526 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/wasm2js 0000777 0000000 0000000 00000000000 15044027432 0020014 2.binaryen-123.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/bin/watchexec 0000777 0000000 0000000 00000000000 15044027432 0020702 2.watchexec-2.3.2.pkg ustar 00root root 0000000 0000000 chroma-2.20.0/biome.json 0000664 0000000 0000000 00000000155 15044027432 0015034 0 ustar 00root root 0000000 0000000 {
"$schema": "https://biomejs.dev/schemas/2.0.5/schema.json",
"formatter": {
"indentStyle": "space"
}
}
chroma-2.20.0/chroma.jpg 0000664 0000000 0000000 00000236066 15044027432 0015035 0 ustar 00root root 0000000 0000000 Exif MM * V ^( i f H H 0221 0100 @ "
} !1AQa"q2#BR$3br
%&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz
w !1AQaq"2B #3Rbr
$4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz ? n
Npy?
Lm?~TEjtoҝ@^ӠJ.Z
Z~Cӵ,k11REv R4E rǪNOn=)A8큊5v?ҫO\zg9^2M r21YZ3ejכy܈+F0)P{Үp7 *)~T^F3Js1V:cA)Hc*1{TkB3>ʧHw|v##SⵉFb.NX?Ʈc=*o!Oҭ#H9jGJ 8=3t#Lmyֆo']69$v-[O5QPҷ<