⚒️

Remote-wslを使わずにWSL2上のLaTeXでVSCodeからビルドする方法 (+外部PDFビューワの起動&同期)

2022/11/15に公開

概要

Windowsで\LaTeX{}執筆環境を構築したい場合は、TeX Liveを

  1. Windows上に直接インストールする
  2. WSL2上にインストールする

の2択がある.そしてどちらの場合もVSCodeで編集し、強力な拡張機能であるLaTeX-Workshopを介してビルドを行うのが主流である.TeX LiveはWindowsのネイティブ上で動かすよりも、WSL2にインストールしたほうが挙動が早い(参考記事)ため、2つ目の選択肢が理想である.
しかし、このデメリットとして、VSCodeをRemote-wslで起動する必要があること、そして外部PDFビューワの扱いがめんどくさい、ということがある.VSCodeをRemote-wslで起動するには手間がかかる(というより、ビルドしようとしたときにエラーが出て気づく時の精神負荷が大きい)し、WSL2からWindowsにインストールされているPDFビューワを起動するとプロセスが分かれるため私のようにSumatraPDFを使用していると不都合が多い.

よって、WSL2上にTeX Live (LaTeX)をインストールしてVSCodeで編集しつつも、Remote-wslを使わずビルドするように設定した.Remote-wslを使わなければ、PDFビューワの問題は発生しない.

補足

なぜ内部PDFビューワではなく外部PDFビューワ(SumatraPDF)を使うのか

LaTeX-WorkshopにはVSCode内に展開できるPDFビューワ(内部PDFビューワ)がある.しかし作業環境がマルチモニターだと、メインモニターに資料とTeXファイルを開いて、ビルドしたPDFはサブモニターに置いておきたいということになる.そのため内部PDFビューワでは使いづらく今回は外部PDFビューワを使用する流れになった.
SumatraPDFは、軽量であり、SyncTeXとファイルの自動更新に対応しているためLaTeXを使う際にはおすすめである.

この記事で扱わないこと

  • WSL2、VSCodeのインストール
  • LaTeX-Workshopのインストール・解説
  • LaTeX周りの解説(軽くはするかも)
  • TeX Liveのインストール(参考にするならTeX Wikiがおすすめ)

方法

WSL2上にlatexmkrcを作成し、それをLaTeX-Workshopから呼び出してビルドするように設定する.

まずWSL2のホームディレクトリに.latexmkrcを以下のように作成する.

.latexmkrc
#!/usr/bin/env perl
$latex = 'uplatex %O -kanji=utf8 -synctex=1 -halt-on-error -file-line-error %T';
$bibtex = 'upbibtex';
$biber = 'biber --bblencoding=utf8 -u -U --output_safechars';
$dvipdf = 'dvipdfmx %O %S';

$max_repeat = 5;
$pdf_mode = 3; # generate pdf from dvi

現在は最低限の設定しかしていないため、各自でTeX Wikiおすすめの記事を参考にして設定すること.

メモ(軽い解説)
  • -silentオプションを使いたいため%Oを記述しているが、そうするとlatexmkのファイル名補完がうまく機能しないため%Tなども適宜記述する.
  • uplatexには自動エンコード機能があるが特に理由がなければ-kanji=utf8をつけておいたほうがいい.
  • BibTeX周りの記事(latexmkが主題だけどほかに詳しいBibTeXの記事が見つからない)
  • $pdf_modeは、PDFの生成手順(DVI経由なのか、PS経由なのかなど)を設定する.

latexmk -commandsで設定が反映されていることを確認できる.

