在python中将unicode文本输出到RTF文件

时间:2012-03-28 13:33:34

标签: python rtf

我正在尝试从python脚本将unicode文本输出到RTF文件。对于背景,Wikipedia

  

对于Unicode转义,使用控制字\ u,然后使用16位带符号十进制整数,给出Unicode UTF-16代码单元号。为了没有Unicode支持的程序的好处,必须在指定的代码页中跟随此字符的最近表示。例如,\ u1576?将给出阿拉伯字母bā'ب,指明没有Unicode支持的旧程序应该将其作为问号呈现。

还有this question on outputting RTF from Javathis one on doing so in C#

然而,我无法弄清楚的是如何将Python的unicode代码点输出为“带有Unicode UTF-16代码单元号的16位带符号十进制整数”。我试过这个:

for char in unicode_string:
    print '\\' + 'u' + ord(char) + '?',

但输出只在文字处理器中打开时呈现为乱码;问题似乎是它不是UTF-16代码。但不知道如何得到它;虽然可以用utf-16编码,但是如何获得代码?

顺便提一句PyRTF不支持unicode(它被列为“todo”),虽然pyrtf-NG应该这样做,但该项目似乎没有维护并且文档很少,所以我对使用它很谨慎在准生产系统中。

编辑:我的错误。上面的代码中有两个错误 - 正如Wobble所指出的那样,字符串必须是一个unicode字符串,而不是已编码的字符串,而上面的代码产生一个结果,字符之间有空格。正确的代码是:

convertstring=""
for char in unicode(<my_encoded_string>,'utf-8'):
    convertstring = convertstring + '\\' + 'u' + str(ord(char)) + '?'

这很好,至少对于OpenOffice。我将此作为其他人的参考 (以下讨论后进一步纠正了一个错误。)

2 个答案:

答案 0 :(得分:3)

根据您最新编辑中的信息,我认为此功能可以正常使用。除了下面的改进版本。

def rtf_encode(unistr):
    return ''.join([c if ord(c) < 128 else u'\\u' + unicode(ord(c)) + u'?' for c in unistr])

>>> test_unicode = u'\xa92012'
>>> print test_unicode
©2012
>>> test_utf8 = test_unicode.encode('utf-8')
>>> print test_utf8
©2012
>>> print rtf_encode(test_utf8.decode('utf-8'))
\u169?2012

这是另一个版本,有点分解,更容易理解。我还在返回一个ASCII字符串时保持一致,而不是保留Unicode并在join上插入它。它还包含基于评论的修复程序。

def rtf_encode_char(unichar):
    code = ord(unichar)
    if code < 128:
        return str(unichar)
    return '\\u' + str(code if code <= 32767 else code-65536) + '?'

def rtf_encode(unistr):
    return ''.join(rtf_encode_char(c) for c in unistr)

答案 1 :(得分:1)

Mark Ransom的回答并不正确,因为它不会正确编码U + 7fff上的代码点,也不会按照RTF标准的建议转义低于0x20的字符。

我创建了一个简单的模块,将python unicode编码为名为rtfunicodewrote about the subject on my blog的RTF控制代码。

总之,我的方法使用正则表达式将正确的代码点映射到适合包含在PyRTF或pyrtf-ng中的RTF控制代码。