13 August 2026
Syntax highlighting of sessions with TeXmacs
I finished writing the theological book I mentioned in the previous blog entries.
I continuously updated the
GitHub repo that contains the whole book.
In this blog entry I summarize my technical experiences, the biggest challenges, and possible solutions.
Not all problems have already been solved yet: displaying ␣ instead of invisible space in string
contexts is still an issue to address.
Syntax highlighting of a computer program is a typical task nowadays. My first experience with syntax highlighting
was back in 1992: Borland introduced Turbo Pascal 7.0. This was the first time for me when I felt: it makes a difference
in coding.
When printing a book, however, there may be restrictions. Black-and-white books are obviously cheaper than books with colors.
And technically, one needs to have a reliable way to color the program code automatically. A well-known standard is
LaTeX's listings package. TeXmacs's session-oriented text processing
approach is somewhat different and has nothing to do with LaTeX packages.
TeXmacs is written in C++ but its configuration is mostly based on
Scheme
scripts. Unfortunately, there is only one supported
language with session integration, Python, and the documentation on how to add support for other languages, is incomplete.
For me, it took several months to figure out how a new language can properly be added, because I assumed that
everything works out-of-the-box. In reality, TeXmacs seems to be a discontinued project by its creator
Joris van der Hoeven,
even if there is still official support that provides new releases. (I know, this is not completely
true since Joris still contributes a lot to the source code and there are several commits done by himself.
But my final user experience is that this project receives much less spotlight than earlier.) In fact, a new
project
Mogan seems to take over the lead by fixing several
issues and improving many features. It is, however, still in beta stage in several aspects: for example,
its EPS support is partially broken and my book (that works perfectly in TeXmacs) cannot be properly loaded
in Mogan. Unfortunately, most part of Mogan's development is contributed by Chinese developers and some
improvements are commented in Chinese – this makes non-Chinese contributions difficult. Also, my
help requests at Mogan's Discord channel were not completely answered – my final conclusion is
that I cannot count on anybody who knows the source code well enough so I need to go ahead alone.
I did so, and with a little help given by ChatGPT, I managed to fix some issues on my own. (ChatGPT had also
difficulties with the code and I really needed my own creative approach and perseverance to address the issues.)
One of the biggest challenges for me was to learn how to compile TeXmacs and have a local version that
contains eventual changes according to my feature requests. The most difficult part was to compile
guile
that works together with TeXmacs. It turned out that TeXmacs requires
its
own fork of guile, and one needs
to have
gcc-12 to compile it. This package is
available
in all recent Ubuntu versions. To enable syntax highlighting, however, it was not required to recompile TeXmacs.
Steps one needs to do for syntax highlighting
Assume we want syntax highlighting for a new language, say
newlang. We need to create the folder
~/.TeXmacs/plugins/newlang/progs/ first. This folder is mainly for Linux users, for other platforms this may be different.
In this folder we need to put three files:
newlang-format.scm with the content
(texmacs-module (newlang-format))
(define-format newlang (:name "newlang source code"))
and another file
newlang-lang.scm with the minimal example content
(texmacs-module (newlang-lang) (:use (prog default-lang)))
(tm-define (parser-feature lan key)
(:require (and (== lan "newlang") (== key "keyword")))
`(,(string->symbol key)
(keyword "print" "if" "and" "other" "keywords")
(keyword_control "more")
(constant_module "etc"))) ;; and so on...
(define (notify-newlang-syntax var val) (syntax-read-preferences "newlang"))
and the third file init-newlang.scm with something like this:
(plugin-configure newlang
(:require (url-exists-in-path? "newlang-cli"))
;; here newlang-cli is an interpreter (executable) for newlang
(:launch "newlang-cli")
(:session "newlang"))
(lazy-format (newlang-format) newlang)
This last line was crucial and it took me several months to figure out.
Usually it already appears in the system-wide startup script
progs/init-texmacs.scm
for the already working languages like Python.
To enable this only for session inputs but not for session outputs and session errors, we
need to create the file
~/.TeXmacs/plugins/newlang/packages/session/newlang.ts with some minimal content like
<TeXmacs|1.99.19>
<style|source>
<\body>
<active*|<\src-title>
<src-package|newlang|1.0>
<\src-purpose>
Markup for newlang sessions.
</src-purpose>
<src-copyright|2026|Your Name>
<\src-license>
Some license
</src-license>
</src-title>>
<\active*>
<\src-comment>
Use verbatim output
</src-comment>
</active*>
<assign|newlang-output|<\macro|body>
<\with|mode|text|language|verbatim|font-family|tt>
<\generic-output>
<arg|body>
</generic-output>
</with>
</macro>>
<assign|newlang-errput|<\macro|body>
<\with|mode|text|language|verbatim|font-family|tt>
<\generic-errput>
<arg|body>
</generic-errput>
</with>
</macro>>
\;
</body>
<\initial>
<\collection>
<associate|preamble|true>
</collection>
</initial>
I used Joris'
.ts file for Python with technically no modification.
A re-initialization of TeXmacs' settings may be required (I used the -S option on command line).