マクロツイーター

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

TeX Liveで令和してみる話

新しいTeX Live 2019が、日本のCTANミラーサイトにも届き始めているようである。

というわけで、早速、TeX Live 2019で令和してみる。和暦機能の説明については平成の記事で済ませてあるので、ここでは単純に結果だけを示す。

令和してみた結果

% pLaTeX文書
\documentclass[a4paper]{jarticle}
\和暦
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190503072821p:plain
jarticleな出力結果

令和!

% upLaTeX文書; UTF-8
\documentclass[a4paper]{ujarticle}
\和暦
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190503072842p:plain
ujarticleな出力結果

令和!

% upLaTeX文書; UTF-8
\documentclass[uplatex,a4paper]{jsarticle}
\和暦
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190503072857p:plain
jsarticleな出力結果

令和!

% LuaLaTeX文書; UTF-8
\documentclass[a4paper]{ltjsarticle}
\和暦
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190503072913p:plain
ltjsarticleな出力結果

令和!

% LuaLaTeX文書; UTF-8
\documentclass[lualatex,ja=standard,a4paper]{bxjsarticle}
\和暦
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190503072940p:plain
bxjsarticleな出力結果

令和!

% LuaLaTeX文書; UTF-8
\documentclass[paper=a4]{jlreq}
\和暦
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190503072959p:plain
jlreqな出力結果

令和!

% LuaLaTeX文書; UTF-8
\documentclass[tate,book,paper=b6,jafontsize=9pt]{jlreq}
\和暦
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190503074100p:plain
縦組のjlreqな出力結果

令和!

