マクロツイーター

はてダから移行した記事の表示が崩れてますが、そのうちに直せればいいのに(えっ)

TeXのプリミティブで展開可能なやつ(1)

まとめてみた。

注意事項

  • 多くのプリミティブは展開結果が必ず\the-文字列になる。そうでないものについて注意のため印を付けている。
    • 無印:(状態変化無しで)展開結果が必ず\the-文字列になる。
    • ★印:(状態変化無しで)展開結果が\the-文字列以外になりえる。
    • ☆印:展開に付随して内部状態が変化し、展開結果が必ず空になる。
    • ◇印:展開に付随して内部状態が変化し、展開結果が非空になりえる。
  • 各項目の説明には「そのプリミティブの一回展開結果のトークン列が何か」を記した。ただし☆・◇印のものは“動作”を記した。
  • 展開結果の記述に関する注意:
    • 展開結果が“文字列”として述べられている場合、それは実際には\the-文字列*1を指す。
    • 数値・寸法・グルー値を\the-文字列として表す場合の書式は「そのデータ型のパラメタを\theで出力する場合」と同じである。※例えば寸法値10ptは10.0ptという\the-文字列で表される。
  • 引数の記述に関する注意:
    • 角括弧 [ ] は省略可能であることを示す。角括弧自体は入力しない。
    • 引数が“文字列”として述べられている場合、それは「与えられたトークン列を完全展開して脱トークン化した結果の文字列」が使われることを示す。
    • 引数に現れる“フォント”は「fontdefトークン」「\font」「\textfont‹整数›」「\scriptfont‹整数›」「\scriptscriptfont‹整数›」の何れか*2を指す。

元祖TeXのやつ

  • “条件トークン”☆:TeXの内部の「条件判断に関する内部状態」を変化させる。

    • “条件トークン”とは「if-トークン」「\else」「\or」「\fi」を指す。元祖TeXがもつif-トークンは以下の通り:
      • \if‹トークン1›‹トークン2›
      • \ifcase‹整数›
      • \ifcat‹トークン1›‹トークン2›
      • \ifdim‹寸法比較›
      • \ifeof‹整数:ストリーム番号›
      • \iffalse
      • \ifhbox‹整数:ボックス番号›
      • \ifhmode
      • \ifinner
      • \ifmmode
      • \ifnum‹整数比較›
      • \ifodd‹整数›
      • \iftrue
      • \ifvbox‹整数:ボックス番号›
      • \ifvmode
      • \ifvoid‹整数:ボックス番号›
      • \ifx‹トークン1›‹トークン2›
    • 詳細は以下の記事を参照。
  • “マーク変数” ★:現在の状況で(各々のマーク変数の機能に即して)該当するマークのトークン列。

    • ここで“マーク変数”は以下のものを指す:
      • \botmark
      • \firstmark
      • \splitbotmark
      • \splitfirstmark
      • \topmark
  • \csname‹トークン列›\endcsname ◇:「‹トークン列›を完全展開して得られる文字トークン列を脱トークン化した文字列を名前とする制御綴」のトークンに展開される。

    • 当該の制御綴が未定義の場合は、「その制御綴がローカルに\relaxに等値される」という副作用をもつ。
    • 完全展開の結果に制御綴が含まれる場合はエラーになる。
    • \endcsname自体は展開不能である。
  • \endinput ☆:現在のファイルからの読込を「既に読んだ行」までで停止する。

  • \expandafter‹トークン1›‹トークン2›… ★:‹トークン1›の後に「‹トークン2›以降のトークン列を一回展開した結果」を続けたトークン列。

  • \fontname‹フォント›:そのフォントの定義を表す文字列。

    • 書式は「‹TFM名› at ‹寸法:使用サイズ›」だが、使用サイズがデザインサイズに等しい場合は「‹TFM名›」のみになる。
  • \input‹ファイル名› ☆:以降は指定のファイルから入力を読むようになる。

    • 引数の‹ファイル名›は空白トークン(これは吸収される)または展開不能の制御綴で終結する。引数が終結するまで完全展開が起こる。
    • ただし最近の処理系だと文字列をクオートする("…"で囲う)ことで「空白を含むファイル名」を引数にとれる(参照)
    • もっと最近の処理系だと\input{‹ファイル名›}のように引数を波括弧で囲う書式も可能である。この場合は「引数のトークン列を完全展開した結果(制御綴を含んでもよい)を脱トークン化した文字列」がファイル名として用いられる。
  • \jobname:ジョブ名の文字列。

    • 「ジョブ名」はコマンドオプションの-jobnameの値。既定値はシステム依存だが、多くの場合は「最初に読んだファイルのベース名」になる。
  • \meaning‹トークン›:そのトークンの意味を説明した文字列。

    • 例えば、\meaning$は「math shift character $」、\meaning\quadは「macro:->\hskip 1em\relax」に展開される。
  • \noexpand‹トークン› ★:引数のトークンを展開不能にしたトークン。

    • 通常は展開限定文脈において「引数のトークン自身に展開されそれ以上展開されない」という挙動のために用いられる。
    • 引数のトークンが元々展開不能だった場合は単純にそれ自身になる。展開可能だった場合は「一時的に意味を\relaxに置き換えた」トークン(なので、展開限定文脈外においてそれが実行されたとしても何も起こらない)になる。厳密な仕様は結構ヤヤコシイ。
  • \number‹整数›:その整数の(典型の)十進表記の文字列。

  • \romannumeral‹整数›:その整数の小文字ローマ数字表記の文字列。ゼロ以下の場合は空になる。

  • \string‹トークン›トークンが文字トークンの場合は、その文字。制御綴の場合はそれを文字列化したもの(後続の空白は無し)。

    • 「制御綴の文字列化」は、制御綴名の前に\escapecharの文字を前置した形の文字列。ただし\escapecharが(欧文)文字コードの範囲外の値の場合は何も前置されない。
  • \the‹内部値›:その内部値(レジスタ・パラメタ)の現在の値を表すトークン列。普通は\the-文字列であるが、以下の場合は例外となる:

    • \the‹トークン列レジスタ・パラメタ› ★:そのレジスタ・パラメタが現在保持するトークン列そのもの。※展開限定文脈である場合はそれ以上展開されない。
    • \the‹フォント› ★:そのフォントを選択するためのfontdefトークン。
      • ここで生じるトークンの“外形”については少しヤヤコシイことになっている。

