この問題は、MATLAB 文字エンコーディングが UTF-8 の場合に発生します。これは通常、Linux ユーザーの場合です (したがって、CP1252 を使用する Amro の構成では問題ありません)。MATLAB 文字セット エンコーディング (で取得slCharacterEncoding()
) が UTF-8 の場合、MATLAB の eps エクスポート関数は (少なくとも R2011b までは) バグが発生します。Postscript が 8 進エスケープされた UTF-8 形式 (2 バイト) で非 ASCII 文字をエクスポートするためです。インタープリターは、1 バイト形式をデコードするように設定されています。
文字 ö U+00F6 のバグを説明しましょう。そのいくつかの表現は次のとおりです。
- UTF-16: 0x00F6
- UTF-8: 0xC3 0xB6
- C 8 進数エスケープ UTF-8: \303\266
- XML 10 進数エンティティ: ö
MATLAB によって作成された eps ファイルには、以下が含まれます。
/Helvetica /ISOLatin1Encoding 120 FMSR
(\303\266) s
MATLAB は、eps ファイルで、FMSR
Helvetica フォントを別のエンコーディングに再エンコードする関数を定義します。ここでは、2 つの組み込みエンコーディング ベクトルの 1 つであり、ISO-8859-1 (Latin1) 標準に厳密に一致する ISOLatin1Encoding です (p.329 を参照) 。詳細については、Postscript Language Reference Manual の 330 を参照してください)。簡単に言うと、エンコーディング ベクトルは、文字名を文字コードに関連付ける 256 要素の配列です。そのため、1 バイトの文字コードのみを読み取ります。ISO-8859-1 では、\303=195=à および \266=182=¶ です。その結果、それは ö を出力します。
UTF-8 ロケール環境で非 ASCII ISO-8859-1 文字をエクスポートするためのオプション
8 進 UTF-8 コードを 8 進 ISO-8859-1 コードに変換します。これは、非 ASCII ISO-8859-1 文字が UTF-8 で同じレイアウトに従うため、簡単です。たとえば、コマンド ウィンドウまたはエクスポート スクリプトから実行できるプログラム sed を使用すると、次のようになります。
!sed -i -e 's/\\302\(\\2[4-7][0-7]\)/\1/g' -e 's/\\303\\2\([0-7][0-7]\)/\\3\1/g' file.eps
したがって、=246=ö\303\266
となります。\366
非 ASCII 文字を MATLAB に直接入力できます。
Figure にテキストを追加する前にMATLAB 文字セットのエンコードを変更slCharacterEncoding('ISO-8859-1')
し、コマンド ウィンドウからテキストを追加する場合は、非 ASCII 文字に char(number) を使用します。プロット ツールを使用して Figure にテキストを直接追加する場合は、非 ASCII 文字を入力できます。非 ASCII 文字は既定のフォント (Linux 上の MATLAB では既定で Helvetica) では Figure に表示されず、Figure の作成をスクリプト化する場合は char(number) を使用する必要があるため、このソリューションは理想的ではありません。
LaPrint などのユーザーが送信した MATLAB 関数またはそのフォークの 1 つを使用して、後でテキストを LaTex でレンダリングします。これにより、Figure のテキストを含む tex ファイルと、Figure のテキスト以外の部分を含む eps ファイルが作成されます。同様のソリューションは、tikz/pgfplot ファイルと tex ファイルを作成する matlab2tikz です。
MATLAB の Latex インタープリターを使用します\"{o}
。MATLAB は ASCII 文字とその分音記号を組み合わせて文字を作成しますが、相対位置が不適切であるため、結果の品質は低くなります (分音記号は文字に比べて少し右寄りです)。MATLAB は、Computer Modern フォントのグリフを使用し、そのフォントを eps ファイルに埋め込みます (これにより ~ 80 Ko が追加されます)。さらに、eps から作成された pdf の生のテキストにはö
but が含まれていませんo ̈
。
非 ISO-8859-1 文字のエクスポート
こちらで質問された ISO-8859-1 にない文字をエクスポートする場合、必要な文字数が 256 (8 ビット形式) 未満で、理想的には標準のエンコーディング セットである場合、おそらく合理的な解決策があります。次の手順が含まれます。
- 8 進コードを Unicode 文字に変換します。
- ファイルをターゲットのエンコード標準 (8 ビット形式) に保存します。
- ターゲット エンコーディング セットのエンコーディング ベクトルを追加します。
たとえば、ポーランド語のテキストをエクスポートする場合は、ファイルを ISO-8859-2 に変換する必要があります。Bash を使用した Linux での実装は次のとおりです。
#!/bin/bash
name=$(basename "$1" .eps)
ascii2uni -a K "$1" > /tmp/eps_uni.eps
iconv -t ISO-8859-2 /tmp/eps_uni.eps -o "$name"_latin2.eps
sed -i -e '/%EndPageSetup/ r ISOLatin2Encoding.ps' -e 's/ISOLatin1Encoding/MyEncoding/' "$name"_latin2.eps
eps_lat2 として保存されます。次にコマンドを実行するsh eps_lat2 file.eps
と、Latin-2 エンコーディングで file_latin2.eps が作成されます。ファイル ISOLatin2Encoding.ps には次のものが含まれています。
/MyEncoding
% The first 144 entries are the same as the ISO Latin-1 encoding.
ISOLatin1Encoding 0 144 getinterval aload pop
% \22x
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef
% \24x
/nbspace /Aogonek /breve /Lslash /currency /Lcaron /Sacute /section
/dieresis /Scaron /Scedilla /Tcaron /Zacute /hyphen /Zcaron /Zdotaccent
/degree /aogonek /ogonek /lslash /acute /lcaron /sacute /caron
/cedilla /scaron /scedilla /tcaron /zacute /hungarumlaut /zcaron /zdotaccent
% \30x
/Racute /Aacute /Acircumflex /Abreve /Adieresis /Lacute /Cacute /Ccedilla
/Ccaron /Eacute /Eogonek /Edieresis /Ecaron /Iacute /Icircumflex /Dcaron
/Dcroat /Nacute /Ncaron /Oacute /Ocircumflex /Ohungarumlaut /Odieresis /multiply
/Rcaron /Uring /Uacute /Uhungarumlaut /Udieresis /Yacute /Tcedilla /germandbls
% \34x
/racute /aacute /acircumflex /abreve /adieresis /lacute /cacute /ccedilla
/ccaron /eacute /eogonek /edieresis /ecaron /iacute /icircumflex /dcaron
/dcroat /nacute /ncaron /oacute /ocircumflex /ohungarumlaut /odieresis /divide
/rcaron /uring /uacute /uhungarumlaut /udieresis /yacute /tcedilla /dotaccent
256 packedarray def
Python を使用した別の実装を次に示します (したがって、Windows と Mac でも動作します)。
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys,codecs
input = sys.argv[1]
fo = codecs.open(input[:-4]+'_latin2.eps','w','latin2')
with codecs.open(input,'r','string_escape') as fi:
data = fi.readlines()
with open('ISOLatin2Encoding.ps') as fenc:
for line in data:
fo.write(line.decode('utf-8').replace('ISOLatin1Encoding','MyEncoding'))
if line.startswith('%%EndPageSetup'):
fo.write(fenc.read())
fo.close()
eps_lat2.py として保存されます。次にコマンドを実行するpython eps_lat2.py file.eps
と、Latin-2 エンコーディングで file_latin2.eps が作成されます。
スクリプト内のエンコーディング ベクトルと iconv (または codecs.open) パラメータを変更することで、他の 8 ビット エンコーディング標準に簡単に適合させることができます。