TeX Alchemist Online

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

共通テスト「情報Ⅰ」対策教材の組版技法

この記事は TeX & LaTeX Advent Calendar 2024 の19日目の記事です。18日目はzr_tex8rさんでした。 20日目はtasusuさんです。


【目次】


3日目に引き続き,共通テスト「情報Ⅰ」対策の話です。 今回,共通テスト「情報Ⅰ」の対策のため,次のような教材を作りました。

この教材を作るときに使った,組版上の技法について,いくつか紹介しておこうと思います。

紙面縁までの塗りを用いた小口見出し(ツメ)

紙面縁のこの部分は,次のようにして生成しています。

  • gentombowパッケージを用いて,デジタルトンボ(PDFのTrimBoxやBleedBox)が入ったPDFを生成する。
  • fancyhdrパッケージを用いて,奇数ページ・偶数ページそれぞれのヘッダまたはフッタとして,これらの飾りを出力する。
  • 塗り足し領域にまではみ出してこれらの飾りを描画する。
  • 飾りの描画は TikZ で行う。
  • TikZ で絶対的なページ座標に基づく描画を行うため,[remember picture, overlay] オプションを利用する。
  • 非10ptの jsarticle クラスのような \mag ありの環境下でも TikZ の (current page) を正しく動作させるために,bxpgfcurpageパッケージを利用する。
  • 章番号を管理しているカウンタの値をもとに,現在の章番号に当たるツメ位置の座標を算出し,そこだけ色を変えて出力する。

ページ番号の10進・2進・16進表記の共存

共通テスト「情報Ⅰ」では,10進 ⇄ 2進 ⇄ 16進 の相互変換が重要なテーマの1つとなります。そこで,全ページのページ番号について,10進・2進・16進それぞれのページ番号を併記しました。これにより,基数変換が面倒なときはページをめくるだけで調べられるというスグレモノ(!?)です。

この基数変換は,前記事でも用いた,expl3 の \int_to_bin:n\int_to_Hex:n を使えば簡単です。LaTeXのページ番号を管理しているカウンタ \c@page の数値をこれらのexpl3関数に投入すれば2進・16進のページ番号が得られるので,それをTikZで所定の位置に描画しています。

グルグル回る柱飾りを描画する

共通テスト「情報Ⅰ」では,「静止画の集まりが動画である」という話が出てきます。誰もがやったことがあるであろう,「教科書の隅に落書きでパラパラ漫画を作る」というやつですね。今回の教材では,読者がパラパラ漫画の落書きを書く手間を減らすため,初めからページヘッダ(柱)にパラパラ漫画を仕込んでおきました。

この「グルグル回る柱飾り」を実現するには,次のようにしています。

まず,ベースとなる次の図形を,TikZを使って描画しておきます。

このような図形の描画は,直交座標で描画してもいいですし,極座標を使うのもよいでしょう。

次に,この図形を,ページ番号 \c@page に呼応した適切な角度だけ回転して,柱に描画します。 ページ隅のパラパラ漫画は,「奇数ページだけ」「偶数ページだけ」でそれぞれパラパラするということに注意すると,次の条件を満たしてほしいところです。

  • 1,3,5,... ページを見たときに,この図形が45度ずつ回転する。
  • 2,4,6,... ページを見たときに,この図形が45度ずつ回転する。
  • 見開きページで位相がπだけずれていた方が綺麗なので,2ページと3ページ,4ページと5ページでは,それぞれ角度が180度ずれて描画されるようにしたい。

つまり,45度の整数倍だけ回転するとしたとき,その整数倍の係数が,ページ番号に対して 0,4,1,5,2,6,3,7,4,0,5,1,6,2,7,3,... と変化してくれると嬉しいわけです。これはつまり, (4 * (n mod 2) + [n/2]) mod 8 という数列です。これを完全展開可能な形で計算するために,次のようにしました。

