2
4

2 に答える 2

5

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つの符号付き整数にエンコードするだけで、これらをサポートします。\Uxxxxxxxxrtfunicode\uDDDDD?

于 2012-06-01T15:13:18.293 に答える
0

良いニュースは、あなたが何も悪いことをしていないということです。悪いニュースは、RTFがISO8859-1として読み取られていることです。

>>> print u'€'.encode('iso-8859-15').decode('iso-8859-1')
¤

正しく読み取るには、 Unicodeエスケープを使用する必要があります。

>>> print hex(ord(u'€'))
0x20ac
于 2012-06-01T15:12:46.820 に答える