マクロツイーター

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

またもやアドベントがはじまった ― \begin{texadvent2025}


TeX & LaTeX Advent Calendar 2025

TeX界における年末の恒例イベントとなったということにまたもやしたいアドベントカレンダーが今年も始まりました。今年は14回目の開催となります。

重点テーマ

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

「(La)TeXをカンタンにする方法」

どうやらイマドキはカンタン😍な組版ソフトウェアが流行りのようです。これまでの(la)TeXはその複雑性を誇ってきた歴史がありますが、今年は少し視点を変えて、カンタン😍な(La)TeXの話をしてみましょう。

※例によって、重点テーマは「必須」ではありません。あらゆるTeXネタを歓迎しております。

で、初日のネタは

こちらになります。

blog.wtsnjp.com

まだ参加できます!

TeX & LaTeX Advent Calendar 2025(#texadvent2025)は

まだまだ参加者募集中です。

カンタンなLaTeX数式の話、カンタンなTeX環境構築の話、カンタンな展開制御の話、カンタンな新マクロパッケージ開発の話、カンタンな \expandafter シャウトの話、その他、お持ちの方はぜひぜひ、

ご参加おねがいします!

今ならまだ好きな日を選べます! 登録はお早めに!

* * *

Typst推し✨な人はこっち。

Typst Advent Calendar 2025

エッ、SATySFi……? そういえば、昔そんな名前のやつがありましたね……😐

またもや去年のアレ(アレ)を振り返ってみる


TeX & LaTeX Advent Calendar 2025

昨年(2024年)の「TeX & LaTeX Advent Calendar」はこんな感じでした。

12/01zr_tex8rLaTeXでもっと段落を継続できる件 #LaTeX
12/02津茶利休TeXの表組みで区切り文字をコンマにして読みやすく書く
12/03doraTeX共通テスト「情報Ⅰ」対策の計算練習帳をexpl3でランダム生成する
12/04ut獣を馴らす準備
12/05鴎海ねこTeX-MyTools/unicode-math-snippets at main
12/06ththTeX で限界を突破する
12/07CareleSmith9LaTeX だけ勉強しても周辺知識が足りないよねという話
12/08zr_tex8rLuaLaTeXを爆速にする方法(※ただし画期的)
12/09CareleSmith9hm Latain Modern—フォントをいじった話
12/10k16shikanoLaTeXでコードブロックの長い行を折り返せるfvextraを手なずける
12/11ut長い s と丸い r
12/12津茶利休一度きりのTeX実行で番号参照する試み
12/13zr_tex8r某ZR的徹底比較! LaTeXとTypstの数式記法
12/14TPKatoQA: 日本語版 chemfig マニュアル
12/15MatsuiOverleafのGit連携でGitHub上にバックアップ
12/16やまい行分割アルゴリズムの話。
12/17250kLuaTeXの数式用追加プリミティブについて
12/18zr_tex8rLaTeXで☃のマフラーの塗り潰しをもっともっと指定する方法
12/19doraTeX共通テスト「情報Ⅰ」対策教材の組版技法
12/20tasusuTikZを使って文書内の好きな位置に注釈をつける
12/21_MadChemiker_(8) mol2chemfig でお手軽に分子を描いてみる
12/22hid_alma1026LaTeXに触れられなくなってきた人間の『TikZによるLaTeXグラフィックス』読書
12/23wtsnjpもうLaTeX文書は生成AIに書かせよう
12/24k16shikanoTeXの「エンコーディング」とは何だったのか
12/25zr_tex8r重点解説! イマドキのLaTeXの“命令フック機能”

というわけで、今年はこれを1Qも参考にせずに、自分が素敵だと思うネタを全力でぶつけていきましょう!

今年もまたもやTeXでAdvent Calendarする件について

またもや!!


TeX & LaTeX Advent Calendar 2025

TeXLaTeX Advent Calendar 2025

とっておきのTeXLaTeXネタを皆で持ち寄って楽しむ
TeX & LaTeX Advent Calendar」
今年は 14回目 の開催となります。
皆さんの、心をこめた素敵なネタを例によってお待ちしております!
ハッシュタグは「 #texadvent2025 」
TeXLaTeX初心者大歓迎。 ←重要
TeXLaTeX非初心者大歓迎。

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

(La)TeXをカンタンにする方法

今年の重点テーマ

今年の重点テーマはコレです。 「(La)TeXをカンタンにする方法」

よく言われているようにTeXは“奥が深い”ソフトウェアで、極めれば極めるほど膨大な可能性を手にすることができます。しかしそのせいか、(La)TeXの話はどうしても「もっと難しくする」方向に発展しがちです。でも現実を鑑みると、(La)TeXのユーザの大多数は初心者であり、その人たちの多くは(La)TeXカンタンに使いたいと思っているはずです。

「スゴイ(La)TeXの話」は一旦脇に置いて「カンタンな(La)TeXの話」をして(La)TeXの裾野を拡げていきましょう。

参加方法

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

  • 「(La)TeXをカンタンにする方法」に大いに関連するTeXLaTeXネタ。
  • 「(La)TeXをカンタンにする方法」にチョット関連するTeXLaTeXネタ。
  • 「(La)TeXをカンタンにする方法」にサッパリ関連しないTeXLaTeXネタ。

このように、以前と同じく、TeXに関連するもの(\expandafter 睡眠法😴とか、\futurelet 快眠法😴😴とか、\afterassignment 熟睡法😴😴😴とか、……)なら何でも構いません。

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

イマドキのTypstでも安心してsc1Typstできる件

今日11月11日は、皆さんお待ちかねのきりたんぽの日

そして皆さんご存じの通り、きりたんぽの日といえばsc1Typstですね!1

念のため、sc1Typstについて語ってみる

sc1Typstは2年前(2023年)のきりたんぽの日にリリースされたTypst画期的なテンプレートモジュールで、​「1」をたくさん書くことにより本質的な文書を作ることを目的としています。

同日に(ツイッタァー上で)開催されたナントカConf2023においてsc1Typstの概要についての発表を行いました。

念のため、sc1Typstの動作を確認してみる

さてそんな画期的なsc1Typstですが、リリース当時の最新のTypstのバージョンは0.9.0版でした。それから2年の間にTypstは改版を重ねて今は0.14.0版になっています。現状のTypstはベータ版の段階であり多数の非互換変更が行われています。なのでsc1Typstが最新版のTypstで動作しなくなっている可能性もありそうです。

画期的なsc1Typstが動かなかったら問題なので、チョット動作確認してみましょう😃

[test.typ]

#import "sc1typst.typ":*; #show:_1
111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111
1111111111111111111

この文書ソースファイルを0.14.0版のTypstでコンパイルしてみます。出力結果は……。

出力結果(素敵😊)

……問題ないですね(素敵😊)……アレレ?

>typst c test.typ
warning: the `path` function is deprecated, use `curve` instead
    ┌─ \\?\C:\tmp\sc1typst.typ:100:65
    │
100 │ "1111Il111II111II111111!l1));1111!l(I111I111l1!1l1111)}}";};l111(l11(l1I))
    │                                                                  ^^^^^^^^

