😸

VSCodeとDockerでLaTeXを用いた多機能論文執筆環境を整える

2022/06/12に公開

はじめに

面倒な\LaTeXの環境構築と論文執筆テンプレートを作った

https://github.com/being24/latex-template-ja

https://github.com/being24/latex-docker

前提

\LaTeXを使っていますか?
自分が所属する研究室では基本的に\LaTeXを使用する事が前提です。また、学会に論文を投稿するときにスタイルファイルでテンプレートを渡されることもあります。

自分は学部と大学院で研究室を移っているのですが、学部時代の研究室は卒業論文をワードで執筆するようにと指定されました。控えめに言って地獄でした。(自分が使えこなせていなかったのかもしれませんが、図表が勝手に移動したりキャプションがずれたりフォントが勝手に変わったり変更してるのに変わらなかったり…)

移動後の研究室では\LaTeXを使用しており、これまでは各々が独自に環境を構築していました。
TeX Liveを自分でインストールする人もいればクラウド系のコンパイラを使う人もいて、それぞれ使用できるライブラリなどが微妙に食い違っている気持ちが悪い状態でした。

また、TeX Liveは毎年新バージョンがリリースされ、特に理由がなければ最新版を常に使いたい病の私は割とめんどくさい環境構築と初期設定を行うことを強いられていました。複数台PCをもっているためその分手間も増えましたし、何故かうまくインストールできないこともあり、もう嫌になったのでdockerに環境を構築することにしました。

さらに、今回の環境は研究室の後輩などが使用することを前提に構築したため使用者が\LaTeX以外の勉強をしなくてもとりあえず動くことを目標にしています。

2023/01/11追記

従来はLaTeX workshopの機能を用いてdockerコマンドを直接叩いていましたが、dev containerを使用したほうがパフォーマンスが向上することが判明したため、そちらに移行しています。

現在のmasterブランチはそちらに移行しており、従来のバージョンはcommand_arcブランチに移動していますが、要望がない限り保守はしない予定です。

\LaTeXの環境構築はDockerを使おう

Dockerって便利ですよね、可搬性も高いですしアーキテクチャが同じならどの環境でも同じように動きます。一回docker imageをbuild・pushしてしまえばあとは

docker pull ghcr.io/being24/latex-docker:latest

で環境が構築できます。

今回使用するimageについて

このリポジトリをお借りし一部変更したこのリポジトリのimageを使用します。個人的に必要だと思ったmintedlatexindentsiunitxが動くように改変してあります。

Dockerのインストールや仕組みの解説は専門の方々にお任せします。

VSCodeとgithubによる執筆環境の構築・共有

上で述べた通り、初学者でもとりあえず動くことを目標に環境を構築していきます。
構築した環境のテンプレートはこちらにおいてあります。

VSCodeは.vscode内にsettings.jsonが存在する場合、個人設定を上書きしてくれます。
よって、必要な環境を構築した上でこのリポジトリのテンプレートを用いることですべての設定が完結します。

\LaTeXのbuildができる環境の構築

Buildソフトウェアのインストール

早速\LaTeXソースをビルドできる環境を整えていきます。

この記事の内容を使用する場合は、必ずdockerが使用できる状態にしておいてください!!

必要なソフトウェアは

です。
また、githubのアカウントを作成しgitの初期設定を行い、

docker pull ghcr.io/being24/latex-docker:latest

を実行して環境構築済みのimageをローカルにpullしてください。

テンプレートのclone

github上に存在するリポジトリはcloneによってローカル環境にダウンロードできます。

今回使用するリポジトリはテンプレートリポジトリにしてありますので画面右上の

Use this template

Use this templateをクリックし、

Repository name

Repository nameに適当な名前を入力してリポジトリを作成、GitHubの処理が終了した後、自分のローカル環境にcloneしてください。vscodeを使用してクローンしたリポジトリを開くとvscodeが右下のポップアップで、推奨される拡張機能のインストールと、dev containerを使用するかどうかの質問をしてくれます。すべてyesで進めてください。

基本的にこの手順でリポジトリを作成し、文章を作成していきます。

構築したシステムでの\LaTeXソースのbuild方法

