Acetaminophen’s diary

化学に関すること,TeXに関すること,ゆきだるまに関すること。

TeX でゆきだるまを“もっともっと”たくさん

これは TeX & LaTeX Advent Calendar 2015 の13日目の記事です。昨日は MNukazawa さんでした。明日は kuroky_plus さんです。

TeXLaTeX Advent Calendar 2015 もちょうど折り返し地点です。今年のテーマは「今さら人に聞けない、TeXのキホン」というわけで、今日は「“TeX でゆきだるま”のキホン」です。

次のような文を書きたいとします:

私の名前は「黒☃大輔」です。

たとえば、upLaTeX を使うと次のようになるでしょう(pLaTeX の場合は☃の代わりに otf パッケージを使って \ajSnowman とするとよいでしょう):

% upLaTeX 文書
\documentclass[dvipdfmx,uplatex]{jsarticle}
\begin{document}
私の名前は「黒☃大輔」です。
\end{document}

簡単ですね…と思いきや、ここで気になることがあります。

たとえば「IPA明朝」埋め込みで PDF 化すると次のようになります:

f:id:acetaminophen:20151212235316p:plain

しかし、「小塚明朝」や「ヒラギノ明朝」の場合はそれぞれ以下のようになります:

f:id:acetaminophen:20151212235342p:plain

f:id:acetaminophen:20151212235358p:plain

これを「IPA明朝」の場合と比較すると、小塚明朝は帽子がなくなってマフラーを付けていますし、ヒラギノ明朝は雪がなくなってしまいます。これはいわば「大輔」が「太輔」や「犬輔」や「人輔」になってしまったようなもので、一大事です。JIS90 から JIS2004 に変わったときに「フォントのバージョンによって“しんにょう”の点のかずが違う!」と辻さんや渡邊さんは困惑したでしょう。それと同じかさらに深刻な問題に、黒☃さんは常に直面しているわけです*1

ゆきだるまのキホン:フォントによって違うゆきだるまたち(復習)

このような問題が起きるのは、フォントによってゆきだるまの字形が全く異なることが原因です。しかも、歴史的経緯によって事態はより複雑になっています:

  • 初期の Unicode には「ゆきだるま」は "U+2603 SNOWMAN" 一点だった。
  • Unicode 5.2 で日本の ARIB 外字が追加されたことにより "U+26C4 SNOWMAN WITHOUT SNOW" と "U+26C7 BLACK SNOWMAN" が登場。

この時点で、従来のコードポイント "U+2603 SNOWMAN" は突然暗黙に「雪あり白ゆきだるま」になってしまいました*2。結果的に、それ以前にデザインされたフォントの中には、U+2603 に「雪なしゆきだるま」のグリフを割り当てたものが一定数存在します。

これほどの「字形の多様性」があるのは Unicode の膨大な文字のなかでも☃が群を抜いており、これだけで一記事書けるほど興味深いものです。このあたりの事情について良く知らないという読者の方は、以下の記事(調査レポートと参考文献含む)をご一読ください:

しかし、情報を伝えるにあたって「フォントによってマフラーの有無が異なる」というのは不都合でしょう。また逆に、ゆきだるまが Unicode にたった3人しかいないのは不満だという意見もあるでしょう。(ちなみに私は「ゆきだるまが足りない」派で、Unicode に「追加ゆきだるま面 (Additional Snowman Plane)」くらいあってもよいと思っています☃)

この両者の不満を解消すべく、画期的なパッケージを開発しました。

 

scsnowman パッケージの使い方

ふつうの LaTeX パッケージですので、\usepackage で読み込みます。ただし、TikZ の描画機能を使って実装してありますので、ドライバ依存です。dvipdfmx を使う場合などはクラスオプション(グローバルオプション)が必要です。

% pLaTeX 文書(upLaTeX も同様)
\documentclass[dvipdfmx]{jsarticle}
\usepackage{scsnowman}
\begin{document}
これはゆきだるま\scsnowman です。
\end{document}

出力のゆきだるまに注目してください。埋め込みフォントに依らず次のように「プレーンのゆきだるま」になります。

f:id:acetaminophen:20151213002104p:plain

このゆきだるまは、tikzpicture 環境の描画で実現されています。したがって、フォントに依存せずにどこでも同じゆきだるまを印刷することができるようになります。scsnowman.sty パッケージが提供しているユーザ向け命令は \scsnowman だけで、非常に簡単ですね! でもここからが本番です。

雪を降らせる:雪ありゆきだるま

先ほどの「ヒラギノ明朝」では雪が勝手に止んでしまいました。scsnowman パッケージのゆきだるまは、すべてオプション引数で “異体字” を調節することができます。雪は snow オプションです。

