マクロツイーター

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

今年もやっぱりTeXでAdvent Calendarする件について

やっぱりやります!!

f:id:zrbabbler:20191123154250p:plain
TeX & LaTeX Advent Calendar 2019

TeXLaTeX Advent Calendar 2019

とっておきのTeXLaTeXネタを皆で持ち寄って楽しむ
TeXLaTeX Advent Calendar」
今年で8回目の開催となります。
皆さんの、心をこめた素敵なネタをやっぱりお待ちしております!
ハッシュタグは「#texadvent2019
TeXLaTeX 初心者大歓迎。 (重要)
TeXLaTeX 非初心者大歓迎。

今年の重点テーマは……コレです!

今年の重点テーマ

今年の重点テーマはコレです。
「やっぱりLua(La)TeXしよう」

昨年の重点テーマは「とにかくLua(La)TeXしよう」ということで、
LuaTeX/LuaLaTeXに関する素敵な記事がたくさん集まりました。
しかし、LuaTeXを使い始めようと試みる人もさらに増えています。
LuaTeXに関する知見をもっともっと広めていきましょう。

LuaTeX がやっぱりもっと普及すべきだと思っている皆さん、その理想の実現にやっぱり必要なのはあなたの書く貴重な記事です。TeX界隈の人々に「LuaTeXをやっぱり使ってみよう」と思わせるような、そんな素敵な記事をやっぱり書いてみましょう。

例によって「重点テーマ」はやっぱり「制限」ではありません。

(前略)……以下の何れかテーマに該当する何かを書きます。

「やっぱりLua(La)TeXしよう」に大いに関連するTeXLaTeXネタ。
「やっぱりLua(La)TeXしよう」にチョット関連するTeXLaTeXネタ。
「やっぱりLua(La)TeXしよう」にサッパリ関連しないTeXLaTeXネタ。

このように、やっぱり以前と同じく、TeXに関連するもの(LaTeX、plain TeX、ConTeXt、Texdoc、Latexmk、arara、ClutTeX、llmk、……)ならやっぱり何でも構いません。

皆さんの、心温まる TeX ネタでやっぱり寒い冬を乗り越えましょう☃︎

TeX Liveで絶対に使えるLaTeXパッケージ・クラスの一覧

「絶対に使える」とは

ここでは、TeX LiveのLaTeX用の最小構成である「scheme-basic」に含まれる、という意味だということにする。TeX Live系のTeX配布(MacTeXやBasicTeX1も含む)でLaTeXを使っている環境であれば、以下で挙げる一覧に含まれるパッケージやクラスは必ずインストールされていることが期待できる。

scheme-basicで使えるLaTeXパッケージ・クラス

凡例

  • TeX Live 2019の2019/11/17あたりの版。
  • 「:」の前にあるのはTeX Liveのパッケージ名。(LaTeXのパッケージ名ではない。)
  • 「:」の後に、そのTeX Liveパッケージに属するLaTeXのパッケージ・クラスを列挙した(「.cls」を付けたのがクラス、それ以外がパッケージ)。ただし、*比較的著名なものに限って列挙している。
  • LaTeXパッケージ・クラスを含まないTeX Liveパッケージ(バイナリやフォントの配布など)は省略している。

一覧

  • ae: ae, aecompl
  • amscls: amsart.cls, amsproc, amsthm
  • amsfonts: amsfonts, amssymb, eucal
  • amsmath: amsbsy, amscd, amsmath, amstext
  • babel: babel
  • babelbib: babelbib
  • bibtex: apalike
  • carlisle: remreset, scalefnt
  • colorprofiles: colorprofiles
  • colortbl: colortbl
  • dvips: colordvi, rotate
  • etex-pkg: etex
  • fancyhdr: fancyhdr
  • fix2col: fix2col
  • geometry: geometry
  • graphics: color, graphics, graphicx, keyval, lscape, trig
  • hyperref: backref, hyperref, nameref
  • ifplatform: ifplatform
  • iftex: ifetex, ifluatex, ifpdf, iftex, ifvtex, ifxetex
  • latex: alltt, article.cls, book.cls, exscale, fix-cm, fixltx2e, fontenc, ifthen, inputenc, latexrelease, letter.cls, ltxdoc.cls, makeidx, minimal.cls, report.cls, shortvrb, slides.cls, syntonly, textcomp, tracefnt
  • lm: lmodern
  • ltxmisc: bibcheck, concrete, topcapt
  • luaotfload: luaotfload
  • mflogo: mflogo
  • mfnfss: oldgerm, pandora
  • natbib: natbib, bibentry
  • oberdiek: aliascnt, atbegshi, atenddvi, attachfile2, auxhook, bmpsize, bigintcalc, bookmark, catchfile, epstopdf, etexcmds, hologo, hyphsubst, ifdraft, iflang, infwarerr, intcalc, kvoptions, letltxmacro, listingsutf8, mleftright, pagesel, pdfescape, pdflscape, pdftexcmds, picture, rerunfilecheck, soulutf8, stringenc, zref
  • pslatex: pslatex
  • psnfss: avant, helvet, mathpazo, mathptmx, utopia
  • pspicture: pspicture
  • tools: afterpage, array, bm, calc, dcolumn, delarray, enumerate, ftnright, hhline, indentfirst, layout, longtable, multicol, shellesc, showkeys, tabularx, theorem, varioref, verbatim, xr, xspace
  • url: url

