XeTeXやLuaTeXでUnicode文字を置き換えるマクロ

XeTeXやLuaTeXでUnicode文字を置き換えるマクロ

- TrueRoad の投稿
返信数: 9
XeTeXやLuaTeXでも、デフォルトのフォントは普通のTeXと同じ Computer Modern なので、そのまま特にフォントの設定をせずに、「ü」(U+00FC LATIN SMALL LETTER U WITH DIAERESIS) のような文字を UTF-8 で直接ソース中に記述すると、文字が出てこない、ということになると思います。
もちろん、フォントを Latin Modern などの Unicode に対応したものに変えれば出てくるようになります。また、たとえデフォルトフォントのままでも、普通のTeXと同じように「\"u」のように書けば出てくるようになります。

ですが、あえて、デフォルトフォントのまま、かつ、UTF-8 の文字のままこのような文字を出せるようにしたいと思っています。

以下のようなことをすると、とりあえず「ü」が「\"u」に置き換えられるので、上記の目的は達成できることがわかりました。
(LaTeXではありません。)

% -*- encoding: utf-8 -*-

\catcode`^^^^00fc=\active
\def^^^^00fc{\"u}

für

\bye

あとは置き換えの定義をたくさん書いていけばよい、ということになるのですが、それなりにたくさん必要になります。そこで、上記のサンプルではカテゴリコードの書き換えと文字の置き換えの2行に分かれているものを1行で書けるようにマクロを作りたいと思っています。

\DeclareUnicodeCharacter{00FC}{\"u}

と書くと、

\catcode`^^^^00fc=\active
\def^^^^00fc{\"u}

に展開されるようなマクロです。
カテゴリコードの書き換えまでは何とかできたのですが、
文字の置き換えで苦戦しています。
カテゴリコードの書き換えだけであれば、

\newcount\countUTFz

\def\DeclareUnicodeCharacter#1#2{%
\countUTFz = "#1\relax
\catcode\countUTFz=\active
% ここで文字の置き換えもしたい
}

のようにするとできましたが、文字の置き換えができません。

皆さまのお力添えをいただければ幸いです。
よろしくお願いいたします。
TrueRoad への返信

Re: XeTeXやLuaTeXでUnicode文字を置き換えるマクロ

- 前田 一貴 の投稿
コードポイントでなくて,文字で直接指定でもよければ,