何やら警告が出てますね……😲

この警告はTypstのpath関数に関するものです。この関数はスプライン曲線を描くためのものですが、0.13.0版において新設のcurve関数に置き換えられることになり非推奨の扱いになりました。非推奨機能は近い将来のバージョンにおいて廃止される可能性が高いので、これでは画期的なsc1Typstを安心して使い続けることができません😨

ざんねん🙃

ざんねん🙃のため、sc1Typstを改修してみる

画期的なsc1Typstが将来動かなくなるのは大問題なので、改修しました😃

改修後の新しいsc1typst.typを用いてさっきのtest.typをコンパイルしてみると……

>typst c test.typ

>

警告が消えてイイカンジ🙂 そして出力結果は……

出力結果(素敵😊)

やっぱり素敵😊

念のため、sc1Typstの改修を語ってみる

もしかしたら、読者の中に改修内容、特にpath関数についての対処法3に興味がある人がいるかもしれません。そこで、改修時のsc1Typst.typの差分を示しておきます。

……うーむ、これは(例によって)チョット読みにくいですね(ざんねん🙃)

まとめ

⛄「sc1Typstが新しくなったのはスバラシイけど、それより今年のナントカの日のネタを早く(ry


  1. エッ、1TeX? 何ソレおいしいの?
  2. ナントカConf2023はツイッタァー上での開催であるため、これらの一連のツイートが「発表内容」です🙃
  3. 新しいcurve関数は古いpath関数を単に改名したものではなく、そもそも曲線の指定の方法なども含めて両者で大きく設計が異なるため、curveに置き換える作業は決して自明ではありません。

LaTeXでフツーにエスペラントする方法

この辺りの話をもう少し詳しく解説しておく。

フツーにエスペラントするコツ

LaTeXエスペラントを含む文書をフツーに作りたいという場合に絶対に把握しておくべきポイントがあります。それは

Unicode LaTeXを使え

ということです。つまり、フツーにエスペラントしたかったらLuaLaTeXまたはXeLaTeXを使う必要があるわけです。

その理由は明確で、エスペラントでは割と独特の(他の西欧語では見かけない)アクセント付き文字が使われるからです。

Ĉĉ Ĝĝ Ĥĥ Ĵĵ Ŝŝ Ŭŭ

一方でレガシーなLaTeXで通常使われる文字コードはOT1やT11であり、これでエスペラントを書こうとすると明らかに文字が不足しています。

OT1の文字コード

T1の文字コード

ここで「でもLaTeXではアクセント付き文字は合成で作れるから別に問題ないんじゃないの」と思ったかもしれませんが、それは違います。LaTeXの重要な機能の一つに「行分割の際に自動的に単語を分綴(ハイフンを付けて分割)する」ことがありますが、分綴処理では「単語を文字列として扱う」ことが前提になるため“本物の文字”が必要となるのです。

一方で、エスペラントの文字は当然Unicodeでは全てサポートされているため、Unicode LaTeXであれば分綴の問題は解決されています。実際、現在のTeX LiveのLuaLaTeX・XeLaTeXではエスペラントを扱うための準備が整えられています2。だからエスペラントフツーに扱いたければ、当然エスペラントフツーに扱えるLaTeXを選ぶべきなのです。

フツーにエスペラントする例

「LuaLaTeXかXeLaTeXを使う」ということさえ解っていれば、後の話は簡単3です。フランス語やドイツ語の文書を作る場合と同様で、Babel(やPolyglossia)をフツーに読み込んで“文書の言語”をフツーにエスペラントに設定するだけです。もしさらに文書を素敵⛄にしたいのであれば、フツーにscsnowmanパッケージを読み込みましょう(素敵😊)

ここではLuaLaTeX+Babelを利用することにします。

[example1.tex]

% LuaLaTeX-a dokumento, en UTF-8
\documentclass[a4paper,twocolumn]{article}
\usepackage[svgnames]{xcolor}
\usepackage{scsnowman,bxcoloremoji}
% Esperantu!
\usepackage[main=esperanto]{babel}
% Dokumentaj informoj
\title{Ni Esperantu!}
\author{S-ro Iu Iea\coloremoji{🙃}}
\date{\today}
\begin{document}
\maketitle

\section{Mi Estas Kato\coloremoji{🐱}}

Mi estas kato.
Mi ankoraŭ ne havas nomon.

Mi tute ne scias, kie mi naskiĝis.
Mi memoras nur, ke mi miaŭis en iu obskura kaj malseka loko.
Tie mi unuafoje vidis tion, kion oni nomas homoj.
Kaj krome, kiel mi poste eksciis, ĝi estis studento,
laŭdire la plej kruela raso inter la homoj.
Oni diras, ke tiu studento foje kaptas nin
kaj boligas kaj manĝas.
Sed en tiu tempo mi havis nenian penson, do mi ne aparte timis.
Kiam li min levis sur la manplato,
nur mi sentis min leĝere ŝvebanta.

\newpage

\section{Konkludo}

Neĝhomo estas mirinda!\coloremoji{😊}

% Esenco😍
\begin{center}
\scsnowman[scale=12, hat=Green, muffler=Red,
  arms=Brown, snow=SkyBlue, buttons=RoyalBlue]
\end{center}

% La Fino🙂
\end{document}

この文書ファイルはフツーにlualatexコマンドでタイプセットできます。

lualatex example1.tex

エスペラントの文書の出力結果(素敵😊)

カンタン😍

日本語文書でフツーにエスペラントする例

ご存じの通り、LuaLaTeXでは日本語を扱えるため、「LaTeXエスペラントが混じった日本語文書」も作れます。フツーにBabelの多言語用の設定(基底言語が日本語、追加言語がエスペラント)をするだけです。

[example2.tex]

% LuaLaTeX文書; UTF-8
\documentclass[paper=a5]{jlreq}
\usepackage{bxcoloremoji}
% メインは日本語, 時々エスペラント
\usepackage[esperanto,main=japanese]{babel}
\newcommand*{\cEo}{\foreignlanguage{esperanto}}
\newcommand*{\cE}{\coloremoji}%絵文字
\newcommand*{\cLineSkip}{\par\vspace{\baselineskip}}%1行空き
% 文書情報
\title{エスペラントの本質的\cE{}な話}
\author{某ZR}
\date{あさって}
\begin{document}
\maketitle

\section{「ゆきだるま\cE{}」の表現}

エスペラントで「ゆきだるま」を表す単語はいくつかありますが、
最も一般的なのは“\cEo{neĝhomo}”です。
これは英語のsnowmanと同様に
“\cEo{neĝ}-”(雪)と“\cEo{hom}-”(人)からなる合成語です。
「ゆきだるま」はイタリア語では“\mbox{pupazzo di neve}”、
つまり「雪の人形」といいますが、
これと同様の構成で
“\cEo{neĝ}-”(雪)と“\cEo{pup}-”(人形)からなる
“\cEo{neĝpupo}”という単語もあります。
\cLineSkip
\begin{quote}
\cEo{Grupo da neĝhomoj flugas en la ĉielo.}\\
雪だるまの群れが空を飛んでいます。
\cLineSkip
\cEo{Mia neĝpupo apenaŭ iam enterigas \cE{🙃}.}\\
うちの雪だるまは滅多に\cE{🙃}を埋めません。
\end{quote}

\end{document}

この文書もフツーにlualatexでタイプセットできます。

エスペラント入り日本語文書の出力結果(チョット素敵🙂🙂)

カンタン😍

まとめ

というわけで、LaTeXエスペラントしたい場合は、難しいことは一切考えずにフツーにカンタン😍な手段を選びましょう!💁


  1. 標準的なLaTeXの構成でサポートされているラテン文字エンコーディングはOT1やT1の他にもありますが、エスペラントのアルファベットの全ての文字を含むものはありません。「新たにエンコーディングを定義すること」も可能ですが、その場合その新たなエンコーディングに基づく(TeXの意味での)フォント一式も用意する必要があり、膨大な手間がかかります。
  2. Unicodeに基づくエスペラント用の分綴パターンは既に組み込まれていますし、またUnicode LaTeXの既定の欧文フォント(Latin Modern)はエスペラントの文字を全てサポートしています。
  3. もちろん、これまでにLuaLaTeXやXeLaTeXを使った経験がない場合は、新しいLaTeXの使い方を修得するのに相応の手間がかかるわけですが……。

Typstでの文字のsizeとサイズの話

この​「フォントサイズが実際にどう決まるのか」​という件について、もう少し詳しく説明する。

以下に述べる内容はTypstを実際に使う実験試行から導出したものである。公式の仕様ではないことに注意してほしい。

フォントサイズはどう扱われるか

まずはフォントサイズに関する基本的な事項を確認する。

  • Typstでのテキストのフォントサイズは「textエレメントのsizeパラメタ」(以降ではこれをtext.sizeと書く1ことにする)の値に一致する。
  • このtext.sizeパラメタはlength型の値をとる。
  • text.sizeパラメタの値を変更したい場合はset規則を用いる。
    例:set text(size: 20pt)
  • Typstの各種のエレメント(rawエレメント、math.equationエレメント、……)は種類ごとに異なる独立したtextエレメントのパラメタ」を保持していて、当然その中にはtext.sizeも含まれる。
  • rawエレメントのテキストのフォントサイズは「rawのtext.size」の値に一致する。
  • 「rawのtext.size」の値を変更したい場合はshow-set規則を用いる。
    例:show raw: set text(size: 20pt)
  • エレメント独自の方ではない本来のパラメタのことを本記事では「メインのパラメタ」と呼ぶことにする。

以上の事項を確認するための例を示す。

// Typstの既定のフォント設定だと"フォント自体の見かけの大きさ"が
// 不揃いであり紛らわしいので, 同じ系統のフォントに合わせる.
#set text(font: "Harano Aji Mincho")
#show raw: set text(font: "Harano Aji Gothic")

#set text(size: 14pt) // フォントサイズを設定
#show raw: set text(size: 14pt) // "rawのフォントサイズ"を設定
☃は素敵。// 14pt
`☃は素敵。`// 14pt

// text.sizeと"rawのtest.size"は独立して設定可能.
#set text(size: 10pt)
#show raw: set text(size: 20pt)
☃は素敵。// 10pt
`☃は素敵。`// 20pt

出力結果

em部分はどう扱われるか

Typstのlength型は、絶対的な長さ(abs)とフォントサイズ相対の長さ(em)からなる複合的な値2(例えば4pt+2em)である。length型の値を「実際の長さ」として解釈する場合にはem部分の値は「現在コンテキストのtext.sizeの値」として換算される(text.sizeが11ptであれば4pt+2emは26ptと解釈される)。一方で、set規則やshow-set規則でtext.sizeパラメタの値を設定する際に「現在コンテキスト」を参照するのは望ましくないだろう。

text.sizeの設定の際にはem部分は以下のように扱われる。

  • set規則やshow-set規則でtext.sizeに「Apt+Eem」を設定すると、実際には「『現在のtext.sizeの値』を E 倍して Apt を加算した値」に更新される。
  • 例えば「現在のtext.size」が8pt+2emであるときにset text(size: 5pt+0.5em)を実行すると、text.sizeの値は(8pt+2em)*0.5+5pt、つまり39pt+1emに更新される。
  • em部分が「現在のコンテキスト」に基づいて“解決”されるのではないことに注意。更新後の値も一般的にはem部分を持つ。
  • ただし、前述の規則から導かれる性質として、現在値がem部分を持たない場合は、どんな値を設定しても更新後の値は決してem部分を持たない。例えば現在値が11ptのときにset text(size: 5pt+0.5em)を実行すると10.5ptに更新される。
  • メインのtext.sizeの初期値は11ptである。従って先述の規則により、メインのtext.sizeは決してem部分を持たない。

text.sizeの値から「実際のフォントサイズ」を求める際にはem部分は以下のように扱われる。

  • メインのtext.sizeはem部分を持たないのでその扱いを考える必要はない。メインのtext.sizeは常に絶対的な長さでこれがそのまま「実際のフォントサイズ」となる。
  • rawのtext.sizeはem部分を持つ。これは当該のrawエレメントを含むすぐ外側のコンテキストの「実際のフォントサイズ」に換算される。
  • 例えば、rawのtext.size4pt+0.5emであり現在のフォントサイズが11ptである場合、rawエレメントの「実際のフォントサイズ」は9.5ptとなる。

text.sizeの初期値は以下の通りである。

  • メインのtext.size11pt
  • rawのtext.size0.8em

ここまで述べた規則を考慮すれば、メインとrawのフォントサイズを完全に把握することができるはずである。

実際にフォントサイズはどう扱われるか

さて今まで散々「規則」を述べてきたわけであるが、Typstの動作がそれと一致していなければ意味がない。そこで実際のTypstの動作を確認したいわけであるが、それには「現在のフォントサイズ」を調べる手段が必要である。

Typstの「現在のフォントサイズ」を調べる

Typstのコードモードにおいてtext.sizeという式を書くと現在のコンテキストにおけるtext.sizeの値が取得できるはずである。ただし実際の動作としてはこれで取得できる値はem部分を解決した後の「現在のフォントサイズ」のようである。ともかく、以下のマークアップで「現在のフォントサイズ」を知ることができる。

#context [#repr(text.size)]

ただしrawエレメントについてはその特質上「rawの中でコードモードに移行する」ことができないので、「現在のフォントサイズ」を知るには少しトリックが必要である。以下のようなコードを利用する。

#show raw: _ => repr(text.size)

すなわちshow規則を利用して「rawの中でコードモードに移行する」ことを無理やり実現するわけ4である。このshow規則が有効な状態で​`x`​と書くと、“x”の代わりに「rawでの現在のフォントサイズ」が出力される。

合わせると、以下のようにcurrentを定義5すると#currentでメイン・raw内の「現在のフォントサイズ」が出力されることになる。

#let current = context {
  show raw: it => repr(text.size)
  [#repr(text.size) / `x`]
}

Typstの「フォントサイズの規則」を調べる

動作確認用に以下の文書コードを用意した。

// 現在フォントサイズを表示するやつ
#let current = context {
  show raw: it => repr(text.size)
  [#repr(text.size) / `x`]
}

//// 実験用コード

// raw/text.size = 0.8em
#show raw: set text(size: 8pt+2.5em)
// raw/text.size = 8pt+2em
#show raw: set text(size: 5pt+0.5em)
// raw/text.size = 9pt+1em
#show raw: set text(size: 2em-13pt)
// raw/text.size = 5pt+2em

// text.size = 11pt
#current // "11pt / 27pt"となるはず

#set text(size: 20pt)
// text.size = 20pt
#current // "20pt / 45pt"となるはず

このコードの要点は以下の通りである。

  • rawのtext.sizeへの設定を何度か繰り返すことで、設定の規則が自分の想定通りになっていることを確認する。
  • メインのtext.sizeの2通りの設定の下でメイン・rawの現在フォントサイズを調べることで、rawのtext.sizeが内部的にはem部分を持っている(そこはメインのフォントサイズに換算される)ことを確認する。

実際にTypstでコンパイルすると以下の出力が得られた。

出力結果

このコードの範囲では、全て想定通りに動作していることが判った😊

まとめ

Typstはナニカより簡単😍(簡単😭)


  1. 実際にTypstのコードモードでtext.sizeと書くことでこのパラメタの現在コンテキストでの値を取得することができる。もちろん「現在コンテキスト」が確立している(例えばcontext式の中にいる)必要がある。
  2. TeXCSSにおいては「長さの値」は絶対的な部分しか持たず、“em単位”は常にその場で解釈される。例えばTeXにおいてem値が12ptのときに\dimen0=1emの代入を行ったとすると、\dimen0がもつ値は単に12ptとなる。これに対してTypstでlet len=1emの代入を行ったとするとlenがもつ値は“1em”そのものとなり、これの実際の長さは「現在のコンテキスト」に応じて変化する。
  3. 実際にTypstでコードモードで(8pt+2em)*0.5+5ptという式の値は9pt+1emとなる。
  4. なお、rawに対するshow規則のコードは「raw独自のtext関連パラメタ」が適用された状態で実行される。show規則の仕様で、この状態のコンテキストが暗黙的に確立されている。
  5. このcurrentが関数ではなく「単一のcontent値」であることにも注意してほしい。currentは「コンテキストに依存するcontent値」であるため、書いた場所によって全く異なる出力になることが可能である。

jlreqしてjlreq-deluxeしてpxchfonしてunicodeする方法

アレForumの質問についての話。

その問題

jlreqクラスの文書でjlreq-deluxeパッケージ1を利用して多書体化している状況において、pxchfonパッケージ和文フォントを変更する場合に、unicodeオプションを指定して“Unicode直接”モードに切り替えると、エラーが発生する。

※jlreq-deluxeを使っていない場合は大丈夫である2

% upLaTeX文書, UTf-8 (以下の例も同じ)
\documentclass[uplatex,dvipdfmx,a4paper]{jlreq}
\usepackage{jlreq-deluxe}
% これはエラーになる
\usepackage[yu-win10,unicode,jis2004]{pxchfon}
\begin{document}
巷で噂の葛飾区☃
\end{document}

(エラーメッセージ)

! Font JT2/hmc/m/n/10=zu-jlreq--upnmlminrn-v at 10.0pt not loadable: Metric (TF
M/OFM) file not found.

pxchfonにおいてnoto-otcsourcehan等の “AI0なフォント3 のためのプリセットを指定する場合はunicodeが自動で有効になる4ため、そういうプリセットを指定したときも同じエラーになる。

\documentclass[uplatex,dvipdfmx,a4paper]{jlreq}
\usepackage{jlreq-deluxe}
% 'unicode'が自動で有効になるのでエラーになる
\usepackage[noto-otc,jis2004]{pxchfon}
\begin{document}
巷で噂の葛飾区☃
\end{document}

その対策方針

前提として、pxchfonパッケージで“Unicode直接指定”モード(unicodeオプション)を有効にする際にはpxufontパッケージが読み込まれて和文フォント設定5が変更される。この設定変更のことをここでは仮に Unicode直接化” と呼ぶことにする。

件のエラーの原因は「そもそもjlreq-deluxeが提供する和文フォント設定が“Unicode直接化”をサポートしていない(そのための和文TFM/VFが提供されていない)」からである。だから「必要な和文TFM/VFを自分で作成する」ことをしない限り完全に解決することは不可能である。

完全な解決は不可能なので次善策を考えることにする。そもそも“Unicode直接化”の目的は「“AJ1を利用した機能”をベストエフォートでエミュレートする」ことである。従って​「“AJ1を利用した機能”を諦める」​という前提であれば“Unicode直接化”を行わずに“AI0なフォント”を使うことができる。

実際に、TeX Liveでは“そういう設定”を行うためのdvipdfmxのマップファイル群が用意されている。$TEXMF/fonts/map/dvipdfmx/ptex-fontmapsの下にある“AI0なフォント”用のマップファイルがそれである。

  • noto/*.map: 「Noto Serif/Sans CJK JP」OTF版
  • noto-otc/*.map: 「Noto Serif/Sans CJK JP」OTC
  • sourcehan/*.map: 「源ノ明朝/角ゴシック」OTF版
  • sourcehan-otc/*.map: 「源ノ明朝/角ゴシック」OTC

この次善策を利用する場合に気を付けないといけないのが“AJ1を利用した機能”である。これは以下のものを含むが、特にクオートに注意が必要である。

  • \CID命令
  • 文字出力命令の\aj~の一部6
  • ルビ用仮名・エキスパート仮名字形
  • クオート文字: ‘ ’ “ ”

もし仮にこれらの文字が使われたとすると、それが「想定通りのフォントで出力される」ことはありえないので「何か別のことが起こる」ことになる。特に「他のフォントで出力される」場合は見た目上は正常なので厄介である。先述のTeX Liveのマップファイルを真っ当に(kanji-config-updmapで)設定した場合は非埋込で出力される。「dvipdfmxの-fオプションで指定する」などの用法の場合は、指定の方法により異なり、例えば「既定のフォントマップ設定に従う(別のフォント7になる)」こともありえる。このため、先述の次善策を利用する場合は、出力PDFについて「想定された以外のフォントが使われていないか」を綿密にチェックする必要があるだろう。

その対策方法

ここからは、先述の「次善策」をpxchfonの機能を利用して実行する方法を説明する。

方法1:TeX Liveのマップファイルを読み込む

pxchfonには「既存のマップファイルを読み込んでそれをプリセットの代わりにする」という機能(ファイルプリセット機能)がある。先述のTeX Liveのマップファイルを利用するには、pxchfonの読込時に以下のオプションを指定すればよい。

  • tl:noto: 「Noto Serif/Sans CJK JP」OTF版
  • tl:noto-otc: 「Noto Serif/Sans CJK JP」OTC
  • tl:sourcehan: 「源ノ明朝/角ゴシック」OTF版
  • tl:sourcehan-otc: 「源ノ明朝/角ゴシック」OTC

※この方法を利用した場合、“AJ1を利用した機能”の文字は非埋込になる。

tl:noto-otcを使用した例を示す。これは2004JIS字形で出力される。

\documentclass[uplatex,dvipdfmx,a4paper]{jlreq}
\usepackage{jlreq-deluxe}
\usepackage[tl:noto-otc,jis2004]{pxchfon}
\begin{document}
巷で噂の葛飾区☃\par
\bfseries
巷で噂の葛飾区☃\par
\end{document}

※jlreq-deluxeの既定動作ではjapanese-otfパッケージをjis2004付で読み込む。事態が複雑になるのを避けるため、pxchfonのjis2004の指定は原則としてjapanese-otfに合わせるべきである8

出力結果

もし敢えて90JIS字形(2000JIS字形)にしたい場合は以下のように各パッケージにオプションを指定する。

\documentclass[uplatex,dvipdfmx,a4paper]{jlreq}
% 既定動作の'jis2004'を無効にする
\usepackage[jis2004=false]{jlreq-deluxe}
% 'jis2004'を付けない
\usepackage[tl:noto-otc]{pxchfon}
\begin{document}
巷で噂の葛飾区☃\par
\bfseries
巷で噂の葛飾区☃\par
\end{document}

出力結果

方法2:“Unicode直接化”を抑止する

pxchfonではunicodeオプションを指定して“Unicode直接指定”を有効にした場合は“Unicode直接化”を実施する(pxufontを読み込む)のであるが、この“Unicode直接化”を敢えて無効にする設定も用意されている。上級者向けの設定でありマニュアルにすらちゃんと説明がされていないのであるが、今回の「次善策」の実現に利用できるのでここで紹介しておく。

unicodeオプション(またはそれを自動有効化するプリセットオプション)と一緒に以下のようにオプションを指定する。

  • legacycode-replace=false,legacycode=ignore: “Unicode直接化”を無効にする。“AJ1を利用した機能”については既定のフォントマップ設定(別のフォント)が適用される。

noto-otcプリセットを使用した例を示す。2004JIS字形の場合は以下の通り。

\documentclass[uplatex,dvipdfmx,a4paper]{jlreq}
\usepackage{jlreq-deluxe}
\usepackage[noto-otc,legacycode-replace=false,legacycode=ignore,jis2004]{pxchfon}
\begin{document}
巷で噂の葛飾区☃\par
\bfseries
巷で噂の葛飾区☃\par
\end{document}

出力結果

90JIS字形にしたい場合は以下の通り。

\documentclass[uplatex,dvipdfmx,a4paper]{jlreq}
\usepackage[jis2004=false]{jlreq-deluxe}
\usepackage[noto-otc,legacycode-replace=false,legacycode=ignore]{pxchfon}
\begin{document}
巷で噂の葛飾区☃\par
\bfseries
巷で噂の葛飾区☃\par
\end{document}

出力結果

まとめ

ワタシハ pxchfon チョット デキル🙃


  1. 「jlreqの機能を損なわずにjapanese-otfパッケージの多書体化を適用した」状態を実現するためのパッケージ。
  2. upLaTeXでかつjapanese-otfが不使用の場合はそもそも“Unicode直接化”(後述)が不要であるため、pxufontを読み込んでも設定は変わらない。
  3. “AI0なフォント”というのは詳しくいうと「内部グリフエンコーディングAdobe-Identity-0であるCFFグリフのOpenTypeフォント」のことであるが、ここでは単純に「Noto CJKや源ノは“ちょっと特殊な”フォントである」と考えてほしい。
  4. “AI0なフォント”は「AJ1を前提とする“CMap指定”」を適用できず、従ってそういうフォントを使うためにはunicodeを有効にする必要があるからである。
  5. ここでいう“和文フォント設定”というのは(DVIウェアでなく)LaTeX側の設定の一種で、例えば「“明朝太字”に対してどういう和文TFMを対応させるか」のようなものを指す。
  6. 例えば\ajMaru{1}は最終的には\CID{7555}を実行する。直接“①”を書いた場合はそれは“Unicodeとして”出力される。
  7. もちろん、逆にそういう動作を利用するというテクニックも成立するであろう。
  8. ただしpxchfonのファイルプリセットの仕様に少し問題があってjis2004指定はプリセットには実は効いていない。つまり、jis2004が有効な場合は本来は(u)ptex-noto-otc-04.mapの方を採用するべきであるが、現在の仕様では常に(u)ptex-noto-otc.mapが採用されてしまう。ただしjapanese-otfを普通に用いている場合は実際にはこのマップファイルの違いが問題になることはないので、取りあえずはこのままで大丈夫である。