たまに(よく?)main.texにすべて記述し、rootディレクトリに画像を置き、参考文献は直接ソースに記述するという論文を見ることがあります。
たしかに出力されるpdfファイルの体裁は整っているかもしれませんが、可読性が低いしルートディレクトリはごちゃっとするし、参考文献の管理はおざなりになります。

今回使用するテンプレートの構造

こういったの問題を解消するため、自分が作成したテンプレートでは以下の前提で構築されています。

  • subfileを使用し、章(Chapter)ごとにファイル分割
  • 図や章ごとのtexファイルを専用のフォルダに格納
  • BibLaTeXをMendeley等の論文管理ソフトウェアから出力されるbibファイルで使用

これらによって、できるだけ整理された状態を維持します。

build方法

texファイルにソースを書いたあと、pdfファイルを作成するにはいくつかの方法があります。
build時にはdockerを実行可能にしておく必要があります。

保存時に自動でbuild

VSCodeには自動保存を行う設定があり、また、LaTeX-Workshopには保存時に自動でbuildを行う設定があります。
標準では保存時の自動buildを行わない設定になっていますが、保存時に自動でbuildを行わせる場合、作成したリポジトリ内の.vscode/settings.jsonの

  "latex-workshop.latex.autoBuild.run": "never",

となっているところを

  "latex-workshop.latex.autoBuild.run": "onSave"

に変更してください。
この設定がonSaveになっていると保存時に自動的にbuildされますが、VSCodeの自動保存を有効にしている場合、構文の入力途中でbuildされエラーが出るなどの問題が生じるため手動でbuildする設定を標準にしています。

GUIでbuild

いちいち入力時にbuildが行われるとエラーメッセージが煩わしく、またbuildに時間がかかってしまうので、buildを行いたいときに実行するためこちらの設定をおすすめします。
LaTeX-workshopのbuildボタンを押すと、buildが行われます。

up-right

上記画像(エディタの右上)の場合は緑色の再生ボタンを、

left-side

上記画像(LaTeX Workshopの拡張機能)の場合はRecipe: compileをクリックしてください。
どちらの場合も、buildが完了すると、pdfファイルが生成されます。

また、執筆が一区切りするごとに変更をcommitして置くことを推奨します。
進行度の管理や差し戻しも簡単になりますし、また、指導教官に複数回確認してもらうときワンタッチで差分ファイルを生成できます。

latexindentを用いたフォーマット

LaTeXにおけるコードのインデントは文章構造の理解などに役立ちます。
というか、コードを記述するときにはインデントは必要不可欠なものです。
ただ、文章を考えてキーボードを叩いているときにインデントまで気にする余裕はないかもしれません。

例えば、pythonにはautopep8というパッケージが存在し、自動でコードを整形してくれます。
同じように、LaTeXにもlatexindentというパッケージがあり、自動で整形をしてくれます。

menu

上記画像のドキュメントをフォーマット Shift+Alt+Fをクリックするか、そこに表示されたショートカットキーを押下してください。設定に従って自動で整形されます。

だたし、latexindentの設定ファイルであるlocalSettings.yamlは発展途上です。バグや改善提案はissueに投げてください。

github actionsにおける文章校正

LaTeXで記述した文章に校正をかけることができます。
記述した文章をtextlintとgithub actionsを使用して校正します。
これはwordなどで行われる自動校正を代替することを目的としており、日本語的におかしな文章や表記ゆれをPRの形で指摘してくれます。

こういった自動ツールで機械的な修正点を指摘することで、内容の推敲に集中できるようになります、が、過信は禁物です。あくまで機械的に指摘しているため精度は完璧とは言い難いです。このため、自分としては印刷した上で音読し、違和感がある言い回しなどを修正することを強く推奨します。

使い方は単純で、PR時に自動でコメントをしてくれるので普段はdevブランチで作業し、一段落したらmain/masterブランチにPRを出しLinterで指摘点を確認、修正したり無視したりを決定するといいと思います。
ただし、一回無視した指摘点は再度指摘されないので注意してください。

文章記述中のtextlint

文章記述中にもtextlintを使用することができます。
まず最初に

sh ./bin/install_textlint.sh

