puripuri2100が進捗の報告をするようです

TeX/LaTeXとゆきだるまと虫食い算と……

LuaLaTeXで部誌を作った話

本稿は TeX & LaTeX Advent Calendar 2018 の2日目の記事です。1日目はZRさんでした。3日目はh-kitagawaさんです。

はじめに

私は某K校に通っているのですが、そこで「パズル研究部」なるところに所属して“編集長”という肩書をもらって活動をしています。

さて、そのパズル研究部では毎年9月中旬に行われる文化祭に団体として参加し、部誌を配るということをしています。 勿論、部誌配布以外にも色々とやっているのですがここでは割愛します。

その部誌ですが、今まではWordなどというソフトで作成していたらしいです。ですが、引き継ぎが引き継がれなかったためLuaLaTeXで作成することにしました。

ということで、LuaLaTeXで作成した部誌について少しここで話してみたいと思います。

この部誌作成の特徴は、

  • 複数人から集めた記事とパズル画像をどう管理するか
  • パズル画像を載せる際に必要な「作者」や「難易度」と言った情報をどのように書くのか
  • 来年以降も使い回せるようにどこまで簡略化するのか

といったことに気をつけながら作成していった点です。ですので、ここらへんについて話したいと思います。

LuaLaTeX要素

TeXLaTeX Advent Calendar 2018の重点テーマはは「とにかくLua(La)TeXしよう」ということらしいので少しだけLuaLaTeX要素を。

今回はLuaLaTeXを使用して部誌を作成しました。

LuaLaTeXを使用した理由はいくつかあります。

1つ目はフォントの変更が容易なことです。学校の印刷機輪転機だと、文字がかすれてしまう可能性があったため、小塚Pr6Nを使用することにしました。なので、小塚フォントへの変更が容易なluatexja-presetパッケージを使用するためにもLuaLaTeXを採用しました。

2つ目はPDFを直接出力することです。部誌の内容の関係でTikZやgraphicxパッケージなどを使用することが多く、dviwareのことを考えるのが面倒だっため、LuaLaTeXにしました。

3つ目は、たまたまLuaLaTeXを触り始めて標準のエンジンをLuaLaTeXにしていたからです。これにはとくに深い理由はありません。

大まかな作成の方法と過程

今回は、このような順番で作成しました。

  1. パズルの種類ごとにあるルールと過去の部誌から流用する記事を.texファイルに書く
  2. 部誌を作るのに必要なコマンドを作成する
  3. 例題用のPDFファイルをLaTeXで作成し、貼り付ける
  4. パズル画像が入るであろう部分に仮の画像を入れて実際に作成
  5. パズルを集めてレベル付けと別解チェックをし、流し込む
  6. 最終確認をして印刷・輪転・製本

部誌のデザイン

部誌のデザインは代々続いてきたデザインをある程度踏まえたものにしました。

内容的には、記事部分とパズル部分、解答部分になります。

パズル部分は以下のようになります。

f:id:puripuri2100:20181125101440p:plain
部誌問題

解答部分は基本このようになります。

f:id:puripuri2100:20181125101442p:plain
部誌解答

ltjsarticleクラスに、geometryパッケージを用いることで余白の調節を行いました。

部誌を作るのに必要なコマンドを作成する

画像を配置する際に、一々コマンドを書くのがめんどうだったので作成しました。

\puzzle{〈作者名〉}{〈難易度〉}{〈パズル画像のファイル名〉}というコマンドでパズルを追加できるようにしたいという気持ちだったので実際に作りました。他にも、例題用にも、解答用にも同様なコマンドを追加しました。

中身はかなり単純で、