% #1 を #2 で割った余りを算出(完全展開可能)
\def\modulo#1#2{%
  \numexpr
    \ifnum\numexpr((#1)-((#1)/(#2))*(#2))\relax<0
      ((#1)-((#1)/(#2))*(#2)+(#2))%
    \else
      ((#1)-((#1)/(#2))*(#2))%
    \fi
  \relax
}

% #1 を #2 で割った商(四捨五入ではなく余りを切り捨て)を算出(完全展開可能)
\def\truncdiv#1#2{\numexpr(((#1)-\modulo{#1}{#2})/(#2))\relax}

% 45度の[0,4,1,5,2,6,3,7,4,0,5,1,6,2,7,3,..]倍の回転角を計算
\def\rotationAngle#1{%
  \the\numexpr
  45*(%
    \modulo{%
      \numexpr
        \the\numexpr4*\modulo{#1}{2}\relax
          +%
        \truncdiv{#1}{2}%
      \relax
    }{8}%
    )%
  \relax
}

このように定義しておき,

\edef\angle{\rotationAngle{\c@page}}

とすれば,ページ番号に対して適切な回転角が得られます。これを,TikZの rotate= オプションの値に指定すれば,上記図形を適切な角度で描画し,奇数ページ・偶数ページそれぞれ位相がπだけずれたパラパラ漫画が実現できる,というわけです。

配布用と投影用で出力を分岐する

フラグによって,配布用と,授業でのプロジェクタ投影用の,出力PDFを分けています。それぞれ,次のように仕様が異なります。

配布用

  • 白黒印刷
  • 重要キーワードは各自が埋めるために空欄にする

プロジェクタ投影用

  • フルカラー原稿
  • 重要キーワードは赤文字で埋めてある

これは,

  • 見出しの色
  • ツメの色
  • 重要語句の色

といったそれぞれの色を \definecolor で定義して,カラーセットとして利用しています。そのカラーセットの定義を,クラスファイルのオプションに仕込んだフラグの値によって切り替えることで,配布原稿と投影用原稿の出力を切り分けています。

配布用/投影用PDFの一括生成

何か一箇所修正するたびに,ドキュメントクラスオプションを切り替えて配布用/投影用のPDFをそれぞれ生成するのは面倒なので,両者を一括生成するような Makefile を含むビルドスクリプトを用意してあります。

コラム記事の飾り枠

次のような,余談的なコラム記事を書くためには,tcolorbox を使った飾り枠を出力するパッケージである ascolorboxパッケージを使っています。

共通テスト用プログラム表記の組版

共通テスト「情報Ⅰ」では,Pythonなどの具体的なプログラミング言語は用いず,共通テスト用プログラム表記 という擬似言語を使ってアルゴリズムが表現されます。共通テスト用プログラム表記の仕様書は,大学入試センターのサイトで見られます。

このPDFの18ページ以降に,次のような仕様とコード例が掲載されています(以下,上記PDFより引用)。

大学入試センターの仕様書とサンプル

LaTeXによる再現の試み

上記のような,“和訳版Python”のような独自の擬似言語の組版をLaTeXでどう実現するか,悩みました。コードの論理構造をセマンティックに書いて組版できるLaTeXパッケージを作ろうとかとも考えましたが,あまりに面倒で諦めました。TeXConf 2024 の場でも有識者に相談しましたが,「まあベタ打ちするのが現実的だろう」という話でした。結局,今回の教材作成でも,「cmttパッケージ が提供する \mtt によるタイプライタ体 + Unicodeの罫線素片のベタ打ち」という泥臭い方法で組版を実現しました。

LaTeXソース

\mtt{ (7) hiradi <= migi and owari==0 の間繰り返す:}\par
\mtt{ (8) │ aida=(hidari+migi) $\div$ 2 }\par
\mtt{ (9) │ もし Data[aida]==atai ならば:}\par
\mtt{(10) │ │ 表示する(atai,"は",aida,"番目にありました")}\par
\mtt{(11) │ │ owari=1}\par
\mtt{(12) │ そうでなくもし Data[aida]<atai ならば:}\par
\mtt{(13) │ │ hidari=aida+1}\par
\mtt{(14) │ そうでなければ:}\par
\mtt{(15) └ └ migi=aida-1}\par

出力

エレガントな解決策では全くありませんが,とりあえず大学入試センターの仕様書に近い出力が得られたのでよしとしましょう。