を実行しtextlintをインストールした上で、VSCodeの拡張機能であるvscode-textlintをインストールしてください。

github actionsを用いたbuildとrelease

論文のバージョンを自分で指定し、releaseの形式でgithub上においておくことができます。
バージョンの数字の付け方自体は自由ですが、git上でvから始まるタグをつけてpushするとgithub actionsによってソースがbuildされ、このようにその名前のreleaseが作成されます。

最後に

ここまで、自分が作成・改造した論文執筆環境の構築方法、使い方をざっくりまとめました。
この文章はgithubで管理しているので、issueやPRは歓迎です。質問もそちらからお願いします。

補遺

研究室内で使って見た結果、いくつかの問題が発生したのでそれつにいて追記します。

画像などを貼るときにエラーが起きる問題

コード自体に問題が無いのに、エラーが生じることがあります。

その時に表示されるエラーの例を下に示します。

extractbb:warning: Can't find file (figures/screen), or it is forbidden to read ...skipping

extractbb:warning: Can't find file (shot.png), or it is forbidden to read ...skipping



! LaTeX Error: Cannot determine size of graphic in figures/screen shot.xbb (no 
BoundingBox).

See the LaTeX manual or LaTeX Companion for explanation.
Type  H <return>  for immediate help.
 ...                                              
                                                  
l.10 ...aphics[width=5cm]{figures/screen shot.png}

この例は、画像のファイル名に空白が含まれている場合に生じるエラーです。
LaTeX側がファイル名を正しく認識できないために生じるため、ファイル名に空白を使用しないでください。
その他にも、ファイル名・パスに日本語が用いられる場合などに同様の問題が生じます。
詳細は以下のリンクを確認してください。

http://www.ic.daito.ac.jp/~mizutani/tex/texfile_name.html

スラッシュ・バックスラッシュ問題

VSCodeのエクスプローラから、対象のファイルを右クリックすることで相対パスを取得する事ができます。(絶対パスは使用しないでください)

Windowsでは、その方法で取得される文字列はfigures\screenshot.pngとなります。
しかし、これをそのままLaTeXに渡すとエラーが起きてしまいます。これはlinuxとwindowsのパスの表し方の違いであるため、figures/screenshot.pngと修正する必要があります。(バックスラッシュをスラッシュにする)

shell scriptの改行コード問題

エラー画面

[19:32:10] Format with command: docker
[19:32:10] Format with command args: ["run","--rm","-v","%DIR%:/workdir","ghcr.io/being24/latex-docker","sh","/workdir/bin/linter.sh"]
[19:32:12] Formatting failed with exit code 2
[19:32:12] stderr: /workdir/bin/linter.sh: 2:
: not found
/workdir/bin/linter.sh: 5: Syntax error: word unexpected (expecting "do")
./bin/build.sh: 2:
: not found
./bin/build.sh: 8: Syntax error: end of file unexpected (expecting "then")

このエラーは、shell scriptの改行コードがLFからCRLFに変更されている場合に生じます。改行コードをLFに変更してください。
windows版gitのインストール時のオプションで、改行コードの自動変更が行われることが原因である可能性があります。
最近のエディタは基本どの改行コードでも対応できると思うため、この設定を切ってしまうことをおすすめします。

画像の幅の問題

これは問題、というわけではありませんが記述します。
多くのサンプルコードにおいて、画像を貼り付ける場合以下のようになっていると思います。

\begin{figure}
    \centering
    \includegraphics[width=5cm]{figures/screenshot.png}
    \caption{スクリーンショット}
\end{figure}

\begin{figure}
    \centering
    \includegraphics[scale=0.8]{figures/screenshot.png}
    \caption{スクリーンショット}
\end{figure}

確かにこれでも表示自体はされますが、表示サイズの指定を長さで指定するとカラムサイズの変更したときにうまくハマりませんし、画像サイズのスケールで指定すると、貼り付けたい画像のサイズで各々に調整が必要となり面倒です。このため、現在の行の幅を基準に画像の幅を指定すると良いと思います

\begin{figure}
    \centering
    \includegraphics[width=\linewidth]{figures/screenshot.png}
    \caption{スクリーンショット}
