VSCode 上でLaTeX の統合環境を実現するための拡張機能 としては「LaTeX Workshop 」が事実上の標準となっている。LaTeX Workshopでは「実行するコマンドのリスト」の指定を完全にユーザに委ねる設計になっている。このため、原理的には、「llmk 」などの新しいビルドツールと組み合わせて使えることが期待できる。
一週間ほど前に、めでたくllmkがCTAN とTeX Liveに収録されたので、さっそく「LaTeX Workshopとllmkを組み合わせる」設定を試してみたら、LaTeX Workshopがアレなせいでアレだった、という話。
※LaTeX Workshopやllmk自体に関する解説は一切省略する。
なぜLaTeX Workshopでllmkしたかったか
基本的にLaTeX Workshopのビルドは「ある決まったコマンドの列(レシピ と呼ばれる)を実行する」というものなので、異なる「コマンドの列」を必要とする文書を扱うたびにレシピを(メニューから)切り替える必要がある。LaTeX WorkshopではLatexmkを呼び出すレシピが既定で登録されていて、Latexmkを使うとある程度は「コマンドの列」の違いを吸収できるが、Latexmkには「利用するTeX エンジンをソースファイルから判別する」機能は持っていないため、エンジン選択の煩雑さは残る。
一方、llmkを使うと「利用するTeX エンジンをソースファイルから判別する」ことが可能になるため、「レシピの切替」の考慮が全く不要になって、幸せになると考えた次第である。
LaTeX Workshopを設定した
「llmk <ファイル名>
」だけを実行するレシピを登録する。
{
"latex-workshop.latex.recipes" : [
{
"name" : "llmk" ,
"tools" : [
"llmk"
]
} ,
] ,
"latex-workshop.latex.tools" : [
{
"name" : "llmk" ,
"command" : "llmk" ,
"args" : [
"%DOC%"
] ,
"env" : {}
} ,
] ,
}
簡単な文書でテストした
「uplatex→dvipdfmx」でビルドできる単純なupLaTeX文書を用意した。
※先頭行にllmkのためのマジックコメントがある。
\documentclass [ uplatex,dvipdfmx,9pt,a5paper ]{ jsarticle }
\usepackage [ scale=0.9 ]{geometry}
\usepackage {scsnowman}
\begin{document}
\section { \TeX }
{ \TeX } はアレ。
\section { 結論☃}
{ \centering\scsnowman [ scale=10,
hat,snow,arms,buttons,muffler=red] \par }
\end{document}
これをコマンドシェルからllmkでビルドしてみる。
llmk main.tex
すると、「uplatex2回1 →dvipdfmx」が実行されて正常にビルドが完了する。
PDF出力(素敵)
では、このソースファイルをVSCode で開いて、LaTeX Workshopの「llmk」レシピでビルドしてみる。
LaTeX WorkshopでビルドしてPDFを表示した様子
これは想定通りの結果になった。
チョット複雑な文書でテストした
フツーにllmkしたら想定通り
続いて、相互参照やbibファイルからの文献参照を含んだ、チョット複雑なupLaTeX文書を用意してみた。
※このソースには一か所ミスがある。8行目に\ref{sec:sconclusion}
とあるが、これは\ref{sec:conclusion}
の誤りである。
\documentclass [ uplatex,dvipdfmx,9pt,a5paper ]{ jsarticle }
\usepackage [ scale=0.9 ]{geometry}
\usepackage {scsnowman}
\begin{document}
\section { はじめに}
\ref{ sec:tex } 節で{ \TeX }\cite{texbook} についてdisる。
\ref{ sec:sconclusion } 節で結論を述べる。
\section { \TeX } \label{ sec:tex }
{ \TeX } はアレ。
\section { 結論☃} \label{ sec:conclusion }
{ \centering\scsnowman [ scale=10,
hat,snow,arms,buttons,muffler=red] \par }
\bibliographystyle { plain} \bibliography{ main }
\end{document}
[main.bib]
@Book{texbook,
author = "Donald Ervin Knuth",
title = "The {\TeX}book",
volume = "A",
publisher = "Addison-Wesley",
address = "Reading, MA, USA",
edition = "23rd printing, with corrections.",
pages = "ix + 483",
year = "1993",
series = "Computers and typesetting",
}
先ほどと同様にコマンドシェルで「llmk main.tex
」でビルドすると、「uplatex2回→bibtex →uplatex2回→dvipdfmx」と実行されて次の出力が得られる。
※\ref
の誤りのところが?? になっている。
PDF出力(素敵)
この文書では\ref
の引数が一か所誤っているため、解決できない参照が最後まで残り、最後のuplatexの実行において以下の警告が発生している。
LaTeX Warning: Reference `sec:sconclusion' on page 1 undefined on input line 8.
LaTeX Warning: There were undefined references.
LaTeX Workshopでllmkしたらアレ
では、このソースファイルをLaTeX Workshopでビルドしたらどうなるか。
LaTeX WorkshopでビルドしてPDFを表示した様子
出力されたPDFを見ると、先ほど示したものと全く同じになっている。つまり、llmkの実行は最後のuplatexの実行まで想定通りに行われたと推定できる。
しかし、今回のビルドの結果には大きな問題がある。それは「PROBLEMS」の表示である。
アレな警告の通知
ここにはLaTeX の実行中に発生したエラーや警告の内容が掲示 される。先述の通り、このソースファイルをビルドすると、最終的に2個の警告が発生するはずである。ところが実際にはPROBLEMSには14個もの警告が出ている。しかも、よく見ると、最終的には正常に解決しているはずのsec:tex
や文献texbook
に対しても「参照未解決」の警告が出ているのである。
sec:tex
やtexbook
の参照は初回のuplatexの実行のときは解決できないはずである。参照未解決の警告の異常な多さを考えると、「途中のものを含めて全てのuplatexの実行における警告をLaTeX Workshopが拾ってしまっている」と推定できる。
※途中の警告を拾うため、仮に「誤りがなくて最終的に全ての参照が解決されるLaTeX 文書」をビルドした場合でも警告が発生したような表示になる。
やっぱり、LaTeX Workshopがアレ
本来問題がないはずの箇所でエラー・警告が通知されるのではPROBLEMS機能がまるで役に立たない。「最後のLaTeX エンジンの実行」で発生したエラー・警告だけを拾うべきなのは明らかだろう。
しかし冷静に考えてみると、「最後のLaTeX エンジンの実行」だけ見る、というのは無理な要求であると思えてくる。なぜなら、LaTeX Workshopからみると、ビルドにおいては「llmk」という単一のコマンドを実行したにすぎないわけで、その標準出力や標準エラーのテキストから「LaTeX のエラー・警告」を拾うとしても、「最後のLaTeX エンジンの実行」に相当する部分を抜粋できそうにない……。
……いや待て、全く同じことはLatexmkを使う場合にも成立するはずである。しかしLaTeX Workshopが既定で設定を登録しているくらいだから、Latexmkで同じ問題が起こっているはずがない。実際に、Latexmkで(upLaTeX用の設定を用意して)ビルドしてみると、PROBLEMSの通知は正常(警告2個)になる。なぜLatexmkの場合は「最後のLaTeX エンジンの実行」の部分を抜粋できるのだろうか。
チョットLaTeX Workshopのソースコード を眺めてみると……あっ!
なんと、Latexmk専用の処理が書かれている!
Latexmkが実際にコマンドを起動する際に次のようなメッセージを端末に出力しているのだが:
Latexmk: applying rule 'latex'
要するに、LaTeX Workshopは、このメッセージを目印にして「抜粋」の処理を行っているようである。
試しに、llmkのプログラムに細工をして、このLatexmkのメッセージを出力する ようにしてみると……。
マトモな警告の通知
ああっ、PROBLEMSの通知が正常になった!
………………これはひどい 。
まとめ