補足

  • 原則として、特定の言語(日本語など)専用のものはscheme-basicには含まれない。
  • Babelは本体は含むが、言語定義ファイル(*.ldf)は含まれない。
    • ただし英語の定義ファイル(english.ldf)は含まれる。(定義ファイルが全くないと、実質的にbabelの読込ができなくなるため。)
    • 分綴パターンファイル群(hyph-utf8パッケージ)は含まれる。
  • iftexパッケージについて:(※ここでは「LaTeXの意味でのパッケージ」のことを「.sty」で表す)
    • 2019年10月にLaTeX3チームによる「新しいiftex.sty」がリリースされた。これは「古いiftex.sty」および従来の“if*tex.sty”を置き換えるものである。
    • 「新しいiftexパッケージ」はこの「新しいiftex.sty」に加えて、互換性のためのiftexのラッパーであるifetex.sty、ifluatex.sty、ifpdf.sty、ifvtex.sty、ifxetex.styを含む。
    • 「新しいiftex.sty」は(ifptex.styと同じ意味で)\ifptex\ifuptex命令も提供する。ifptex.sty、ifuptex.styはそのまま存続している(\ifstrictptexなどはifptex.styにしかない)が、これらはscheme-basicには含まれない。
    • 「新しいiftex.sty」が登場する以前の状況としては、ifpdf.sty・ifvtex.sty(oberdiekパッケージ)、ifluatex.sty(ifluatexパッケージ)、ifxetex.sty(ifxetexパッケージ)がscheme-basicに含まれていた。「古いiftex.sty」(iftexパッケージ)は含まれなかった。

おまけ

scheme-basicの「全てのTeX Liveパッケージ」および「全てのLaTeXパッケージ・クラス」を列挙したリストをGistに掲載した。


  1. BasicTeXは、TeX Liveの構成についてはscheme-basicを採用している。つまり、LateXパッケージ・クラスに関しては、本記事の一覧で挙げたTeX Liveパッケージに含まれるものだけがインストールされている。BasicTeXにおけるTeX Liveの構成についてはscheme-basicではなくてscheme-small(basicよりは大きい)でした。

それでも1SATySFiを作ってみた件

*「今日はきりたんぽの日!」
ZR「ですね」
*「ですね、じゃないでしょう!? 毎年恒例の1TeXネタは?」
ZR「恒例っていっても去年はなかったじゃん」
*「一応ツイッタァーに何かありますよ」
ZR「まあとにかく、1TeXに関してこれ以上ネタを見つけ出すのは無理がある」
*「エーッ! 1TeXがダメだとしても、世の中には“TeX以外”もあるでしょう。例えば“1SATySFi”とかを作れば?」
ZR「SATySFiには“catcodeの概念”がないから字句解析規則が変えられない。要するに想定された書式、現状では“本来のSATySFi言語”とMarkdown、それ以外を読み込めるようにするのは無理。まあ、将来に多段階計算の構想が発展すれば可能性はあるんだろうけど」
*「エーッ! 1SATySFiは作れないの!? きりたんぽの日のネタも作れないなんて、SATySFiはオワコン!!」

どうにかして1SATySFiを作ってみた

SATySFiをオワコンにしてしまうのは忍びないので、無理やり作ってみた

インストールは以下のようにする($LIBROOTはライブラリルート)。

  • 1satysfi.satyh$LIBROOT/dist/packages/
  • 1satysfi.satysfi-md$LIBROOT/dist/md/

……ん、md? そう、要するに「Markdownとして読み込ませる」という手段を使っている。

さっそく1SATySFi文書を作ってみる

1SATySFiのソースは、1TeXと同様に「文字コードを“1”の1進数で表したもの」を改行で区切って書く。