\end{figure}

(そもそもpngを貼るなと言う話もあるかもしれませんが…)

svgファイルを貼り付けるとき

svgファイルを貼り付けるとき、svg packageを使用する方法や、pdfに変換して貼り付ける方法があります。

この環境ではどちらも対応できますが、inkscapeを使用してPDFに変換するスクリプトを用意しています。

sh ./bin/svg2pdf.sh

このスクリプトを使用すると、figuresディレクトリ以下のsvgファイルをすべてPDFに変換します。このとき、図のテキストはすべてパスに変換されます。パスに変換する必要ない場合は、--export-text-to-pathオプションを削除してください。

「未対応の圧縮形式」エラー

実際に後輩が遭遇していた例ですが、論文を学会に提出する際に”未対応の圧縮形式”というエラーが出ることがあります。
画像の圧縮を解除する等の方法が提示されていますが、PDFのバージョンを変更することで対応できました。

(u)pLaTeX使用時

dvipdfmxのオプションを変更して対応します。

.latexmkrcの中にある

$dvipdf = 'dvipdfmx %O -o %D %S';

$dvipdf = 'dvipdfmx -V 4 %O -o %D %S';

に変更してください。

LuaLaTeX使用時

bxpdfverパッケージを使用して対応します。

main.texのdocumentclass指定の後に

\usepackage[1.4]{bxpdfver}

を追加してください。bxpdfverの使い方はこちらを参照してください。

学会指定のスタイルファイルがbuildできないとき

本テンプレートの標準設定はupLaTeXでのビルドを前提としています。
学会などが用意したテンプレートには、どのlatexでビルドするかが指定されていることがあります。
upLaTeXでのビルドが指定されている場合はそのままで問題ありませんが、pLaTeXでのビルドを指定されている場合は、標準の設定のままでは以下のようなエラーが出ることがあります。

tShape{JT1}{gt}{m}{it}{<-> ssub*gt/m/n}{}

このエラーはpLaTeXでビルドすることを指定されているにもかかわらず、upLaTeXでのビルドされているために生じるエラーです。

この場合、.latexmkrcの中にある

# $latex = 'platex -synctex=1 -interaction=nonstopmode -file-line-error -halt-on-error %O %S';
$latex = 'uplatex -synctex=1 -interaction=nonstopmode -file-line-error -halt-on-error %O %S';

の上の行をコメントアウトを外し、下の行をコメントアウトしてください。

$latex = 'platex -synctex=1 -interaction=nonstopmode -file-line-error -halt-on-error %O %S';
# $latex = 'uplatex -synctex=1 -interaction=nonstopmode -file-line-error -halt-on-error %O %S';

この変更によりpLaTeXでのビルドが行われます。

そろそろ(u)pLaTeXは不味そうなので、各学会の迅速な対応をお願いしたいところです。

保存時にエラーが出る、buildが通らない等

このテンプレートを自分のアカウントにforkして使っていると、保存時にエラーが出たり、buildが通らなかったりすることがあります。

これは、fork後にこちらが更新した際に、fork元のテンプレートとの差分が発生してしまうためです。
このため、fork変更を取り込む、fetch upstreamを行う必要があります。
ただし、本リポジトリはtemplateとして使用できるようにしてあるため、PRを出す時以外はforkを行う必要はありません。

docker for windowsでbuild時に"user declined directory sharing"のエラーが出る場合

docker for windowsのアップデートにより、localのディレクトリをdockerコンテナにマウントする際に、ユーザーの許可が必要になりました。
これは、docker for windowsの設定画面から許可を与えることで解決できます。
右上の歯車マークから設定を開き、Settings -> Resources -> FILE SHARINGに、sourceのディレクトリを追加してください。
Apply & Restartを押すと、docker for windowsが再起動され、設定が適応できます。

gitの追跡が遅い、もしくは行われない場合

WSL2側の問題のようです、手動でsyncボタンを押すと反映されます。

画像が表示されない

更新したclsファイルではあえてpngやjpgなどを貼り付けると表示されないようにしています。
画像を直接貼ると画像が劣化したり、buildが遅くなったりするためです。
画像も一度PDFファイルした上で貼り付けることをおすすめします。

