TeX でもシンタクスハイライトしたい話(listings)

TeX Live 2021 の xelatex コマンドを使用しているとします。

listings パッケージでシンタクスハイライトができます。以下の hoge.tex を用意して xelatex hoge.tex を実行すれば hoge.pdf がコンパイルできます(日本語等幅フォントを指定していないので警告が出ますがコンパイルは通ります)。見た目などをカスタマイズしたい場合は \lstset コマンドでグローバル設定しておいてもいいし \begin{lstlisting} のオプションで指定してもいいと思います。

\documentclass[b5paper,xelatex,ja=standard]{bxjsarticle}
\usepackage[svgnames]{xcolor}
\usepackage{listings}
\lstset{  % グローバル設定
  columns=fixed,  % 等幅
  basewidth=0.5em,  % 字間詰め
  lineskip=-3pt,  % 行間詰め
  frame=lines,  % コードの上下にライン (マニュアル18ページ)
  % 書式設定
  basicstyle={\ttfamily\small},  % 全体の書式設定
  keywordstyle=[1]{\color{RoyalBlue}},  % keywords[1]の書式設定 (Python だと予約語)
  keywordstyle=[2]{\color{VioletRed}},  % keywords[2]の書式設定 (Python だと組み込み関数)
  stringstyle={\color{FireBrick}},  % 文字列リテラルの設定
  commentstyle={\color{SeaGreen}},  % コメントの設定
}


\begin{document}
以下に Python のコードを示します。
\begin{lstlisting}[language=python, caption=hoge.py]  % キャプションも要れば指定
from models.model_LRA import ModelForSC, ModelForSCDual
from config import Config

model_config = Config["lra-text"]["model"]
model_config["mixed_precision"] = True
model_config["attn_type"] = "softmax"  # さしあたりsoftmax
model = ModelForSC(model_config)
print(type(model))
x = 10000
\end{lstlisting}

以下に Bash のコマンドも示します。
\begin{lstlisting}[language=bash]
echo "Hello World!" | sed -e "s/\!//g"
\end{lstlisting}

\end{document}

f:id:cookie-box:20220109233302p:plain
keywords やコメントや文字列リテラルの定義が気になりますが、TeX Live 2021 を既定のパスにインストールした場合は以下のフォルダに各種言語の設定があるので探せると思います。Python であったら lstlang1.sty の 2932 行目にあると思います。keywords[1] が予約語、keywords[2] が組み込み関数になっているのがわかると思います。

%%
%% Python definition (c) 1998 Michael Weber
%% Additional definitions (2013) Alexis Dimitriadis
%%
\lst@definelanguage{Python}{%
  morekeywords={access, and, break, class, continue, def, del, elif, else,%
    except, exec, finally, for, from, global, if, import, in, is, lambda,%
    not, or, pass, print, raise, return, try, while},%
  % Built-ins
  morekeywords=[2]{abs, all, any, basestring, bin, bool, bytearray,%
    callable, chr, classmethod, cmp, compile, complex, delattr, dict, dir,%
    divmod, enumerate, eval, execfile, file, filter, float, format,%
    frozenset, getattr, globals, hasattr, hash, help, hex, id, input, int,%
    isinstance, issubclass, iter, len, list, locals, long, map, max,%
    memoryview, min, next, object, oct, open, ord, pow, property, range,%
    raw_input, reduce, reload, repr, reversed, round, set, setattr, slice,%
    sorted, staticmethod, str, sum, super, tuple, type, unichr, unicode,%
    vars, xrange, zip, apply, buffer, coerce, intern},%
  sensitive=true,%
  morecomment=[l]\#,%
  morestring=[b]',%
  morestring=[b]",%
  morecomment=[s]{'''}{'''},% used for documentation text
                            % (mulitiline strings)
  morecomment=[s]{"""}{"""},% added by Philipp Matthias Hahn
  morestring=[s]{r'}{'},% `raw' strings
  morestring=[s]{r"}{"},%
  morestring=[s]{r'''}{'''},%
  morestring=[s]{r"""}{"""},%
  morestring=[s]{u'}{'},% unicode strings
  morestring=[s]{u"}{"},%
  morestring=[s]{u'''}{'''},%
  morestring=[s]{u"""}{"""}%
}%

keywords やコメントや文字列リテラルの定義が間に合っていない場合はその言語を定義し直せばいいと思います。以下では Java で Spring Boot のアノテーションをシンタクスハイライトしたいのでアノテーションをキーワードに含めた lstjava.tex を用意してそれを読み込んでいます。lstjava.tex で書式設定もしています。

ちなみに listings では任意のアノテーション、つまり、「アットマークから改行 or 空白 or 開始カッコの直前まで」をシンタクスにすることはできないので(たぶん)、アットマークごとキーワードにしています。listings 以外だとシンタクスにできるパッケージもあると思いますが、アノテーションは無限にはないのでこれでもいいと思います。アノテーションを常に独立行にかくような人はアットマークを行コメントの開始記号にしてコメントとしてシンタクスハイライトできますがコメントと同色になるしわたしは独立行にかかないです。

ここまでかいておいてなんですがアノテーションのために言語を定義し直すよりは emph オプション(マニュアル 20 ページ)を使った方がいい気もします。→ 上記のリポジトリはその後 lstjava.tex を排除し emph オプションにそのコードブロック内に出てくるアノテーションを指定する式に変更しました。