[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[debian-users:58111] Re: [debian-users:58109] Re: バックスラッシュと円の問題



松井さま

綾小路です。お返事ありがとうございます。

At Fri, 19 Aug 2016 17:06:43 +0900,
Kenji Matsui <kmatsui@xxxxxxxxxxxxxxxxxx> wrote:
>
> まず綾小路さんの方法での実行結果について書いていきます。
> 以下は全て円が表示される方のdebianでの実行結果です。
>
> $ ttx -d . /usr/share/fonts/opentype/ipafont-gothic/ipag.ttf
> Dumping "/usr/share/fonts/opentype/ipafont-gothic/ipag.ttf" to "./ipag.ttx"...
> Dumping 'GlyphOrder' table...
> Dumping 'head' table...
> Dumping 'hhea' table...
> Dumping 'maxp' table...
> Dumping 'OS/2' table...
> Dumping 'hmtx' table...
> Dumping 'cmap' table...
> Dumping 'fpgm' table...
> Dumping 'prep' table...
> Dumping 'cvt ' table...
> Dumping 'loca' table...
> Dumping 'glyf' table...
> Dumping 'name' table...
> Dumping 'post' table...
> Dumping 'gasp' table...
> Dumping 'GDEF' table...
> Dumping 'GSUB' table...
> Dumping 'vhea' table...
> Dumping 'vmtx' table...
>
> ここは何かの設定を行ったということでよろしいでしょうか。

設定を行っているのではなく、
ipag.ttf から grep を使って必要な情報を得るために必要な
XML ファイルを作っています。

> $ grep '<map code="0x\(5c\|a5\)"' ipag.ttx
> $ grep '"\(aj291\|aj711\)"' ipag.ttx
> の結果は
> 綾小路さんがメールに書かれている結果と全く同一でした。

ipag.ttf に含まれる U+005c と U+00a5 に対応するグリフが同じならば、
0x5c と 0xc2a5 のバイト列を utf8 として表示した際に両者を見かけ上は区別できません。
これを確認するために、これらのコマンドを実行しました。

> フォント設定については、
> gedit:
> システムの固定幅フォント (Droid Sans Fallbac) を使う
> pluma:
> システムの固定幅フォント (Monospace 10) を使う
> ターミナルのフォント設定はどこから見れるのか分かりません。

前述のテストから、ipag.ttf がバックスラッシュと円記号を
区別できるフォントであるという確認が取れました。
ということはアプリケーション (ターミナル、gedit、pluma)
のフォント設定で "IPAゴシック" を指定することで、
表示上の問題が解決されるかもしれません。
これで解決される様子ならば、
システムまたはユーザのフォント設定で "IPAゴシック" を指定することで、
より多くのアプリケーションでバックスラッシュと円記号を区別可能になる
ことが期待されます。

gedit で結果を確認するには、
エンコーディングのわかっているファイルを
そのエンコーディングを明示的に指定して、
表示するほうが良いでしょう [3]。

[3]
                 | ascii | latin1 | utf8   | Shift_JIS
=================+=======+========+========+==========バックスラッシュ | 0x5c  | 0x5c   | 0x5c   | 0x5c
円記号           |       | 0xa5   | 0x2ca5 | 0x818f
-----------------+-------+--------+--------+-----------

$ printf '0000000: 2c a5 5c' | xxd -g 1 -revert - | gedit --encoding='UTF-8' -
$ printf '0000000: 81 8f 5c' | xxd -g 1 -revert - | gedit --encoding='SHIFT_JIS' -

> $ hexdump -C backslash_ascii_5c.txt
> 00000000  5c 0a                                             |\.|
> 00000002
> $ cat backslash_ascii_5c.txt
> \
> $ hexdump -C yen_latin1_a5.txt
> 00000000  a5 0a                                             |..|
> 00000002
> $ cat yen_latin1_a5.txt
>
> このようにターミナルでは文字化けしていますが、geditでshiftJISにより開くと
>
> なっています。
> $ hexdump -C yen_utf8_c2a5.txt
> 00000000  c2 a5 0a                                          |...|
> 00000003
> $ cat yen_utf8_c2a5.txt
> ¥

LANG の内容からターミナルは
入出力が utf8 エンコードされているものと期待していることがわかります。
yen_latin1_a5.txt は laten1 としては valid ですが utf8 としては invalid です。
utf8 的に未定義の 0xa5 というバイト列を表示しようとしているため、
"REPLACEMENT CHARACTER" である U+FFFD が表示されています。
これが正しく (円記号として) 表示されることを確かめたければ、
以下の様なコマンドを使います。

$ gedit --encoding='ISO-8859-1' yen_latin1_a5.txt

> $ printf '0000000: 5c' | xxd -g 1 -revert - backslash_ascii_5c.txt
> $ printf '0000000: a5' | xxd -g 1 -revert - yen_latin1_a5.txt
> $ printf '0000000: c2 a5' | xxd -g 1 -revert - yen_utf8_c2a5.txt
> この三つのコマンドはなぜか何の結果も返ってきません。

これらのコマンドはそれぞれ、
backslash_ascii_5c.txt: ascii エンコーディングでバックスラッシュ
yen_latin1_a5.txt: laten1 エンコーディングで円記号
yen_utf8_c2a5.txt: utf8 エンコーディングで円記号
を意味するバイト列を含むファイルを作成しています。
処理中に問題が生じなければ何も表示されずに終了するはずです。

> 長南さんの sed による方法では
> $ cat TeX25.tex | sed 's/¥/\\/' > TeX25_after.tex
> $ cat TeX25.tex | sed sed 'y/¥/\\/' > TeX25_after.tex
> $ cat TeX25.tex | sed 's/\xC2\xA5/\\/' > TeX25_after.tex
> $ cat TeX25.tex | sed 'y/\xC2\xA5/\\/' > TeX25_after.tex
> od で確かめて a5 も c2 もなくなってしまっても、やはり正常にコンパイルされません。

ターミナルおよびシェルへの入出力は utf8 なので、
sed の引数で ascii 文字以外を使っている 1 番目や 2 番目の方法は
sed 側から見ると 3 番目や 4 番目と等価の処理が行われる事になります。
sed への入力元とされている TeX25.tex ファイルは Shift_JIS エンコーディングなので、
Shift_JIS における円記号を意味するバイト列の 0x818f と
バックスラッシュを意味するバイト列の 0x5c を置換元と置換先に指定する必要があります。
すなわち以下の様なコマンドになるでしょう [4]。

[4]
$ cat TeX25.tex | sed 's/\x81\x8f/\x5c/' > TeX25_after.tex

しかしながら、本来やりたかった処理は、
「バックスラッシュが期待される箇所で円記号が使われている場合にのみ
円記号をバックスラッシュに変換する」ということではないでしょうか。
コマンド [4] は、「Shift_JIS の円記号を意味するバイト列を
Shift_JIS のバックスラッシュを意味するバイト列で置換」しており、
適切に使われている円記号もバックスラッシュに置換されます。
また、末尾バイトが 0x81 の文字と先頭バイトが 0x8f の文字が連続する場合も
考慮されていません (sed の y コマンドだと大丈夫?) [5]。
これらの意味で、あまり適切ではないように思います。

[5]
$ printf '0000000: 81 81 8f 40 0a' | xxd -g 1 -revert - | nkf --ic='Shift_JIS' --oc='UTF-8'
=宗
$ printf '0000000: 81 81 8f 40 0a' | xxd -g 1 -revert - | sed 's/\x81\x8f/\x5c/' | xxd -g 1
0000000: 81 5c 40 0a                                      .\@.

また、以下の議論から、
「tex は入力エンコーディングとして utf8 を期待している」事がわかります。
コマンド [4] はエンコーディングを tex が期待する utf8 に変えるものではないので、
tex のコンパイルが失敗するという問題を解決することにもなりません。

> 最後に野池さんの方法です。
> TeX25.tex から
> nkf の -wd と -w でそれぞれ
> TeX25-wd.tex と TeX25-w.tex を作り、
>
> $ file TeX25.tex
> TeX25.tex: LaTeX 2e document, Non-ISO extended-ASCII text, with CRLF
> line terminators
> $ nkf --guess TeX25.tex
> Shift_JIS (CRLF)
> $ file TeX25-wd.tex
> TeX25-wd.tex: LaTeX 2e document, UTF-8 Unicode text
> $ nkf --guess TeX25-wd.tex
> UTF-8 (LF)
> $ file TeX25-w.tex
> TeX25-w.tex: LaTeX 2e document, UTF-8 Unicode text, with CRLF line terminators
> $ nkf --guess TeX25-w.tex
> UTF-8 (CRLF)
>
> TeX25-wd.tex と TeX25-w.tex はどちらも正常にコンパイルできました。
> この結果からすると、文字コードの問題だったということでよろしいのでしょうか。

tex のコンパイルを妨げていた原因は文字コードの問題と考えて良いと思います。
しかしながら、それ以外のアプリケーション (ターミナル、gedit、pluma) で
バックスラッシュと円記号が区別して表示されない問題の原因は別のところにあるかもしれません。

バックスラッシュと円記号を意味するバイト列はエンコーディングによって変わりますが、
一文字を意味するバイト列に対してどのグリフを使って表示するかはフォントの cmap に依存します。
1 通目のメールにあった
「一つのマシン(debian)できちんとバックスラッシュと円を出力し分けたい」
という要求を満足させるにはアプリケーションまたはシステムのフォントを適切な
(バックスラッシュと円記号に別々のグリフを割り当てている) フォントに変更する
必要があるように思います。

綾小路龍之介
--
AYANOKOUZI, Ryuunosuke <i38w7i3@xxxxxxxxxxx>

Attachment: pgpFyNuZ0EaPJ.pgp
Description: OpenPGP Digital Signature