TeX Alchemist Online

TeX のこと,フォントのこと,Mac のこと

相関係数格付けチェックを作る ~目指せ相関係数ソムリエ!~

この記事は TeX & LaTeX Advent Calendar 2023 の18日目の記事です。17日目はYarakashi_Kikohshiさんでした。 19日目は7danmoroboshiさんです。


【目次】

  • 大学入学共通テストの新傾向問題と言えば……!?
  • 検討ポイント
    • 乱数生成アルゴリズムの選択
    • 「指定された相関係数を持つ2つの乱数列」をいかにして生成するか?
      • 定理
      • 証明
    • 注意:生成した乱数列の相関係数は再測定が必要
    • 相関係数格付けチェック問題ランダム生成のアルゴリズム
    • 実装言語
  • 完成品
    • ユーザが指定できるパラメータ
    • 完成PDF・TeXソース

大学入学共通テストの新傾向問題と言えば……!?

旧「大学入試センター試験」が「大学入学共通テスト」に変わってしばらく経ちました。当初予定されていた記述試験導入は見送られましたが,大学入学共通テストになって,旧センター試験には見られなかった癖の強い出題がなされるようになりました。その最たるものが,昨年の大学入学共通テストで話題になった 相関係数格付けチェック です。

※ 原題 → 2022年大学入学共通テスト数学I・A

4択問題のうち,2つの選択肢は平均値などから消去法で消せるのですが,この2択まで絞れてからは,もはや「見た目から勘で選ぶ」しかありません。

共通テスト対策をするには,相関係数ソムリエを目指さねばならないということですね……。

なお,この問題については,Python で画像認識をすることで解くというアプローチもなされています。 vigne-cla.com

TeX & LaTeX Advent Calendar 202311日目には,TeX言語でメルセンヌ・ツイスターが実装されたりと,最近TeX界で乱数が熱いですね!というわけで,TeXエンジンによる疑似乱数生成を利用して, 相関係数格付けチェック対策教材全自動生成することを目指すこととしましょう。

続きを読む

ページ数カウントの活用例:既存PDFの全ページに透かしを入れる

以前,LaTeX文書内から外部PDFファイルのページ数を取得する方法を解説しました。

doratex.hatenablog.jp

その中で,その典型的な用途として,次のように述べました。

LaTeX文書内から,外部PDFファイルのページ数を取得したい状況はよくあります。例えば,「外部PDFファイルの全ページにわたって○○を繰り返す」というような状況のとき,ループ回数を決めるにはそのページ数を取得せねばなりません。

この「外部PDFファイルの全ページにわたって○○を繰り返す」という用途の例として,既存PDFの全ページに透かしを入れたいという状況を考えましょう。

例えば,次のような,複数ページからなる既存のPDF(用紙サイズA4)があったとしましょう。

この文書の全ページの背景に「機密文書」という透かし(ウォーターマーク)を入れたいとします。

用意するもの

コード

(ここでは (u)pLaTeX 用のコードを示しますが,LuaLaTeX 等でもドキュメントクラスだけ変えれば使えます。)

%!uplatex
\documentclass[autodetect-engine,dvipdfmx,a4j]{jsarticle}
\usepackage{countpdfpages}% https://gist.github.com/doraTeX/99366548d6bf8f683328caf09accc74c
\usepackage{bxpgfcurpage}% https://gist.github.com/zr-tex8r/ee0998a76f90338c935ec8915c44d3d8
\usepackage{ifthen}
\usepackage{tikz}
\pagestyle{empty}

\makeatletter
\newcount\forEachPDFPage@count
\long\def\forEachPDFPage#1in#2\do#3{%
  \ifdefined#1\else\newcount#1\fi
  \CountPDFPages{#2}%
  \forEachPDFPage@count=\z@
  \whiledo{\forEachPDFPage@count<\PDFPageCount}{%
    #1=\forEachPDFPage@count
    \advance#1\@ne
    #3%
    \advance\forEachPDFPage@count\@ne
  }%
}
\makeatother

\begin{document}

% 透かしを入れる対象となるPDFのファイル名
\def\target{input.pdf}

% 現在のページ番号を \pageIndex に格納した状態で \target の全ページにわたって処理を繰り返す
\forEachPDFPage \pageIndex in \target \do{%
  \begin{tikzpicture}[remember picture,overlay]
    % 透かしを下に敷く
    \node[font=\sffamily,scale=12,rotate=5,text=pink!80!white,draw=pink!80!white,rectangle,line width=4pt,inner sep=1pt] at (current page.center) {機密文書};
    % その上にページを貼る
    \node at (current page.center) {\includegraphics[page=\the\pageIndex]{\target}};
  \end{tikzpicture}%
  \newpage
}

\end{document}

このLaTeXソースを(u)pLaTeXでコンパイル(2回コンパイルが必要です)すると,次のPDFが生成されます。

このように,ここで定義した \forEachPDFPage は,次のように使います。

\forEachPDFPage \ページカウンタ名 in ファイル名 \do {繰り返し処理}

繰り返し処理 の中では,現在のページ番号をTeXカウンタ \ページカウンタ名 で参照できます(1始まり)。主に,

\includegraphics[page=\the\ページカウンタ名]{ファイル名}

として,「○○ページを挿入」という形で使うことになるでしょう。

上記コードをテンプレートとして使えば,「外部PDFファイルの全ページにわたって○○を繰り返す」という処理に汎用的に応用することができるはずです。

品詞記号出力マクロを設計しよう

この記事は TeX & LaTeX Advent Calendar 2021 の5日目の記事です。4日目は h20y6m さんでした。6日目も自分の記事です。