[hello.1saty]
    111111111111111111111111111111111111111111111111111111111111111111111111
    11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    11111111111111111111111111111111111111111111
    11111111111111111111111111111111
    1111111111111111111111111111111111111111111111111
    11111111111111111111111111111111111111111111111111111111111111111111111111111111111
    11111111111111111111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    11111111111111111111111111111111111111111111111111111111111111111111111111111111111
    1111111111111111111111111111111111111111111111111111111111111111111111
    111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
    111111111111111111111111111111111

ここで注意であるが、各行の先頭に空白文字4つを入れる必要がある。なぜかというと「結局Markdownだから」である。

もう一つ1TeXと異なる点として、1進数表記にする前の元のテキストは「出力する文字列そのもの」とする。SATySFi言語のコードではないことに注意。

文字コードの10(つまり1111111111)を入力すると出力において改行が起こる。

さっそく1SATySFi文書をコンパイルしてみる

Markdownとしてコンパイルするので--markdown 1satysfiというオプションが必要である。

satysfi --markdown 1satysfi hello.1saty

コンパイル結果は……。

f:id:zrbabbler:20191110231231p:plain
hello.1satyの組版結果

スバラシイ。

まとめ

*「アレレ? SATySFiのコードを1進数にするんじゃないの? このままだと『あらゆるSATySFi文書を“1”だけで表記する』ことになってないから全然ダメじゃん」 ZR「………………」

dvipdfmxのフォントマップのunicodeの話(1)

この記事では「dvipdfmxの和文用のフォントマップの書き方は何となくわかるけど、CMap指定(2カラム目)をunicodeにする書き方の意味がわからない」という人のために、従来のCMap指定とunicode指定の違いについて、何となく説明する。

※この記事では「CFFグリフのOpenTypeフォント」のことを“OpenTypeフォント”、「TrueTypeグリフのOpenTypeフォント」のことを“TrueTypeフォント”と呼ぶ。

CMap指定の4つのパターン

pTeX・upTeXの標準和文TFM1およびjapanese-otfパッケージの和文TFMのセットに対象を限ることにする。このセットに対するフォントマップのCMap指定として、主に以下に述べる4つのパターンが使われている。

※フォントマップの例は「横組・明朝・中字」のマップ行を抜粋して示す。他のウェイトについても全く同様になる。

OpenTypeフォント+CMap指定

rml         H                   HogeraMincho-Regular.otf
uprml-h     UniJIS-UTF16-H      HogeraMincho-Regular.otf
uprml-hq    UniJIS-UCS2-H       HogeraMincho-Regular.otf
hminr-h     H                   HogeraMincho-Regular.otf
hminrn-h    2004-H              HogeraMincho-Regular.otf
otf-ujmr-h  UniJIS-UTF16-H      HogeraMincho-Regular.otf
otf-ujmrn-h UniJIS2004-UTF16-H  HogeraMincho-Regular.otf
otf-cjmr-h  Identity-H          HogeraMincho-Regular.otf
(標準和文を2004JIS字形にしたい場合は最初の2行を差し替える)
rml         2004-H              HogeraMincho-Regular.otf
uprml-h     UniJIS2004-UTF16-H  HogeraMincho-Regular.otf

指定したCMapの変換先のCIDのグリフが出力される。

uprml-hの0x2603   ―(UniJIS-UTF16-H)→   CID+8218のグリフ
  • 利点
    • 標準和文フォントにおいてJIS X 0208の範囲の文字が全て全角幅で使える。
      • 標準和文TFMは全角幅なので、物理フォント側のグリフが全角幅でないならそれは使えない。
    • japanese-otfの機能が全て使える。
      • つまり、\CID命令により、固定幅のグリフが全て使える。
    • 文字情報(ToUnicodeの結果)が“変な文字”にならない。(“部首文字問題”が起こらない。)
  • 欠点

ある意味、標準和文とjapanese-otfにとって最も理想的な状態といえる。従って、AJ1のOpenTypeフォントの場合はこれを適用すべきである。次節以降の利点欠点比較はAJ1のOpenType以外のフォントを前提とする。

TrueTypeフォント+CMap指定(フォールバック)

rml         H                   HogeraMincho-Regular.ttf
uprml-h     UniJIS-UTF16-H      HogeraMincho-Regular.ttf
uprml-hq    UniJIS-UCS2-H       HogeraMincho-Regular.ttf
hminr-h     H                   HogeraMincho-Regular.ttf
hminrn-h    2004-H              HogeraMincho-Regular.ttf
otf-ujmr-h  UniJIS-UTF16-H      HogeraMincho-Regular.ttf
otf-ujmrn-h UniJIS2004-UTF16-H  HogeraMincho-Regular.ttf
otf-cjmr-h  Identity-H          HogeraMincho-Regular.ttf

CMapの指定は①と全く同じで、ただマップ先の物理フォントがTrueTypeフォントであることが違う。

