本記事の内容は古い、かつ非効率です。本記事の内容は全て無視して、以下の GitHub リポジトリの README を見ながら LaTeX 環境を構築してみてください。Docker + LaTeX + VSCode で LaTeX 執筆環境を構築しています。
ローカルに LaTeX 環境を作ろうとするとだいたいハマるので、再現性のある環境構築ができる Docker で環境構築を行うべきだと思います。
(以下、内容の古い、非効率な内容となっております)
殴り書き.エラー処理を順に追って LaTeX 環境を VSCode に構築していく泥臭い記事.クリスマスと言えば LaTeX の環境構築ですよね?
クリスマスなのに LaTeX の環境構築してる
— pyteyon (@pyteyon) December 24, 2019
背景
ラップトップを Macbook Air から Macbook Pro に乗り換えたため,新たに LaTeX 環境を構築する必要があった.以前環境構築した際は,再現性を全く考えておらず,エラー処理の過程で設定を書き足したり,ローカルに色んなパッケージを入れまくったりでカオスになってしまったため,その環境に何も触れない状態になってしまった.
本記事ではその反省を生かし,実行したコマンド,その最中で発生したエラーの処理など,行ったこと全てを記録することにした.あくまでも記録であり再現性は保証しない.
概要
以下の記事を進め,VSCode 上に LaTeX 環境を構築する.
本記事のゴールは「VSCode 上で *.tex
ファイルを編集,保存したら PDF が自動生成されてプレビューが速やかに更新される」ことである.
開発環境
# macOS $ sw_vers ProductName: Mac OS X ProductVersion: 10.15.2 # Homebrew $ brew -v Homebrew 2.2.2 Homebrew/homebrew-core (git revision 8fae; last commit 2019-12-23) Homebrew/homebrew-cask (git revision 783b1; last commit 2019-12-23) # VSCode $ code --version 1.41.1 # VSCode の LaTeX 関連の extension $ code --list-extensions | xargs -L 1 echo code --install-extension | grep "latex" --color code --install-extension James-Yu.latex-workshop
環境構築の手順
実行したことを忠実に記録した.
1. brew cask で MacTeX のインストール
GUI はいらんので -no-gui
を付けてる.インストールには 1.5 h くらいかかった(余計なものを入れたくない場合は BasicTeX という最小構成のものがあるが,日本語環境などを追加で設定する必要があるらしく,苦しみたくないので自分は避けた).
$ brew cask install mactex-no-gui
インストール後,シェルを再起動し,platex
や latexmk
が実行できればインストールに成功している.
$ platex This is e-pTeX, Version 3.14159265-p3.8.2-190131-2.6 (utf8.euc) (TeX Live 2019) (preloaded format=platex) restricted \write18 enabled. **^C $ latexmk Latexmk: This is Latexmk, John Collins, 17 March 2019, version: 4.63b. Latexmk: No file name specified, and I couldn't find any Use latexmk -help to get usage information
ちゃんとインストールできてるっぽい.他にもパッケージ管理ツール tlmgr
なども一緒にインストールされている.何がインストールされているかは以下のコマンドで確認できる.
$ ls /Library/TeX/texbin # 省略
2. LaTeX のための VSCode 拡張 LaTeX Workshop をインストール
VSCode(GUI)で LaTeX Workshop
インストールした(実際には,以前使用していた Macbook Air での環境を同期していたのでアップデートしただけ).
また,以下の設定を VSCode の settings.json
に追加した(以前の設定は全て消去してから以下を加えた).内容は冒頭の参考記事のコピペ.
... // ---------- Language ---------- "[tex]": { // スニペット補完中にも補完を使えるようにする "editor.suggest.snippetsPreventQuickSuggestions": false, // インデント幅を2にする "editor.tabSize": 2 }, "[latex]": { // スニペット補完中にも補完を使えるようにする "editor.suggest.snippetsPreventQuickSuggestions": false, // インデント幅を2にする "editor.tabSize": 2 }, "[bibtex]": { // インデント幅を2にする "editor.tabSize": 2 }, // ---------- LaTeX Workshop ---------- // 使用パッケージのコマンドや環境の補完を有効にする "latex-workshop.intellisense.package.enabled": true, // latex のビルドで生成されるファイルの出力先ディレクトリ "latex-workshop.latex.outDir": "out", // 生成ファイルを削除するときに対象とするファイル // デフォルト値に "*.synctex.gz" を追加 "latex-workshop.latex.clean.fileTypes": [ "*.aux", "*.bbl", "*.blg", "*.idx", "*.ind", "*.lof", "*.lot", "*.out", "*.toc", "*.acn", "*.acr", "*.alg", "*.glg", "*.glo", "*.gls", "*.ist", "*.fls", "*.log", "*.fdb_latexmk", "*.snm", "*.nav", "*.dvi", "*.synctex.gz" ], // 生成ファイルを "out" ディレクトリに吐き出す "latex-workshop.latex.outDir": "out", // ビルドのレシピ "latex-workshop.latex.recipes": [ { "name": "latexmk", "tools": ["latexmk"] } ], // ビルドのレシピに使われるパーツ "latex-workshop.latex.tools": [ { "name": "latexmk", "command": "latexmk", "args": ["-silent", "-outdir=%OUTDIR%", "%DOC%"] } ] ...
3. .latexmkrc
の作成,編集
自分の dotfiles に下記の内容の .latexmkrc
を追加し,symlink を張った.
.latexmkrc
こちらも参考記事のコピペ.
#!/usr/bin/env perl # LaTeX $latex = 'platex -synctex=1 -halt-on-error -file-line-error %O %S'; $max_repeat = 5; # BibTeX $bibtex = 'pbibtex %O %S'; $biber = 'biber --bblencoding=utf8 -u -U --output_safechars %O %S'; # index $makeindex = 'mendex %O -o %D %S'; # DVI / PDF $dvipdf = 'dvipdfmx %O -o %D %S'; $pdf_mode = 1; # preview $pvc_view_file_via_temporary = 0; if ($^O eq 'linux') { $dvi_previewer = "xdg-open %S"; $pdf_previewer = "xdg-open %S"; } elsif ($^O eq 'darwin') { $dvi_previewer = "open %S"; $pdf_previewer = "open %S"; } else { $dvi_previewer = "start %S"; $pdf_previewer = "start %S"; } # clean up $clean_full_ext = "%R.synctex.gz"
設定の内容は下記の通り.
特に変わった設定はしていませんが、コマンドラインから latexmk を実行する場合でも、いい感じに動くように以下のように設定しています。
- symlink 時に実行したコマンド
これは本題とはあまり関係がない.ホームディレクトリに直接 ~/.latexmkrc
を置けば良い.
ln -sf $HOME/Projects/dotfiles/latex/.latexmkrc ~/.latexmkrc
4. ビルドしてみる
VSCode を再起動して(latexmk
を VSCode
を認識させるために必須.正確には VSCode
に PATH
を読み込ませるため.), tex ファイルを編集してみる.
- VSCode を再起動後ビルドを実行
cmd + shift + P
(Mac)でコマンドパレットを表示.LaTeX Workshop: Build with recipe
>latexmk
を選択(てかこの段階ではlatexmk
という選択肢しかないはず)
補足:再起動で直るエラー
(めっちゃ単純なことをだらだら殴り書きしてます.飛ばしても後ろの手順には影響ないです.)
VSCode の統合ターミナル(VSCode 内で開けるターミナル)で MacTex をインストール後,VSCode を再起動せずに tex ファイルのビルドを行うと以下のエラーが小さくエディタの下部に表示された(再起動すると直る).
- エラーメッセージ
Recipe terminated fatal error: spawn latexmk ENOENT.
エラーメッセージについて調べる
- spawn:「魚が産卵する」,「生じる」という意味.この文脈では,新しい子プロセスを生成してコマンドを実行するという意味(この単語色んなとこで見る気がする).
ENOENT
:Error NO ENTry
の略.ファイルやディレクトリが存在しないという意味のエラーメッセージらしい.
ログを見る(VSCode のサイドバーの "TEX" マーク > View Log messages > View LaTeX Workshop extension log)
# 深夜 3 時です [03:00:05] Found root file from active editor: [ファイルのフルパス] [03:00:05] Root file remains unchanged from: [ファイルのフルパス] [03:00:05] Building root file: [ファイルのフルパス] [03:00:05] Build root file [ファイルのフルパス] [03:00:05] Recipe step 1: latexmk, -silent,-outdir=out,[ファイルのフルパス(拡張なし)] [03:00:05] LaTeX build process spawned. PID: undefined. [03:00:05] LaTeX fatal error: spawn latexmk ENOENT, . PID: undefined. [03:00:05] Does the executable exist? PATH: [ローカル環境の PATH]
ざっくり解釈すると,ビルドプロセスを立ち上げたけど latexmk
が読み込めなくてエラーが起きてるっぽい.
- エラーについて思ったこと
latexmk
が VSCode に認識されていない- シェルを立ち上げたときは
latexmk
をコマンドとして実行できているためPATH
は通してるはず.ただシェル環境と VSCode の環境でPATH
の認識の仕方が違う? - ↑ と思ったけど,恐らく,これは VSCode の新しいウィンドウの起動時にローカル環境の
PATH
が読み込まれて,その子プロセスである統合ターミナル中でPATH
が更新されてもそれが VSCode 側では更新されないからだと思う.今回の場合,統合ターミナルで MacTeX をインストールして子プロセス内ではPATH
が書き換えられるけど(Homebrew によってlatexmk
などが含まれる/Library/TeX/texbin
が PATH に追加される),それは親プロセス(ウィンドウ)には反映されない.だから,ウィンドウを再起動して更新されたPATH
を VSCode に読み込ませれば,今度はlatexmk
に PATH が通されてるから tex ファイルをビルドできるようになる(殴り書きでだらだら書いてごめんなさい).
これについては VSCode を再起動すれば,ちゃんと latexmk
が認識されビルドできるようになる.
5. ビルドはできた(成功したとは言っていない)
5-1. エラーが出た
今回はクリスマスツリーを出力するコード(How can we draw a Christmas tree with decorations, using TikZ? より引用)をビルドしたが,以下の画像を見ると分かる通り,生成された PDF がダメダメだった.右下にもエラーが出ている.
- エラーメッセージ
Recipe terminated with error. Retry building the project.
- ログ
[17:51:37] File watcher: responding to change in [tex ファイルのフルパス] [17:51:37] Parsing [tex ファイルのフルパス] [17:51:37] [tex ファイルのフルパス] changed. Auto build project. [17:51:37] BUILD command invoked. [17:51:37] Building root file: [tex ファイルのフルパス] [17:51:37] Build root file [tex ファイルのフルパス] [17:51:37] Recipe step 1: latexmk, -silent,-outdir=out,[tex ファイルのフルパス(拡張子なし)] [17:51:37] LaTeX build process spawned. PID: 3257. [17:51:38] Recipe returns with error: 12/null. PID: 3257. message: Latexmk: Run number 1 of rule 'pdflatex' Latexmk: Summary of warnings from last run of (pdf)latex: =====Latex reported missing or unavailable character(s). =====See log file for details. Latexmk: Use the -f option to force complete processing, unless error was exceeding maximum runs, or warnings treated as errors. . [17:51:38] Cleaning auxillary files and retrying build after toolchain error. [17:51:38] Recipe step 1: latexmk, -silent,-outdir=out,[tex ファイルのフルパス(拡張子なし)] [17:51:38] LaTeX build process spawned. PID: 3260. [17:51:38] Recipe of length 1 finished. PID: 3260. [17:51:38] Successfully built [tex ファイルのフルパス]. [17:51:38] Refresh PDF viewer for [tex ファイルのフルパス(拡張子pdf)] [17:51:38] Parse fls file. [17:51:38] Preview PDF file: [tex ファイルのフルパス(拡張子pdf)]
$ latexmk -silent -outdir=out christmas_latex.tex
- 上記ログのエラー箇所
[17:51:38] Recipe returns with error: 12/null. PID: 3257. message: Latexmk: Run number 1 of rule 'pdflatex' Latexmk: Summary of warnings from last run of (pdf)latex: =====Latex reported missing or unavailable character(s). =====See log file for details. Latexmk: Use the -f option to force complete processing, unless error was exceeding maximum runs, or warnings treated as errors.
上記のエラーについてググる前に,下記のコマンドでシェルから直接 tex ファイルをビルドしてみた.するとクリスマスツリーの pdf がちゃんと出力された(画像省略).
$ latexmk -pdflatex=lualatex -pdf christmas_latex.tex
ここから推察するに,LaTeX の VSCode でのビルドコマンド?(てか処理エンジン?,補足)が適切に設定されていない(保存されたときに裏側で走るコマンド).恐らく LaTeX Workshop の下記の設定項目(VSCode の settings.json
)を設定し直す必要がある.
latex-workshop.latex.tools
latex-workshop.latex.recipes
上記二つの設定が適切にできれば VSCode のコマンドパレットの LaTeX Workshop: Build with recipe
の選択肢に lualatex
とかのビルドコマンドを増やせるはず.
5-2. LaTeX Workshop の設定を見直す
というわけで LaTeX Workshop の設定を見直す.
- 現段階での tools,recipes の設定
- 下記の設定では latexmk のデフォルトの処理系しか使えない.
... "latex-workshop.latex.tools": [ { "name": "latexmk", "command": "latexmk", "args": ["-silent", "-outdir=%OUTDIR%", "%DOC%"] } ], "latex-workshop.latex.recipes": [ { "name": "latexmk", "tools": ["latexmk"] } ], ...
LaTeX Workshop: Build with recipe
のビルドの選択肢を増やすには,tools
にコマンド(シェルで実行されるコマンド)を定義し,recipes
で tools
に定義したコマンドと VSCode で使うビルドコマンドを対応付けることができる.
この設定を終えると,VSCode のコマンドパレットから実行する LaTeX Workshop: Build with recipe
の選択肢が増えるはず.下記のように tools
と recipes
の設定を変更した.
- 変更後の tools,recipes の設定
- LaTeX 処理系によってビルドの手順を分けられるようにした.
... "latex-workshop.latex.tools": [ { // latexmk を利用した xelatex によるビルドコマンド "name": "Latexmk (XeLaTeX)", "command": "latexmk", "args": [ "-f", "-gg", "-pv", "-xelatex", "-synctex=1", "-interaction=nonstopmode", "-file-line-error", "-outdir=%OUTDIR%", "%DOC%" ] }, // latexmk を利用した uplatex によるビルドコマンド { "name": "Latexmk (upLaTeX)", "command": "latexmk", "args": [ "-f", "-gg", "-pv", "-synctex=1", "-interaction=nonstopmode", "-file-line-error", "-outdir=%OUTDIR%", "%DOC%" ] }, // latexmk を利用した platex によるビルドコマンド // 古い LaTeX のテンプレートを使いまわしている (ドキュメントクラスが jreport や jsreport ) 場合のため { "name": "Latexmk (pLaTeX)", "command": "latexmk", "args": [ "-f", "-gg", "-pv", "-latex='platex'", "-latexoption='-kanji=utf8 -no-guess-input-env'", "-synctex=1", "-interaction=nonstopmode", "-file-line-error", "-outdir=%OUTDIR%", "%DOC%" ] }, // latexmk を利用した lualatex によるビルドコマンド { "name": "Latexmk (LuaLaTeX)", "command": "latexmk", "args": [ "-f", "-gg", "-pv", "-lualatex", "-synctex=1", "-interaction=nonstopmode", "-file-line-error", "-outdir=%OUTDIR%", "%DOC%" ] } ], // latex-workshop.latex.recipes: Recipe の定義 "latex-workshop.latex.recipes": [ // XeLaTeX で書かれた文書のビルドレシピ { "name": "XeLaTeX", "tools": [ "Latexmk (XeLaTeX)" ] }, // LaTeX(upLaTeX) で書かれた文書のビルドレシピ { "name": "upLaTeX", "tools": [ "Latexmk (upLaTeX)" ] }, // LaTeX(pLaTeX) で書かれた文書のビルドレシピ { "name": "pLaTeX", "tools": [ "Latexmk (pLaTeX)" ] }, // LuaLaTeX で書かれた文書のビルドレシピ { "name": "LuaLaTeX", "tools": [ "Latexmk (LuaLaTeX)" ] } ] ...
設定し終えたため,再度ビルドを実行する.コマンドパレットから LaTeX Workshop: Build with recipe
を検索するとちゃんと選択肢が増えてる(先ほどまでは latexmk
しかなかった!).
クリスマスツリーを表示する今回の tex ファイルは処理系に LuaLaTeX が必要だった.上記の選択肢の内,LuaLaTeX を選択しビルドを実行するとついにクリスマスツリーが表示された!(12/24 22 時過ぎ時点).
補足:LaTeX エンジンの種類と pdf 出力のワークフロー
- LaTeX エンジンの種類
- dvi ファイルを出力するタイプのエンジン
- pLaTeX
- upLaTeX
- pdf ファイルを直接出力するタイプのエンジン
- pdfLaTeX
- XeLaTeX
- LuaLaTeX
- dvi ファイルを出力するタイプのエンジン
最近では,エンジンの種類に関わらず PDF ファイルを成果物とすることが普通だが,「dvi から pdf への変換」について,現状では「dvips を使う」,「dvipdfmx を使う」という 2 種類の方式が並存している.「LaTeX を使って pdf ファイルを得る」というワークフローについては以下 7 つの方式があることになる.
教訓
- 自分はネットの記事を頼ることしかできないので,LaTeX の環境構築系の記事は本当にありがたい.しかし,ネットの記事通りにやっても大体上手く行かない(これは LaTeX 環境の構築に限らないけども).
- エラーメッセージ,ログをちゃんと読めば解決できる.
終わりに
LaTeX の環境構築はハマると辛いイメージがあるので私の書いた記録が誰かの助けになれば幸いです.ハマりどころはそう多くはないはずなので虱潰しに頑張りましょう.
Merry Xmas.
$ xmas ____________________________________ I___|___|___|___|___|__|____|___|__|_I I_|___|___| |___|___|__I )\ I___|__ | ..,a@@@a,a@@@a,.. |___|____I /( ( )) I_|__ .,;*;;@@@@@a@@@@@;;;;,. ___|__I (( ) : I__| ;;;;;;;;;a@@^@@a;;;*;;;;; __|_I : ,uU I_| ;;;;*;;;a@@@ @@@a;;;;*;;; |__I Uu. :Uu I__|;;;;;;;a@@@@ .@@@@@;;;;;;;; __|I uU: | | I_| ;;*;;;a@@@@@ @@'`@@@;;;;;*; _|_I | | |_| I__ ;;;;;;@@;;@@ `@ `@;;;*;;;; ___I |_| _ (___) _ I_|_ ;;;*;;@;;;;@;;;;;*;;;;;;;;; _|__I___ (___) ,-' ) ( ~~~~~ `;;;;;;*;;;;;;;;;;;*;;;;' ~~~~~ ) (`-. ,-____=====_____________`;;;;;;;;*;;;;;;;'_______________=====___`. |~~| _________________________________________________/o\___ |~~| |_|| ||____|____|____|____|____|____|____|____|____|_/ /,\__| ||_| |__| |___|____|____|____|____|____|____|____|____|__/ /,,,\|| ||_| |_||__||____|____|____|____|____|____|____|____|____|\/,,,,,\|__|__| |____|____|____|____|____|____|____|____|____|____|___\,,,,,,\___|_| |_|____|__I####I.......... /%%%%%%%%%%%\ ..........I##\,,,,( )|___| |____|____I####I.......... .%%%%%( )%%%%%. .........I###\,,,,\/__|_| |_|____|__I####I.......... @@%%%%0%0%%%%@@ ........I## /,,,,/_|___| |____|____I####I.......... `@@@@@@@@@@@@@@' ........I# /,,,,/____|_| |_|____|__I####I............ \\\\\\\\\\\\\) ........I ( \,,/___|___| |____|____I####I............. `\\\\\\\\\\) ........I \_)/_|____|_| |_|____|__I####I............ A `\\\\\\\' .. .. I# :_|____|___| |____|____I####I......... AAA .. `\\\' .. A. .I###I___|____|_| |_|____|__I####I...... .A `AAA .... * .. AAA. I ##I_|____|___| |____|____I####I.... AAA AA;AA ... ... `AAA.I ##I___|____|_| |_|____|__I####/~~~,-.A;;A'-A;;;;;A-----A-----,A;;;A ##I_|____|___| |____|____I###/ I.;;;;; ;;;;;;; AAA I;;;A'\###I___|____|_| |_|____|__I##/ I;;;;;; ;;;;;;; A;;;A I;;;; \##I_|____|___| |____|____I#/ !~;;;;;;~~~~~~~~~~~;;;;;;~~~~~!;' \#I___|____|_| |_|____|__I/______! ::::;; ;;;;;; !______\I_|____|___| ~~~~~~~~~/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ \~~~~~~~~~~ /_______________________________________________\ /\____/\ __ .' """" `,-' `--.__ __,- : - - ; " :: `-. -.__ ,-sssss `._ `' _,'" ,'~~~::`.sssss-. |ssssss ,' ,_`--'_ __,' :: ` `.ssssss| |sssssss `-._____~ `,,'_______,---_;; ssssss| |ssssssssss `--'~{__ ____ ,'ssssss| `-ssssssssssssssssss ~~~~~~~~~~~~ ssss.-' `---.sssssssssssssssssssss.---' ------------------------------------------------
sited by asciiart.website.
(クリスマスネタが 2 つでくどいけど可愛いアスキーアートだったので alias にしてみた)