reference.bibに文献を追加したらエラーが出る、reference以降のページが表示されない、など

logファイルを確認すると

! Arithmetic overflow.
<to be read again>
                  =
l.5 \printbibliography[title=参考文献]

! Improper alphabetic or KANJI constant.
<to be read again> 
                  \q__text_recursion_tail 
l.5 \printbibliography[title=参考文献]

などのエラーが出ることがあります。
これは、最近biblatexもしくはbiberに関連するなにかの仕様が変更された事によるものだと思われます。
この場合、reference.bibのtitleの日本語部分を{}で囲うことで解決できます。例えば

title   = {あいうえお},

title   = {{あいうえお}},

に変更してください。

参考文献(biblatex)の書式変更について

参考文献の記述方法は多岐にわたりますが、本環境ではバックエンドにbiberを使用しているため、junsrtなどをそのまま使用することができません。
biber使用時は以前の記述方法は使用できず、biber用のjunsrtは提供されていないため、互換用として提供されいてるtrad-unsrt styleを使用し、細かい設定を自分で修正する必要があります。

\usepackage[backend=biber,style=ieee]{biblatex} % biblatexを使用するためのパッケージ
\addbibresource{references.bib}

これを以下のように変更します。

\usepackage[backend=biber,style=trad-unsrt]{biblatex} % biblatexを使用するためのパッケージ
\addbibresource{references.bib}
\DeclareFieldFormat{journaltitle}{\textit{#1}}

trad-unsrtだけでは、日本語の文献名が太字になってしまうため、journaltitleの書式を上書きしています。

参考文献

参考文献(biblatex)の書式変更について2

学会によっては、参考文献のリストにおいて、1)などの片括弧を使用し、かつ、引用箇所の右肩に1)を表示することを求めています。その場合は、