e-TeXのやつ

  • e-TeX拡張のif-トークン ☆:

    • \ifdefined‹トークン›
    • \ifcsname‹トークン列›\endcsname
      \csnameと異なり“\relax化”の副作用を決して起こさない。
    • \iffontchar‹フォント›‹整数:文字コード›
  • e-TeX拡張の“マーク変数”★:

    • \botmarks‹整数:マーク番号›
    • \firstmarks‹整数:マーク番号›
    • \splitbotmarks‹整数:マーク番号›
    • \splitfirstmarks‹整数:マーク番号›
    • \topmarks‹整数:マーク番号›
  • \detokenize{‹トークン列›}:引数のトークン列を(展開せずに)脱トークン化した結果の文字列。

    • 結果は\the-文字列であることに注意。実質的に「(字句解析前の)文字列に戻す」働きをもつのは\scantokensの方である。
  • \eTeXrevision:e-TeXのリビジョン番号の文字列。

    • なお\eTeXversionは読取専用整数パラメタである。
  • \scantokens{‹トークン列›} ☆:「引数のトークン列を(展開せずに)脱トークン化した結果の文字列」を内容とする仮想的な入力ファイルを作って、以降はこの仮想的なファイルから読み込むようにする。

  • \unexpanded{‹トークン列›} ★:引数のトークン列自身。※展開限定文脈である場合はそれ以上展開されない。

    • 展開限定文脈以外では普通に展開される。\the‹トークン列レジスタ・パラメタ›の展開と同じ規則である。
  • \unless‹ifトークン›… ☆:後続の条件部の真偽を反転させた条件文を開始する。

    • \unlessの直後に真偽型のif-トークンそのものが続く必要がある。条件部を含めて一回で展開されることに注意。

