Help us understand the problem. What is going on with this article?

GitHub Actions で Latexmk&タグを使ってコンパイルする TeX ファイルを指定する話

概要

これまで筆者は

に挑戦してきた.

しかし,上に挙げた記事内の方法ではコンパイルが一度しか実行されない.従って,相互参照を含んでいたり BibTeX を利用していたりする場合,生成される PDF ファイルは (??) を含むなど不完全なものとなる.そこで,一度実行すれば自動的に必要なだけコンパイルをやってくれる Latexmk を利用して,この問題を解決する.

また,上に挙げた記事内の方法ではひとつの TeX ファイルのコンパイルにしか対応していなかった.これはコードの中でコンパイルする TeX ファイルを指定していたからである.そこで,コードでファイルを指定するのではなく,Git の機能の一つであるタグを用いてファイルを指定することで,この問題を解決する.

詳細

コンパイルさせたいファイルをタグ名で指定するため,タグ名は必ず ファイル名-ver.x にする.例えば doc1.tex というファイルをコンパイルさせたいなら,タグ名は doc1-ver.1 などとする.

必要ファイルの準備

下記の通り,必要最低限のファイルを用意する.同じものがこのリポジトリにある.

ファイルツリー
.
│  .latexmkrc
│
└─.github
    ├─actions
    │  └─latex
    │          Dockerfile
    │          entrypoint.sh
    │
    └─workflows
            latexmk.yml

.latexmkrc

.latexmkrc は Latexmk 実行時に何1を使ってコンパイルするかを記述したファイルである.

.latexmkrc
$latex  = 'platex -synctex=1 %O %S';
$bibtex = 'pbibtex %O %B';
$dvipdf = 'dvipdfmx %O -o %D %S';

Dockerfile

Dockerfile にはアクション実行時に行われる動作が一通り書かれている.

Dockerfile
FROM ubuntu:latest

RUN apt-get update \
  && apt-get install -y --no-install-recommends \
    curl \
    python3 \
    latexmk \
    lmodern \
    texlive \
    texlive-latex-extra \
    texlive-lang-japanese \
  && rm -rf /var/lib/apt/lists/*

RUN mktexlsr && mkdir -p /app
WORKDIR /app

ADD entrypoint.sh /entrypoint.sh
RUN ["chmod", "+x", "/entrypoint.sh"]
ENTRYPOINT ["/entrypoint.sh"]

entrypoint.sh

entrypoint.shDockerfile の最後で実行されるシェルスクリプトである.Latexmk の実行と,生成された PDF ファイルのリリース実行が書かれている.
3行目の GITHUB_REF には refs/tags/タグ名 という値が代入されているので,最初の10文字を排除して TAG_NAME としている.また,TAG_NAMEファイル名-ver.x という形に決めていたので,4行目では後ろから見て最初のハイフン以降を排除して FILE_NAME としている.

entrypoint.sh
#!/bin/bash
set -eux
TAG_NAME=${GITHUB_REF:10}
FILE_NAME=${TAG_NAME%-*}

# build pdf (change if necessary)
latexmk -pdfdvi $FILE_NAME.tex

# create release
res=`curl -H "Authorization: token $GITHUB_TOKEN" -X POST https://api.github.com/repos/$GITHUB_REPOSITORY/releases \
-d "
{
  \"tag_name\": \"$TAG_NAME\",
  \"target_commitish\": \"$GITHUB_SHA\",
  \"name\": \"$TAG_NAME\",
  \"draft\": false,
  \"prerelease\": false
}"`

# extract release id
rel_id=`echo ${res} | python3 -c 'import json,sys;print(json.load(sys.stdin)["id"])'`

# upload built pdf
curl -H "Authorization: token $GITHUB_TOKEN" -X POST https://uploads.github.com/repos/$GITHUB_REPOSITORY/releases/${rel_id}/assets?name=$FILE_NAME.pdf\
  --header 'Content-Type: application/pdf'\
  --upload-file $FILE_NAME.pdf

latexmk.yml

latexmk.yml にはアクションの場所や実行される条件が記述されている.実行条件は

  • push された中身に TeX ファイルが含まれていること
  • タグ名が *-ver.* の形になっていること

としている.

latexmk.yml
name: LaTeX to PDF (Latexmk)

on:
  push:
    paths: '*.tex'
    tags: '*-ver.*'

jobs:
  build:
    name: Build
    runs-on: ubuntu-latest
    steps:
      - name: Set up Git repository
        uses: actions/checkout@v1
      - name: Build docker image
        uses: denkiuo604/latexmk/.github/actions/latex@master
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

これでアクション実行に必要なファイルは揃う.

いざリリース

コンパイルしたい TeX ファイルを .latexmkrc と同じディレクトリに配置する.このリポジトリでは,例えば次のファイルを用いている.

doc2.tex
\documentclass{jsarticle}
\usepackage{amssymb}

\begin{document}

$(S,\Sigma,\mu)$を測度空間とする.
このとき,相異なる$i,j$に対して$A_i\cap A_j\neq\varnothing$を満たす
任意の$A_1,A_2,\cdots\in\Sigma$に対して
\begin{equation}\label{可算加法性}
    \mu\left(\bigcup_{k=1}^\infty A_k\right)=\sum_{k=1}^\infty\mu(A_k)
\end{equation}
が成り立つ.
また,(\ref{可算加法性})において$A_{n+1}=A_{n+2}=\cdots=\varnothing$とすることで
\begin{equation}\label{有限加法性}
    \mu\left(\bigcup_{k=1}^nA_k\right)=\sum_{k=1}^n\mu(A_k)
\end{equation}
も得られる.

\end{document}

上記 doc2.tex は相互参照を含むため,コンパイルを少なくとも2回実行しなければならない.しかし,Latexmk を使えば必要回数だけ自動でコンパイルしてくれる.

TeX ファイルを配置できたら,タグ名のルールに注意して push すればよい.今の場合,タグ名は doc2-ver.1 などとする.実際の結果は GitHub リポジトリを参照のこと.

参考


  1. platex か latex か,pbibtex か bibtex かなど.ここでは最低限の設定のみしている. 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away