if len(next) == 1 and next not in string.ascii_letters + string.digits:
doc.append(TextNode(symbols.get(next, next)))
elif next.startswith("'"):
hexchar = next[1:3]
tokens.insert(0, next[3:])
doc.append(TextNode(chr(int(hexchar, 16))))
else:
doc.append(ControlNode(token + next))
next not in string.ascii_letters + string.digits
if token in string.whitespace:
last = doc[-1]
if type(last) is WhitespaceNode:
doc[-1] = WhitespaceNode(last + token)
else:
doc.append(WhitespaceNode(token))
type(last) is WhitespaceNode
last = doc[-1]
if type(last) is TextNode:
doc[-1] = TextNode(last + token)
continue
token == '}'
doc.append(TextNode(token))
doc = compress_text(doc)
return doc
def tree_to_plain(tree):
tree = tree[:]
if not tree:
return ''
if type(tree[0]) is ControlNode and str(tree[0]) in ('\\colortbl', '\\fonttbl'):
return ''
res = []
encoding = None
last = None
uni_replace_len = None
while tree:
node = tree.pop(0)
last = node
continue
None if type(node) is ControlNode else None if type(node) is WhitespaceNode else None if type(node) is TextNode else None if type(node) is Group else tree
for test_string, test_plain in (('{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fmodern\\fprq1\\fcharset0 Courier New;}}{\\colortbl ;\\red0\\green255\\blue64;}\\viewkind4\\uc1\\pard\\cf1\\b\\f0\\fs32 this is the body\\par}', 'this is the body\n'), ('{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fswiss\\fcharset0 Arial;}{\\f1\\froman\\fprq2\\fcharset0 Bodoni;}}\\viewkind4\\uc1\\pard\\i\\f0\\fs20 first line\\par\\b second line\\par\\ul\\i0 third line\\par\\b0 fourth line\\par\\ulnone\\b bold\\par\\f1 newfont\\ul\\b0\\f0\\par}', ' first line\nsecond line\nthird line\nfourth line\nbold\nnewfont\n'), ('{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1033{\\fonttbl{\\f0\\fmodern\\fprq1\\fcharset0 Courier New;}}\n{\\colortbl ;\\red0\\green255\\blue64;}\n\\viewkind4\\uc1\\pard\\cf1\\b\\f0\\fs32 newline\\par\nbackslash\\\\ rawr end\\par\n}', 'newline\nbackslash\\ rawr end\n')):