\DeclareFieldFormat{labelnumberwidth}{{#1})\hspace{.5\jlreq@zw}} % 参考文献番号の後ろに)をつける

% \mkbibparens のコピーを作成して片括弧のマクロを作成
\let\onebrackets\mkbibparens
\renewcommand*{\onebrackets}[1]{\textsuperscript{#1)}}

\DeclareCiteCommand{\cite}[\onebrackets]
    {\usebibmacro{prenote}}
    {\usebibmacro{citeindex}%
    \usebibmacro{cite}}
    {\multicitedelim}
    {\usebibmacro{postnote}}

を追加してください。

昔のバージョンのTeX Liveを使用したい場合

互換性の問題などから、昔のバージョンのTeX Liveを使用したい場合があります。
本当は専用のリポジトリなりを作成すべきですが、frozenのTeX Liveをimageにしておくことで対応しています。

frozen version frozen tag
2022 3.2.6
2023 2023-frozen

本来は2022などのタグを付けることが好ましいですが、自分の理解不足かうまくいかなかったため、3.2.6になっています。
2023からは2023-frozenというタグを付けています。

CloudLaTeX, Overleafなどのクラウドサービスを使用したい場合

クラウドサービスを使用する場合、dockerを使用する必要はありません。
その場合は、リポジトリ右上のCodeをクリックし、Download ZIPをクリックしてダウンロードしてください。

CloudLaTeXの場合は、新規プロジェクトをクリックし、ZIPをアップロードからzipファイルをアップロードしてください。(プロジェクト名は適したものに変更してください)

この場合、コンパイラの設定は自動で行われますが、もし行われない場合は、設定からコンパイラをLuaLaTeXに変更してください。

Overleafの場合は、新規プロジェクトをクリックし、プロジェクトのアップロードからzipファイルをアップロードしてください。(プロジェクト名は適したものに変更してください)

その後、メニューの設定欄のコンパイラをLuaLaTeXに変更し、主要文章がmain.texであることを確認した上で、コンパイルを行ってください。

ただし、Overleafのプラン変更により、フリープランではコンパイル完了までにタイムアウトしてしまう可能性があります。
そういった場合はOverleaf以外のサービスや、ローカル環境にdockerやインストーラを用いてTexlive環境を構築することをおすすめします。

docker imageを更新したらパーミッションエラーが出る場合

特にLinux環境においては、devcontainer内で作成したファイルがroot権限になってしまい、色々と不便でした。
このため、新たなdocker image からはlatexユーザーでコンテナを起動するようにしています。

この修正により、旧バージョンのdocker imageを使用していた文章を新しいdocker imageでbuildしようとするとエラーが出ます。
ただしこのエラーはパーミッションエラーなどとは表示されないことが多いです。

確認するためには

ls -l

を実行して、ファイルの所有者がrootになっているか確認してください。
この場合の解決方法は2つあります。

ファイルのパーミッションを変更する

ファイルのオーナーを変更すればこの問題は解決しますが、rootユーザーがオーナーのファイルを変更するためには、root権限が必要です。
dockerコンテナ内でroot権限を取得するのはできないので、コンテナを起動した状態のときにホストコンピュータのターミナルで

docker ps

を実行してコンテナのIDを取得し、

docker exec -it -u root コンテナID /bin/bash

を実行してroot権限でコンテナに入り

chown -R latex:latex /workdir

を実行してオーナーを変更してください。

フォルダをダウンロードし直す

githubに現状の内容をpushしておいて、再度cloneして起動してください。
この場合、ファイルのオーナーはlatexユーザーになっているため、エラーが出ないはずです。

突然github actionsでのビルドが通らなくなった場合

docker imageのユーザを変更した影響で、従来通っていたリポジトリでgithub actionsでのbuildが通らなくなる事象が確認されています。
これは、github actionsの仕様によるものです。こういった場合は、.github/workflows/build.ymlを確認してください。

.github/workflows/build.yml

# 実行されるジョブの定義
jobs:
  # PDFのビルドジョブ
  build:
    runs-on: ubuntu-20.04
    container:
      # もし独自のDockerイメージを変更したい場合、ここを変更する
      image: ghcr.io/being24/latex-docker:latest

imageの後にoptions: --user rootを追加して、

# 実行されるジョブの定義
jobs:
  # PDFのビルドジョブ
  build:
    runs-on: ubuntu-20.04
    container:
      # もし独自のDockerイメージを変更したい場合、ここを変更する
      image: ghcr.io/being24/latex-docker:latest
      options: --user root

としてください。

jlreqとupLaTeXを併用したときに文字化けが発生する場合

2024/10/19追記:jlreqの更新により、この問題は解消されました。

2024-08-23にjlreqが更新され、このバージョンのjlreq(clsやstyでの使用を含む)をupLaTeXでbuildすると文字化けが発生することを確認しています。
開発者様も確認されているようなので、そのうち解決させると思いますが、luaLaTeXを使用するか、jlreqのバージョンを下げる、docker imageを使用している場合は前のバージョンのimageを使用するなどで対応可能です。

自分のテンプレートでluaLaTeXを使用するには、.latexmkrc

$pdf_mode = 3;

$pdf_mode = 4;

に変更してください。

docker imageの前のバージョンを使用する場合は、ghcr.io/being24/latex-docker:24.08.0を使用してください。

.devcontainer/devcontainer.json

"image": "ghcr.io/being24/latex-docker",

"image": "ghcr.io/being24/latex-docker:24.08.0",

に変更すると正常にbuildできることを確認しています。

フォーマッタが動作しない

フォーマッタを使用したときに、

LaTeX formatter is set to "none" by `formatting.latex`.

と表示される場合があります。
これはlatex-workshopの設定が変更され、フォーマッタにlatexindentのみではなく、tex-fmtも使用できるようになったためです。

最新版のテンプレートでは、この設定ファイルの変更に対応しているため、このエラーに遭遇した場合は、最新版のsettings.jsonでローカルのsettings.jsonを上書きしてください。

手動で修正する場合は、settings.json

    "latex-workshop.latexindent.path": "sh",
    "latex-workshop.latexindent.args": [
        "./bin/linter.sh",
    ],

    "latex-workshop.formatting.latex": "latexindent",
    "latex-workshop.formatting.latexindent.path": "sh",
    "latex-workshop.formatting.latexindent.args": [
        "./bin/linter.sh",
    ],

に変更してください。

GitHubで編集を提案

Discussion