TrueTypeフォントはAJ1のCIDでアクセスできないので、CMapの変換先のCIDにさらにToUnicodeを適用して結果のUnicode値の(既定の)グリフが出力される。(この場合、2004JIS字形用のCMapを指定しても結果は変わらない。)

uprml-hの0x2603   ―(UniJIS-UTF16-H)→   CID+8218   ―(ToUnicode)→   U+2603のグリフ
  • 利点
    • Unicode以外のTFM(rmlなど)でも対応できる。
    • 古いdvipdfmxでもサポートしている。
    • 文字情報(ToUnicodeの結果)が“変な文字”にならない。
      • 内部的にはAJ1のフォントと同じ扱いになるため、らしい。
  • 欠点
    • Unicode文字に対する既定のグリフしか使えない。
      • 例えば、90JIS字形と2004JIS字形の区別は(物理フォントの側が対応していたとしても)無効になる。
    • このため、標準和文フォントにおいてJIS X 0208の範囲の一部の文字が使えない可能性が生じる。
      • 例えば、最近のフォントではクオートの既定のグリフがプロポーショナル幅になっているので、標準和文としては使えない。たとえそのフォントが全角幅のクオートのグリフを別にもっていたとしても、それは使えない。
    • UnicodeのTFMについて、一度CIDの変換を挟むため、一部のUnicode文字が利用できない、あるいは、入力した文字とは別の文字が出力される場合がある。
      • 例えば、U+22EF は、U+22EF→CID+668→U+2026 と変換される。
      • U+263A(☺)はAJ1にない文字なので使えない。

昔は「AJ1のOpenTypeフォント」と「TrueTypeフォント」しかなかったので、①②のパターンだけ(つまり常に「CMap指定」を行う)で全て済んでいた2。この場合、前者の場合は①、後者の場合は②と解釈されることになる。

Unicode直接指定

%rml は無理
uprml-h     unicode             HogeraMincho-Regular.otf
uprml-hq    unicode             HogeraMincho-Regular.otf
%hminr-h は無理
%hminrn-h は無理
otf-ujmr-h  unicode             HogeraMincho-Regular.otf
otf-ujmrn-h unicode             HogeraMincho-Regular.otf
%otf-cjmr-h は無理
(縦組用TFMについては以下のようにする)
uprml-v     unicode             HogeraMincho-Regular.otf -w 1

CMap指定をunicodeにした場合、TFMの符号値をUnicode値とするグリフを出力する。物理フォントの種類は問わない。

uprml-hの0x2603   ―→   U+2603のグリフ
  • 利点
    • AJ1でないOpenTypeフォントにも適用できる。
    • 必ず入力したUnicodeの文字が出力される。
    • 古いdvipdfmxでもサポートしている。
  • 欠点
    • UnicodeのTFMにしか通用しない。
      • つまり、pTeXでは使えないし、japanese-otfの\CIDも全く使えなくなる。
    • Unicode文字に対する既定のグリフしか使えない。
    • このため、標準和文フォントにおいてJIS X 0208の範囲の一部の文字が使えない可能性が生じる。
      • ②と同じ。
    • フォントの中で異なるUnicode文字が同じグリフを共有する場合、文字情報(ToUnicodeの結果)が“変な文字”になる可能性がある。(“部首文字問題”が発生しうる。)

古いdvipdfmxの場合、AJ1でないOpenTypeフォントではこの③しか使えない。

Unicode直接指定+フィーチャ指定

%rml は無理
uprml-h     unicode             HogeraMincho-Regular.otf -l jp90
uprml-hq    unicode             HogeraMincho-Regular.otf -l fwid
%hminr-h は無理
%hminrn-h は無理
otf-ujmr-h  unicode             HogeraMincho-Regular.otf -l jp90
otf-ujmrn-h unicode             HogeraMincho-Regular.otf -l jp04
%otf-cjmr-h は無理
(標準和文を2004JIS字形にしたい場合は以下のようにする)
uprml-h     unicode             HogeraMincho-Regular.otf -l jp04

③の拡張版で、Unicode値によりグリフを選ぶ際にOpenTypeフィーチャを有効にする。最近(20170918版以降)のdvipdfmxでのみサポートされる。

uprml-hの0x2603   ―→   U+2603のjp90指定のグリフ
  • 利点
    • AJ1でないOpenTypeフォントにも適用できる。
    • 必ず入力したUnicodeの文字が出力される。
    • Unicode文字に対するグリフをある程度制御できる。
      • クオートは全角幅で出力される。
  • 欠点
    • 新しいdvipdfmxでしかサポートしていない。
    • UnicodeのTFMにしか通用しない。
    • フォントの中で異なるUnicode文字が同じグリフを共有する場合、文字情報(ToUnicodeの結果)が“変な文字”になる可能性がある。(“部首文字問題”が発生しうる。)