今回は,英和辞典とか単語帳とかでよく見かける,次のような品詞記号を出力するマクロを設計してみましょう。

f:id:doraTeX:20211205150502p:plain

要は単に「文字を角丸長方形で囲む」だけなのですが,気をつけるべき点が結構あります。

  • okumacro パッケージの \keytop を使う方法
  • TikZ を用いた描画
    • 不満点の解決(その1)~中身が欧文文字の場合~
    • 不満点の解決(その2)~色指定オプションを設ける~
    • 不満点の解決(その3)~周囲の文字サイズに応じて相似拡大されるように~
    • 不満点の解決(その4)~適切な字間空白が入るように~
      • upLaTeX + dvipdfmx + jsarticle.cls の場合
      • LuaLaTeX + jlreq.cls の場合
      • upLaTeX + jlreq.cls の場合
    • 不満点の解決(その5)~upLaTeX + dvipdfmx での縦組対応~
      • upLaTeX + jlreq.cls の場合
  • 完成版
    • LuaLaTeX + jlreq.cls の場合
    • upLaTeX + jlreq.cls の場合
続きを読む

帳票生成ツールとしての LaTeX の活用

f:id:doraTeX:20190119114207p:plain

この記事は TeX & LaTeX Advent Calendar 2020 の5日目の記事です。4日目は wtsnjp さんでした。 6日目は kn1cht さんです。


【追記】 本記事を受けて,ZRさんが key-value型の引数指定をもつユーザ命令を(LaTeXレベルで)定義するための bxkvcmd パッケージ を作成してくださいました!これを使えば,本稿の内容をより容易に実現できます。


【目次】

皆さんは LaTeX を何に使われていますか?

  • レポート作成
  • 論文執筆
  • 書籍執筆/編集
  • 教材/テスト作成

 ⋮

といった用途に使われている方が多いと思います。

他に「一般企業の定型業務で LaTeX を活用する方法」の一例として,様々な帳票処理への活用を考えてみましょう。

差し込み印刷

  • 年賀状
  • 案内文書
  • 領収書・見積書・納品書・請求書・督促状
  • アンケート
  • 試験の受験票

 ⋮

といったものを作成するとき,「定型フォーマットの文面に対して,相手ごとにわずかに異なる内容(氏名・住所・顧客ID・品目・金額・受験会場など)を差し込んだ文書を大量生成したい」という状況がよくあります。いわゆる「差し込み印刷」と呼ばれるものです。それを LaTeX でどうやって実現すればよいか,という疑問をよく耳にしますので,いくつかのアイデアを示しておきましょう。

最も単純なアイデア ~マクロの引数に可変要素を並べる~

TeX ソースの概形

最も単純なアイデアは,個人ごとに異なる可変要素をマクロの引数にするという方法です。概形としては,

\documentclass[dvipdfmx,autodetect-engine]{jsarticle}
\pagestyle{empty}% 全体のページ番号出力を抑制

\newcommand\帳票出力A[引数の数]{%
  %<ここに一人分の出力内容を書く>
  %<個人ごとに異なる部分は #1, #2, ... といった引数を代入>
  %<たとえば「拝啓 #1 #2 様」のように>
  \newpage% ⬅ 一人分が終わるごとに紙を改める
}

\begin{document}

\帳票出力A{保毛田}{保毛彦}{ほげた}{ほげひこ}{東京都千代田区}{赤色}
\帳票出力A{保毛村}{保毛太郎}{ほげむら}{ほげたろう}{北海道札幌市}{青色}
%……<以下これを人数分並べる>……

\end{document}

といった方法になります。

Excel による TeX ソース生成

なお,元データからこの形の TeX ソースを生成するには,たとえば元データを Excel で管理しているのであれば,関数を使って加工・結合すると楽でしょう。

たとえば,元データシートが次のようになっていたとします。

f:id:doraTeX:20201204024912p:plain

出力シートの方で,& を使った文字列結合により,Excel で TeX ソースを生成させます。

f:id:doraTeX:20201204131128p:plain

="\帳票出力A{" & 元データ!A2 & "}{" & 元データ!B2 & "}{" & 元データ!C2 & "}{" & 元データ!D2 & "}{" & 元データ!E2 & "}{" & 元データ!F2 & "}"

としておけば,1行目からオートフィルで2行目以降を埋められます。

(なお,本稿の主旨とはずれますが,一般に Excel においては,「ネ申Excel」化を避けて再利用性・機械可読性を高めるため,生データを入力するシート,データを加工するシート,整形して最終出力を得るシートは分けるようにしましょう。)

引数の数が9個を超えるとき ~ xkeyval パッケージの利用~

単純なケースなら上記の方法でカバーできますが,複雑な帳票になってくると,相手ごとに変更したい可変要素の数が9個を超えてしまいます。TeX においては「マクロの引数は最大9個まで」という仕様となっており,これが壁となります。そういうときは,xkeyval パッケージkey-value リストの機能を使うとよいでしょう。

xkeyval パッケージについては,wtsnjp さんの次の記事にまとめられています。

qiita.com

TeX ソースの概形

xkeyval パッケージはとても高機能ですが,今回の用途では,最も単純な使い方しかしません。全体の概形は以下のようになります。

\documentclass[dvipdfmx,autodetect-engine]{jsarticle}
\usepackage{xkeyval}
\pagestyle{empty}

\makeatletter

%% パラメータとなるキー命令名を一括定義
\define@cmdkeys{帳票パラメータ}[]{姓,名,せい,めい,住所,好きなマフラーの色}

