2 に答える
RTF標準はUTF-16を使用しますが、RTFコマンドシーケンス形式に適合するように形作られています。http://en.wikipedia.org/wiki/Rich_Text_Format#Character_encodingに記載されています。残念ながら、pyRTFはエンコーディングを行いません。これを処理することはプロジェクトのTODOにありましたが、明らかに彼らはライブラリを放棄する前にそれに到達することはありませんでした。
これは、最近プロジェクトで使用したコードに基づいています。私はこれrtfunicode
をPyPIと同様にリリースし、Python2と3をサポートしています。Python 2バージョン:
import codecs
import re
_charescape = re.compile(u'([\x00-\x1f\\\\{}\x80-\uffff])')
def _replace(match):
codepoint = ord(match.group(1))
# Convert codepoint into a signed integer, insert into escape sequence
return '\\u%s?' % (codepoint if codepoint < 32768 else codepoint - 65536)
def rtfunicode_encode(text, errors):
# Encode to RTF \uDDDDD? signed 16 integers and replacement char
return _charescape.sub(_replace, escaped).encode('ascii')
class Codec(codecs.Codec):
def encode(self, input, errors='strict'):
return rtfunicode_encode(input, errors), len(input)
class IncrementalEncoder(codecs.IncrementalEncoder):
def encode(self, input, final=False):
return rtfunicode_encode(input, self.errors)
class StreamWriter(Codec, codecs.StreamWriter):
pass
def rtfunicode(name):
if name == 'rtfunicode':
return codecs.CodecInfo(
name='rtfunicode',
encode=Codec().encode,
decode=Codec().decode,
incrementalencoder=IncrementalEncoder,
streamwriter=StreamWriter,
)
codecs.register(rtfunicode)
「iso-8859-15」にエンコードする代わりに、代わりに「rtfunicode」にエンコードできます。
>>> u'\u20AC'.encode('rtfunicode') # EURO currency symbol
'\\u8364?'
この方法で、RTFドキュメントに挿入するテキストをエンコードします。
UCS-4( 、4バイト)\uxxxx
ではなく、UCS-2ユニコード(、2バイト)のみをサポートすることに注意してください。1.1は、UTF-16サロゲートペアを2つの符号付き整数にエンコードするだけで、これらをサポートします。\Uxxxxxxxx
rtfunicode
\uDDDDD?
良いニュースは、あなたが何も悪いことをしていないということです。悪いニュースは、RTFがISO8859-1として読み取られていることです。
>>> print u'€'.encode('iso-8859-15').decode('iso-8859-1')
¤
正しく読み取るには、 Unicodeエスケープを使用する必要があります。
>>> print hex(ord(u'€'))
0x20ac