ひとまずまとめ

だめだ dvipdfmxのフォントマップ なにもわからない

(つづけ)

  1. (u)pLaTeXでパッケージを何も用いられない場合の和文フォントとして使われる和文TFMのこと。以下では「標準和文」と呼ぶ。

  2. AJ1のOpenTypeフォントについては①が最適である。TrueTypeフォントについては、昔は④は使えなかったし、③はほとんどの場合に②に劣るのでわざわざ選択する必要がない。

チョットpdfTeXでTrueTypeフォントしてみる話

チョット調べてみたところ、某マクロツイーターでは2011年に書かれた一連の「TeXのフォントの取扱」に関する解説記事の中で少しだけ「pdfTeXでTrueTypeフォントする話1」に触れられている。

zrbabbler.hatenablog.com

とはいえ、その記事では「dvipdfmxでOpenTypeフォントする話」のおまけのような扱いに留まっている感じもする。そこで、改めて「pdfTeXでTrueTypeフォントする」方法についての完結した記事を書くことにする。ただし単発の記事で完結させるために以下の方針をとる:

  • 動作原理などの詳細については過去の記事の方に全て任せることにして、ここでは手順だけを述べる。
  • 話を単純にするため、「フォントの中の1つのグリフだけを使えるようにする」というケースについて扱う。

pdfTeXで素敵に源真ゴシックする話

題材として「源真ゴシック」を使うことにする。源真ゴシックには2万弱のグリフがあるが、その中で一つだけ使いたいグリフを選ぶとなると、当然コレになるだろう。

f:id:zrbabbler:20190921032125p:plain
源真ゴシックのU+2603(SNOWMAN)

というわけで、このグリフのみを(文字コード0の位置に)含む本質的なTeX欧文フォント(TFM)である「genshinessential-r」を作成することにする2

※もちろん源真ゴシックの☃は「源ノ角ゴシック」の☃そのものであるが、源ノ角ゴシックはCFFグリフのOpenTypeフォントであるため、ここでは使えない。

encファイルをつくる

文字コード0をU+2603にマップする」ようなエンコーディングを表すencファイル「essential.map」を作る。

[essential.map]
/essential-enc [
/u2603
] def

少し補足しておくと、encファイルの書式は以下の通りである。

/エンコーディング名 [
/文字コード0に対するグリフ名
/文字コード1に対するグリフ名
/文字コード2に対するグリフ名
・・・・・・
/文字コード255に対するグリフ名
] def

「グリフ名とは何か」というのは本当はヤヤコシイ話なのであるが、ここで紹介する手順に従う(otftotfmを使う)のであれば、単純に「U+2603のグリフ名はu26033と考えてかまわない。

エンコーディング名」については後の設定と整合する限りは勝手に決めてかまわない。

encファイルの仕様としては必ず文字コード0~255に対するグリフ名を書く必要があり、今回のように「0しか使わない」という場合でも、残りの255個の位置に“未定義”を表す.notdefというグリフ名を並べる必要がある。でもどうやらotftotfmでは後ろの.notdefは省略しても通用する4ようなので、ここでは横着をした。

TFMをつくる

このessential.encとフォントファイルGenShinGothic-Regular.ttfを入力として、otftotfmを用いてTFMを作成する5

※入力ファイルはカレントディレクトリに置いておく。

otftotfm -e essential.enc GenShinGothic-Regular.ttf genshinessential-r >genshinessential.map

ここで標準出力をリダイレクトしていることに注意。otftotfmはpdfTeX用のマップ行を標準出力に出すので、これをgenshinessential.mapに保存しておく。このコマンドの実行により、以下のファイルが生成される。

  • genshinessential-r.tfm: TFMファイル。
  • a_fdlbd4.enc6: 元のessential.encを“加工”して作られたencファイル。実際にpdfTeXで使うのはこちらの方である。(essential.encはもはや不要。)
  • genshinessetial.map: pdfTeX用のマップファイル。

otftotfmは“間にVFを挟んだTFM”を生成する7ことが多いのであるが、今回は非常に単純な事例であったため単純に.tfmファイル一つだけからなるTFMになったようだ。

早速pdfTeXでgenshinessentialしてみる

これで“TeXレベル”でgenshinessential-rを利用するための準備は全て整った。そこでまずはplain pdfTeXの文書で動作をテストしてみる8

[test-plain.tex]
% plain pdfTeX document
% マップファイル読込の指定
\pdfmapfile{+genshinessential.map}
% TFM"genshinessential-r"からフォント \fEsssential を生成
\font\fEssential=genshinessential-r
% フォントを \fEssential に切り替えてコード0のグリフを出力
Test: {\fEssential\char0}
\bye