% 雪ありゆきだるま
今日の天気は\scsnowman[snow]です。

f:id:acetaminophen:20151213003442p:plain

帽子をかぶったゆきだるま

次は帽子(バケツ)です。帽子は hat オプションです。

% 帽子をかぶったゆきだるま
ゆきだるま\scsnowman[hat]が帽子をかぶりました。

f:id:acetaminophen:20151213003710p:plain

帽子の色を変えてみましょう。hat オプションは値として true / false / 色 を受け付け、オプション未指定は false に、値なしの指定(すぐ上の例)は true に対応しています。青い帽子をかぶらせてみます。

% 帽子をかぶったゆきだるま(帽子の色は青)
私は青い帽子をかぶった\scsnowman[hat=blue]が大好きです。

f:id:acetaminophen:20151213004116p:plain

マフラーを付ける

次はマフラーです。お察しの通り(?)オプション名は muffler です。hat オプションと同様に値として true / false / 色 を受け付けます。

% 帽子とマフラー付(マフラーの色は赤)
マフラー\scsnowman[hat=true,muffler=red]を付けてあげましょう。

f:id:acetaminophen:20151213004819p:plain

腕を付ける

腕は arms です。やはり true / false / 色 を受け付けます。

% 腕あり
腕も作って\scsnowman[hat=true,muffler=red,arms=true]あげましょう。

f:id:acetaminophen:20151213005015p:plain

サイズ調節

テキストの文字サイズに対する相対的なゆきだるまのサイズを変更したい場合は、scale オプションを使います。未指定の場合は scale=1 に対応しますので、適宜調節してください。

% サイズ変更\scsnowman、
中\scsnowman[scale=3]、
大\scsnowman[scale=5]

f:id:acetaminophen:20151213010339p:plain

ゆきだるま三兄弟

さて、ここまでで「雪ありゆきだるま (☃ = U+2603)」と「雪なしゆきだるま (⛄ = U+26C4)」に該当しそうな字形が登場しました。では、Unicode のもうひとつのゆきだるま「黒ゆきだるま (⛇ = U+26C7)」(ARIB 外字に由来する「大雪」を表す絵文字)はどうでしょうか。

scsnowman パッケージは、これを body オプションで制御しています。オプション未指定は false に対応し、「白ゆきだるま」すなわち中を塗らないゆきだるまを印字していました。true にすると「黒ゆきだるま」すなわち中を塗ったゆきだるまに変化します。色を指定することもでき、この場合はその色で中を塗ります。

% ゆきだるま三兄弟
\begin{table}[htb]
  \begin{tabular}{ccc}
    \texttt{U+2603} & \texttt{U+26C4} & \texttt{U+26C7} \\
    \texttt{SNOWMAN} & \texttt{SNOWMAN WITHOUT SNOW} & \texttt{BLACK SNOWMAN} \\
    \scsnowman[scale=5,body=false,snow=true] & \scsnowman[scale=5,body=false,snow=false] & \scsnowman[scale=5,body=true,snow=true]
  \end{tabular}
\end{table}

f:id:acetaminophen:20151213011256p:plain

もちろん、他のオプションと組み合わせると実に多様なゆきだるま三兄弟になります。muffler=true を追加してみましょう:

f:id:acetaminophen:20151213011831p:plain

今度は hat=true,arms=true を追加します:

f:id:acetaminophen:20151213011842p:plain

ついでにいろいろな色のゆきだるまも例示します:

% ゆきだるまの色変更
\begin{table}[htb]
  \begin{tabular}{ccc}
    \texttt{U+????} & \texttt{U+????} & \texttt{U+????} \\
    \texttt{RED SNOWMAN} & \texttt{BLUE SNOWMAN} & \texttt{GREEN SNOWMAN} \\
    \scsnowman[scale=5,body=red,snow=red,hat=red] & \scsnowman[scale=5,body=blue,hat=blue,arms=blue,muffler=blue] & \scsnowman[scale=5,body=green,snow=green,arms=green]
  \end{tabular}
\end{table}

f:id:acetaminophen:20151213014321p:plain

scsnowman パッケージの実用例

Twitter で拾ったさまざま不満(?)にお答えします。

これはもう body=<color> オプションで一発解決です(なお、まだ中を塗らないゆきだるまの線の色を変えるインタフェースがありませんが…)。

はい、muffler=true を使いましょう。いちいち \scsnowman[muffler,...] と書くのが面倒な場合は、UnicodeTeX (XeTeX, LuaTeX) を使って次のようにしてしまいましょう。

