【結論】
— 某ZR(ざんねん🙃) (@zr_tex8r) 2020年9月19日
LaTeX Workshopは、任意のビルドツールと組み合わせて使えるわけではない。
(ざんねん🙃)#TeX #むむむ
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のためのマジックコメントがある。
%#!uplatex \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」が実行されて正常にビルドが完了する。
では、このソースファイルをVSCodeで開いて、LaTeX Workshopの「llmk」レシピでビルドしてみる。
これは想定通りの結果になった。
チョット複雑な文書でテストした
フツーにllmkしたら想定通り
続いて、相互参照やbibファイルからの文献参照を含んだ、チョット複雑なupLaTeX文書を用意してみた。
※このソースには一か所ミスがある。8行目に\ref{sec:sconclusion}
とあるが、これは\ref{sec:conclusion}
の誤りである。
%#!uplatex \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}
@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
の誤りのところが??になっている。
この文書では\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でビルドしたらどうなるか。
出力された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の通知が正常になった!
………………これはひどい。
まとめ
LaTeX Workshopでllmkできなくて、
— 某ZR(ざんねん🙃) (@zr_tex8r) 2020年9月19日
仕方がないので、
scsnowman+の☃を回すことにしよう……😐#ナントカ pic.twitter.com/fOo92CvFCU
-
\section
の情報が.auxファイルに書き出されるため、uplatexは2回実行される。↩