plain pdfTeXなのでpdftexコンパイルする。

pdftex test-plain

端末出力をみると、今の作業で作ったファイルや源真ゴシックのフォントファイルがちゃんと読み込まれていることが確認できる。

(./test-plain.tex{c:/texlive/2019/texmf-var/fonts/map/pdftex/updmap/pdftex.map}
{genshinessential.map} [1] ){a_fdlbd4.enc}<c:/texlive/texmf-local/fonts/truetyp
e/public/GenShinGothic/GenShinGothic-Regular.ttf><c:/texlive/2019/texmf-dist/fo
nts/type1/public/amsfonts/cm/cmr10.pfb>
Output written on test-plain.pdf (1 page, 14867 bytes).

そして出力されたtest-plain.pdfの中身を確認すると……。

f:id:zrbabbler:20190921044841p:plain
plain pdfTeXな出力結果

素敵☃!

今度はpdfLaTeXでgenshinessentialしてみる

無事にplain TeXで源真ゴシックできたので次はLaTeXでのサポートについて考えることにしよう。

LaTeXのサポートというと「当該のフォント(ファミリ)に切り替える命令」を提供するのが普通であるが、今の事例ではそれは意味を成さないだおる。今作ったTFMは「文字コード0しかない」という特殊なものであり、それでできることは「源真ゴシックの☃を出す」ことだけなので、そのための専用の命令を用意するべきだろう。そこで、LaTeXパッケージ「genshinessential」の設計について、次のような方針にする。

  • 「源真ゴシックのU+2603〈☃〉を出力する」ための命令\genshinsnowmanを提供する。
  • U+2603のグリフにはシェープ(ウェイトなど)による差異が元々存在しない。だから、単一のシェープのみを定義して、\genshinsnowmanは常にそれを使うことにする。
  • マップファイルをパッケージファイルと別に用意する必然性は乏しいので、パッケージ中でマップ行を宣言することにする。

現状のマップ行自動生成の名前が入っていて少し汚らしいので整理しよう。まずは、a_fdlbd4.encの先頭の部分(%00の行より前)を次のように書き換えたものを新たにessential.encとして保存する。(つまり、a_fdlbd4.encの代わりにessential.enc、AutoEnc_fdl・・・2raの代わりにessential-encを使うようにする。)