\newcommand\帳票出力B[1]{%
  \begingroup
  \setkeys{帳票パラメータ}{#1}% 与えられたパラメータを各命令に格納
  %<ここに一人分の出力内容を書く>
  %<個人ごとに異なる部分は \姓, \名, ... といった命令を代入>
  %<たとえば「拝啓 \姓 \名 様」のように>
  \endgroup
  \newpage% ⬅ 一人分が終わるごとに紙を改める
}

\makeatother

\begin{document}

\帳票出力B{姓=保毛田,名=保毛彦,せい=ほげた,めい=ほげひこ,住所=東京都千代田区,好きなマフラーの色=赤色}
\帳票出力B{姓=保毛村,名=保毛太郎,せい=ほげむら,めい=ほげたろう,住所=北海道札幌市,好きなマフラーの色=青色}
%……<以下これを人数分並べる>……

\end{document}

しくみ

要になるのは

\define@cmdkeys{帳票パラメータ}[]{姓,名,せい,めい,住所,好きなマフラーの色}

の部分です。ここで,キーとなる項目を一括登録しておきます。(なお,[] の部分は定義される命令名の接頭辞をなくすためです。これがないと,帳票の中からパラメータ値を参照するときに \cmdKV@帳票パラメータ@姓 のような長ったらしい名前で参照する必要が出てきてしまいます。)

次に,\帳票出力B の定義において,引数の数は1つとし,その定義の冒頭に

\setkeys{帳票パラメータ}{#1}%

を仕込んでおきます。そして,\帳票出力B を呼び出す側では

\帳票出力B{姓=保毛田,名=保毛彦,せい=ほげた,めい=ほげひこ,住所=東京都千代田区,好きなマフラーの色=赤色}

という key-value 形式で呼び出します。すると,この key-value の列が #1 として \帳票出力 に渡され,それが展開される過程で

\setkeys{帳票パラメータ}{姓=保毛田,名=保毛彦,せい=ほげた,めい=ほげひこ,住所=東京都千代田区,好きなマフラーの色=赤色}

が実行されることになります。\define@cmdkeys での指定に基づき,これは

\def\姓{保毛田}
\def\名{保毛彦}
\def\せ{ほげた}
\def\め{ほげひこ}
……

と同等の動きをします。すなわち,それ以降で \姓 と打つことにより,「key-value リストに与えられた個人の姓」を参照することができます。(なお,\帳票出力B の定義部で個人ごとの内容を \begingroup ~ \endgroup で囲んでいるのは,1つ前の個人の定義内容が次の人に波及する事故を防ぐためです。)

すると,帳票出力定義部では,

拝啓 \姓 \名 様

日頃よりお世話になっております。お客様の好きなマフラーの色は\好きなマフラーの色 と伺っております。

のように打ち込めばよいことになります。

xkeyval パッケージによる key-value 形式を用いた場合,

  • 「引数9個」の壁を越えられる。
  • 順番を気にする必要がない。
  • パラメータの内容が #1, #2 など番号ではなく \姓\名 といった分かりやすい命令名で参照できるので可読性・メンテナンス性が高い。

といったメリットがあります。ただし,パラメータの内容に半角コンマ , が含まれるときは

好きなマフラーの色={赤色,青色}

のように,ブレースで囲んでおく必要があります。いっそのこと,

\帳票出力B{姓={保毛田},名={保毛彦},せい={ほげた},めい={ほげひこ},住所={東京都千代田区},好きなマフラーの色={赤色,青色}}

のように,パラメータの内容は一律にブレースで囲むようにする,という安全な運用もありでしょう。

Excel による TeX ソース生成

この形の TeX ソースを Excel から生成するには,次のようにするとよいでしょう。

まず,元データが以下のようになっていたとします。

f:id:doraTeX:20201204041217p:plain

これをまず,加工シートにおいて,各パラメータごとに key={value} の形に加工します。(ここでは「パラメータの内容は一律にブレースで囲む」運用でゆくことにします。)

f:id:doraTeX:20201204041342p:plain

A1セルの内容をドラッグでオートフィルすれば,他のセルも一斉に key={value} 形式に加工されます。

次に,出力用シートにおいて,個人ごとに1行の \帳票出力 命令を組み上げます。ここは最新の Office 365 や Excel 2019 で追加された TEXTJOIN 関数を使うと便利です。これは,「複数セルの内容を特定の区切り文字を使って結合してくれる関数」です。

f:id:doraTeX:20201204125039p:plain

A1セルには

="\帳票出力B{" & TEXTJOIN(",",FALSE,加工!A1:加工!F1) & "}"

という関数を仕込んであります。TEXTJOIN(",",FALSE,加工!A1:加工!F1) の部分で,「加工シートのA1からF1のセルの内容を "," 区切りで結合した文字列を得る」という処理をしています。(FALSE は「空のセルを無視しない」という指示です。)このA1セルを下にドラッグしてオートフィルすれば,全データに対する key-value 形式の \帳票出力B のソースが一気に得られます。

別解:見かけ上10個以上の引数をとる命令を定義する

key-value 形式ではなく「マクロ引数に可変要素を並べる」方式のままで,引数10個以上に対応させることはできないか,という質問を受けることがあります。「元々引数は9個以内に収まる前提で帳票出力命令を設計していたが,後から要件定義が変わって,可変要素が10個以上になってしまった,今から大幅な設計変更は大変なので,できるだけこれまでの形を活かせないか」といった場合ですね。 つまり,

\帳票出力A{保毛田}{保毛彦}{ほげた}{ほげひこ}{123-4567}{東京都千代田区}{03(1234)5678}{赤色}{ピッチャー}{右利き}{左投げ}{右打ち}{...}...

と,後から可変要素の種類が次々に増えてきてしまい,マクロ引数が破綻した場合です。key-value 形式に作り直すのが筋が良いとは思いますが,既存ソースや Excel ファイルの構造を極力変えたくないとき,応急処置的にこの形に対応することを考えます。

たとえば引数を12個取りたいとしましょう。最初の9個の引数は #1#9 でとれるので,残り10~12個目の引数を \十個目, \十一個目, \十二個目 でとれればそれでよい,としましょう。その場合,とりあえず9個の引数を取ってマクロに格納しておき,そこからあふれた引数は次に読んでまとめてマクロに格納,最後に帳票出力の本体に入る,という小手先の手法で,一応対応可能ではあります。

\documentclass[dvipdfmx,autodetect-engine]{jsarticle}
\pagestyle{empty}
\makeatletter

%% まずは9個の引数を記憶して次へ回す
\newcommand\帳票出力C[9]{%
  \def\一個目{#1}%
  \def\二個目{#2}%
  \def\三個目{#3}%
  \def\四個目{#4}%
  \def\五個目{#5}%
  \def\六個目{#6}%
  \def\七個目{#7}%
  \def\八個目{#8}%
  \def\九個目{#9}%
  %%% はじめの9個の引数の内容を記憶した上で次の引数群を受け取りにかかる
  \帳票出力C@二グループ目
}

%% 次に10~12番目の引数を受け取って帳票出力の本体を開始させる
\newcommand\帳票出力C@二グループ目[3]{%
  \def\十個目{#1}%
  \def\十一個目{#2}%
  \def\十二個目{#3}%
  %%% 残り3個の引数の内容を記憶した上で帳票出力の本体に入る
  \帳票出力C@本体{\一個目}{\二個目}{\三個目}{\四個目}{\五個目}{\六個目}{\七個目}{\八個目}{\九個目}%
}

%% 個人別帳票の出力の本体部
\newcommand\帳票出力C@本体[9]{%
  %<ここに一人分の出力内容を書く>
  % 1~9番目の引数には #1 ~ #9,\一個目 ~ \九個目 のどちらでもアクセスできるが,残り3つは  \十個目 ~ \十二個目 のマクロを通してしかアクセスできない。
  #1 #2様のポジションは#9,利き手は「\十個目」,投げ方は「\十一個目」ですね。
  \newpage% ⬅ 一人分が終わるごとに紙を改める
}

\makeatother

\begin{document}

%%% 使用者側からはあたかも12個の引数を処理できているように見える
\帳票出力C{保毛田}{保毛彦}{ほげた}{ほげひこ}{123-4567}{東京都千代田区}{03(1234)5678}{赤色}{ピッチャー}{右利き}{左投げ}{右打ち}
%……<以下これを人数分並べる>……

\end{document}

※ 厳密に言えば,元の \帳票出力A と比べて,\帳票出力C#1#9 の内容がマクロ展開で1段階分包まれているという点で等価ではありませんが,最終的に文字列に展開される帳票であれば,その差が問題になるケースは少ないでしょう。どうしてもその差が問題になるケースであれば,expl3 の \cs_generate_variant:Nn\帳票出力C@本体 の引数指定を ooooooooo 指定に差し替えたバリアントを作成する手が考えられます(これを \expandafter chain で直書きするととんでもないことになりそう)。

その他のアイデア

このように,「構造を持ったデータの列」を扱いたい場合,

  • expl3 で property list の sequence を使う
  • LuaTeX で Lua のテーブルを使う

といった,より本格的にデータ構造をきちんと反映させる設計も考えられるでしょう。ただ,そこまでゆくと「プログラミング」感が強くなり,「ちょっとした差し込み印刷をしたい😊」という幸せな LaTeX ユーザからは遠くなってしまいそうです。やはり「Excel を用いて key-value 形式のソースを生成して貼る」というあたりが,単調な事務処理の延長としては最も現実的で幸せなラインではないでしょうか。

既存PDFを下敷きにして上から文字を貼り込む

帳票を一から LaTeX で作成するのではなく,「下敷きとなる既存PDFファイルに上から次々に文字を貼り込みたい」というケースもあります。

たとえば,下敷きとして既に次のようなPDFファイルがあったとします。

f:id:doraTeX:20201205012132p:plain

この「受験番号」「氏名」の欄に個別化された値を流し込みたいとしましょう。

考え方

このとき,考え方としては以下のようになります。

  1. 生成する LaTeX 文書の用紙サイズを,下敷きとなるPDFの用紙サイズを同じに設定する。
  2. 下敷きとなるPDFを,ページ中央にピン留めする感じで貼り込む。
  3. その上から LaTeX で文字を適切な位置に貼り込む。
  4. 2., 3. を改ページしながら人数分繰り返す。

となります。

サンプル

既存PDFを下敷きに,個別化された受験票を生成する具体例を示しましょう。

\documentclass[dvipdfmx,autodetect-engine,a5j,papersize]{jsarticle}
\usepackage{xkeyval}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepackage{bxpgfcurpage}% https://gist.github.com/zr-tex8r/ee0998a76f90338c935ec8915c44d3d8

\pagestyle{empty}

\makeatletter

% 下敷き画像をボックスに保存
\newsavebox\templatebox
\setbox\templatebox=\hbox{\includegraphics[pagebox=mediabox]{template.pdf}}

\define@cmdkeys{受験票パラメータ}[]{受験番号,姓,名}

\newcommand\受験票出力[1]{%
  \begingroup
  \setkeys{受験票パラメータ}{#1}% 与えられたパラメータを各命令に格納
  \begin{tikzpicture}[remember picture,overlay]
    \node at (current page.center) {\usebox\templatebox};% 下敷きPDFをページ中央に貼る
    \node[font=\Large\ttfamily,anchor=west] (受験番号欄) at ($(current page.north west) + (4.4cm,-3.9cm)$) {\受験番号}; %%% 受験番号を貼り込む
    \node[font=\Large,anchor=west] at ($(受験番号欄.north west) + (0cm,-1.75cm)$) {\姓\hspace{1zw}\名}; %%% 氏名を貼り込む
  \end{tikzpicture}
  \endgroup
  \newpage% ⬅ 一人分が終わるごとに紙を改める
}

\makeatother

\begin{document}

\受験票出力{受験番号={0001},姓={保毛田},名={保毛彦}}
\受験票出力{受験番号={0002},姓={保毛村},名={保毛太郎}}
\受験票出力{受験番号={0003},姓={保毛山},名={保毛子}}
\受験票出力{受験番号={0004},姓={保毛杉},名={保毛美}}

\end{document}

解説

全体の構成は,前半で述べた \帳票出力B と同じ,xkeyval パッケージの key-value リストを用いた個別化です。

\documentclass[dvipdfmx,autodetect-engine,a5j,papersize]{jsarticle}

今回,下敷きとなるPDFがA5サイズだったので,出力用紙サイズもA5に設定しています。

\usepackage{tikz}
\usetikzlibrary{calc}

後で下敷き画像の配置,受験番号・氏名の貼り込みに TikZ を使います。

\usepackage{bxpgfcurpage}

今回のサンプルではこの行はなくても問題ありませんが,TikZ の (current page) を使いたいときは ZR さんによる bxpgfcurpage パッケージをロードしておくのが安全です。jsclasses の \mag がかかっていたり,pTeX系エンジンでトンボが出力されていたりしても,(current page) が期待通りに機能するようになります。

(なお,bxpgfcurpage パッケージをロードする前提ならば,bxpgfcurpage パッケージが出力用紙サイズ設定もやってくれるので,jsarticle の papersize オプションはなくても大丈夫です。)

\newsavebox\templatebox
\setbox\templatebox=\hbox{\includegraphics[pagebox=mediabox]{template.pdf}}

各ページごとに毎回同じ画像の \includegraphics を発行すると,ページごとに画像ロードがかかり重くなるので,一度だけ下敷き画像をロードして記憶しておき,それを使い回すことにします。採用するバウンディングボックスはPDFの MediaBox を用いています。適宜 CropBox, TrimBox, BleedBox, ArtBox を使用します。

\define@cmdkeys{受験票パラメータ}[]{受験番号,姓,名}
……
\setkeys{受験票パラメータ}{#1}

前半で述べた \帳票出力B と同じ,xkeyval パッケージの key-value リストを用いた個別化の手法です。以下,\受験番号\姓\名 で各パラメータにアクセスできます。

\begin{tikzpicture}[remember picture,overlay]

これにより TikZ の (current page) が使えるようになります。

\node at (current page.center) {\usebox\templatebox};

台紙となるページ中央に下敷き画像の中央を合わせて貼り込みます(注:正しい位置に来るためにコンパイルが2回必要です)。

f:id:doraTeX:20201205110450p:plain

\node[font=\Large\ttfamily,anchor=west] (受験番号欄) at ($(current page.north west) + (4.4cm,-3.9cm)$) {\受験番号};

ページ左上 (current page.north west) からの相対変位を指定して,受験番号を上から貼り込みます。相対変位の数値は目分量で最適な値を探します。($ ... $) というのは TikZ の calc ライブラリの機能です。

この手法は,帳票出力に限らず,LaTeX で紙面上の絶対位置を指定して文字や図を配置したいというときに広く役立ちます。

f:id:doraTeX:20201205110920p:plain

\受験票出力{受験番号={0001},姓={保毛田},名={保毛彦}}
……

key={value} 形式で個別のパラメータを渡し,受験票本体を1枚ずつ出力します。

完成品

今回作成した個別化受験票生成のサンプルを,Overleaf に置いておきました。

www.overleaf.com

というわけで,一般企業での定型事務作業にも LaTeX は色々役立たせることができるのではないでしょうか。退屈なことは LaTeX にやらせてしまいましょう!

TikZ でベン図をたくさん描いてみよう!

f:id:doraTeX:20191211062518p:plain

この記事は TeX & LaTeX Advent Calendar 2019 の11日目の記事です。10日目は mod_poppo さんでした。 12日目は Mahito TANNO さんです。

今日は TikZ を使ってベン図を描いてみます。

【目次】

2 個のベン図

まずは基本中の基本,2 個の集合のベン図です。

完成図

f:id:doraTeX:20191211035245p:plain

ソース

www.overleaf.com

工夫

  • 色に透明度を使用することで,集合の交叉部分の色が自動的に重ね合わせられます。
  • \ratio で 2 つの集合の噛み合い具合をコントロールできます。
  • 集合名のラベルの \nodefill=white を指定して,背景に白い円を描くことでラベルを見やすくしています。

3 個のベン図

次は 3 個の集合のベン図です。極座標表示を使って,$\theta=90^\circ, 210^\circ, 330^\circ$ の方向に円の中心を配置するとよいでしょう。

完成図

f:id:doraTeX:20191211035726p:plain

ソース

www.overleaf.com

応用例:集合の分配法則の図解

完成図

f:id:doraTeX:20191211041857p:plain

ソース

www.overleaf.com

工夫

  • \usetikzlibrary{patterns} して pattern=north west lines と指定することで,斜線塗りを実現しています。
  • \clip で「切り抜き」を行うことで,中途半端な領域の塗りを実現しています。
  • なお,上記サンプルコードは pdfLaTeX で実行していますが,dvipdfmx を使う場合は注意が必要です。PGFの dvipdfmx 用ドライバは現時点では不具合があり,patterns ライブラリが dvipdfmx で上手く機能しません。これに対してはとりあえずこのパッチが有効です。このパッチを本家 PGF にプルリクエストを出したところマージされましたので,PGFの次期リリース版では修正されていることでしょう。
    【更新】12/21付けでリリースされた PGF v.3.1.5 において修正されました。

4 個のベン図

4 個の円で $ {2^{4} =16} $ 個に分割されたベン図を描くことはできないので,楕円を使って実現します。

完成図

f:id:doraTeX:20191211050328p:plain

工夫

  • 先に楕円を描き,それを \begin{scope}[rotate=...] で回転させています。

ソース

www.overleaf.com

5 個のベン図

Wikipedia (en) によると,楕円 5 つを用いた対称的ベン図は,数学者 Branko Grünbaum によって1975年に考案されたそうです。

完成図

f:id:doraTeX:20191211062518p:plain

ソース

www.overleaf.com

工夫

  • 中心が原点から少しずれた楕円を,原点の周りに 72° ずつ回転させて対称的に生成しています。

一般の n 個のベン図をグレイコードを用いて自動生成する

これ以上集合の数が増えると,ますます複雑さが増して,なかなか手に負えなくなってきます。そこで,グレイコードを用いて,ベン図を機械的に生成しましょう。

グレイコードとは

グレイコード*1とは,隣接する符号間でビットが異なる桁が必ず 1 桁しか存在しない,という性質を持つ符号化法です。たとえば 4-bit グレイコードは次のように並びます。

0000
0001
0011
0010
0110
0111
0101
0100
1100
1101
1111
1110
1010
1011
1001
1000

グレイコードとベン図の関係

上記の 4-bit グレイコードを次のように桁ごとに分解して集合 A~D に割り当てます。また,縦方向を回転角 $\theta$ と見ます。それぞれの角度においてビットが変わった集合の境界線の半径を変えてやる,と考えます。

$ \theta $ A B C D
$ 0 $ 0 0 0 0
$\pi / 8$ 0 0 0 1
$\pi / 4$ 0 0 1 1
$3\pi / 8$ 0 0 1 0
$\pi / 2$ 0 1 1 0
$5\pi / 8$ 0 1 1 1
$3\pi / 4$ 0 1 0 1
$7\pi / 8$ 0 1 0 0
$\pi $ 1 1 0 0
$9\pi / 8$ 1 1 0 1
$5\pi / 4$ 1 1 1 1
$11\pi / 8$ 1 1 1 0
$3\pi / 2$ 1 0 1 0
$13\pi / 8$ 1 0 1 1
$7\pi / 4$ 1 0 0 1
$15\pi / 8$ 1 0 0 0

より詳細は,次の記事において大変詳しく説明されています。本記事でも,下記の記事のアルゴリズムを TeX 言語で実装し,TikZ で可視化することを目指しましょう。

nunuki.hatenablog.com

グレイコードの生成

グレイコードを生成するには,再帰的に生成する方法と,ビット演算で一発で生成する方法とがあります。ビット演算が使える言語であれば,g = v ^ (v >> 1) (右シフトしたものと自身とを XOR)によって,値 v を対応するグレイコード g に変換することができます。

TeX 言語でビット演算

TeX 言語の場合,ビット演算は標準では用意されていません。また,expl3 の関数群にもビット演算はないようです。ですが,TeX Live に収録されている Oberdiek 氏の作品の一つ bitset パッケージ を使えば,ビット演算が可能となります。

たとえば,10進法で表した 11 という値を 4-bit グレイコードに変換したいときは,次のようにして変換できます。

% 10進法での 11 を2進法表示した 1011 をビットセット gray としてセット
\bitsetSetDec{gray}{11}
% gray のコピーを gray2 として定義(⇒ gray = gray2 = 1011)
\bitsetLet{gray2}{gray}
% gray2  を右に1桁ビットシフト(⇒ gray2 = 0101)
\bitsetShiftRight{gray2}{1}
% gray と gray2  を XOR したものを gray として定義(⇒ gray = 1011 ^ 0101 = 1110)
\bitsetXor{gray}{gray2}
% gray を4桁の2進法表示した文字列を \graycode として定義 (\graycode -> 1110)
\edef\graycode{\bitsetGetBin{gray}{4}}

TikZ + グレイコードによるベン図の自動生成結果

各集合の色は,色相環を n 等分することで決定しています。

3 個のベン図

f:id:doraTeX:20191211070931p:plain

4 個のベン図

f:id:doraTeX:20191211071021p:plain

5 個のベン図

f:id:doraTeX:20191211071111p:plain

6 個のベン図

f:id:doraTeX:20191211071344p:plain

7 個のベン図

f:id:doraTeX:20191211071423p:plain

8 個のベン図

f:id:doraTeX:20191211071458p:plain

9 個のベン図

f:id:doraTeX:20191211071558p:plain

10 個のベン図

f:id:doraTeX:20191211071906p:plain

もはやわけが分からなくなってきましたが,込み入っている部分を拡大するとこうなっています。

f:id:doraTeX:20191211071955p:plain

集合の境界線が激しく動いていますね……!

TikZ + グレイコードによるベン図の自動生成ソースコード

一般の n 個の集合からなるベン図を TikZ で自動生成する TeX コードです。\drawVenn{...} の引数をいじることで任意の個数の集合からなるベン図を自動生成できます。

www.overleaf.com

参考:回転対称性を持つ美しいベン図は?

今回はグレイコードを用いてベン図を自動生成しましたが,対称性はなくあまり綺麗なベン図ではありませんでした。ちなみに,回転対称性を持つベン図が描けるのは $n$ が素数の場合に限るのだそうです。$n=7, 11, 13$ の場合の美しい対称的ベン図の構造,および論文へのリンクが,次のページに掲載されています。

webhome.cs.uvic.ca

webhome.cs.uvic.ca

リンク先のページ・論文から,$n=7, 11, 13$ の場合の美しい対称的ベン図を引用しておきます。

7 個の対称的ベン図

11 個の対称的ベン図

13 個の対称的ベン図

*1:グレイコードの「グレイ」は,Frank Gray という人名に由来するので,灰色 (grey/gray) やロックバンド (GLAY) とは無関係です。

Overleaf v2 で日本語を使用する方法

この記事は,過去の記事「Overleaf で日本語を使用する方法」を,新サービス Overleaf v2 仕様にアップデートしたものです。

Overleaf(旧writeLaTeX) は,オンラインで使える LaTeX 原稿執筆環境として非常に便利です。自分のマシン内に TeX 環境を構築するのは一手間二手間かかりますし,インストールする権限がない場合や,出先の端末を使う場合などにも,環境整備の必要なくブラウザのみですぐに LaTeX 原稿を執筆できるのは好都合でしょう。

また,Google Document のような複数人による共同編集機能もあります。複数人で環境を揃えて同時共同執筆を行うことができるのは,クラウドならではのメリットでしょう。

2017年,Overleaf と同様のオンラインLaTeXエディタである ShareLaTeX というサービスが,Overleaf に買収されることが発表されました。そして,それを受けて,昨日,両者の長所を“いいとこ取り”した新サービス Overleaf v2 が公開されました。現時点ではベータ版サービスとなっていますが,旧バージョンと比べて動作も快適,見た目も綺麗になっており,SyncTeX にも対応しているなど,とてもいい感じになっていますので,早速 v2 に移行してしまってもよさそうです。

【目次】

  • Overleaf の用途
  • Overleaf v2 による TikZ 図版の展示例
  • Overleaf v2 で日本語を使用する
    • 手順1:新規文書を作成して文書設定を行う
    • 手順2:latexmkrc を作成する
      • pLaTeX + dvipdfmx を使用する場合
      • upLaTeX + dvipdfmx を使用する場合
  • 和文フォントについて
  • 活用例:日本語の入った TikZ 図版を作成する
    • 手順1:preview パッケージの dvipdfmx 用ドライバを準備
    • 手順2:preview パッケージの使用設定
      • 補足
  • 別の方法1:LuaTeX-ja を利用する
    • 手順1:新規文書を作成して文書設定を行う
    • 手順2: LuaTeX-ja を用いて和文フォント埋め込んだ和文文書を作成するための基本設定を行う
  • 別の方法2:XeLaTeX で日本語を使用する【最もお手軽】

Overleaf の用途

Overleaf は,

  1. 自分の LaTeX 原稿を,自分で環境を構築することなくオンラインで作成する。
  2. 複数の著者で原稿を共同編集する。
  3. ソースとコンパイル結果のセットを閲覧専用で展示する。

といった使い方ができます。自分が愛用しているのは3番の機能(link sharing と呼ばれています)です。「このソースをコンパイルするとこんな結果になりますよ」というのを見やすく示すことができます。

Overleaf v2 による TikZ 図版の展示例

自分はこの機能を,TikZ 図版のソース例を示すのによく用いています。

Overleaf v2 で日本語を使用する

Overleaf v2 は,現時点ではバックグラウンドで TeX Live 2018 が動いています。ということは,(u)pLaTeX や dvipdfmx も入っているわけで,日本語を用いた和文文書も作れるはずです。 ただし,Overleaf は,v2 になっても依然としてデフォルトでは (u)pLaTeX エンジンを使う設定が用意されておりませんので,和文文書を作成するには多少設定が必要です。

公式のヘルプに Overleaf で pTeX を使う方法 の簡単な解説があります。ここではより詳細な手順を解説いたします。

続きを読む

ゴシックのローマ数字にヒゲを付ける

f:id:doraTeX:20161206113714p:plain

この記事は TeX & LaTeX Advent Calendar 2016 の8日目の記事です。 2日目6日目に続く今年3回目のエントリーとなります(スミマセン)。 7日目はaminophenさんでした。 9日目はyuracoさんです。

ローマ数字 Ⅲ はアイアイアイか組文字か

昨年の TeX & LaTeX Advent Calendar 2015 の3日目の記事「今さら人に聞けないローマ数字とその組み方」や『LaTeX2e 美文書作成入門』などで繰り返し言及されているように,LaTeX でローマ数字を組む場合,半角アルファベットを単に並べて,I(アイ),II(アイアイ),III(アイアイアイ),IV(アイブイ),…… のように書くのが正しい組み方です。「Ⅲ」のような全角(組文字)のローマ数字は用いるべきでないとされています。

しかし,本田さんが TeX Q&A 237649355 で述べておられるように,実際の現場では,「組文字のローマ数字(時計文字)でなければ受け入れてもらえない」場面が多々あります。(また,特に縦書きのときには,全角ローマ数字が馴染みます。)

新聞社におけるローマ数字の取り扱いについては,次の朝日新聞の記事が参考になります。

www.asahi.com

どうしても LaTeX で組文字ローマ数字を使いたいなら

従来の pLaTeX では,JIS X 0208 までしか扱えず,組文字ローマ字は「機種依存文字」(環境依存文字)という扱いでしたので,「組文字のローマ数字を出力する」というのは多少厄介な課題でした(otfパッケージを使えば可能)。

それに対し,今時の upLaTeX の場合,Unicode に含まれる Ⅲ (U+2162 ROMAN NUMERAL THREE) のような全角ローマ数字をソース中にそのまま入力すれば,普通に出力できます。ですから,「正しい組み方はどうであるか」という問題はさておき,もし「どうしても組文字のローマ数字を出力したい」というのであれば,それに技術的困難はなくなりました。

ゴシック体のローマ数字にヒゲは付くべきか?

続きを読む

鉄緑会 東大問題集シリーズ 最新刊発売!

先週,鉄緑会 東大問題集シリーズの最新刊が発売となりました。昨年は,11月にこのシリーズに新規科目として物理が加わりました。今年は,物理も含めて4科目が7月に一斉発売の運びとなりました。

2017年度用 鉄緑会東大数学問題集 資料・問題篇/解答篇 2007‐2016

2017年度用 鉄緑会東大数学問題集 資料・問題篇/解答篇 2007‐2016

2017年度用 鉄緑会東大古典問題集 資料・問題篇/解答篇 2007‐2016

2017年度用 鉄緑会東大古典問題集 資料・問題篇/解答篇 2007‐2016

2017年度用 鉄緑会東大化学問題集 資料・問題篇/解答篇 2007‐2016

2017年度用 鉄緑会東大化学問題集 資料・問題篇/解答篇 2007‐2016

2017年度用 鉄緑会東大物理問題集 資料・問題篇/解答篇 2007‐2016

2017年度用 鉄緑会東大物理問題集 資料・問題篇/解答篇 2007‐2016

さて,今年のTeX組版的な注目点としては,物理の章扉を TikZ で全面的に作り直した点が挙げられます。

ページサンプル

f:id:doraTeX:20160712120342p:plain

このページは,Illustrator などのグラフィックソフトは一切使わずに,LaTeX + TikZ のみで作成しています。

続きを読む

和文ゴーストとしての全角スペース

f:id:doraTeX:20160611003733p:plain

全角スペースは,プログラマやDTPerの間ではしばしば嫌われがちな存在です。TeX文書においても例外ではありません。TeXソース中に全角スペースが入り込んでいると思わぬ害をもたらすことが多く,基本的には避けた方がよい存在です。

ですが,TeXにおいて,珍しく全角スペースが大活躍する場面があります。それは(\kern-1zw と組み合わせることによる)和文ゴーストとしての用途です。例えば,ZRさんの BXglyphwiki パッケージ にその用例が見られます。

BXglyphwiki パッケージ を使うと,GlyphWiki に登録されているグリフの字形データをダウンロードして,その画像を1文字の和文文字であるかのように整形して出力してくれます。

このように,「和文1文字として使用するために画像や図形を出力したい」という状況においては,単に「ボックスの幅・高さ・ベースラインを他の和文文字と同じに揃えて出力する」というだけでは不十分です。なぜなら,TeXエンジンによって文字間に自動挿入されるべきグルーの問題があるからです。

(u)pTeX の場合,和文文字と和文文字が隣接した場合には \kanjiskip が,和文文字と欧文文字が隣接した場合には \xkanjiskip が自動挿入されます。しかし,自分で作成したボックスの場合,そのようなグルー挿入がなされないため,「和文1文字としての使用」という意図に反した組版結果が生まれてしまいます。

例えば, を四角で囲んだ ★⃞ という合成文字を作成し,これを和文1文字として出力したい状況を考えましょう。そのために,次のような命令 \squarestar を定義したとします。

【定義】

\def\squarestar{\begingroup
  \fboxsep=0pt
  \fboxrule=.5pt
  \framebox[1zw][c]{}%
  \endgroup}
続きを読む

TikZ の current page と jsclasses との相性問題

日本で主流であろう,(u)pLaTeX + jsclasses + dvipdfmx のワークフローにおいて,TikZ の remember picture を使う際に発生する相性問題について,一つの解決策の提案です。

【追記】
この問題は,現在は bxpgfcurpage パッケージをロードすることで一括解決されるようになりました。

remember picture を dvipdfmx で使うには

TikZ 標準の dvipdfmx ドライバファイルでは,remember picture を用いた図形間結合(inter-picture connections)など,TikZ の一部の機能が使用できません。 しかし,次の記事でZRさんが作成された pxpgfmarkパッケージ を使うと,dvipdfmx でも remember picture を使用することが可能になります。

d.hatena.ne.jp

current page によるページ上の絶対配置

TikZ で remember picture を使うと,current page というノードが使えるようになります。例えば,ページの中央は (current page.center) のようにして取得することができます。

current page は,通常 overlay オプションと一緒に用いられ,「ページの背景に何かを書き込む」という用途に使われます。(正しく座標を取得するために2回コンパイルが必要です。)

使用例1:ページ中央にウォーターマークを入れる

% pLaTeX + pxpgfmark.sty + dvipdfmx
\documentclass[dvipdfmx,papersize]{jsarticle}
\usepackage{tikz}
\usepackage{pxpgfmark}
\usepackage{lipsum}
\begin{document}
\begin{tikzpicture}[remember picture, overlay]
\node[color=red!30!white,draw,line width=10pt,
rectangle,font=\gtfamily,scale=10,rotate=30]
 at (current page.center) {部外秘};
\end{tikzpicture}
\lipsum
\end{document}

f:id:doraTeX:20160322111227p:plain

続きを読む