% LuaLaTeX文書; UTF-8
\documentclass[a4paper]{ltjsarticle}
% 例によってエスペラント
\usepackage[main=japanese,esperanto]{babel}
\newcommand{\Eo}[1]{%
  \begin{otherlanguage}{esperanto}#1\end{otherlanguage}}
\和暦
\title{しあわせ{\TeX}言語入門\\
  \Eo{Feliĉa Kurso pri la Lingvo {\TeX}}}
\author{mal-ZR}
\date{\today\quad(\Eo{\today})}
\begin{document}
\maketitle
% Neniu enhavo.
\end{document}

f:id:zrbabbler:20190503074141p:plain
Babelな出力結果

令和!

% upLaTeX文書; UTF-8
\documentclass[dvipdfmx,14pt]{beamer}
\usepackage{pxjahyper}
\renewcommand{\kanjifamilydefault}{\gtdefault}
\usepackage{bxwareki}% 和暦したい
\usetheme{EastLansing}
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\date{\warekitoday}% 和暦日付を明示指定する
\begin{document}
\begin{frame}
\titlepage
\end{frame}
\end{document}

f:id:zrbabbler:20190503074406p:plain
Beamerな出力結果

令和!

まとめ

令和したい人は、新しいTeX Liveをインストールしよう!

TeXで平成してみる話

普通にやればオッケー。

% upLaTeX文書; UTF-8
\documentclass[uplatex,a4paper]{jsarticle}
\和暦
\title{{\TeX}言語、ダメゼッタイ!}
\author{某ZR}
\begin{document}
\maketitle
% ダメゼッタイ
\end{document}

f:id:zrbabbler:20190430143858p:plain
平成できた

平成!

……なのであるが、日本語LaTeXの「和暦の日付」に関する機能について、もう少しキチンとまとめておく。

\today を和暦にする話

以下に挙げる和文文書クラスでは、当日日付(\today)を和暦で出力することができる。

  • pLaTeXの標準和文クラス: jarticle、jreport、jbook、tarticle、treport、tbook
  • upLaTeXの標準和文クラス: ujarticle、ujreport、ujbook、utarticle、utreport、utbook
  • jsclassesバンドルのクラス: jsarticle、jsreport、jsbook
  • LuaTeX-jaの和文クラス: ltjarticle、ltjreport、ltjbook、ltjtarticle、ltjtreport、ltjtbook、ltjsarticle、ltjsreport、ltjsbook
  • BXjsclsバンドルのクラス: bxjsarticle、bxjsreport、bxjsbook、bxjsslide
  • jlreqクラス

(恐らく、TeX Live収録の日本語用文書クラスはこれが全てである。)

これらのクラスでは、以下の命令を用いて\todayの和暦・西暦表示を切り替える。

  • \和暦\todayの年表示を和暦(元号)にする。
  • \西暦\todayの年表示を西暦にする。

既定値については注意が必要である。

  • pLaTeX/upLaTeXの標準和文クラス」および「LuaTeX-jaの“pLaTeX標準の互換クラス”1」については旧来は和暦が既定であったが、改元後に不適切な表示が出るのを防ぐため、2018年7月頃のリリースで既定が西暦に変更された。従って、これらのクラスにおいて\today命令を利用している(\dateを省略する場合も含む)場合は\和暦\西暦を明示的に宣言してほうがよいであろう。
  • それ以外のクラスについては、西暦表示が既定である。

それで結局令和できるのか

以前の記事の時点では一部のクラスは「令和」に未対応であった。しかし現在においては、和暦対応のクラスの全てが対応を済ませている。従って、最新のW32TeXでは明日の改元後に「令和」が出力される。

TeX Liveについては……、そう、ちょうど今朝(日本時間の午前7時頃)TeX Live 2019がリリースされた。従って、新しいTeX Live 2019をインストールすれば、和暦対応のクラスの全てで「令和」が出力される。ただし、国内のミラーへの反映に時間がかかるため、TeX Live 2019が一般に入手できるのは明日になるだろう。「令和」の時代の初日から「令和」が使えるようになる見込みである。

和暦なのか西暦なのか

実用上の必要はないだろうが、実は「現在\和暦\西暦のどちらが有効であるか」を判定することができる。

  • ifthenパッケージを読みこむ。和暦対応のクラスにおいては西暦という名の真偽値変数が定義された状態になるので、これを用いて判定ができる。

    \ifthenelse{\boolean{西暦}}{%
      % \西暦 が有効
    }{%
      % \和暦 が有効
    }
    
  • ただし、BXjsclsのクラスと欧文(pdf)LaTeXの組み合わせの場合は例外で、この場合は西暦の代わりにjsSeirekiという真偽値変数を用いる。(和文の変数名が使えないため。)

例えば次のようにできる。

% upLaTeX文書; UTF-8
\documentclass[uplatex,a4paper]{jsarticle}
\usepackage{ifthen}
\和暦
\title{新しいテフライブがリリースされた件}
\author{非ZR}
\begin{document}
\maketitle
\begin{abstract}
{\TeX}~Live \ifthenelse{\boolean{西暦}}{2019}{平成31}% ええっ
における変更点(特にアレ性)について解説する。
\end{abstract}
\end{document}

f:id:zrbabbler:20190430144456p:plain
トッテモ実用的

Babelする場合は

Babelパッケージを利用する場合、\todayの表記はBabelの言語定義の内容に従うことになる。現在の版のBabelの日本語(japanese)用の定義では、和文クラスと同様に、\和暦\西暦命令がサポートされていて\todayの表記の切替ができる。

% upLaTeX文書; UTF-8
\documentclass[uplatex,a4paper]{jsarticle}
\usepackage[T2A,T1]{fontenc}
\usepackage{paratype}% PTフォント使用
\usepackage[prefercjkvar]{pxcjkcat}
% なぜか唐突にロシア語
\usepackage[main=japanese,russian]{babel}
\newcommand{\Ru}[1]{%
  \begin{otherlanguage}{russian}#1\end{otherlanguage}}
\和暦
\title{{\TeX}言語、ダメゼッタイ!\\
  \Ru{Никогда не делай {\TeX} язык!}}
\author{\Ru{не-ZR}}
\date{\today\quad(\Ru{\today})}
\begin{document}
\maketitle
% Ничего
\end{document}

f:id:zrbabbler:20190430145337p:plain
Babelしてみた

BXwarekiパッケージ

Beamerなどのスライド用の文書クラスでは、和文も欧文も共通のものが使われるのが一般的である。そういうクラスでは当然、\today命令は和暦表示どころが日本語での表示にも対応していない。

% upLaTeX文書; UTF-8
\documentclass[dvipdfmx,14pt]{beamer}
\usepackage{pxjahyper}% いつもの設定
\renewcommand{\kanjifamilydefault}{\gtdefault}
\usetheme{EastLansing}
\title{{\TeX}言語、ダメゼッタイ!}
\author{某ZR}
\date{\today}
\begin{document}
\begin{frame}
\titlepage
\end{frame}
\end{document}

f:id:zrbabbler:20190430151243p:plain
日本語ですらない

日付が英語表記の「April 30, 2019」になっている。

このような文書クラスで\todayを和暦で表示したい場合は、bxwarekiパッケージを使うのが手っ取り早い2。bxwarekiは次の命令を提供する。

  • \warekitoday: 今日の和暦の日付を算用数字(平成31年4月30日)で出力する。
  • \warekikanjitoday: 今日の和暦の日付を漢数字(平成三一年四月三〇日)で出力する。
  • \warekijkanjitoday: 今日の和暦の日付を漢数字(平成三十一年四月三十日)で出力する。
% upLaTeX文書; UTF-8
\documentclass[dvipdfmx,14pt]{beamer}
\usepackage{pxjahyper}
\renewcommand{\kanjifamilydefault}{\gtdefault}
\usepackage{bxwareki}% 和暦したい
\usetheme{EastLansing}
\title{{\TeX}言語、ダメゼッタイ!}
\author{某ZR}
\date{\warekitoday}% 和暦日付を明示指定する
\begin{document}
\begin{frame}
\titlepage
\end{frame}
\end{document}

f:id:zrbabbler:20190430152742p:plain
平成できた

さらに、\warekicustomdateという命令を使うと、日付3を様々な形式で出力することができる。だから実は「西暦の日本語の日付」を出力したい場合にも使える4

% upLaTeX文書; UTF-8
\documentclass[dvipdfmx,14pt]{beamer}
\usepackage{pxjahyper}
\renewcommand{\kanjifamilydefault}{\gtdefault}
\usepackage{bxwareki}
\usetheme{EastLansing}
\title{{\TeX}言語、ダメゼッタイ!}
\author{某ZR}
\date{\warekicustomdate{}}% 和暦じゃない
\begin{document}
\begin{frame}
\titlepage
\end{frame}
\end{document}

f:id:zrbabbler:20190430154226p:plain
西暦できた(えっ)

まとめ

というわけで、和暦したい人も、西暦したい人も、困った場合はbxwarekiパッケージを使おう!


  1. すなわち以下のクラス:ltjarticle、ltjreport、ltjbook、ltjtarticle、ltjtreport、ltjtbook

  2. 先述の通り、Babelを読み込んでメイン言語にjapaneseを指定すると\和暦が使えるので、こちらを利用する方法もあり、また(Babelの目的が多言語対応なので)その方がある意味で正攻法なのであるが、Babelは副作用も多いので、できるならば避けたいところである。

  3. \warekitoday等は必ず今日の日付を出力するが、\warekicustomdateは予め\warekisetdate命令で指定した日付を出力する。ただし、\warekisetdateの初期値は今日の日付であるので、\warekisetdateを使わない場合は\warekicustomdateの出力も今日の日付になる。

  4. \warekicustomdateの書式指定の文字列を引数にとる。引数が空の\warekicustomdate{}は西暦・算用数字で出力する。この他に、例えば\warekicustomdate{wk}だと和暦・漢数字(\warekikanjitodayと同じ書式)で出力する。

TeXで昭和してみるテスト

もしかして:令和

以下の結果は最新(昨日の版)のW32TeXでのもの。

TeX Liveについては、現在は2019のプレテスト中である。

\today の和暦表示で昭和してみるテスト

TeXエンジンのSOURCE_DATE_EPOCHの機能を用いて「現在日時が1983年8月8日である」と見なされるようにする。

# 以下の環境変数を設定する
set SOURCE_DATE_EPOCH=429148800
set FORCE_SOURCE_DATE=1

BXjsclsのクラスの場合

% upLaTeX文書; UTF-8
\documentclass[uplatex,dvipdfmx,ja=standard,a4paper]{bxjsarticle}
\和暦
\title{できる! ネ申Multiplan活用術}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190429143843p:plain
bxjarticleな出力結果

昭和!

jlreqクラスの場合

% LuaLaTeX文書; UTF-8
\documentclass[paper=a4]{jlreq}
\和暦
\title{できる! ネ申Multiplan活用術}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190429143855p:plain
jlreqな出力結果

昭和!

jsclassesのクラスの場合

% pLaTeX文書; UTF-8
\documentclass[a4paper]{jsarticle}
\和暦
\title{できる! ネ申Multiplan活用術}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190429143904p:plain
jsarticleな出力結果

昭和!

pLaTeX標準和文クラスの場合

% pLaTeX文書; UTF-8
\documentclass[a4paper]{jarticle}
\和暦
\title{できる! ネ申Multiplan活用術}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190429143915p:plain
jarticleな出力結果

昭和!

LuaTeX-jaのクラスの場合

% LuaLaTeX文書; UTF-8
\documentclass[a4paper]{ltjsarticle}
\和暦
\title{できる! ネ申Multiplan活用術}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190429141949p:plain
ltjsarticleな出力結果

昭和!

※ltj系列のクラスでも同様。

Babelする場合

Babelパッケージを利用する場合、\todayの表記はBabelの言語定義の設定に従う。\和暦もサポートされている。

% LuaLaTeX文書; UTF-8
\documentclass[a4paper]{ltjsarticle}
% なぜか唐突にラテン語
\usepackage[main=japanese,latin]{babel}
\newcommand{\La}[1]{%
  \begin{otherlanguage}{latin}#1\end{otherlanguage}}
\和暦
\title{できる! ネ申Multiplan活用術\\
  \La{Multa Nemōsuia Multiplāna faciāmus!}}
\author{nōn-ZR}
\date{\today\quad(\La{\today})}
\begin{document}
\maketitle
% nihil
\end{document}

f:id:zrbabbler:20190429144452p:plain
babelな出力結果

昭和!

bxwarekiパッケージ

例えばBeamerクラスはそもそも和暦に対応してないが、bxwarekiパッケージ\warekitoday命令を使うことで今日の日付を和暦で出力できる。

% upLaTeX文書; UTF-8
\documentclass[dvipdfmx,14pt]{beamer}
\usepackage{pxjahyper}
\renewcommand{\kanjifamilydefault}{\gtdefault}
\usepackage{bxwareki}% 和暦したい
\usetheme{EastLansing}
\title{できる!\\ネ申Multiplan活用術}
\author{非ZR氏}
\date{\warekitoday}% 明示指定する
\begin{document}
\begin{frame}
\titlepage
\end{frame}
\end{document}

f:id:zrbabbler:20190429144515p:plain
bxwarekiな出力結果

昭和!

まとめ

どうやら、イマドキの日本語LaTeXは昭和できるらしい。

TeXで令和してみるテスト(2)

前回の続き。

W32TeXの最新版による。

令和な組文字を書いてみるテスト

「令和」の組文字(U+32FF)をイロイロな方法で入力してみて、正しく出力されているかを調べる。

当然、U+32FFに対応したフォントが必要になるわけであるが、今回は「和田研中丸ゴシック2004絵文字」を使用する。ただし、このフォントは組文字の縦組用字形には対応していないので、縦組のテストは行わない。

※「和田研中丸ゴシック2004絵文字」はTrueTypeグリフのフォントである1

upLaTeXの標準和文フォントの場合

% upLaTeX文書; UTF-8
\documentclass[uplatex,dvipdfmx,a4paper]{jsarticle}
\usepackage[ipaex]{pxchfon}
\setminchofont{wlcmaru2004emoji.ttf}% 和田研中丸ゴシック
\begin{document}
%↓先頭にU+32FFの文字
㋿ゃーん(\symbol{"32FF}ゃーん)
\end{document}

f:id:zrbabbler:20190407045725p:plain
標準な出力結果

令和!

pLaTeX+japanese-otfの場合

最新のjananese-otfパッケージでは、\ajLig{令和}でU+32FFを入力できる2

% pLaTeX文書
\documentclass[dvipdfmx,a4paper]{jsarticle}
\usepackage{otf}
\usepackage[ipaex]{pxchfon}
\setminchofont{wlcmaru2004emoji.ttf}% 和田研中丸ゴシック
\begin{document}
\UTF{32FF}ぁ? \CID{23058}ぁ? \ajLig{令和}ぁ?
\end{document}

f:id:zrbabbler:20190407045800p:plain
japanese-otfな出力結果

令和!

upLaTeX+japanese-otfの場合

% upLaTeX文書; UTF-8
\documentclass[uplatex,dvipdfmx,a4paper]{jsarticle}
\usepackage{otf}
\usepackage[ipaex]{pxchfon}
\setminchofont{wlcmaru2004emoji.ttf}% 和田研中丸ゴシック
\begin{document}
%↓先頭にU+32FFの文字
㋿っ! \UTF{32FF}っ! \CID{23058}っ! \ajLig{令和}っ!
\end{document}

f:id:zrbabbler:20190407045843p:plain
japanese-otfでupLaTeXな出力結果

令和!

pxchfonで“Unicode直接指定”にした場合

pxchfonパッケージで“Unicode直接指定”(unicodeオプション)を使うとフォントに関する内部処理が大きく変更される3ので、この場合もテストしておく。

% upLaTeX文書; UTF-8
\documentclass[uplatex,dvipdfmx,a4paper]{jsarticle}
\usepackage{otf}
\usepackage[ipaex,unicode]{pxchfon}% Unicode直接指定
\setminchofont{wlcmaru2004emoji.ttf}% 和田研中丸ゴシック
\begin{document}
%↓先頭にU+32FFの文字
㋿っ! \UTF{32FF}っ! \CID{23058}っ! \ajLig{令和}っ!
\end{document}

f:id:zrbabbler:20190407045915p:plain
japanese-otfでunicodeな出力結果

令和!

jlreqクラスする場合

jlreqクラスでは独自の和文VFが使われるので、念のためこれも試してみよう。

% upLaTeX文書; UTF-8
\documentclass[paper=a4]{jlreq}
\usepackage[ipaex]{pxchfon}
\setminchofont{wlcmaru2004emoji.ttf}% 和田研中丸ゴシック
\begin{document}
%↓U+32FFの文字がたくさん
㋿㋿㋿㋿ーン
\end{document}

f:id:zrbabbler:20190407045936p:plain
jlreqな出力結果

令和!

まとめ

まあ、LaTeX文書で元号の組文字を使う人なんていないだろうから、別にドウデモイイネ。


  1. 標準のフォントマップ設定(所謂“CMap指定”)の場合、AJ1対応のOpenTypeフォントよりもTrueTypeフォントの方が正常に出力するのが“難しい”。

  2. 実際には\ajLig{令和}はAJ1のCIDを利用して文字を出力している。AJ1-7において、「令和」の組文字は横組がCID 23058、縦組がCID 23059に割り当てられている。従ってこの場合、\ajLig{令和}\CID{23058}と等価になるが、フォントがAJ1対応でない場合、CID 23058・23059の指定は何れもUnicodeのU+32FFの指定に(dvipdfmxの内部処理において)フォールバックする。

  3. この場合、CID 23058・23059は和文VFを用いて明示的にUnicodeのU+32FFに変換されている。“Unicode直接指定”であるため「UnicodeのU+32FFのグリフ指定」がそのまま適用される。

TeXで令和してみるテスト(1)

以下の結果は最新(今日の版)のW32TeXでのもの。

TeX Liveについては、現在は2019のプレテスト中である。TeX Live 2019のリリースの予定日は4月30日であるので、新元号への対応を済ませたTeX Liveは連休明けの頃には一般に入手可能になっていると思われる。

\today の和暦表示で令和してみるテスト

TeXエンジンのSOURCE_DATE_EPOCHの機能を用いて「現在日時が2019年8月8日である」と見なされるようにする。

# 以下の環境変数を設定する
set SOURCE_DATE_EPOCH=1565222400
set FORCE_SOURCE_DATE=1

BXjsclsのクラスの場合

% upLaTeX文書; UTF-8
\documentclass[uplatex,dvipdfmx,ja=standard,a4paper]{bxjsarticle}
\和暦
\title{しあわせ{\TeX}言語入門}
\subtitle{~新時代の{\TeX}言語教科書~}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190406111821p:plain
bxjarticleな出力結果

令和!

jlreqクラスの場合

% LuaLaTeX文書; UTF-8
\documentclass[paper=a4]{jlreq}
\和暦
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190406111936p:plain
jlreqな出力結果

令和!

jsclassesのクラスの場合

% pLaTeX文書; UTF-8
\documentclass[uplatex,a4paper]{jsarticle}
\和暦
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190406112016p:plain
jsarticleな出力結果

アレ!

LuaTeX-jaのクラスの場合

% LuaLaTeX文書; UTF-8
\documentclass[a4paper]{ltjsarticle}
\和暦
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190406112038p:plain
ltjsarticleな出力結果

アレ!

Babelする場合

Babelパッケージを利用する場合、\todayの表記はBabelの言語定義の設定に従う。現在の版のBabelの日本語(japanese)用の定義では和暦がサポートされていて、jsclassesと同様に、\和暦命令で日本語用の\todayの表記が和暦に切り替わる。

% LuaLaTeX文書; UTF-8
\documentclass[a4paper]{ltjsarticle}
% なぜか唐突にエスペラント
\usepackage[main=japanese,esperanto]{babel}
\newcommand{\Eo}[1]{%
  \begin{otherlanguage}{esperanto}#1\end{otherlanguage}}
\和暦
\title{しあわせ{\TeX}言語入門\\
  \Eo{Feliĉa Kurso pri la Lingvo {\TeX}}}
\author{mal-ZR}
\date{\today\quad(\Eo{\today})}
\begin{document}
\maketitle
% Neniu enhavo.
\end{document}

f:id:zrbabbler:20190406112249p:plain
babelな出力結果

令和!

bxwarekiパッケージ

文書クラスが新元号に非対応(あるいはそもそも和暦に非対応)であっても、bxwarekiパッケージを使用すると正しい和暦表記が得られる。\warekitoday命令で今日の日付が和暦で出力されるので、明示的に\date\warekitodayを指定すればよい1

% pLaTeX文書; UTF-8
\documentclass[uplatex,a4paper]{jsarticle}
\usepackage{bxwareki}% 和暦したい
\title{しあわせ{\TeX}言語入門}
\author{非ZR氏}
\date{\warekitoday}% 明示指定する
\begin{document}
\maketitle
% 中身はまだ無い。
\end{document}

f:id:zrbabbler:20190406112105p:plain
bxwarekiな出力結果

令和!

まとめ

というわけで、もしアレだった場合はbxwarekiを使おう。


  1. bxwarekiパッケージは\todayの出力に関しては何の影響もおよぼさない。

jfmutilで和文VFをカスタマイズする話(1)

どうやらアヒルらしいので、雑に何か書いてみようと思う。

※ただし、例の「黄色い本」の10章に書いてあるようなVFのキホン的な事項については余裕で解っていることを前提とする(うわぁ)

事例1:倍角ダーシをつなげたい話

同人誌で小説を書く人の間では有名なように、世の中にはダーシを2つ並べた場合につながってみえるフォントと隙間ができるフォントがある。TeX Live(のDVIウェアのフォントマップ設定)において既定の明朝体フォントとなっている「IPAex明朝」はダーシがつながらない。

ダーシがつながらない例
ダーシがつながらない例

そして、世の中には「ダーシがつながる」ことに非常に拘る人がいる。それだけなら「ダーシがつながるフォントを選択すればよい」だけであるが、そういう拘りをもつ人は大抵フォント自体にも拘る。なので「〇〇のフォントが大好きだからぜひ使いたいのだけど、〇〇のダーシがつながらないのだけは困る」という悩みが出てくる。

VFを活用すると、「フォント〇〇を使いつつ、全角ダーシ(U+2015)だけは“つながるダーシ”をもつ別のフォント△△を使う」というような設定が可能になる。

要件を整理してみる件

  • upTeXの標準の横組和文フォントupjisr-hをカスタマイズして新しいフォントmy1upjisr-hを作製する。
  • my1upjisr-hでは全角ダーシ(U+2015)の字形が「梅明朝1」(ume-tmo3.ttf)のものになる。
    ※「梅明朝」は“つながるダーシ”の字形をもつ。
  • my1upjisr-hのその他の性質は全て元のupjisr-hに合わせる。
    • 従って、全角ダーシ以外の文字のフォントは“通常の”設定に従う。(TeX Liveの既定の設定では「IPAex明朝」である。)

基本的な設計を考える件

upjisr-hの参照関係は以下のようになっている2

upjisr-h (VF)
   0→uprml-h (原TFM)
   2→upjisr-hq (VF)
         0→uprml-hq (原TFM)

ここで現れる2つの原TFM3は「upTeXの標準の原TFM」であり、TeX Liveの和文フォント設定ツール(kanji-config-updmapなど)の設定対象となっている。初期設定では以下のようになっていて4、「IPAex明朝」が割り当てられている。

uprml-h   UniJIS-UTF16-H  ipaexm.ttf %!PS IPAexMincho
uprml-hq  UniJIS-UCS2-H   ipaexm.ttf %!PS IPAexMincho

さて、これから作製するmy1upjisr-hでは、「梅明朝」への参照を追加する必要がある。従って、新たな原TFMである「my1uprml-hd」5を用意して、それをフォントIDの1番に追加することにしよう6

my1upjisr-h (VF)
   0→uprml-h (原TFM)
   1→my1uprml-h (原TFM) ※追加
   2→upjisr-hq (VF)
         0→uprml-hq (原TFM)

これ以上の設計の詳細については、作業しながら考えていくことにしよう。

作業を開始する件

まずはupjisr-hのVFをZVP形式のテキストに変換する。

$ jfmutil upjisr-h

upjisr-h.zvpが出力されるが、これから行うのは「my1upjisr-hというVFを作る」ことであるので、ファイル名をmy1upjisr-h.zvpに変えておこう。

参照TFMを追加する件

ZVP形式においては、VPL形式と同様のFONTMAP要素によって参照TFMを定義を行う。

[my1upjisr-h.zvp:18行目]

(MAPFONT D 0
   (FONTNAME uprml-h)
   (FONTCHECKSUM O 0)
   (FONTAT R 1.0)
   (FONTDSIZE R 10.0)
   )
(MAPFONT D 2
   (FONTNAME upjisr-hq)
   (FONTCHECKSUM O 0)
   (FONTAT R 1.0)
   (FONTDSIZE R 10.0)
   )

ID=0にuprml-h、ID=2にupjisr-hqが定義されている。ID=1にmy1uprml-hdを追加することにしよう。

(MAPFONT D 1               ;ID
   (FONTNAME my1uprml-hd)  ;TFM名
   (FONTCHECKSUM O 0)      ;チェックサム値を使わない
   ; パラメタ……

参照TFMのパラメタはどうすればいいだろうか。元のupjisr-hのグリフはダーシも含めて大部分がuprml-hを用いて出力されている。ここで追加したいmy1uprml-hdとuprml-hを比べると物理フォントが異なる(これはVFの外で指定する事項)他は同じ性質をもつ前提である。なので、uprml-hと同じにすればよい。

(MAPFONT D 1
   (FONTNAME my1uprml-hd)
   (FONTCHECKSUM O 0)
   (FONTCHECKSUM O 0)
   (FONTAT R 1.0)          ;スケール
   (FONTDSIZE R 10.0)      ;my1uprml-hdのデザインサイズ
   )

これをmy1uprml-h.zvpに追記するわけであるが、その場所については一つだけ注意がある。ZVP中で最初に書かれたMAPFONTには特別な意味がある。なので、特にその意図がない限りは「先頭のMAPFONTがどれか」を変えてはいけない。その他については制約はなく7、特にIDの番号順に並んでいる必要はない。

ダーシの定義を与える件

VPL形式では(仮想の)グリフの定義はCHARACTER要素で行うのであった。ZVP形式のmy1upjisr-h.zvpを見ると、CHARACTER要素とJPL形式のTYPE要素が複合したような形の「中にMAP要素を含むTYPE要素」がある。

[my1upjisr-h.zvp:173行目]

(TYPE D 0
   (CHARWD R 1.0)
   (CHARHT R 0.88)
   (CHARDP R 0.12)
   (MAP
      (SETCHAR)
      )
   )

このようにZVP形式においてはグリフの定義は「TYPE要素」「SUBTYPE要素」「CHARACER要素」の組み合わせで表す。しかし、今回のように「メトリックの変更を伴わない」カスタマイズの場合は、取りあえずは「変更したい文字のCHARACTER要素を追記する8」という方法だけを知っていれば対処できる。今回はU+2015の定義を修正したいので、次のようなものを書くことになる。

(CHARACTER H 2015      ;U+2015の文字の定義
   (MAP
      ;仮想グリフを出力するDVI命令…
      )
   )

ここで、U+2015が元々どのように定義されていたかを確認してみる。CHARSINTYPEの定義から判断すると、U+2015は文字クラス5に該当するので、TYPEの5の定義を見る。

[my1upjisr-h.zvp:222行目]

(TYPE D 5
   (CHARWD R 1.0)
   (CHARHT R 0.88)
   (CHARDP R 0.12)
   (MAP
      (SETCHAR)
      )
   )

「引数のないSETCHAR」という妙な要素があるが、これはZVP形式独自の拡張で、「入力の文字と同じ文字コードのグリフをsetcharする」ことを表す9。つまり、U+2015に対する定義としては、この(SETCHAR)(SETCHAR H 2015)と等価になる。要するに、元の文字を何も加工せずにそのまま出しているだけである。

※そのまま出力するといってもフォントはどれになるのかが気になるだろう。実は、SELECTFONTを実行する前の「既定のフォント」は「ZVP中で最初に出現したMAPFONT」である。つまりU+2015の定義は「uprml-hのU+2015を出力する」となる。先に「先頭のMAPFONTは特別」と書いたのはこういう意味である。

今回のカスタマイズでは、U+2015のフォントをmy1uprml-hdに変えたいのであった。従って、SETCHARの前にSELECTFONT命令を入れればよい。

(CHARACTER H 2015      ;U+2015の文字の定義
   (MAP
      (SELECTFONT D 1) ;フォントをID=1の参照TFMに変える
      (SETCHAR)        ;U+2015を出力
      )
   )

VFが完成した件

以上でZVPの改修の作業は完了である。結局、以下のコードを追加することになった。

(MAPFONT D 1
   (FONTNAME my1uprml-hd)
   (FONTCHECKSUM O 0)
   (FONTAT R 1.0)
   (FONTDSIZE R 10.0)
   )
(CHARACTER H 2015
   (MAP
      (SELECTFONT D 1)
      (SETCHAR)
      )
   )

これらをmy1upjisr-h.zvpに追記した上で、VFに変換する。

> jfmutil my1upjisr-h

無事にmy1upjisr-h.vfとmy1upjisr-h.tfmが出力されれば、VFは完成である。

(つづけ)


  1. 「梅明朝」を選択した理由は単に“つながるダーシ”をもつフォントの一つであるからであり、それ以上の理由はない。物理フォントの選択はフォントマップの部分に切り出されるので後で他の物理フォントに変更するのも容易である。

  2. こういう情報は事前に知識として知っておく必要がある。知らないのであれば、取りあえずZVP形式に変換してその結果を読んで調査することになるだろう。

  3. 「VFではないTFM」のことをこの記事では「原TFM」を呼ぶことにする。jfmutilの説明書では「原メトリックTFM」、makejvfでは「PSフォントTFM」と呼ばれている。原TFMはフォントマップによって物理フォントに割り当てられる。

  4. これは「updmap用のフォントマップ」である。updmap用の和文のフォントマップは基本的にはdvipdfmx用のフォントマップの書式に準じるが、%!PSの後にdvips用の情報を補足するという規則になっている。

  5. TFMの名前は何でもよい。標準のTFMの「uprml-hq」の「q」は「引用符(quotation)用」という意図であろうから、それにならって「ダーシ(dash)用」ということで「-hd」という語尾にした。

  6. フォントIDの番号については、0~255の範囲で空いている番号なら何でもよい。なお、TFM名の語尾の「-hd」は「ダーシ(dash)用」という

  7. VPL形式については、確か「FONTMAPは全てCHARACTERの前に書く必要がある」などの制約があったはずである。

  8. 同じ文字のCHARACTER要素が複数回現れてはいけないので、既に当該の文字のCHARACTER要素がある場合はそれを修正する。

  9. 一般にVFのほとんどの文字は「入力と同じ文字コードのグリフをsetcharする」だけという単純なMAP定義をもつ。引数なしのSETCHARを導入することで、これらが全て「全く同一のMAP定義」と見なすことができて同じサブタイプにまとめることができるので、ZVPの記述を大幅に簡潔化できるわけである。

VFがアレでもjfmutilで変換できる話

jfmutilで和文VFの中身を調べる

jfmutilコマンドは、(u)pTeX系エンジンにおける和文用のTFMやVFファイルの作成・編集を支援するための機能を集めたユーティリティプログラムである。欧文TeXにおけるpltotfやvptovfなどのコマンドに対する和文版に相当する。

TeX LiveおよびW32TeXに標準で含まれている。
※詳細については過去の記事も参照してほしい。

例えば、jfmutilの「vf2zvp」サブコマンドを用いると、和文のVF(.tfm.vfの組)をテキスト形式(ZVP形式1)に変換することができる。

> jfmutil vf2zvp upjisr-h

これを実行する2と、upjisr-h(upTeXの標準和文フォントの一つ)の情報をテキストで表した、以下のようなファイルが出力される。

[upjisr-h.zvp]

(VTITLE )
(FAMILY UPJIS KANJI)
(FACE F MRR)
(CODINGSCHEME TEX KANJI TEXT)
(DESIGNSIZE R 10.0)
(CHECKSUM O 0)
(FONTDIMEN
   (SLANT R 0.0)
   (SPACE R 0.0)
   (STRETCH R 0.1)
   (SHRINK R 0.0)
   (XHEIGHT R 1.0)
   (QUAD R 1.0)
   (EXTRASPACE R 0.25)
   (EXTRASTRETCH R 0.2)
   (EXTRASHRINK R 0.125)
   )
(MAPFONT D 0
   (FONTNAME uprml-h)
   (FONTCHECKSUM O 0)
   (FONTAT R 1.0)
   (FONTDSIZE R 10.0)
   )
(MAPFONT D 2
   (FONTNAME upjisr-hq)
   (FONTCHECKSUM O 0)
   (FONTAT R 1.0)
   (FONTDSIZE R 10.0)
   )
(GLUEKERN
   (LABEL D 0)
   (GLUE D 1 R 0.5 R 0.0 R 0.5)
   (GLUE D 3 R 0.25 R 0.0 R 0.25)
   (STOP)
;(…略…)
(TYPE D 0
   (CHARWD R 1.0)
   (CHARHT R 0.88)
   (CHARDP R 0.12)
   (MAP
      (SETCHAR)
      )
   )
(TYPE D 1
   (CHARWD R 0.5)
   (CHARHT R 0.88)
   (CHARDP R 0.12)
   (MAP
      (MOVERIGHT R -0.5)
      (SETCHAR)
      )
   )
;(…略…)

このZVP形式のテキストファイルから本来のVF(.tfm.vfの組)に変換するためのサブコマンド「zvp2vf」も用意されているので、これらを利用することで既存の和文VFの編集が可能になる。

upnmlminr-hを変換しようとするとアレ

ところが、フォントによってはvf2zvpの変換が失敗することがある。例えば、[japanese-otf]パッケージのupTeX用のフォントの一つであるupnmlminr-hの中身を調べたいと思って、vf2zvpを使おうとしても、エラーが出て変換は失敗していしまう。(ちなみに、pTeX用のnmlminr-hは大丈夫である。)

> jfmutil vf2zvp upnmlminr-h
jfmutil: CHARWD value mismatch: code 00B7

このエラーの意味は「符号位置0xB7の文字の幅について、.tfm.vfに記録された値が食い違っている3」ということである。この動作自体は正常であり、実際にupnmlminr-hにおいて、0xB7の文字の幅の値は食い違っている4。従って、厳密に言うと当該のVFは「壊れている」ので変換のしようがない、ということになる。

しかし、実際の運用としては、どのDVIウェアも「.vfの方の文字幅の情報は無視する」という動作をする。なのでupnmlminr-hは「実際にはちゃんと使える」のである。となると、この「.vfの文字幅は無視する」という慣習を前提にした上でとにかく変換はしてほしい、と思うことになるだろう。

アレでもとにかく変換してしまう件(--lenientオプション)

このような事態に対処するため、jfmutilの1.2.0版(2019-02-02付)において、--lenientというオプションが追加された。

  --lenient       ignore non-fatal error on VFs

--lenientを指定すると、「実用上は問題ない軽微なエラー」を無視して(実用に即した)変換を行うようになる。

> jfmutil vf2zvp --lenient upnmlminr-h

[upnmlminr-h.zvp;抜粋]

(CHARSINTYPE D 3
   X00B7 X30FB XFF1A XFF1B
   )
;(…略…)
(TYPE D 3
   (CHARWD R 0.5)
   (CHARHT R 0.88)
   (CHARDP R 0.12)
   (MAP
      (MOVERIGHT R -0.25)
      (SETCHAR)
      )
   )

この結果をみると、0xB7の文字(符号化がUnicodeであるので、これは「U+00B7 MIDDLE DOT」のことである)の文字クラスは3で、.tfmの情報に従って文字幅は0.5zw5となっている。


  1. 欧文のVPL形式に相当するもので、書式はVPL形式とJPL形式を混ぜたようなものになっている。

  2. なお、.vfファイルや.tfmファイルなどの“TeXシステムにおける標準的なファイル形式”に関しては、Kpathseaの検索が有効なので、upjisr-h.tfmやupjisr-h.vfはカレントにある必要はなく、インストールされていれば十分である。jfmutilの独自形式(.zvp等)のファイルはKpathseaの検索対象にならない。

  3. つまり、VFの仕様としては、文字の幅は.vf.tfmの両方に記録されることになっている。なぜそのような仕様であるかはよく解らない。なお、文字の高さと深さの情報は.tfmのみに記録される。

  4. 0xB7の文字の幅は、upnmlminr-h.tfmでは0.5zwでupnmlminr-h.vfでは1zwとなっている。jfmutilの「tfm2zpl」や「vf2zvp0」のサブコマンドを使うと、.tfm.vfを単独でテキスト形式に変換できるので、これらを使うとそれぞれの文字幅の情報が確認できる。

  5. 厳密にいうとCHARWDの0.5は「要求フォントサイズを単位として0.5単位」を表す。upnmlminr-hでは1単位が1zwに等しいので0.5zwということになる。