home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 February / maximum-cd-2011-02.iso / DiscContents / digsby_setup85.exe / lib / util / rtf.pyo (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-11-24  |  11.1 KB  |  324 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.6)
  3.  
  4. import string
  5. symbols = {
  6.     '\\': '\\',
  7.     '~': ' ',
  8.     'tab': '\t',
  9.     "'7b": '{',
  10.     "'7d": '}' }
  11. rev_symbols = { }
  12. for k, v in symbols.items():
  13.     rev_symbols[v] = k
  14.  
  15. rtf_fcharsets = {
  16.     0: 'ANSI',
  17.     1: 'Default',
  18.     2: 'Symbol',
  19.     3: 'Invalid',
  20.     77: 'Mac',
  21.     128: 'shiftjis',
  22.     130: 'johab',
  23.     134: 'GB2312',
  24.     136: 'Big5',
  25.     161: 'Greek',
  26.     162: 'iso-8859-9',
  27.     163: 'cp1258',
  28.     177: 'Hebrew',
  29.     178: 'Arabic',
  30.     179: 'Arabic Traditional',
  31.     180: 'Arabic user',
  32.     181: 'Hebrew user',
  33.     186: 'Baltic',
  34.     204: 'Russian',
  35.     222: 'Thai',
  36.     238: 'Eastern European',
  37.     254: 'PC 437',
  38.     255: 'OEM' }
  39.  
  40. def tokenize(string):
  41.     tokens = []
  42.     curr_token = ''
  43.     for c in string:
  44.         if c in '\\{} \r\n':
  45.             if curr_token:
  46.                 tokens.append(curr_token)
  47.                 curr_token = ''
  48.             
  49.             if c == '\n' and tokens[-1] == '\r':
  50.                 tokens[-1] = c
  51.             else:
  52.                 tokens.append(c)
  53.         tokens[-1] == '\r'
  54.         curr_token += c
  55.     
  56.     if curr_token:
  57.         tokens.append(curr_token)
  58.     
  59.     return tokens
  60.  
  61.  
  62. class TypedString(str):
  63.     
  64.     def __repr__(self):
  65.         return '<%s %s>' % (type(self).__name__, str.__repr__(self))
  66.  
  67.  
  68.  
  69. class TypedList(list):
  70.     
  71.     def __repr__(self):
  72.         return '<%s %s>' % (type(self).__name__, list.__repr__(self))
  73.  
  74.  
  75.  
  76. class ControlNode(TypedString):
  77.     pass
  78.  
  79.  
  80. class TextNode(TypedString):
  81.     pass
  82.  
  83.  
  84. class WhitespaceNode(TypedString):
  85.     pass
  86.  
  87.  
  88. class Group(TypedList):
  89.     pass
  90.  
  91.  
  92. def compress_text(doc):
  93.     new = Group()
  94.     cur_text = []
  95.     while doc:
  96.         node = doc.pop(0)
  97.         if type(node) is WhitespaceNode:
  98.             if cur_text:
  99.                 cur_text.append(node)
  100.             
  101.         cur_text
  102.         if type(node) is TextNode:
  103.             cur_text.append(node)
  104.             continue
  105.         if type(node) is Group:
  106.             if cur_text:
  107.                 new.append(TextNode(''.join(cur_text)))
  108.             
  109.             new.append(compress_text(node))
  110.             continue
  111.     return new
  112.  
  113.  
  114. def parse(tokens):
  115.     doc = None
  116.     while tokens:
  117.         token = tokens.pop(0)
  118.         if token == '{':
  119.             if doc is None:
  120.                 doc = Group()
  121.             else:
  122.                 tokens.insert(0, '{')
  123.                 doc.append(parse(tokens))
  124.         doc is None
  125.         if token == '}':
  126.             return doc
  127.         if token == '\\':
  128.             next = tokens.pop(0)
  129.             if len(next) == 1 and next not in string.ascii_letters + string.digits:
  130.                 doc.append(TextNode(symbols.get(next, next)))
  131.             elif next.startswith("'"):
  132.                 hexchar = next[1:3]
  133.                 tokens.insert(0, next[3:])
  134.                 doc.append(TextNode(chr(int(hexchar, 16))))
  135.             else:
  136.                 doc.append(ControlNode(token + next))
  137.         next not in string.ascii_letters + string.digits
  138.         if token in string.whitespace:
  139.             last = doc[-1]
  140.             if type(last) is WhitespaceNode:
  141.                 doc[-1] = WhitespaceNode(last + token)
  142.             else:
  143.                 doc.append(WhitespaceNode(token))
  144.         type(last) is WhitespaceNode
  145.         last = doc[-1]
  146.         if type(last) is TextNode:
  147.             doc[-1] = TextNode(last + token)
  148.             continue
  149.         token == '}'
  150.         doc.append(TextNode(token))
  151.     doc = compress_text(doc)
  152.     return doc
  153.  
  154.  
  155. def tree_to_plain(tree):
  156.     tree = tree[:]
  157.     if not tree:
  158.         return ''
  159.     if type(tree[0]) is ControlNode and str(tree[0]) in ('\\colortbl', '\\fonttbl'):
  160.         return ''
  161.     res = []
  162.     encoding = None
  163.     last = None
  164.     uni_replace_len = None
  165.     while tree:
  166.         node = tree.pop(0)
  167.         last = node
  168.         continue
  169.         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
  170.     final = ''.join(res)
  171.     return final
  172.  
  173.  
  174. def rtf_to_plain(s):
  175.     return tree_to_plain(parse(tokenize(s)))
  176.  
  177.  
  178. def make_color_table(colors):
  179.     table = Group()
  180.     table.append(ControlNode('\\colortbl'))
  181.     table.append(TextNode(';'))
  182.     for color in colors:
  183.         (r, g, b, a) = tuple(color)
  184.         table.extend((ControlNode('\\red%d' % r), ControlNode('\\green%d' % g), ControlNode('\\blue%d' % b), TextNode(';')))
  185.     
  186.     return table
  187.  
  188.  
  189. def normalize_font_family(family):
  190.     family = family.lower()
  191.     if family not in set(('nil', 'roman', 'swiss', 'modern', 'script', 'decor', 'tech')):
  192.         return 'nil'
  193.     return family
  194.  
  195.  
  196. def make_font_table(fonts):
  197.     table = Group()
  198.     table.append(ControlNode('\\fonttbl'))
  199.     for family, font in enumerate(fonts):
  200.         table.extend((ControlNode('\\f%d' % i), ControlNode('\\' + normalize_font_family(family)), TextNode(' ' + font + ';')))
  201.     
  202.     return table
  203.  
  204.  
  205. def storage_to_tree(s):
  206.     if s.get('backgrouncolor') and s.get('foregroundcolor'):
  207.         color_table = make_color_table([
  208.             s.backgroundcolor,
  209.             s.foregroundcolor])
  210.     else:
  211.         color_table = TextNode('')
  212.     if s.get('family') and s.get('font'):
  213.         font_table = make_font_table([
  214.             (s.family, s.font)])
  215.     else:
  216.         font_table = TextNode('')
  217.     top_level = Group([
  218.         ControlNode('\\rtf1'),
  219.         ControlNode('\\ansi'),
  220.         ControlNode('\\uc1'),
  221.         color_table,
  222.         font_table])
  223.     format_group = Group([])
  224.     if font_table:
  225.         format_group.append(ControlNode('\\f1'))
  226.     
  227.     if color_table:
  228.         format_group.append(ControlNode('\\cb1'))
  229.         format_group.append(ControlNode('\\cf2'))
  230.     
  231.     if s.get('bold'):
  232.         format_group.append(ControlNode('\\b'))
  233.     
  234.     if s.get('italic'):
  235.         format_group.append(ControlNode('\\i'))
  236.     
  237.     if s.get('underline'):
  238.         format_group.append(ControlNode('\\ul'))
  239.     
  240.     if s.get('size'):
  241.         format_group.append(ControlNode('\\fs%d' % s.size * 2))
  242.     
  243.     top_level.append(format_group)
  244.     return (top_level, format_group.append)
  245.  
  246.  
  247. def storage_to_rtf(s, text):
  248.     escaped = rtf_escape(text)
  249.     (doc, add_text) = storage_to_tree(s)
  250.     add_text(escaped)
  251.     return tree_to_rtf(doc)
  252.  
  253.  
  254. def rtf_escape(node):
  255.     if isinstance(node, unicode):
  256.         s = unicode(node)
  257.         
  258.         try:
  259.             s = s.encode('ascii')
  260.         except UnicodeEncodeError:
  261.             pass
  262.         except:
  263.             None<EXCEPTION MATCH>UnicodeEncodeError
  264.         
  265.  
  266.     None<EXCEPTION MATCH>UnicodeEncodeError
  267.     s = str(node)
  268.     return ''.join((lambda .0: for c in .0:
  269. rtf_escape_chr(c))(s))
  270.  
  271.  
  272. def rtf_escape_chr(c):
  273.     if c in rev_symbols:
  274.         return '\\' + rev_symbols[c]
  275.     if isinstance(c, unicode):
  276.         val = ord(c)
  277.         (negate, val) = divmod(val, 32767)
  278.         if negate:
  279.             val = -abs(val)
  280.         
  281.         return '\\u%d ?' % val
  282.     if ord(c) > 127 and isinstance(c, str):
  283.         return "\\'%x" % ord(c)
  284.     return str(c)
  285.  
  286.  
  287. def tree_to_rtf(tree):
  288.     res = []
  289.     res.append('{')
  290.     for node in tree:
  291.         t = type(node)
  292.         if t is Group:
  293.             res.append(tree_to_rtf(node))
  294.             continue
  295.         if t is TextNode:
  296.             res.append(rtf_escape(node))
  297.             continue
  298.         res.append(str(node))
  299.     
  300.     res.append('}')
  301.     return ''.join(res)
  302.  
  303.  
  304. def main():
  305.     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')):
  306.         parsed = parse(tokenize(test_string))
  307.         plain = tree_to_plain(parsed)
  308.         print plain
  309.         if not test_plain == plain:
  310.             print repr(test_plain)
  311.             print repr(plain)
  312.             print 
  313.         
  314.         if not test_string == tree_to_rtf(parsed):
  315.             print repr(test_string)
  316.             print repr(tree_to_rtf(parsed))
  317.             print 
  318.             continue
  319.     
  320.  
  321. if __name__ == '__main__':
  322.     print main()
  323.  
  324.