\newcounter{toi}[syu]
\newcommand{\puzzle}[3]{%
\stepcounter{toi}
\caption{\thetoi \hspace{2\zw} 作/#1\hfill Lv.#2  }
\includegraphics[clip,width=\figurewidth]{#3}
}

という風に、\caption\includegraphicsを肩代わりさせるだけのものです。なので、実際に使う際には

\begin{figure}[ht]
 \centering
  \begin{minipage}{0.4\hsize}
  \centering
  \puzzle{ぷりにゃん}{2}{nurikabe/puri-3-toi}
  \end{minipage}
  \begin{minipage}{0.4\hsize}
  \centering
  \puzzle{ぷりにゃん}{2}{nurikabe/puri-1-toi}
  \end{minipage}
\end{figure}
\vspace{-2\zw}
\begin{figure}[ht]
 \centering
  \begin{minipage}{0.4\hsize}
  \centering
  \puzzle{ぷりにゃん}{2}{nurikabe/puri-1-toi}
  \end{minipage}
  \begin{minipage}{0.4\hsize}
  \centering
  \puzzle{ぷりにゃん}{2}{nurikabe/puri-2-toi}
  \end{minipage}
\end{figure}

のようにしなければならず、かなりわかりにくいものになってしまいました。 ただ、コマンドをある程度省略できたことは大きかったです。

例題用のPDFファイルをLaTeXで作成する

パズルというものはルールだけ読んでもわかりにくいものも多いため、我が部の部誌では例題を付けるようにしています(定石を入れておくという意味もあったり……)。

ところが、この例題の画像も引き継がれなかったため、LaTeXで作成することにしました。

描く方法はもちろんTikZです。

今回の部誌に乗るパズルは以下のようになっていました。

この内、虫食い算はmusikuiパッケージを使えば作成できるので考えませんでした。

さて、残りのパズルのうちイラストロジックだけ数字を枠の外に並べていくという特異な点があるものの、概ね似たような構造になっていたのでパッケージ化して楽に作成してしまうことにしました。そのパッケージは一応ここに上げておきます。

さて、パッケージ化にあたってはある程度パズルの描画方法を一般化しておかないと使い回せませんのでしていきます。 説明の都合上、上に上がっているパズルのうち虫食い算を除いたパズルについてのみ話します。

  1. このパズルは正方形をしていて、その中が碁盤の目のように区切られています。ただし、このとき区切られ方は様々で、線の種類も様々です。また、区切られている数も異なります。

  2. これらの内の大半では直線が引かれます。ただし、その直線の引かれ方にも種類があり、区画の中央を通っていくものと区画と区画の境目を通っていくものの2通りになります。

  3. これらにはだいたい数字や黒丸などが書かれます。これらは区画の中央に配置されます。この内、数字については時折白文字にする必要があります。

  4. 黒塗りのマスです。これは三角形もしくは四角形の集合体です。

これらを一気に実現するには座標による直接的な指定が一番良いでしょう。

ということでこのようにして要素を指定してくことにしました

  • 盤面は固定なので、各パズルごとに設定する
  • 線は、始点と終点の座標を指定させて引く
  • 数字は、\nodeコマンド等を使用して直接置く
  • 四角形の黒塗りのマスは、長方形を書く要領で座標を2つ指定して描画する
  • 三角形の黒塗りのマスは、三点指定する

あとは頑張って座標を指定していくだけです。

この作業は死ぬほど疲れました。

パズルの回収と保管

我が部では連絡をLINEで行い、実際に作ったパズルも各自作成したアルバムに入れるという方法を取っていました。

また、アルバムに入っている写真も、ノートに書いたパズルを写真で撮っただけのものから、きちんと画像化してあるものまでバラバラでした。

ここで全員にGitをインストールさせて進捗を作るという手もあったのですが、流石にみんな対応してくれないだろうということで自分が頑張ることにしました。

  1. アルバムからパズルの画像をダウンロードする
  2. もし、そのパズルの画像が、きちんとしたものになっていなかったならばぱずぷれを使って画像化してダウンロードする
  3. ダウンロードする際に、〈作成者名〉-〈そのパズルの中で、何個目のものなのか〉-〈問もしくは解〉という命名法で名前をつけて保存
  4. 保存先は、それぞれのパズルの種類ごとに作成したフォルダ
  5. GitLabに予め作成してあったリポジトリにpush
  6. アルバムに更新があったら同じことをする

以上の繰り返しです。これを3ヶ月間くらい行いました。

パズル画像が入るであろう部分に仮の画像を入れて実際に作成

パズルがすべて提出されるのを待っていたらいつまで経っても作成できないので、仮置き用の画像を使って作成しておいてあとでファイル名を変更していく方法を取りました。その仮置き用の画像がこれです。

仮置き画像

パズルを集めて別解チェックとレベル付けをし、流し込む

いくら金を取らないものであったとしても、解が複数個あるものやそもそもとして成立しないものを配布するのは良くないことなので対策をします。また、初心者がいきなり難しい問題を解こうとすると地獄なので、難易度もつけておかないといけません。

まずは別解チェックです。 これは単純に問題を解くだけです。しかし、適当に解くと別解を潰せないのでしっかりとやります。具体的には、「必ず埋められるところは埋めていき、2通り以上の可能性がある場合はその可能性を全て試して潰していく」という方法を取ります。 かなり辛いです。前に15進法の虫食い算の別解チェックをした際には5個くらいの別解が出てしまい、紙が8枚ほど溶けました。

このとき、別解が出てしまったら作成者に連絡して修正してもらいます。大概の場合は条件を少し増やすだけで乗り切れますが、それでも無理な場合は諦めます。と言う前のことですが、修正後のパズルも、もう一度最初から別解チェックをします。

別解が無いことを確認できたら難易度をつけます。4段階ですが、あまり明確な基準はありません。解かないと難易度はわからないので別解チェックをした人がレベル付けを担当します。

ちなみに人によって解けるパズルと解けないパズルがあるのでこれをうまく割り振って回収する必要があります。この作業がかなり辛く、何日か消えました。

最終確認をして印刷・輪転・製本

出来上がったPDFファイルを印刷して部の人に見てもらい、誤字脱字等を直してもらいました。「このパズル入れられないの~?」とか言った要望を急に言われたりしましたが、なんとか乗り切り輪転と製本に入ることができました。

輪転は学校の輪転機を数日間占領して行いました。その結果、毎年恒例だったらしい「文化祭準備中の輪転」を回避することができました(前日の朝に少しだけ輪転してしまったので前日輪転回避とはなりませんでしたが……)。

自分は他の団体での活動があったので製本はあまり手伝えなかったのですが、ページ数が増えたのでかなり辛い作業になっていたようです。ですが、今までより時間的余裕があったことから製本を文化祭前日に全て終わらすことができ、これもまた伝統となっていた「当日製本」を回避することにせいこうしました。

ファイル構造

その結果ファイル関係は以下のようになりました。

│  nipori.sty
│  nipori15.pdf
│  nipori15.tex
│  titlepage.tex
│
├─bijutukan
│      bijutukan-kaitou.tex
│      bijutukan.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
├─heyawake
│      heyawake-kaitou.tex
│      heyawake.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
├─iraroji
│      iraroji-kaitou.tex
│      iraroji.sty
│      iraroji.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
├─LITS
│      LITS-kaitou.tex
│      LITS.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
├─masyu
│      masyu-kaitou.tex
│      masyu.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
├─musikuizan
│      musikuizan-kaitou.tex
│      musikuizan.tex
│      demo.jpeg
│      puri-1-kai.pdf
│      puri-1-kai.tex
│      puri-1-toi.pdf
│      puri-1-toi.tex
│
├─norinori
│      norinori-kaitou.tex
│      norinori.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
├─nurikabe
│      nurikabe-kaitou.tex
│      nurikabe.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
│
├─sikakunikire
│      sikakunikire-kaitou.tex
│      sikakunikire.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
├─sudoku
│      sudoku-kaitou.tex
│      sudoku.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
├─suririn
│      suririn-kaitou.tex
│      suririn.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
├─syakasyaka
│      syakasyaka-kaitou.tex
│      syakasyaka.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
├─yajirin
│      yajirin-kaitou.tex
│      yajirin.tex
│      demo.jpeg
│      puri-1-kai.jpg
│      puri-1-toi.jpg
│      .
│      .
│      .
│
├─kaitou
│      kabe-kaitou.tex
│      kabe-toi.tex
│      kabe1.indd
│      kabe1.pdf
│      kaitou.tex
│
├─rei
│      demo-puzzle.sty
│      bijutukan1.pdf
│      bijutukan1.tex
│      bijutukan2.pdf
│      bijutukan2.tex
│      bijutukan3.pdf
│      bijutukan3.tex
│      bijutukan4.pdf
│      bijutukan4.tex
│      heyawake1.pdf
│      heyawake1.tex
│      heyawake2.pdf
│      .
│      .
│      .

ファイル関係の構成に関しては失敗したと思っています。

ファイルの読み込みは

nipori15.tex <- bijutukan.tex <- bijutukan1.pdf
                              <- bijutukan2.pdf
                              <- bijutukan3.pdf
                              <- bijutukan4.pdf
                              <- puripuri-1-toi.png

             <- heyawake.tex <- heyawake1.pdf
                             .
                             .
                             .

             .
             .
             .

             <- kaitou.tex <- bijutukan-kaitou.tex <- puripuri-1-kai.png
                                                   .
                                                   .
                                                   .

                           <- heyawake-kaitou.tex
                           .
                           .
                           .

という風になっており、かなり複雑になってしまいました。

課題

例題作成等はうまく行った思っていますが、パズルの配置とファイル関係に関しては改善の余地があると考えています。

パズルの配置に関しては、もっとコマンドを省略できるはずです。しかし、提出されるパズルの中には通常の2倍のサイズのものや、4倍のサイズのものもあるので、そこの例外をどう処理すればよいのか少し悩んでいます。

ファイル関係に関しては、流石にファイルを分割しすぎたと思っています。もっとファイルを纏めても問題ないような気がします。

何にせよ、自分が卒業したあとも後輩が問題なく部誌を作り続けられるような仕組みを今のうちに作っておきたいものです。

さいごに

いろいろと苦労しましたが部誌ができて良かったです。どうせ来年も編集長をやるので好き勝手やりたいと思っていますが、その後に後輩に引き継いでいくことを考えるとわかりやすいファイル構造や、ドキュメント作成等を考えなければなと思っています。

commit数は以下のようになっていました。

f:id:puripuri2100:20181125101444p:plain
commit数