3.7 KiB
{ blurb: "Add a new lexer to chroma" } $index
Intro
Gitea uses Chroma for syntax highlighting. Chroma doesn't have a MoonScript lexer. It does has a Python script that can convert Pygments lexers, though, and Pygments has a MoonScript lexer.
Run MoonScript lexer generation script
To create the lexer, in the Chroma root directory run:
$ docker run --rm -it -w /opt -v $PWD:/opt python bash -c \
"pip install pystache pygments \
&& python _tools/pygments2chroma_xml.py \
pygments.lexers.scripting.MoonScriptLexer > lexers/embedded/moonscript.xml \
&& pip list"
Use the Chroma MoonScript lexer to highlight some code
Create a file like this:
::: filename-for-code-block
main.go
:::
package main
import (
"fmt"
"os"
"github.com/alecthomas/chroma/v2/quick"
)
func main() {
code := `package main
func main() { }
`
fmt.Println(quick.Highlight(os.Stdout, code, "go", "html", "monokai"))
}
I did one of these:
$ docker run --rm -it -w /opt -v $PWD:/opt golang:tip-bookworm \
go mod init main
Which gave me the go.mod
file.
::: filename-for-code-block
go.mod
:::
module main
go 1.25
require (
github.com/alecthomas/chroma/v2 v2.18.0 // indirect
github.com/dlclark/regexp2 v1.11.5 // indirect
)
Then I did one of these:
$ docker run --rm -it -w /opt -v $PWD:/opt golang:tip-bookworm \
go run main.go
And that should output markup (and styles) for highlighting that block of Go
code to the console. But if we notice, it's importing the Chroma package from
the GitHub repo. We want to use our local version of chroma, so we use go mod edit
to replace the chroma import with our local version:
$ docker run --rm -it -w /opt -v $PWD:/opt golang:tip-bookworm \
go mod edit -replace github.com/alecthomas/chroma/v2@v2.18.0=./chroma
Which adds this line to our go.mod
file:
::: filename-for-code-block
go.mod
:::
...
replace github.com/alecthomas/chroma/v2 v2.18.0 => ./chroma
Now we can put some MoonScript in main.go
.
code := `print "Hello, #{@name}!"`
fmt.Println(quick.Highlight(os.Stdout, code, "moonscript", "html", "monokai"))
And we have it:
$ docker run --rm -it -w /opt -v $PWD:/opt golang:tip-bookworm \
go run main.go
go: downloading github.com/dlclark/regexp2 v1.11.5
That should output syntax highlighting using our local version of chroma.
Create testdata
Create a file in lexers/testdata
called moonscript.actual
. Add the tokens
from the language in this file.
Record test output
Create another file called lexers/testdata/moonscript.expected
. This is the
file we will record to.
$ RECORD=true go test ./lexers
Visually inspect and verify that the expected data is correct.
Run tests
$ go test ./lexers
Bonus!: Use local pygments
with pygments2chroma_xml.py
These lines in pygments2chroma_xml.py
:
import pystache
from pygments import lexer as pygments_lexer
from pygments.token import _TokenType
Import pygments from pip? How do we get it to load a local version of
pygments
?
In Pygments root directory:
$ docker run --rm -it -w /opt -v $PWD:/opt \
-v ../gitea-syntax-highlight/chroma/_tools/pygments2chroma_xml.py:/opt/pygments2chroma_xml.py \
python bash -c "pip install pystache && pip list \
&& python pygments2chroma_xml.py pygments.lexers.scripting.LuaLexer"
Should see.
Package Version
-------- -------
pip 25.0.1
pystache 0.6.8
That shows no remote pygments package is installed. After that you will see the lexer markup output.
<lexer>
<config>
...