/essential-enc [
%00
  /uni2603 /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
  /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
・・・・・・

パッケージファイルgenshinessential.styの実装は次のようにした。

※マップ行でessential.encや/essential-encを使っていることに注意。

[genshinessential.sty]
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{genshinessential}

% マップ行読込の指定.
\pdfmapline{+genshinessential-r GenShinGothic-Regular "essential-enc ReEncodeFont" <[essential.enc <GenShinGothic-Regular.ttf}

% ファミリ'genshinessential'の定義.
% エンコーディングは'U'(不定形)を指定する.
\DeclareFontFamily{U}{genshinessential}{}
% m/nシェープしか使わないのでそれだけを定義する.
\DeclareFontShape{U}{genshinessential}{m}{n}{<->genshinessential-r}{}

%<*> \genshinsnowman: "源真ゴシック"のU+2603を出力する.
\newcommand{\genshinsnowman}{{\usefont{U}{genshinessential}{m}{n}\symbol{0}}}

これでLaTeXのサポートが完成したことになる。改めて整理すると:

  • genshinessential-r.tfm: TFMファイル。
  • essential.enc: (判りやすい名前の)encファイル。
  • genshinessetial.sty: LaTeXパッケージファイル。

早速genshinessetialパッケージを使ってみよう。

[test-latex.tex]
% pdfLaTeX document
\documentclass[a4paper]{article}
% 素敵なパッケージを読み込もう
\usepackage{genshinessential}
\begin{document}
% 素敵な命令を使おう
Hello \genshinsnowman\ world!
\end{document}

もちろん今度はpdflatexでコンパイルする。出力結果は……。

f:id:zrbabbler:20190921051700p:plain
pdfLaTeXな出力結果

トッテモ素敵☃!

まとめ

源真ゴシックの☃は素敵!


  1. 当該の記事ではTrueTypeフォントだけに限らず一般のOpenTypeフォント(TrueTypeグリフもCFFグリフも含めて)が対象になっている。実際、pdfTeXで両種のOpenTypeフォントが扱えるのであるが、CFFグリフのOpenTypeについては「サブセット埋込ができない」という重大な制限がある。このため、実用的に使えるのは専らTrueTypeフォントに限られることになるだろう。

  2. 「genshinessential-r」の名前は例によって“ZR命名規則”に依る。エンコーディング不定形(1つしかグリフがない)なので省略し、バリアント部を「r」(Regular)、ファミリ部を「genshinessentia」とした。

  3. Unicode値は「4桁以上の大文字16進数で書く」という規則なので、例えばU+0038ならu0038、U+1F92Eならu1F92Eがグリフ名となる。uni2603というグリフ名も可能だが、この方式は5桁以上では使えない。

  4. 最初に手動で作るencファイルはotftotfmの入力となった後は一切使われない。

  5. TrueTypeフォントが与えられた場合、Type1への変換は非対応であるため--no-type1--no-dotlessjは事実上常に有効になる。今の目的に照らすとOpenTypeフィーチャ(-f ligaなど)を指定する必要もないだろう。

  6. 生成されたencファイルの名前(およびその中に記されたエンコーディング名)は自動生成されるので、環境によって異なる可能性がある。

  7. VFが使用された場合、「genshinessential-r.tfm」の他に「genshinessential-r.vf」と「genshinessential-r–base.tfm」が生成されるはずである。つまり、「genshinessential-r」は「genshinessential-r–base」を参照するVFである。

  8. pdfTeXの普通のマップ設定に割り込むのは面倒なので、代わりに「文書内で(\pdfmap...プリミティブで)マップ設定を行う」という方法をとる。詳細については[過去の記事]の方を参照。

scsnowmanでつくる対称コルーチン(※最新の定義)

猛暑! 台風! ゆきだるま☃︎

コルーチンのイロイロな定義

某ZR氏の某ツイッタァーをフォローしている方ならご存知だと思いますが、去る5月30日に、某出版社の某『n月刊ラムダノート』の創刊を記念したパーティーが催されました。

このパーティーにおいてメインのテーマとなったのが、

コルーチンの定義がイロイロありすぎてアレ

ということでした。この話題についての詳細は以下の記事に譲ることにしますが、要するにコルーチンの定義が本質的に問題なわけです。

コルーチンの素敵な定義

この問題に対して、そのパーティとは全然サッパリ関係のない某ZR氏が、画期的な解決法を提案しています。

スバラシイ☃︎

scsnowmanで対称コルーチン(※最新の定義)したい話

せっかくコルーチンの定義が素敵☃︎になったのですから、LaTeXのscsnowmanパッケージを使ってコルーチン(※最新の定義)に関する技術文書を作りたくなりますね。ところが、ここで大きな問題があります。それは、

対称コルーチン(※最新の定義)は対称でないといけない

ということです。

f:id:zrbabbler:20190808163349p:plain
対称コルーチン(※最新の定義)

一方で、scsnowmanで出力されるゆきだるま☃︎は、どれも素敵ですが非対称です。

かの画期的なscsnowmanパッケージも対称コルーチン(※最新の定義)はサポートできないのでしょうか。いや、決してそんなことはありません。実は、scsnowmanには「ゆきだるま形状をユーザが独自に定義する」ための機能が用意されています。

Any users can define and use custom snowman shape definitions. Here is a description of adding a shape named myfavorite.
  1. Prepare a snowman definition file scsnowman-myfavorite.def and put it into $TEXMF tree (e.g. texmf-local/tex/latex/scsnowman/). (後略)
  2. (scsnowman マニュアル; §6 “Adding User-defined Snowman Shapes”)

つまり、対称なゆきだるま形状を定義したファイルscsnowman-zrsymmetric.defを用意すれば、次のようにして対称なゆきだるまが出力できるはずです。

% pdfLaTeX document
\documentclass[a4paper]{article}
\usepackage{scsnowman}% ゆきだるま!
\usescsnowmanlibrary{zrsymmetric}% 対称!
\begin{document}
% 'shape'キーで形状を指定する
\scsnowman[shape=zrsymmetric,‹他オプション›...]
\end{document}

scsnowmanで対称コルーチン(※最新の定義)する話

というわけで、作ってみました

早速、対称コルーチン(※最新の定義)をつくってみましょう。

% upLaTeX文書
\documentclass[uplatex,dvipdfmx]{jsarticle}
\usepackage[a6paper,scale=0.75]{geometry}
\usepackage{xcolor,scsnowman}
\usescsnowmanlibrary{zrsymmetric}% 対称ゆきだるま
\begin{document}
非対称コルーチン
\scsnowman[hat=green!35!black,arms=green!20!black,
buttons=green!35!black,snow,muffler=green!50!black,
adjustbaseline,scale=2]% フツー(非対称)
も、対称コルーチン
\scsnowman[hat=green!35!black,arms=green!20!black,
buttons=green!35!black,snow,muffler=green!50!black,
adjustbaseline,scale=2,shape=zrsymmetric]% 対称!
もどちらも素敵なので、
両者は等価です。
\end{document}

f:id:zrbabbler:20190808180932p:plain
コルーチン(※最新の定義)に関する技術文書

バッチリですね!

イロイロな対称ゆきだるま

形状オプションshape=zrsymmetricを付けた場合でも、\scsnowmanの他のオプション(hatmuffler、などなど)は自由に設定できます。

% pdfLaTeX document
\documentclass{article}
\usepackage[a6paper,scale=0.75]{geometry}
\usepackage[svgnames]{xcolor}
\usepackage{scsnowman}
\usescsnowmanlibrary{zrsymmetric}% 対称!
%% \CompareSnowmen{<オプション>...}
% 非対称と対称のゆきだるまを並べて出力する.
\newcommand{\CompareSnowmen}[1]{\par
  \scsnowman[scale=4,#1]%
  \scsnowman[scale=4,shape=zrsymmetric,#1]%
  \par\smallskip}
\begin{document}
% シンプル
\CompareSnowmen{hat,arms,snow,muffler}
% ミカン付き
\CompareSnowmen{mouthshape=tight,
  mikan=Orange,leaf=Olive,sweat=SkyBlue}
% 箒付き
\CompareSnowmen{hat=Green,arms=Brown,muffler=Red,
  buttons=Blue,snow=SkyBlue,broom=DarkGoldenrod}
\end{document}

f:id:zrbabbler:20190808181012p:plain
イロイロな対称ゆきだるま(非対称もあるよ)

scsnowmanのゆきだるまの多様性がもっともっと増えたわけですね。スバラシイ☃︎

まとめ

というわけで、非対称コルーチン(※最新の定義)も、対称コルーチン(※最新の定義)も、それ以外のゆきだるま☃︎も、すべて素敵!

Markdownでデカイ文字を書けて便利な話(ただしPandoc)

聞くところによると、Markdownでとにかくデカイ文字が簡単に書けると便利なようです。

しかし残念なことに、元来のMarkdownは意味的なマークアップを指向したものであるため、今世にあるMarkdownの各種方言はどれも「見出しを書く」ことができても「デカイ文字を書く」ことができません。このことがデカイ文字の熱狂的ファンがMarkdownの採用を躊躇する一因となっていることは否めないでしょう。

というわけで、Markdownでデカイ文字を書くためのPandocフィルタを作ってみました

文字をデカくする

このフィルタを使う場合、デカイ文字は「bigクラスをつけたspan要素」として表されます。Pandoc Markdownの記法では次のように書きます。

[sample1.md]

Pandocは[アレ]{.big}。

早速このMarkdownをHTMLに変換してみましょう。

pandoc sample1.md --lua-filter biggggg.lua -s -o sample1.html

f:id:zrbabbler:20190731210533p:plain
HTMLでデカイ文字

デカイ! 便利!

今度はLuaLaTeX経由でPDFに変換してみましょう。

pandoc sample1.md --lua-filter biggggg.lua -o sample1.pdf --pdf-engine=lualatex -V documentclass=bxjsarticle -V classoption=pandoc

f:id:zrbabbler:20190731210622p:plain
PDFでデカイ文字

デカイ! 便利!

※現状では、対応する出力形式はHTMLとLaTeX(経由のPDF)に限ります。

文字をもっともっとデカくする

「これだけのデカさでは物足りない」という人はもっともっとデカイ文字も使えます。クラス名としてbigの代わりにbiggbigggbigggg、……とすることで、文字をどんどんデカくできます。

[sample2.md]

Pandocは[アレ]{.bigg}[アレ]{.bigggg}
[アレ]{.bigggggg}[アレ]{.bigggggggg}。

※見やすさのため、Markdown中に改行を入れました。この改行は(空白にならずに)無視されてほしいので、pandoc実行時にオプションに-f markdown+ignore_line_breaksを追加することにします。

f:id:zrbabbler:20190731210654p:plain
HTMLでもっともっとデカイ文字
f:id:zrbabbler:20190731210716p:plain
PDFでもっともっとデカイ文字

もっともっとデカイ! 便利!

強調文字もデカくする

もちろん、デカイ文字を他の文字装飾と組み合わせることもできます。

[sample3.md]

Pandocは[アレ]{.bigg}、TeXは[超絶**アレ**]{.bigggggg}。

f:id:zrbabbler:20190731211010p:plain
HTMLでデカイ強調文字
f:id:zrbabbler:20190731211035p:plain
PDFでデカイ強調文字

強調付きでデカイ! 便利!

まとめ

Pandocはネタ記事を書くのに便利!(えっ)