(続く)

*1:「\the-文字列」は「TeXの文字トークン列によって文字列を表現する」際の規約で、ASCII空白(文字コード32)についてはカテゴリコード10、それ以外の文字についてはカテゴリコード12の文字トークンを用いる。

*2:\textfont・\scriptfont・\scriptscriptfontの引数の整数は数式ファミリ番号を指す。

\index 命令中の”\”の機能がヤヤコシイ話

LaTeXでMakeIndex(mendexやupmendexも含む)を利用して索引を作る場合の、\index命令中の「エスケープ処理」について。具体的には、quote(")とescape(\)の違いについて。

※実はMakeIndexは「LaTeX専用」でも「TeX専用」でもないのであるが、ここではLaTeXとの併用を前提とする。

\index にイロイロ書ける件

\index命令の「実際のテキスト」の部分(@の右側に相当する部分)には「索引中でその項目を実際に出力するためのLaTeXコード」を書く。このLaTeXコードはその場では実行されず、コードの文字列が.idxファイル(MakeIndexの入力)を経由して.indファイル(同じく出力)にそのまま書き出されて、それがLaTeXで読み込まれる際に実行されることになる。従って、\verbなどの「呪われた命令」を書くこともできる。

\index{%@\verb+%+ (comment)}

※つまり、\index命令の引数はverbatimなものとして解釈されている。なので、引数中に「呪われた命令」を書ける代わりに、\index自体が「呪われた命令」になってしまう。この辺りの「実際の仕様」については以下の記事を参照されたい。

\index でquoteする件

ただし、\indexの引数の書式では、幾つかの文字に特別な意味を持たせている。例えば、@は「『キー』と『実際のテキスト』の区切り文字」であり、!は「階層の区切り文字」として使われる。従って、「実際のテキスト」の内容にこれらの文字を含めたい場合は“エスケープ”をする必要がある。もちろん、これはMakeIndexのレベルのもので、LaTeXにおけるエスケープとは別物である。(LaTeXエスケープ文字\は寧ろそのまま出力されてほしい。)MakeIndex(の既定)では、“エスケープ”の役割を"に割り当てていて、これを“quote”と呼んでいる。

例えば、MakeIndexの特殊文字である!を「実際のテキスト」(および「キー」)に書くには、これをquoteして"!と書く必要がある。

% ! を " でquoteした
\index{Happy TeXing"!@Happy {\TeX}ing"!}
%→"実際のテキスト"は Happy {\TeX}ing!

※quoteを付けた文字列は.idxにはそのまま書き出される。.idxを読み込み“引数を解析する”際に「quoteの解釈」が行われる。

注意として、MakeIndexの処理においては原則的に(La)TeXの文法は考慮されない。(前述の通り、そもそもMakeIndexは(La)TeX専用ではない。)従って、例えば\verbが絡む場合でも「MakeIndexの特殊文字をquoteする("を前置する)」という規則は変わらない。

% ! を " でquoteした
\index{"!@\verb+"!+ (level operator)}
%→"実際のテキスト"は \verb+!+

% もし \verb の区切りを | にしたい場合は,
% | も特殊文字なのでquoteする必要がある.
\index{"!@\verb"|"!"| (level operator)}
%→"実際のテキスト"は \verb|!|

quoteをquoteする件

"がquoteに使われるということは、"自身もMakeIndexの特殊文字の一種ということになる。もし"を「実際のテキスト」に含みたい場合は""と書く必要がある。

% " を " でquoteした
\index{""@\verb+""+ (quote)}
%→"実際のテキスト"は \verb+"+

\index で“\”も特殊な件

これまでの話から考えると、(La)TeXエスケープ文字である\はMakeIndexにおいては特殊文字ではないように思える。事実、\!を「実際のテキスト」に書いた場合、!エスケープされることなく「階層の区切り文字」として働く。

% 失敗: ! で階層が分けられるので不正な入力になる
\index{\!@\verb+\!+ (negative thin space)}

ところが実は\もMakeIndexの特殊文字なのである。実際、MakeIndexの索引スタイルの中には“escape”という項目がありこれの既定値が\になっている。(恐らくLaTeX以外でMakeIndexを使う場合は別の文字を指定するのであろう。)といってもMakeIndexで\(つまりescape)が特殊な働きをする場面は限られていて、それは\"という文字列の扱いである。

\index{Godel@G\"odel}

この例では「実際のテキスト」の中でLaTeXのアクセント命令\"を使おうとしている。一見すると、"はquote文字であるためoを(無意味に)quoteするのに使われてしまって、結果的にG\odelと解釈されてしまうように思える。しかし実はMakeIndexでは「quoteはescapeでエスケープされる」ということになっているのである((\"命令を使うために\""oと書く必要が生じるのをMakeIndexの作者が嫌ったらしい。TeX Liveに含まれるind.pdfという文書にその旨が書かれている。))。従って、先ほどの例はこのままで正しい。

% \" の " はquoteにならない
\index{Godel@G\"odel}
%→"実際のテキスト"は G\"odel

\index の規則がさらにややこしくなる件

ただこのように\を特殊扱いしたせいで、MakeIndexの規則が不用意に複雑になっている感じもする。例えば以前に出した\!を書く例を考える。単純にquoteだけ考えると、!"!に変えればよさそうに見える。

% 実はこれでもダメ: " はquoteにならない
\index{\"!@\verb+\"!+ (negative thin space)}

ところがこれだと\"という形になっているため、"がquoteにならないのである。正しい解決策は何かというと、\の特殊性を消すために\"でquoteすればよい。

% \ と ! の両方をquoteした
\index{"\"!@\verb+"\"!+ (negative thin space)}
%→"実際のテキスト"は \verb+\"+

本の種類によっては、索引のテキストでLaTeX命令を多用することもあるだろうから、\に注意を払わないといけないのは少し不便であると感じる。

escapeをescapeする件

LaTeXの規則で、\"はアクセント命令であるが、その前にさらに\がある場合は\\が命令になるため\"の部分は命令にならない。これに合わせる形で、MakeIndexの規則でも「escapeはescapeでエスケープされる」、つまり\\は(結果的に)通常の文字の\\と解釈される。

% \\ の \ はescapeにならない
\index{bogus@bo\\"!gus}
%→"実際のテキスト"は bo\\!gus

波括弧をescapeする件

MakeIndexの入力において波括弧({})は特に特殊な役割をもつわけではないが、「{}は均衡する必要がある」ことになっている。LaTeX文書中の\index命令では「均衡していないとそもそも\indexの引数が正しく読み取れない」ので当然であるが、.idxファイルの入力でも同じ規則が適用される。

自分が調べた限りだと、前にescapeのついた\{\}については「波括弧の均衡の判定」からは除外されるようである。従って、この場合もescapeは特殊な役割をもつことになる。

% \{ の波括弧は気にしない
\index{\{@$\{$ (left brace)}
%→"実際のテキスト"は $\{$

※ただしMakeIndexのマニュアル(makeindex.pdf、日付が1987年であり古い)では逆に「例外にならない」と書いてある。どこかの時点で仕様が変わったのかもしれない。

なお、\verb絡みで単独の(\のない){を入力に含めようとして"{と書くと、\index命令の引数の読取が失敗してしまう。(\index命令は波括弧はverbatim扱いしないので。)

% 失敗: \index が実行できない
\index{"{@\verb+"{+ (left brace)}

これについては簡単な解決策はないので「単独の{」は避けるしかなさそうである。それにしても、「実際のテキスト」では諸々の回避策をとれても、「キー」の部分では対処は極めて難しいように思う。

.idxファイルの入力としては「quoteされた単独の{」を含む形は許される。そのため、「ビルドのワークフローの中で.idxアドホックに書き換える」という手段で一応解決できる。

% .idxファイルの中でこの行はOK
\indexentry{"{@\verb+"{+ (left brace)}{8}   
%→"実際のテキスト"は \verb+{+

まとめ

f:id:zrbabbler:20210504102004p:plain

某ZR流パラメタトークン思考法

課題

次のTeXコードを実行したときのTeXの動作を、字句解析を中心にして述べよ。

LaTeXフォーマットで\makeatletterの状態のカテゴリコードを仮定する。

\toks@{\def\xx@#1}\the\toks@{!#1}

某ZR氏の解答

表記

  • 制御綴のトークンを“[def]”等で表す。
  • 文字トークンを“‹A›₁₁”等で表す。
  • パラメタトークンを“①”等で表す。

動作の解説

  • \toks@を読み [toks@] と解釈する。\toks@(0番のtoksレジスタ)に対する代入文を開始する。
  • {を読み ‹{›₁ と解釈する。これ以降は代入すべきトークン列の内容であり、展開抑止の状態に入る。
  • \def\xx@#1を読み、[def] [xx@] ‹#›₆ ‹1›₁₂ と解釈する。
  • }を読み ‹}›₂ と解釈する。代入すべきトークン列が確定し、展開抑止が終わる。\tokS@に“[def] [xx@] ‹#›₆ ‹1›₁₂”が代入される。
  • \theを読み、[the] と解釈する。プリミティブ\theの引数を待つ状態になる。
  • \toks@を読み [toks@] と解釈する。\theの展開を行う。\theプリミティブの引数がtoksレジスタなので、そのレジスタの内容の“[def] [xx@] ‹#›₆ ‹1›₁₂”をバッファに吐き出し、以降はここからトークンを読み出す。
  • [def] を読む。\def文を開始し、展開抑止の状態に入る。以降に続く「代入先トークン」「パラメタテキスト」「置換テキスト」を待つ。
  • [xx@] を読む。これが「代入先トークン」である。
  • ‹#›₆ ‹1›₁₂ を読む。パラメタテキストの読取の途中に“‹#›₆ ‹1›₁₂”が現れたので、パラメタトークン“①”に置き換える。
  • (バッファのトークンが尽きたので再びソース文字列から読む。)
  • {を読み ‹{›₁ と解釈する。ここでパラメタテキストが終わり、“①”と確定する。
  • !#1を読み、‹!›₁₂ ‹#›₆ ‹1›₁₂ と解釈する。置換テキストの読取の途中に“‹#›₆ ‹1›₁₂”が現れたので、パラメタトークン“①”に置き換える。
  • }を読み ‹}›₂ と解釈する。ここで置換テキストが終わり、“‹!›₁₂ ①”と確定する。
  • すなわち、以下の引数を以て、\def文が実行される。展開抑止が終わる。`
    • 代入先=[xx@]
    • パラメタテキスト=①
    • 置換テキスト=‹!›₁₂ ①

補足

つまり、某ZRのモデルでは、パラメタトークン(① など)は「パラメタテキスト」や「置換テキスト」のトークン列の内容には現れるが、入力バッファの中には決して現れない。

もしこの後、\xx@?を実行したとすると、[xx@] ‹?›₁₂ の展開結果として、置換テキストの ① を ‹?›₁₂ に置き換えたトークン列である“‹!›₁₂ ‹?›₁₂”がバッファに吐き出される。この場合もパラメタトークン自体はバッファには現れない。

2021年のパズル年賀状

今年の年賀状。

f:id:zrbabbler:20210101105711j:plain

以前に述べたとおり、年賀状にはその年の数に関連した数学パズルを載せるのが通例である1。しかし去年はパズルを作っている時間が8時間しかなかったので2、割と普通の(ある意味で)虫食い算で済ませた。

肝心のパズル問題の部分の文字が小さくで読みづらいが、以下のように書かれている。

以下の条件に従って、割り算の虫食い算を解きなさい。

  • 横に並ぶ一連の数字を全体で一つの整数と考えたとき、それが3の倍数または3のつく数である場合は赤色のマス、そうでない場合は緑色のマスに入れなければならない。

※例えば、□□には3524は入るが、25は入らない。

(問題の図)
f:id:zrbabbler:20210101105808p:plain

一番上にある新年の挨拶はトク・ピシンではない。(何の言語でしょう?)

* * *
(パズル問題についての補足)

この問題は、TeX芸人にとってはお馴染みの「ナベアツ」(3の倍数と3のつく数字でアホになる)が元ネタになっている。条件が少しわかりにくいが、以下のような意味である。

f:id:zrbabbler:20210111021239p:plain
* * *

新年の挨拶の言語はビスラマ語でした。
(※ちなみに、トク・ピシンでの新年の挨拶は“Hepi Nu Yia!”です。)


  1. LaTeXカーネルの仕様・動作変更に自作の文書クラス・パッケージを対応させるのに時間を取られている人が多いためか、年を追うごとに年賀状で数学パズルを見ることが少なくなっているようで感じる。

  2. そのうち本腰を入れて数学パズルを作りたいですね……。

例によって、暮れのご挨拶的な何か

2020年はイロイロとアレな年でしたが、「自分にとっての2020年」を振り返ってみました。

今年は

f:id:zrbabbler:20201231165007g:plain

ゆきだるま☃がいっぱい回る年でした(素敵🙂)

来年は

f:id:zrbabbler:20201231165058g:plain

ゆきだるま☃がもっといっぱい回る年になってほしいですね(素敵🙂)

* * *

ZR「いやー、やっぱり、半日でネタを仕上げるのは無理でしたねー」
*「だったら無理にブログ記事を書く必要ないじゃん!」
ZR「というわけで、来年も当(くだらない)ブログをよろしくお願いします!」

今年も Merry TeXmas! ― \end{texadvent2020}

f:id:zrbabbler:20201122184755g:plain
TeX & LaTeX アドベントカレンダー 2020
*  *  *

アドベントカレンダー完走!

^^`^^;^^`\^^$^^%^^&\!^^;\^^$^^%^^&^^=^^`\!\^^:#1^^;^^=^^`%^^'^^`1~^^`^^"
\!\[{^^2}\!\<{%% --:--:--:--:--:--:--:-- 2 @ 2 @ --:--:--:--:--:--:--:--
\^^#^^3^^.^^!^^-^^%}\!\]{^^3}\^^:?\!\>{\^^%^^.^^$^^#^^3^^.^^!^^-^^%}%**%
\!\={\^^,^^%^^4}\=\?\^^#^^!^^4^^#^^/^^$^^%\=\#\^^:\?`*\?`\^\?`.\?`\*%[#\
\?`/\?`\^\!\|{^^5}\=\@\^^%^^$**%**&\?`\@\?`//*\=\+%+5.//)=\?..{**!};@^^:
\..!^^$//6..!^^.//#..%\=\&\..'//,^^/.."^^!//,\#6\=\%\^^,**#..#///..$**%%
\@\_{\<..,**/..7^^%\[^^#..!\]..%\>}\!\^^!{\?\(\?`+\%\(\)\+\(\@^^.//%%7;)
\+\)\@**.^^%}\=\^^"\**!\=\^^#\..!\!\..${\^^!\**"\..#}\=\..%\..$%.:8:*:8:
\@\({\**$//!**9}\@\){\<//9..%**!\[\>}\!\**'{{\)`/\+\)\@...**%\(\)\+\(\)%
\//$\..%\^^!\..$\+\)\?`\^\//$\^^%\_{\&\!\..:@^^:{%%.(.**$!\\;//:%@>./++.
^^%**,//&..$**&^^/^^&^^#//'..%//&//-**&^^%..&**.//'//$//&//#..&**,**&**!
//'..#..'..#**'//+^^'^^#..'**$//&//!..&**.//&^^$^^&**!//&**,**&**/..&...
**&**%**'//-^^%^^,..'^^%..'**#..&**%^^'`//&**!..&//#**&^^+..&**!^^&^^'%^
**&^^%//'^^+**'//(**&//#//&///**&//,..&../**'//"**"..,**'^^$//&..)..&//+
..'..*.."^^,..'**#..&//#..'^^#..&...^^&/////'//'^^&..-//&..!//&^^...'//-
**%//,^^'..%**'..#..&..%**'^^$**&..)**&**+**'***//&..,**&^^)**&.."..'^^"
^^&^^!^^'**"**'**)^^'^^+**&..$//&//%//&**#..&/////'**"//&..!**'^^$^^&//)
//&..///&...^^'**#^^"**.//'^^$..&//%..'..(**'**$**'..-//%^^,..'`**&//!%/
//&//'^^&**%^^&..#//&../^^&**,//&../..'^^"^^'..+^^&//'**'^^"..&^^%..&^^%
//&//.//"..!**#**)^^#^^%^^"**!**'//"^^&..%..&//$//"**!**#//#..#`**"..!%*
//&^^"//&^^,..&//!//&^^#..&//+^^'..-..%//,^^&..#**&^^///&^^,//&/////'**"
..&//,^^&..%//'..$**'//+//&**&**&^^!**&..#..&**%..'**-**'..+//'//"^^&..%
**&..$//"..!//#**#..#`//"..!**'..)**&^^%**&**,^^&**,..&../..'^^'//"//!%.
..#//'..#`**'**-..%**,**&^^#^^&**/**&^^,..&^^/**'^^"//&//,..&..%..'//$%^
**'**+..&**)..&**...&..+//'**-..'//+**&^^&//&**!//&**#^^&**%**"..!^^#..#
..#`//"..!//&**"^^&**,^^&//!**&^^#..&**+//'..-//%//,**&...//&//%//'^^'%/
^^&^^#//&**/**&..-^^&..-^^&..!**&**.**&..$.."..*//'//+//%**,^^&^^&^^%..$
..'**-**'//+..%^^,^^&^^&..&^^/**&^^.**'//$**'//#//&^^)//'^^*..&//%^^'**+
**#^^!**#..$..'**-^^'**+**#`^^'..-**%**,//&..&..&///..&^^.//'^^$//&**&%*
**&^^!**&**-..&//)^^&**,**'..)//'..+**'`**&//(**'**&^^'//-**%//,//&^^&%/
^^&../**&**.**'//$**'^^#..&..%..'**"..&**)**&..%**'..#//'^^+//&**"..&..#
^^'^^-//%..,..'**#..&//%..&//,//&//%..&..#**'..$**&..&//&../..&**.//'//$
**'//-^^%^^,^^&**"^^&//%**&^^'**&^^)^^&^^.^^'**+//&**$//&../..&//#**'^^%
^^&//-^^&..%//&//.//'..$**'//-..%//,^^&**"^^&^^%..&//'**&..)^^&^^.^^'//+
..'//$..&//)..&**+//'*****'`//&..)^^&**#^^'**$//'..%**'^^"//&**%..'^^-%.
..%**,^^'**%**'**#//&**%//&**!**'..#..&//"^^&^^/**'**%**&//.//&..$**&..)
**&^^.^^&//'//&//"..&**/..'..(**"..(//#`.."..,^^#`//"^^)//'.."**&//%%^^)
**&^^#**'^^$**&..!//&^^.**&..'//&..,..&^^%//"^^(**#^^!..#`**"^^,^^#**!%.
**#`//"^^)//#..+^^%**,..&..&^^&..)//&..,//&^^,**%..+**&**&..&^^!//&//#%*
//&//%..%..-.."**(**#^^%.."//,^^#..%^^"**)**&//#^^&//)**'.."**&//#..&//,
^^&^^%//%..+//'.."..&^^!**&..$//&**)..'//%..'//#//#//-//#^^#.."...//#..%
..%..-**#**+**%^^,**'`..&..!//'^^$**&**(^^%^^+..&//)^^&//.^^&//+//"^^,%.
^^&../**'//%..'//$..#**-^^#..$^^#`**"**,..&**)//&//.**#**-//#**!//#^^$%^
^^#`.."^^,**&..$//&**%^^&//#**&///**'^^"^^&**!//'**$**&//%.."..,//&^^$%^
..&^^%**&^^#..&..///'**"**&..!..'**$**&**)^^&**/**&//...#..-//'**+..'..$
..&^^%..'..(**'^^$//"`..&//!**&..,^^&..///&^^...&**'**"`//'`//&**!%//(**
^^'^^$**&..(//"..,//'**$..&..%..'//(//'..$..#..-..'**+//'**,//%**,^^&**&
^^%^^$//'**,..%**#..$//%^^$..%**"`//%//)^^$..///%..%^^"`..$^^...$^^%%//-
//%^^(//%^^$.."`**%//)//$//%//$^^!..%..".."//!..'..-^^'..-**%**-^^"//(%*
^^#^^#**"//,//#^^&.."//)//'//$^^&**///"//(..#..'^^"//,..#//&//"^^)//#**+
//%^^,^^&**&^^&///**'**"//&**%^^&//!//&..#^^&..(^^%//,^^'**(**"`//&..)%/
**&//...'..+^^#^^#//"**.//#..'**"**,**#//&..".....#..#..'..-//'..+^^%//,
^^&^^.//&^^/**&..$**&^^%//%//+..'**$..&^^%//'^^(**'^^$..#..-^^&**)^^&^^.
//&//+..%^^-**&//!//'^^$**"**(..%//,^^'//(**"^^,//#..$.."^^.//#^^%^^"^^)
..'..+**%**,//'**#^^&^^#**'//#//&**.//&^^/..'^^'**&^^-**&//!**&.....%//+
//'//#..&**#..&^^!..&**,//&**%..#..-^^#//&**"//,**&.."**&**///&//$**'//)
^^"//,^^&//"..'..%..'..$^^'//$^^&..///&**.^^'**#**#..-^^&^^)//&//...&//+
//"^^,//&..-^^'//%^^&**&..&**&//&**,^^&//%**'^^"**#**-^^&**)**&^^.^^&..+
^^%//-..'^^-^^#..+**'..-..#^^+//%//,..&..%//&...**&..$**'^^+**'^^$..&**)
//&**+..'^^*//'`^^&**)..&//#..'//$..'**%^^'^^"^^&^^%..'//-**%//,//&**%%/
..&...^^&**$^^'**+..&**$//&../..&^^#//'^^%..&..-..&**%..&//.^^'..$**'//-
}}\//:*}\^^:$}\..'\(`../\+\(\?`\{\%`,=\(\+\(\?`\&\%`.=\(\+\(\?`\&\%`;=\(
\_{\@\^^!{,..$//&\|...**%\]^^#**!,..%**(^^%;}\@\^^"{\]**#**!^^..**/..+%)
//%^^.\]}\@\..%{**%;,..!^^.^^$//!**&.^^%\[}}{\<\**%\>\=\<\+\=\%%% __ __ 
\+\&\@\^^:@^^!{\&\=\%\<}}\**:@..!\<\^^%\>\=\%\.."\>\+\&\@%.^../%%  / |_>
\..:..:..$../{\<\.."\>{\<\..!\>{\..:@..:}}\#?}\#;}\^^:^^:^^$^^/%% /_ | \

(↑pdflatexでコンパイル)

というわけで、9回目の開催となる TeX & LaTeX Advent Calendar 2020 も、素敵なTeXネタを途絶えさせることなく例によって無事にクリスマスの日を迎えられました。今年の参加者は全部で19名、うち5名が初参加でした。参加者の皆様に心からの感謝を例によって捧げたいと思います。

今年の重点テーマは「このパッケージもスゴイ!」でした。改めて見返すと、テーマに沿った記事が割と多く、たくさんのパッケージが紹介されました。その一覧をあげておきます。

  • bxpdfver
  • fewerfloatpages
  • hmtrump
  • jlreq-deluxe
  • manfnt
  • mathabx
  • mleftright
  • pdfx
  • pxchfon
  • pxjodel
  • qrcode
  • scsnowman
  • scsnowman+
  • tcsushihead
  • tegaki
  • tikzducks

TeX & LaTeX Advent Calendar 2020 を楽しんでくれた皆さんに、

例によってありがとう!

そして

*  *  *

*「やっぱり……」
ZR「例によって……」
*「………………」