% XeLaTeX 文書
\documentclass[xelatex,ja=standard]{bxjsarticle}
\usepackage{scsnowman}
\catcode`\☃=13
\def{\scsnowman[body=true,hat,snow,muffler]}
\begin{document}
私の名前は「黒☃大輔」です。
\end{document}

f:id:acetaminophen:20151213015900p:plain

うーん、ごめんなさい。「筆押さえを入れる・入れない」のいい場所が思いつきませんでした…

まだ実装は途中で、たとえば口の形を IPA明朝のような「にっこり」以外にヒラギノ明朝のような「真一文字」も選択可能にすることも検討しています。「ボタン」や「帽子や腕の形」など、多様な字形を網羅するにはまだまだ足りません。欧米風な「三段ゆきだるま」も必要かもしれません。その他、ご要望がありましたらお寄せください。ご提案お待ちしております。

 

おわりに

残念ながら今年の TeX ユーザの集い2015 では🍣は出てきたものの☃が登場しないという由々しき事態でした。昨年の資料では大量登場していたのに!

そこにやってきた報せが今年の TeXLaTeX Advent Calendar 2015 で、重点テーマは「今さら人に聞けない、TeXのキホン」でした。

今年も結局 TeX で Advent Calendar する件について - マクロツイーター
以前と同じく、TeX に関連するもの(LaTeX、plain TeX、ConTeXt、Lollipop、1TeX、METAFONT、MetaPost、BibTeX、Asymptote、MakeIndex、ゆきだるま、……)なら何でも構いません。

今回の記事(と前置きに掲げた以前の記事)をきっかけに、ゆきだるまのキホンに触れて親しんでいただけると幸いです。それでは、Have a happy snowman life!

【追記:2016-08-08】本記事の続編です:

 

(補足1)scsnowman パッケージの現状

現時点 (2015-12-13, v0.1) で実装されているオプションは、以下のとおりです:

- scale    scale=<val> (default:1)
- body     body=false/true/<color> (default:false)
           false:        [W] stroke (black)
           true/<color>: [B] stroke & fill
- eyes     eyes=false/true (default:true)
           false:   none
       [W] true:    fill (black)
       [B] true:    fill (white)
- mouth    mouth=false/true (default:true)
           false:   none
       [W] true:    stroke (black)
       [B] true:    stroke (white)
- hat      hat=false/true/<color> (default:false)
           false:        none
           true/<color>: stroke & fill
- arms arms=false/true/<color> (default:false) false: none true/<color>: stroke & fill
- muffler muffler=false/true/<color> (default:false) false: none [W] true/<color>: stroke & fill
[B] true/<color>: stroke (white) & fill
- snow snow=false/true/<color> (default:false) false: none [W] true/<color>: stroke
[B] true/<color>: stroke & fill

ちなみに、scsnowman.sty の実装はかなり地味です。

しかも keyval パッケージを使った実装も初めて・マクロの入れ子(##1 が登場)も初めての気がします。scsnowman.sty パッケージを眺めていろいろツッコんでください。

(補足2)絵文字シリーズの可能性?

scsnowman.sty の方法はゆきだるまに限らずほかの絵文字にも応用できると考えています。たとえば、寿司が好きなら🍣の異体字を表示する scsushi パッケージを作ることも考えられます。…とはいうものの、ゆきだるまは胴体の色・各パーツの形や有無で指数関数的に増大しますが、寿司の異体字はせいぜいネタの種類 N と寿司の個数 (1~3) の積程度で、あまり興味深くないというのが個人的な感想です*3。ぜひ多様な絵文字を楽しんでください。

(補足3)他のゆきだるま:tikzsymbols パッケージ

ちなみに、有名な The Comprehensive LaTeX Symbol List (symbols-a4.pdf) にもゆきだるまが登場します。昔はこんなの当然なかったのですが、今では symbols-a4.pdf は全331ページに膨れ上がっています(cf. 2001年7月は全58ページ)。

f:id:acetaminophen:20151213033558p:plain

これは tikzsymbols という、これまた TikZ の描画機能で文字のような出力を実現したパッケージです。\Snowman という命令が用意されていて、次のような出力が得られます。

f:id:acetaminophen:20151213033624p:plain

ただし、大きさを変える以上の variant は確保できず、あまり興味がわきませんでした… 「木」だけは variant があるようですが、ちょっと不満。そこで scsnowman の出番ですね。

*1:えっ、☃なんて人名に使えない? それは心の中でのツッコミにとどめてこの記事を楽しんでください☃⛄⛇

*2:最初に Unicode 1.0 が策定されたときの "U+2603 SNOWMAN" の例示グリフは、モリサワのリュウミン(IPA明朝とほぼ同じ)でした。そのグリフデザインを踏襲したのでしょう。

*3:ちなみに scsnowman の sc は snowman comedian の略、scsushi の sc は sushi comedian の略です。