\catcode`\@=11
\def\DeclareUnicodeCharacter#1#2{%
  \catcode`#1=\active
  \edef\@tempa{\scantokens{\unexpanded{#1}\noexpand}}%
  \expandafter\def\@tempa{#2}}
\catcode`\@=12

\DeclareUnicodeCharacter{ü}{\"u}

für

\bye

でうまくいきそうですね.コードポイントで指定するにはどうすればよいのだろう?
前田 一貴 への返信

Re: XeTeXやLuaTeXでUnicode文字を置き換えるマクロ

- Z. R. の投稿

ごく最近の XeTeX や LuaTeX であれば \Uchar というプリミティブがあります。

  • \Uchar <整数> : 一回展開すると、文字コードが指定の整数で、カテゴリコードが 12 の文字トークンになる。

それを使うと同じようにできます。

\catcode`\@=11
\def\DeclareUnicodeCharacter#1#2{%
  \catcode"#1=\active
  \edef\@tempa{\scantokens\expandafter{%
    \expandafter\noexpand\Uchar"#1 \noexpand}}%
  \expandafter\def\@tempa{#2}}
\catcode`\@=12

\DeclareUnicodeCharacter{00FC}{\"u}
\show ü
\bye
Z. R. への返信

Re: XeTeXやLuaTeXでUnicode文字を置き換えるマクロ

- 前田 一貴 の投稿
おお,ありがとうございます.新プリミティブ便利ですね.

自分では下のようなコードを書いてみていました.
\Uchar を縛る意味がないので,ただの余興です(古い環境で \Uchar がなければ使えるかも).
"00fc や ^^^^00FC はだめとかややこしい……. 

\begingroup
\catcode`\@=11
\catcode`\^=12
\gdef\DeclareUnicodeCharacter#1#2{%
  \edef\@tempa{\scantokens{\unexpanded{^^^^#1}\noexpand}}%
  \expandafter\catcode\expandafter`\@tempa=\active
  \edef\@tempa{\scantokens{\unexpanded{^^^^#1}\noexpand}}%
  \expandafter\def\@tempa{#2}}
\endgroup

\DeclareUnicodeCharacter{00fc}{\"u}
\show ü
\bye
前田 一貴 への返信

Re: XeTeXやLuaTeXでUnicode文字を置き換えるマクロ

- Z. R. の投稿

最新の機能を使いこなすのもいいですが。

「指定の整数の文字コードをもった文字トークンを得る」ための定番の方法は「\lowercase トリック」です。これはどのエンジンでも(サポートされる文字コードの範囲で)使えるので覚えておくとよいでしょう。

\catcode`\@=11
\def\DeclareUnicodeCharacter#1#2{%
  \catcode"#1=\active
  \begingroup
    \lccode`\~="#1\relax
    % \lowercase を実行すると'~'がカテゴリコード13のまま
    % 文字コード "#1 のトークンに置き換わる.
    \lowercase{\gdef~}{#2}%
  \endgroup}
\catcode`\@=12

\DeclareUnicodeCharacter{00FC}{\"u}
\show ü
\bye
Z. R. への返信

Re: XeTeXやLuaTeXでUnicode文字を置き換えるマクロ

- 前田 一貴 の投稿
> 「\lowercase トリック」
そういえば,そんなのありましたね.言われて思い出しました…….

ありがとうございました.
TrueRoad への返信

Re: XeTeXやLuaTeXでUnicode文字を置き換えるマクロ

- 前田 一貴 の投稿
ところで,「マクロを作りたい」とおっしゃるので,その方法についてばかり書いてしまって
いましたが,LuaLaTeX の場合には luainputenc というパッケージがあります.
これは,Unicode のソースを読んで,古い8ビットのフォントで出力したい場合に使うもののようです.
ただし,LuaTeX では Unicode 対応フォントを使うことが強く推奨されています.

\documentclass{article}
\usepackage[utf8]{luainputenc}
\begin{document}
\show ü                        % ü=macro:->\"u.
für
\end{document}
TrueRoad への返信

Re: XeTeXやLuaTeXでUnicode文字を置き換えるマクロ

- TrueRoad の投稿
前田様、Z.R.様
ありがとうございます。

大変助かりました。

実は Texinfo についている texinfo.tex には、入力された UTF-8 な「ü」を「\"u」に置き換える、等の処理が入っています。これは pdfTeX ではちゃんと動作していたのですが、最近、XeTeX や LuaTeX ではちゃんと動かないということが発覚したため、

・入力の UTF-8 を byte 単位でぶった切って pdfTeX と同じ置き換え処理が動くようにする

という変更が入りました。

byte 単位でぶった切ってしまうと、日本語的には大変困ったことになってしまうわけです。

置き換えをやめて、Native Unicode のまま、Latin Modern のような Unicode なフォントを使う方法を提案したのですが、様々な理由で難色を示されていて、上記のぶった切り置き換えがデフォルト動作、スイッチで Native Unicode が選択できるようにする、的なところで落ち着きそうな状況です。(ただ、ぶった切りは別の問題もあり、そのままでは済まないと思いますが。)

そこで、UTF-8 のぶった切ったバイト列から置き換えるのではなく、ぶった切らない Native Unicode の文字から直接置き換えることができれば、日本語的にも問題なくなりますし、Computer Modern のまま「ü」が「\"u」に置き換わって使えるようになるよね、ということ思い付きました。

texinfo.tex にある UTF-8 バイト列を置き換えるマクロ \DeclareUnicodeCharacter のコードを読みつつ、Native Unicode から直接置き換えるような書き換えを試みていたのですが力及ばず、質問させていただいた次第です。

その UTF-8 バイト列から置き換えるマクロを読んでいると、\uccode と \uppercase が使われているところがあり、一体何だこりゃ、と思っていたのですが、「\lowercase トリック」の変形?なんですね。何をしているコードなのか、やっとわかりました。

いただいたマクロを、もともとあった「\uppercase トリック」に書き直して、提案してみたいと思います。

ありがとうございました。
TrueRoad への返信

Re: XeTeXやLuaTeXでUnicode文字を置き換えるマクロ

- 前田 一貴 の投稿
私のコメントは蛇足でしかなかったようですが,よかったです.

bug-texinfo (http://lists.gnu.org/archive/html/bug-texinfo/) でそんなことが議論されていたのですね.
私は自分では Texinfo も,Texinfo を内部で呼び出すプログラムも使うことがないので,
あまりお役に立てない感じがします.
もしこれをご覧の方で Texinfo を使っている方がいれば,議論に目を通してみるとよいかもしれないです.
前田 一貴 への返信

Re: XeTeXやLuaTeXでUnicode文字を置き換えるマクロ

- TrueRoad の投稿
1か月ほど前の古い話で申し訳ありません。

最終的に私の提案した Native Unicode を使うパッチが、本家 Texinfo に取り込まれました。

ですので、Texinfo で XeTeX や LuaTeX をエンジンとすれば
https://okumuralab.org/tex/mod/forum/discuss.php?d=1812
で教えていただきましたようにすると日本語を使うことができます。

実は、もともと日本語対応を考えていたのではなく、私がかかわっている LilyPond のドキュメントが Texinfo なのがはじまりです。これが pdfTeX のバグを踏んでしまったらしく、代わりに LuaTeX や XeTeX なら大丈夫では?という議論が lilypond-devel でありました。それが Texinfo に手を染め始めたきっかけでしたが、結果として日本語も使うことができるようになりました。

皆さまのお力添えのおかげです。
ありがとうございました。

#オマケですが、bug-texinfo にパッチを投稿して議論させていただいていたら、Texinfo のコミッタにされてしまいました。。。