参考
$ latexmk -commands
Commands used by latexmk:
   To run latex, I use "uplatex %O -kanji=utf8 -synctex=1 -halt-on-error -file-line-error %T"
   To run pdflatex, I use "pdflatex %O %S"
   To run lualatex, I use "lualatex %O %S"
   To run xelatex, I use "xelatex %O %S"
   To run biber, I use "biber --bblencoding=utf8 -u -U --output_safechars"
   To run bibtex, I use "upbibtex"
   To run makeindex, I use "makeindex %O -o %D %S"
   To make a ps file from a dvi file, I use "dvips %O -o %D %S"
   To make a ps file from a dvi file with landscape format, I use "dvips -tlandscape %O -o %D %S"
   To make a pdf file from a dvi file, I use "dvipdfmx %O %S"
   To make a pdf file from a ps file, I use "ps2pdf -dALLOWPSTRANSPARENCY %O %S %D"
   To make a pdf file from an xdv file, I use "xdvipdfmx -E -o %D %O %S"
   To view a pdf file, I use "start acroread %O %S"
   To view a ps file, I use "start gv %O %S"
   To view a ps file in landscape format, I use "start gv -swap %O %S"
   To view a dvi file, I use "start xdvi %O %S"
   To view a dvi file in landscape format, I use "start xdvi -paper usr %O %S"
   To print a ps file, I use "lpr %O %S"
   To print a dvi file, I use "NONE $lpr_dvi variable is not configured to allow printing of dvi files"
   To print a pdf file, I use "NONE $lpr_pdf variable is not configured to allow printing of pdf files"
   To find running processes, I use "ps -f -u USERNAME",
      and the process number is at position 1
Notes:
  Command starting with "start" is run detached
  Command that is just "start" without any other command, is
     used under MS-Windows to run the command the operating system
     has associated with the relevant file.
  Command starting with "NONE" is not used at all

次に、VSCodeのsetting.jsonでLaTeX-Workshopの設定を追記する

ビルドに関する設定

setting.json
    "latex-workshop.latex.recipes": [
        {
            "name": "latexmk",
            "tools": [
                "latexmk via cmd"
            ]
        },
    ],
    "latex-workshop.latex.tools": [
        {
            "name": "latexmk via cmd",
            "command": "wsl.exe",
            "args": [
                "latexmk",
                "$(wslpath -u '%DOC%')",
                "-silent",
            ]
        }
    ],
    "latex-workshop.latex.autoBuild.run": "onSave",
軽い解説

VSCodeがRemote-wslで起動していない場合、LaTeX-Workshopからのコマンドはcmd.exe(コマンドプロンプト)に渡される.よってlatex-workshop.latex.toolにあるように、WSLがLinuxコマンドと一緒に呼べる機能や、ファイルパスの形式を変換してくれるwslpath(WSL2の機能)を使ってlatexmkと対象ファイルを呼ぶ.
%DOC%は、LaTeX-Workshopのプレースホルダであり、texファイルへの絶対パスを示している.プレースホルダはほかにも%PDF%とか%DIR%とかあるが、どこにもまとまっていないので頑張ってwikiから探して使う.
$()はLinuxの機能で、カッコ内の結果を渡してくれる.
-silentオプションをつけることでログが減る.
01/15/23追記: Windowsのパスにはスペースが含まれる可能性があるので,%DOC%はクォーテーションで囲っておきましょう.

PDFビューワに関する設定

setting.json
    "latex-workshop.view.pdf.viewer": "external",
    "latex-workshop.view.pdf.external.viewer.command": "SumatraPDFへのWindowsパス",
    "latex-workshop.view.autoFocus.enabled": false,
    "latex-workshop.view.pdf.external.synctex.command": "SumatraPDFへのWindowsパス",
    "latex-workshop.view.pdf.external.synctex.args": [
        "-forward-search",
        "%TEX%",
        "%LINE%",
        "-reuse-instance",
        "-inverse-search",
        "\"C:\\Users\\medim\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe\" \"C:\\Users\\medim\\AppData\\Local\\Programs\\Microsoft VS Code\\resources\\app\\out\\cli.js\" --ms-enable-electron-run-as-node -r -g \"%f:%l\"",
        "%PDF%"
    ],

wikiからそのまま持ってきたので特に解説はない.SyncTeXに関しては知識が不足しているので詳しい説明はできないが、これによってビルドが完了した際にSumatraPDFでPDFを開いてくれる.

ほかのPDFビューワも対応していればwikiに説明がある.

あとがき

LaTeX、WSL2、VSCodeの仕様が絡んでいるので、調べるのに時間がかかったり設定も試行錯誤したけれど、書き出してみると意外となんてことはなかった.これに関する記事がなかったので書いたけれど当たり前すぎてないだけだったのかもしれない.
あまり時間がなくて雑になっているので後日余裕があれば修正するかもしれない.

Discussion