LaTeX
Lua
Ghq
VSCode

ptex2pdfがghq管理下のリポジトリでPDFを作成できないことがある

この記事は、TeX & LaTeX Advent Calendar 2018 12日目の記事です。
Lua(La)TeXとは無関係ですが、Lua要素はあります(強引)。

昨日の記事は、p_typoさんの「添字のお話」でした。


TL;DR

はじめに

初めて参加させていただきます。@kn1chtです。

$\rm{\LaTeX}$歴0年の初心者です。環境だけは手元に揃えていたものの、pandocでMarkdown文書をPDF化するのに使っていただけでした。
いよいよ学位論文を書くことになり、流石に$\rm{\LaTeX}$で書かねばと思い執筆環境を整えました。
その過程でptex2pdfのバグを踏んで報告&Pull Requestしたら採用していただいたので、経緯を書きたいと思います。

環境

問題の発見

ghqによるリポジトリの取得

VS Codeで書くのが快適だと聞き、Visual Studio CodeでTeXのコンパイルをできるようにする方法を参考に設定しました。
日本語の文書が無事コンパイルできるか試すため、適当なテンプレートをGitHubからcloneします。

※実際に使ったリポジトリはprivateのため、ここでは情報システム工学研究室(JSK) 様のテンプレートを使用させていただきます

$ ghq get jsk-report-template/ci-thesis.git

ここで使ったツールはghqというGitリポジトリ管理ツールです。散乱しがちなローカルリポジトリを~/.ghq/[hostname]/[user|org]/[repo]のディレクトリ構成で整理してくれます。
上記の例なら~/.ghq/github.com/jsk-report-template/ci-thesisとなります。

ビルドがdvipdfmxの段階で失敗する

それでは準備も整ったのでLaTeX Workshop経由でビルドしてみます。

error.png

エラーで止まったのでログを見てみると、ある異変に気づきます。

Output written on main.dvi (19 pages, 30576 bytes).
SyncTeX written on main.synctex.gz.
Transcript written on main.log.
github.dvi -> github.pdf

dvipdfmx:fatal: Could not open specified DVI (or XDV) file: github.dvi

いやgithub.pdfどっから出てきたんだよ

当然ディレクトリにgithub.texなんてあるわけないですし、そもそもmain.dviの作成までは成功しています。

エラー原因の検証

この段階では原因の見当もついていませんが、とりあえずターミナルを開いてコマンドでのビルドを試します。

$ ptex2pdf -l -ot -kanji=utf8 main.tex
# ...
Output written on main.dvi (21 pages, 33736 bytes).
Transcript written on main.log.
main.dvi -> main.pdf
[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16][17][18][19][20][21]
117951 bytes written
main.pdf generated by dvipdfmx.

すんなり通りました。つまり手元の環境やテンプレート自体の問題ではなさそうです。
VS Code & LaTeX Workshopを使う時だけうまくいかないという謎の状況となってしまいました。

その後色々試したのち、ghq管理でないディレクトリでのコンパイルをやってみたところ、

changed-dir.png

できました! つまりghqのディレクトリでLaTeX Workshopを使うときだけこの問題が起こると言えます。

解決

LaTeX Workshopがコマンドにフルパスを渡していた

あらためてLaTeX Workshopのログを見てみます。

This is ptex2pdf[.lua] version 20180514.0.
Processing /Users/[ユーザー名]/.ghq/github.com/jsk-report-template/ci-thesis/main
This is e-pTeX, Version 3.14159265-p3.8.1-180226-2.6 (utf8.euc) (TeX Live 2018) (preloaded format=platex)
 restricted \write18 enabled.

ptex2pdfフルパスが渡されていました
ghq管理のディレクトリパスには、はじめに触れたようにgithub.comの文字列が入っています。これが謎のgithub.dviの正体とみて間違いないでしょう。

ptex2pdfのコードから問題箇所を特定する

ptex2pdfは、指定したTeXコマンドとdvipdfmxを連続実行するLuaスクリプトであり、テキストエディタで開けば中身を見ることができます。

私はLuaを読んだことすらないため、雰囲気でdvipdfmxが登場する部分を見てみると、

ptex2pdf.lua(ll.426-431)
print("Processing ".. filename)
if (os.execute(tex .. " " .. texopts .. prefilename .. " \"" .. filename .. "\"") == 0) and
   (dvipdf == "" or  (os.execute(dvipdf .. " " .. dvipdfopts .. " \"" .. bname .. ".dvi" .. "\"") == 0)) then
  if dvipdf ~= "" then
    print(bname .. ".pdf generated by " .. dvipdf .. ".")
  end

どうやらbnameなる変数が渡されています。これが"main"でなく"github"になってしまう原因がもっと前にあるはずです。

ptex2pdf.lua(ll.403-405)
    -- if it has already an extension, we need to drop it to get the dvi name
    bname = string.gsub(filename, "^(.*)%.[^.]+$", "%1")
  end

なにやら正規表現で置換しています。コメントによると、「dviのファイル名を得るために拡張子を消す」そうです。

filenameから最後の.以下を削ったため、~/.ghq/github.com/jsk-report-template/ci-thesis/main~/.ghq/githubにされたというのが、今回のバグの元凶でした。

正規表現の修正

拡張子を削るのが目的ならば、パスの途中で.を含むディレクトリがあっても無視しなくてはなりません。
後に/が出てくる.を除外すれば良さそうです。

正規表現の中に謎の%が出てきて一瞬戸惑いましたが、Luaではエスケープに\でなく%を使うと知って納得しました。
\に置き換えれば、regex101などの正規表現テスターが使えます。

regex-ng.png

3つ目のパターンを除外するため、右の[]内にスラッシュを追加しましょう。

regex-ok.png

良さそうなのでptex2pdf.luaを修正します。Luaでは/をエスケープする必要がないらしく、以下のように1文字の追加でOKです。

ptex2pdf.lua(diff)
@@ -399,7 +399,7 @@
     end
   else
     -- if it has already an extension, we need to drop it to get the dvi name
-    bname = string.gsub(filename, "^(.*)%.[^.]+$", "%1")
+    bname = string.gsub(filename, "^(.*)%.[^./]+$", "%1")
   end
   -- filename may contain "/", but the intermediate output is written
   -- in current directory, so we need to drop it

バグ報告・Pull Request

手元では無事ビルドが通るようになりました。

検証中に何度も検索したものの、この問題は報告されていません。
困っている人が少ないとはいえ、想定外の挙動をしているのは確かなのでptex2pdfのGitHubリポジトリにissueを出しました。

この時点で上記の解決手段にたどり着いていたのでプルリクも出したところ、開発者のNorbert Preiningさんがその日のうちにマージしてくださいました。

おわりに

今回のような状況でビルドに困っているという方がもしいれば、ptex2pdf20181212.0にアップデートしてみてください。

先程報告が上がっていないと書きましたが、実はすべてが終わったあと @__pandaman64__さんのこんなツイートを見つけました。

困っていたのは私だけではなかったということで、少し安心ですね(?)

最後になりますが、TeXの日本コミュニティはgithub.com/texjporgで各種リポジトリを公開しています。
私のような部外者であっても、Pull Requestすれば見ていただけると思うので、気づいた点があれば積極的に報告していくと良いと思いました。


明日はmattskalaさんの「TeXLiveからMediaWikiのために最小のインストールは何ですか?」です。