はじめに
TeXのlistingのソースコードの一部分をハイライトしたい、でもどうすれば良いのか分からない、あるいは上手くいかない。
そんなお悩みをお持ちの方はぜひ呼んでいってください。
上手くいかない例: escapechar
/escapeinside
を使う
listingの中でコマンドを入力したい場合(例えば数式を組み込む場合)、escapechar
やescapeinside
をよく使う。
それを利用して文字の太さ、色を変えることができるはできるが、、
\lstset{
...
escapeinside={(@}{@)},
}
\begin{lstlisting}
quicksort(data) {
if (data.length <= 1) {
return data;
} else {
(@\color{Purple}\textbf{p = select\_pivot(data);}@)
{lo, hi} = partition(p, data);
lo_sorted = quicksort(lo);
hi_sorted = quicksort(hi);
return (lo_sorted ++ p ++ hi_sorted);
}
}
\end{lstlisting}
このようにアラインメントが崩れがちになる。
さらに、コードが一旦listingの外に出てしまうのでアンダーバー_
をエスケープする必要もあって面倒。
上手くいく例: moredelim
を使う
modedelim
を指定することで、ある文字に挟まれた領域の書体を変更することが可能。
\lstset{
...
moredelim=[is][\color{Purple}\bfseries]{<\#}{\#>},
}
\begin{lstlisting}
quicksort(data) {
if (data.length <= 1) {
return data;
} else {
<#p = select_pivot(data);#>
{lo, hi} = partition(p, data);
lo_sorted = quicksort(lo);
hi_sorted = quicksort(hi);
return (lo_sorted ++ p ++ hi_sorted);
}
}
\end{lstlisting}
簡単だし、綺麗に出力される。
ちなみに複数の色を使い分けて遊ぶこともできて、
\lstset{
...
moredelim=[is][\color{Blue}\bfseries]{<\#blue\#}{\#>},
moredelim=[is][\color{Orange}\bfseries]{<\#orange\#}{\#>},
moredelim=[is][\color{Green}\bfseries]{<\#green\#}{\#>},
moredelim=[is][\color{Purple}\bfseries]{<\#purple\#}{\#>},
}
\begin{lstlisting}
quicksort(data) {
if (data.length <= 1) {
return data;
} else {
<#purple#p = select_pivot(data);#>
{<#blue#lo#>, <#orange#hi#>} = partition(<#purple#p#>, data);
<#blue#lo_sorted#> = quicksort(<#blue#lo#>);
<#orange#hi_sorted#> = quicksort(<#orange#hi#>);
return (<#blue#lo_sorted#> ++ <#purple#p#> ++ <#orange#hi_sorted#>);
}
}
\end{lstlisting}
こんなこともできる。
おわりに
vim上のシンタックスハイライトを元にmoredelim
を機械的に生成し、TeXのlistingの色に対応付けているのが
vimのカラースキームでLaTeXのコードを彩る、carbonpaper.vim
このvimプラグイン。こちらもよろしくお願いします。
ちなみにアラインメントがおかしい場合は以下の記事を参照してください。
TeXにソースコードを等幅フォントで"ちゃんと"載せる
最後に全ソース:
\documentclass[uplatex]{jsarticle}
\usepackage{xcolor}
\usepackage{listings}
\usepackage{inconsolata}
% Color
\definecolor{Blue}{HTML}{2d5ae0}
\definecolor{Orange}{HTML}{e33900}
\definecolor{Green}{HTML}{009e73}
\definecolor{Purple}{HTML}{9400d3}
% Listings
\lstset{
language=C++,
basicstyle=\ttfamily\Large,
keywordstyle=\bfseries\color{Green},
stringstyle=\color{Orange},
commentstyle=\color{Purple},
showstringspaces=false,
frame={tb},
numbers=left,
xrightmargin=0zw,
xleftmargin=2zw,
columns=fixed,
basewidth=0.5em,
moredelim=[is][\color{Blue}\bfseries]{<\#blue\#}{\#>},
moredelim=[is][\color{Orange}\bfseries]{<\#orange\#}{\#>},
moredelim=[is][\color{Green}\bfseries]{<\#green\#}{\#>},
moredelim=[is][\color{Purple}\bfseries]{<\#purple\#}{\#>},
escapeinside={(@}{@)},
}
\begin{document}
\begin{lstlisting}
quicksort(data) {
if (data.length <= 1) {
return data;
} else {
(@\color{Purple}\textbf{p = select\_pivot(data);}@)
{lo, hi} = partition(p, data);
lo_sorted = quicksort(lo);
hi_sorted = quicksort(hi);
return (lo_sorted ++ p ++ hi_sorted);
}
}
\end{lstlisting}
\clearpage
\begin{lstlisting}
quicksort(data) {
if (data.length <= 1) {
return data;
} else {
<#purple#p = select_pivot(data);#>
{lo, hi} = partition(p, data);
lo_sorted = quicksort(lo);
hi_sorted = quicksort(hi);
return (lo_sorted ++ p ++ hi_sorted);
}
}
\end{lstlisting}
\clearpage
\begin{lstlisting}
quicksort(data) {
if (data.length <= 1) {
return data;
} else {
<#purple#p = select_pivot(data);#>
{<#blue#lo#>, <#orange#hi#>} = partition(<#purple#p#>, data);
<#blue#lo_sorted#> = quicksort(<#blue#lo#>);
<#orange#hi_sorted#> = quicksort(<#orange#hi#>);
return (<#blue#lo_sorted#> ++ <#purple#p#> ++ <#orange#hi_sorted#>);
}
}
\end{lstlisting}
\end{document}