home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2010 November / maximum-cd-2010-11.iso / DiscContents / calibre-0.7.13.msi / file_2103 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-08-06  |  44.2 KB  |  1,311 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import zipfile
  5. import xml.sax as xml
  6. from xml.sax import handler, expatreader
  7. from xml.sax.xmlreader import InputSource
  8. from xml.sax.saxutils import escape, quoteattr
  9. from cStringIO import StringIO
  10. from namespaces import ANIMNS, CHARTNS, CONFIGNS, DCNS, DR3DNS, DRAWNS, FONS, FORMNS, MATHNS, METANS, NUMBERNS, OFFICENS, PRESENTATIONNS, SCRIPTNS, SMILNS, STYLENS, SVGNS, TABLENS, TEXTNS, XLINKNS
  11.  
  12. class StyleToCSS:
  13.     
  14.     def __init__(self):
  15.         self.fontdict = { }
  16.         self.fillimages = { }
  17.         self.ruleconversions = {
  18.             (DRAWNS, u'fill-image-name'): self.c_drawfillimage,
  19.             (FONS, u'background-color'): self.c_fo,
  20.             (FONS, u'border'): self.c_fo,
  21.             (FONS, u'border-bottom'): self.c_fo,
  22.             (FONS, u'border-left'): self.c_fo,
  23.             (FONS, u'border-right'): self.c_fo,
  24.             (FONS, u'border-top'): self.c_fo,
  25.             (FONS, u'break-after'): self.c_break,
  26.             (FONS, u'break-before'): self.c_break,
  27.             (FONS, u'color'): self.c_fo,
  28.             (FONS, u'font-family'): self.c_fo,
  29.             (FONS, u'font-size'): self.c_fo,
  30.             (FONS, u'font-style'): self.c_fo,
  31.             (FONS, u'font-variant'): self.c_fo,
  32.             (FONS, u'font-weight'): self.c_fo,
  33.             (FONS, u'line-height'): self.c_fo,
  34.             (FONS, u'margin'): self.c_fo,
  35.             (FONS, u'margin-bottom'): self.c_fo,
  36.             (FONS, u'margin-left'): self.c_fo,
  37.             (FONS, u'margin-right'): self.c_fo,
  38.             (FONS, u'margin-top'): self.c_fo,
  39.             (FONS, u'min-height'): self.c_fo,
  40.             (FONS, u'padding'): self.c_fo,
  41.             (FONS, u'padding-bottom'): self.c_fo,
  42.             (FONS, u'padding-left'): self.c_fo,
  43.             (FONS, u'padding-right'): self.c_fo,
  44.             (FONS, u'padding-top'): self.c_fo,
  45.             (FONS, u'page-width'): self.c_page_width,
  46.             (FONS, u'page-height'): self.c_page_height,
  47.             (FONS, u'text-align'): self.c_text_align,
  48.             (FONS, u'text-indent'): self.c_fo,
  49.             (TABLENS, u'border-model'): self.c_border_model,
  50.             (STYLENS, u'column-width'): self.c_width,
  51.             (STYLENS, u'font-name'): self.c_fn,
  52.             (STYLENS, u'horizontal-pos'): self.c_hp,
  53.             (STYLENS, u'text-position'): self.c_text_position,
  54.             (STYLENS, u'text-line-through-style'): self.c_text_line_through_style,
  55.             (STYLENS, u'text-underline-style'): self.c_text_underline_style,
  56.             (STYLENS, u'width'): self.c_width }
  57.  
  58.     
  59.     def save_font(self, name, family, generic):
  60.         htmlgeneric = 'sans-serif'
  61.         if generic == 'roman':
  62.             htmlgeneric = 'serif'
  63.         elif generic == 'swiss':
  64.             htmlgeneric = 'sans-serif'
  65.         elif generic == 'modern':
  66.             htmlgeneric = 'monospace'
  67.         elif generic == 'decorative':
  68.             htmlgeneric = 'sans-serif'
  69.         elif generic == 'script':
  70.             htmlgeneric = 'monospace'
  71.         elif generic == 'system':
  72.             htmlgeneric = 'serif'
  73.         
  74.         self.fontdict[name] = (family, htmlgeneric)
  75.  
  76.     
  77.     def c_drawfillimage(self, ruleset, sdict, rule, val):
  78.         sdict['background-image'] = "url('%s')" % self.fillimages[val]
  79.  
  80.     
  81.     def c_fo(self, ruleset, sdict, rule, val):
  82.         selector = rule[1]
  83.         sdict[selector] = val
  84.  
  85.     
  86.     def c_break(self, ruleset, sdict, rule, val):
  87.         property = 'page-' + rule[1]
  88.         values = {
  89.             'auto': 'auto',
  90.             'column': 'always',
  91.             'page': 'always',
  92.             'even-page': 'left',
  93.             'odd-page': 'right',
  94.             'inherit': 'inherit' }
  95.         sdict[property] = values.get(val, 'auto')
  96.  
  97.     
  98.     def c_border_model(self, ruleset, sdict, rule, val):
  99.         if val == 'collapsing':
  100.             sdict['border-collapse'] = 'collapse'
  101.         else:
  102.             sdict['border-collapse'] = 'separate'
  103.  
  104.     
  105.     def c_width(self, ruleset, sdict, rule, val):
  106.         sdict['width'] = val
  107.  
  108.     
  109.     def c_text_align(self, ruleset, sdict, rule, align):
  110.         if align == 'start':
  111.             align = 'left'
  112.         
  113.         if align == 'end':
  114.             align = 'right'
  115.         
  116.         sdict['text-align'] = align
  117.  
  118.     
  119.     def c_fn(self, ruleset, sdict, rule, fontstyle):
  120.         generic = ruleset.get((STYLENS, 'font-family-generic'))
  121.         if generic is not None:
  122.             self.save_font(fontstyle, fontstyle, generic)
  123.         
  124.         (family, htmlgeneric) = self.fontdict.get(fontstyle, (fontstyle, 'serif'))
  125.         sdict['font-family'] = '%s, %s' % (family, htmlgeneric)
  126.  
  127.     
  128.     def c_text_position(self, ruleset, sdict, rule, tp):
  129.         textpos = tp.split(' ')
  130.         if len(textpos) == 2 and textpos[0] != '0%':
  131.             sdict['font-size'] = textpos[1]
  132.         
  133.         if textpos[0] == 'super':
  134.             sdict['vertical-align'] = '33%'
  135.         elif textpos[0] == 'sub':
  136.             sdict['vertical-align'] = '-33%'
  137.         else:
  138.             sdict['vertical-align'] = textpos[0]
  139.  
  140.     
  141.     def c_hp(self, ruleset, sdict, rule, hpos):
  142.         wrap = ruleset.get((STYLENS, 'wrap'), 'parallel')
  143.         if hpos == 'center':
  144.             sdict['margin-left'] = 'auto'
  145.             sdict['margin-right'] = 'auto'
  146.         
  147.         if hpos in ('right', 'outside'):
  148.             if wrap in ('left', 'parallel', 'dynamic'):
  149.                 sdict['float'] = 'right'
  150.             elif wrap == 'run-through':
  151.                 sdict['position'] = 'absolute'
  152.                 sdict['top'] = '0'
  153.                 sdict['right'] = '0'
  154.             else:
  155.                 sdict['margin-left'] = 'auto'
  156.                 sdict['margin-right'] = '0px'
  157.         elif hpos in ('left', 'inside'):
  158.             if wrap in ('right', 'parallel', 'dynamic'):
  159.                 sdict['float'] = 'left'
  160.             elif wrap == 'run-through':
  161.                 sdict['position'] = 'absolute'
  162.                 sdict['top'] = '0'
  163.                 sdict['left'] = '0'
  164.             else:
  165.                 sdict['margin-left'] = '0px'
  166.                 sdict['margin-right'] = 'auto'
  167.         elif hpos in ('from-left', 'from-inside'):
  168.             if wrap in ('right', 'parallel'):
  169.                 sdict['float'] = 'left'
  170.             else:
  171.                 sdict['position'] = 'relative'
  172.                 if ruleset.has_key((SVGNS, 'x')):
  173.                     sdict['left'] = ruleset[(SVGNS, 'x')]
  174.                 
  175.         
  176.  
  177.     
  178.     def c_page_width(self, ruleset, sdict, rule, val):
  179.         sdict['width'] = val
  180.  
  181.     
  182.     def c_text_underline_style(self, ruleset, sdict, rule, val):
  183.         if val and val != 'none':
  184.             sdict['text-decoration'] = 'underline'
  185.         
  186.  
  187.     
  188.     def c_text_line_through_style(self, ruleset, sdict, rule, val):
  189.         if val and val != 'none':
  190.             sdict['text-decoration'] = 'line-through'
  191.         
  192.  
  193.     
  194.     def c_page_height(self, ruleset, sdict, rule, val):
  195.         sdict['height'] = val
  196.  
  197.     
  198.     def convert_styles(self, ruleset):
  199.         sdict = { }
  200.         for rule, val in ruleset.items():
  201.             if rule[0] == '':
  202.                 sdict[rule[1]] = val
  203.                 continue
  204.             
  205.             method = self.ruleconversions.get(rule, None)
  206.             if method:
  207.                 method(ruleset, sdict, rule, val)
  208.                 continue
  209.         
  210.         return sdict
  211.  
  212.  
  213.  
  214. class TagStack:
  215.     
  216.     def __init__(self):
  217.         self.stack = []
  218.  
  219.     
  220.     def push(self, tag, attrs):
  221.         self.stack.append((tag, attrs))
  222.  
  223.     
  224.     def pop(self):
  225.         item = self.stack.pop()
  226.         return item
  227.  
  228.     
  229.     def stackparent(self):
  230.         item = self.stack[-1]
  231.         return item[1]
  232.  
  233.     
  234.     def rfindattr(self, attr):
  235.         for tag, attrs in self.stack:
  236.             if attrs.has_key(attr):
  237.                 return attrs[attr]
  238.         
  239.  
  240.     
  241.     def count_tags(self, tag):
  242.         c = 0
  243.         for ttag, tattrs in self.stack:
  244.             if ttag == tag:
  245.                 c = c + 1
  246.                 continue
  247.         
  248.         return c
  249.  
  250.  
  251. special_styles = {
  252.     'S-Emphasis': 'em',
  253.     'S-Citation': 'cite',
  254.     'S-Strong_20_Emphasis': 'strong',
  255.     'S-Variable': 'var',
  256.     'S-Definition': 'dfn',
  257.     'S-Teletype': 'tt',
  258.     'P-Heading_20_1': 'h1',
  259.     'P-Heading_20_2': 'h2',
  260.     'P-Heading_20_3': 'h3',
  261.     'P-Heading_20_4': 'h4',
  262.     'P-Heading_20_5': 'h5',
  263.     'P-Heading_20_6': 'h6',
  264.     'P-Addressee': 'address',
  265.     'P-Preformatted_20_Text': 'pre' }
  266.  
  267. class ODF2XHTML(handler.ContentHandler):
  268.     
  269.     def __init__(self, generate_css = True, embedable = False):
  270.         self.generate_css = generate_css
  271.         self.elements = {
  272.             (DCNS, 'title'): (self.s_processcont, self.e_dc_title),
  273.             (DCNS, 'language'): (self.s_processcont, self.e_dc_contentlanguage),
  274.             (DCNS, 'creator'): (self.s_processcont, self.e_dc_metatag),
  275.             (DCNS, 'description'): (self.s_processcont, self.e_dc_metatag),
  276.             (DCNS, 'date'): (self.s_processcont, self.e_dc_metatag),
  277.             (DRAWNS, 'frame'): (self.s_draw_frame, self.e_draw_frame),
  278.             (DRAWNS, 'image'): (self.s_draw_image, None),
  279.             (DRAWNS, 'fill-image'): (self.s_draw_fill_image, None),
  280.             (DRAWNS, 'layer-set'): (self.s_ignorexml, None),
  281.             (DRAWNS, 'page'): (self.s_draw_page, self.e_draw_page),
  282.             (DRAWNS, 'text-box'): (self.s_draw_textbox, self.e_draw_textbox),
  283.             (METANS, 'creation-date'): (self.s_processcont, self.e_dc_metatag),
  284.             (METANS, 'generator'): (self.s_processcont, self.e_dc_metatag),
  285.             (METANS, 'initial-creator'): (self.s_processcont, self.e_dc_metatag),
  286.             (METANS, 'keyword'): (self.s_processcont, self.e_dc_metatag),
  287.             (NUMBERNS, 'boolean-style'): (self.s_ignorexml, None),
  288.             (NUMBERNS, 'currency-style'): (self.s_ignorexml, None),
  289.             (NUMBERNS, 'date-style'): (self.s_ignorexml, None),
  290.             (NUMBERNS, 'number-style'): (self.s_ignorexml, None),
  291.             (NUMBERNS, 'text-style'): (self.s_ignorexml, None),
  292.             (OFFICENS, 'automatic-styles'): (self.s_office_automatic_styles, None),
  293.             (OFFICENS, 'document-content'): (self.s_office_document_content, self.e_office_document_content),
  294.             (OFFICENS, 'forms'): (self.s_ignorexml, None),
  295.             (OFFICENS, 'master-styles'): (self.s_office_master_styles, None),
  296.             (OFFICENS, 'meta'): (self.s_ignorecont, None),
  297.             (OFFICENS, 'presentation'): (self.s_office_presentation, self.e_office_presentation),
  298.             (OFFICENS, 'spreadsheet'): (self.s_office_spreadsheet, self.e_office_spreadsheet),
  299.             (OFFICENS, 'styles'): (self.s_office_styles, None),
  300.             (OFFICENS, 'text'): (self.s_office_text, self.e_office_text),
  301.             (OFFICENS, 'scripts'): (self.s_ignorexml, None),
  302.             (PRESENTATIONNS, 'notes'): (self.s_ignorexml, None),
  303.             (STYLENS, 'default-page-layout'): (self.s_ignorexml, None),
  304.             (STYLENS, 'default-style'): (self.s_style_default_style, self.e_style_default_style),
  305.             (STYLENS, 'drawing-page-properties'): (self.s_style_handle_properties, None),
  306.             (STYLENS, 'font-face'): (self.s_style_font_face, None),
  307.             (STYLENS, 'graphic-properties'): (self.s_style_handle_properties, None),
  308.             (STYLENS, 'handout-master'): (self.s_ignorexml, None),
  309.             (STYLENS, 'master-page'): (self.s_style_master_page, None),
  310.             (STYLENS, 'page-layout-properties'): (self.s_style_handle_properties, None),
  311.             (STYLENS, 'page-layout'): (self.s_ignorexml, None),
  312.             (STYLENS, 'paragraph-properties'): (self.s_style_handle_properties, None),
  313.             (STYLENS, 'style'): (self.s_style_style, self.e_style_style),
  314.             (STYLENS, 'table-cell-properties'): (self.s_style_handle_properties, None),
  315.             (STYLENS, 'table-column-properties'): (self.s_style_handle_properties, None),
  316.             (STYLENS, 'table-properties'): (self.s_style_handle_properties, None),
  317.             (STYLENS, 'text-properties'): (self.s_style_handle_properties, None),
  318.             (SVGNS, 'desc'): (self.s_ignorexml, None),
  319.             (TABLENS, 'covered-table-cell'): (self.s_ignorexml, None),
  320.             (TABLENS, 'table-cell'): (self.s_table_table_cell, self.e_table_table_cell),
  321.             (TABLENS, 'table-column'): (self.s_table_table_column, None),
  322.             (TABLENS, 'table-row'): (self.s_table_table_row, self.e_table_table_row),
  323.             (TABLENS, 'table'): (self.s_table_table, self.e_table_table),
  324.             (TEXTNS, 'a'): (self.s_text_a, self.e_text_a),
  325.             (TEXTNS, 'alphabetical-index-source'): (self.s_text_x_source, self.e_text_x_source),
  326.             (TEXTNS, 'bibliography-configuration'): (self.s_ignorexml, None),
  327.             (TEXTNS, 'bibliography-source'): (self.s_text_x_source, self.e_text_x_source),
  328.             (TEXTNS, 'h'): (self.s_text_h, self.e_text_h),
  329.             (TEXTNS, 'illustration-index-source'): (self.s_text_x_source, self.e_text_x_source),
  330.             (TEXTNS, 'line-break'): (self.s_text_line_break, None),
  331.             (TEXTNS, 'linenumbering-configuration'): (self.s_ignorexml, None),
  332.             (TEXTNS, 'list'): (self.s_text_list, self.e_text_list),
  333.             (TEXTNS, 'list-item'): (self.s_text_list_item, self.e_text_list_item),
  334.             (TEXTNS, 'list-level-style-bullet'): (self.s_text_list_level_style_bullet, self.e_text_list_level_style_bullet),
  335.             (TEXTNS, 'list-level-style-number'): (self.s_text_list_level_style_number, self.e_text_list_level_style_number),
  336.             (TEXTNS, 'list-style'): (None, None),
  337.             (TEXTNS, 'note'): (self.s_text_note, None),
  338.             (TEXTNS, 'note-body'): (self.s_text_note_body, self.e_text_note_body),
  339.             (TEXTNS, 'note-citation'): (None, self.e_text_note_citation),
  340.             (TEXTNS, 'notes-configuration'): (self.s_ignorexml, None),
  341.             (TEXTNS, 'object-index-source'): (self.s_text_x_source, self.e_text_x_source),
  342.             (TEXTNS, 'p'): (self.s_text_p, self.e_text_p),
  343.             (TEXTNS, 's'): (self.s_text_s, None),
  344.             (TEXTNS, 'span'): (self.s_text_span, self.e_text_span),
  345.             (TEXTNS, 'tab'): (self.s_text_tab, None),
  346.             (TEXTNS, 'table-index-source'): (self.s_text_x_source, self.e_text_x_source),
  347.             (TEXTNS, 'table-of-content-source'): (self.s_text_x_source, self.e_text_x_source),
  348.             (TEXTNS, 'user-index-source'): (self.s_text_x_source, self.e_text_x_source) }
  349.         if embedable:
  350.             self.elements[(OFFICENS, u'text')] = (None, None)
  351.             self.elements[(OFFICENS, u'spreadsheet')] = (None, None)
  352.             self.elements[(OFFICENS, u'presentation')] = (None, None)
  353.             self.elements[(OFFICENS, u'document-content')] = (None, None)
  354.         
  355.  
  356.     
  357.     def writeout(self, s):
  358.         if s != '':
  359.             self._wfunc(s)
  360.         
  361.  
  362.     
  363.     def writedata(self):
  364.         d = ''.join(self.data)
  365.         if d != '':
  366.             self.writeout(escape(d))
  367.         
  368.  
  369.     
  370.     def opentag(self, tag, attrs = { }, block = False):
  371.         a = []
  372.         for key, val in attrs.items():
  373.             a.append('%s=%s' % (key, quoteattr(val)))
  374.         
  375.         if len(a) == 0:
  376.             self.writeout('<%s>' % tag)
  377.         else:
  378.             self.writeout('<%s %s>' % (tag, ' '.join(a)))
  379.         if block == True:
  380.             self.writeout('\n')
  381.         
  382.  
  383.     
  384.     def closetag(self, tag, block = True):
  385.         self.writeout('</%s>' % tag)
  386.         if block == True:
  387.             self.writeout('\n')
  388.         
  389.  
  390.     
  391.     def emptytag(self, tag, attrs = { }):
  392.         a = []
  393.         for key, val in attrs.items():
  394.             a.append('%s=%s' % (key, quoteattr(val)))
  395.         
  396.         self.writeout('<%s %s/>\n' % (tag, ' '.join(a)))
  397.  
  398.     
  399.     def characters(self, data):
  400.         if self.processelem and self.processcont:
  401.             self.data.append(data)
  402.         
  403.  
  404.     
  405.     def handle_starttag(self, tag, method, attrs):
  406.         method(tag, attrs)
  407.  
  408.     
  409.     def handle_endtag(self, tag, attrs, method):
  410.         method(tag, attrs)
  411.  
  412.     
  413.     def startElementNS(self, tag, qname, attrs):
  414.         self.pstack.append((self.processelem, self.processcont))
  415.         if self.processelem:
  416.             method = self.elements.get(tag, (None, None))[0]
  417.             if method:
  418.                 self.handle_starttag(tag, method, attrs)
  419.             else:
  420.                 self.unknown_starttag(tag, attrs)
  421.         
  422.         self.tagstack.push(tag, attrs)
  423.  
  424.     
  425.     def endElementNS(self, tag, qname):
  426.         (stag, attrs) = self.tagstack.pop()
  427.         if self.processelem:
  428.             method = self.elements.get(tag, (None, None))[1]
  429.             if method:
  430.                 self.handle_endtag(tag, attrs, method)
  431.             else:
  432.                 self.unknown_endtag(tag, attrs)
  433.         
  434.         (self.processelem, self.processcont) = self.pstack.pop()
  435.  
  436.     
  437.     def unknown_starttag(self, tag, attrs):
  438.         pass
  439.  
  440.     
  441.     def unknown_endtag(self, tag, attrs):
  442.         pass
  443.  
  444.     
  445.     def s_ignorexml(self, tag, attrs):
  446.         self.processelem = False
  447.  
  448.     
  449.     def s_ignorecont(self, tag, attrs):
  450.         self.processcont = False
  451.  
  452.     
  453.     def s_processcont(self, tag, attrs):
  454.         self.processcont = True
  455.  
  456.     
  457.     def classname(self, attrs):
  458.         c = attrs[(TEXTNS, 'style-name')]
  459.         c = c.replace('.', '_')
  460.         return c
  461.  
  462.     
  463.     def get_anchor(self, name):
  464.         if not self.anchors.has_key(name):
  465.             self.anchors[name] = 'anchor%03d' % (len(self.anchors) + 1)
  466.         
  467.         return self.anchors.get(name)
  468.  
  469.     
  470.     def purgedata(self):
  471.         self.data = []
  472.  
  473.     
  474.     def e_dc_title(self, tag, attrs):
  475.         self.metatags.append('<title>%s</title>\n' % escape(''.join(self.data)))
  476.         self.title = ''.join(self.data)
  477.         self.data = []
  478.  
  479.     
  480.     def e_dc_metatag(self, tag, attrs):
  481.         self.metatags.append('<meta name="%s" content=%s/>\n' % (tag[1], quoteattr(''.join(self.data))))
  482.         self.data = []
  483.  
  484.     
  485.     def e_dc_contentlanguage(self, tag, attrs):
  486.         self.metatags.append('<meta http-equiv="content-language" content="%s"/>\n' % ''.join(self.data))
  487.         self.data = []
  488.  
  489.     
  490.     def s_draw_frame(self, tag, attrs):
  491.         anchor_type = attrs.get((TEXTNS, 'anchor-type'), 'char')
  492.         htmltag = 'div'
  493.         name = 'G-' + attrs.get((DRAWNS, 'style-name'), '')
  494.         if name == 'G-':
  495.             name = 'PR-' + attrs.get((PRESENTATIONNS, 'style-name'), '')
  496.         
  497.         name = name.replace('.', '_')
  498.         if anchor_type == 'paragraph':
  499.             style = 'position:relative;'
  500.         elif anchor_type == 'char':
  501.             style = 'position:relative;'
  502.         elif anchor_type == 'as-char':
  503.             htmltag = 'div'
  504.             style = ''
  505.         else:
  506.             style = 'position: absolute;'
  507.         if attrs.has_key((SVGNS, 'width')):
  508.             style = style + 'width:' + attrs[(SVGNS, 'width')] + ';'
  509.         
  510.         if attrs.has_key((SVGNS, 'height')):
  511.             style = style + 'height:' + attrs[(SVGNS, 'height')] + ';'
  512.         
  513.         if attrs.has_key((SVGNS, 'x')):
  514.             style = style + 'left:' + attrs[(SVGNS, 'x')] + ';'
  515.         
  516.         if attrs.has_key((SVGNS, 'y')):
  517.             style = style + 'top:' + attrs[(SVGNS, 'y')] + ';'
  518.         
  519.         if self.generate_css:
  520.             self.opentag(htmltag, {
  521.                 'class': name,
  522.                 'style': style })
  523.         else:
  524.             self.opentag(htmltag)
  525.  
  526.     
  527.     def e_draw_frame(self, tag, attrs):
  528.         self.closetag('div')
  529.  
  530.     
  531.     def s_draw_fill_image(self, tag, attrs):
  532.         name = attrs.get((DRAWNS, 'name'), 'NoName')
  533.         imghref = attrs[(XLINKNS, 'href')]
  534.         imghref = self.rewritelink(imghref)
  535.         self.cs.fillimages[name] = imghref
  536.  
  537.     
  538.     def rewritelink(self, imghref):
  539.         return imghref
  540.  
  541.     
  542.     def s_draw_image(self, tag, attrs):
  543.         parent = self.tagstack.stackparent()
  544.         anchor_type = parent.get((TEXTNS, 'anchor-type'))
  545.         imghref = attrs[(XLINKNS, 'href')]
  546.         imghref = self.rewritelink(imghref)
  547.         htmlattrs = {
  548.             'alt': '',
  549.             'src': imghref }
  550.         if self.generate_css:
  551.             if anchor_type != 'char':
  552.                 htmlattrs['style'] = 'display: block;'
  553.             
  554.         
  555.         self.emptytag('img', htmlattrs)
  556.  
  557.     
  558.     def s_draw_page(self, tag, attrs):
  559.         name = attrs.get((DRAWNS, 'name'), 'NoName')
  560.         stylename = attrs.get((DRAWNS, 'style-name'), '')
  561.         stylename = stylename.replace('.', '_')
  562.         masterpage = attrs.get((DRAWNS, 'master-page-name'), '')
  563.         masterpage = masterpage.replace('.', '_')
  564.         if self.generate_css:
  565.             self.opentag('fieldset', {
  566.                 'class': 'DP-%s MP-%s' % (stylename, masterpage) })
  567.         else:
  568.             self.opentag('fieldset')
  569.         self.opentag('legend')
  570.         self.writeout(escape(name))
  571.         self.closetag('legend')
  572.  
  573.     
  574.     def e_draw_page(self, tag, attrs):
  575.         self.closetag('fieldset')
  576.  
  577.     
  578.     def s_draw_textbox(self, tag, attrs):
  579.         style = ''
  580.         if attrs.has_key((FONS, 'min-height')):
  581.             style = style + 'min-height:' + attrs[(FONS, 'min-height')] + ';'
  582.         
  583.         self.opentag('div')
  584.  
  585.     
  586.     def e_draw_textbox(self, tag, attrs):
  587.         self.closetag('div')
  588.  
  589.     
  590.     def html_body(self, tag, attrs):
  591.         self.writedata()
  592.         if self.generate_css:
  593.             self.opentag('style', {
  594.                 'type': 'text/css' }, True)
  595.             self.writeout('/*<![CDATA[*/\n')
  596.             self.writeout('\nimg { width: 100%; height: 100%; }\n')
  597.             self.writeout('* { padding: 0; margin: 0;  background-color:white; }\n')
  598.             self.writeout('body { margin: 0 1em; }\n')
  599.             self.writeout('ol, ul { padding-left: 2em; }\n')
  600.             self.generate_stylesheet()
  601.             self.writeout('/*]]>*/\n')
  602.             self.closetag('style')
  603.         
  604.         self.purgedata()
  605.         self.closetag('head')
  606.         self.opentag('body', block = True)
  607.  
  608.     
  609.     def generate_stylesheet(self):
  610.         for name in self.stylestack:
  611.             styles = self.styledict.get(name)
  612.             if styles.has_key('__style-family') and self.styledict.has_key(styles['__style-family']):
  613.                 familystyle = self.styledict[styles['__style-family']].copy()
  614.                 del styles['__style-family']
  615.                 for style, val in styles.items():
  616.                     familystyle[style] = val
  617.                 
  618.                 styles = familystyle
  619.             
  620.             while styles.has_key('__parent-style-name') and self.styledict.has_key(styles['__parent-style-name']):
  621.                 parentstyle = self.styledict[styles['__parent-style-name']].copy()
  622.                 del styles['__parent-style-name']
  623.                 for style, val in styles.items():
  624.                     parentstyle[style] = val
  625.                 
  626.                 styles = parentstyle
  627.             self.styledict[name] = styles
  628.         
  629.         for name in self.stylestack:
  630.             styles = self.styledict.get(name)
  631.             css2 = self.cs.convert_styles(styles)
  632.             self.writeout('%s {\n' % name)
  633.             for style, val in css2.items():
  634.                 self.writeout('\t%s: %s;\n' % (style, val))
  635.             
  636.             self.writeout('}\n')
  637.         
  638.  
  639.     
  640.     def generate_footnotes(self):
  641.         if self.currentnote == 0:
  642.             return None
  643.         if self.generate_css:
  644.             self.opentag('ol', {
  645.                 'style': 'border-top: 1px solid black' }, True)
  646.         else:
  647.             self.opentag('ol')
  648.         for key in range(1, self.currentnote + 1):
  649.             note = self.notedict[key]
  650.             self.opentag('li', {
  651.                 'id': 'footnote-%d' % key })
  652.             self.writeout(note['body'])
  653.             self.closetag('li')
  654.         
  655.         self.closetag('ol')
  656.  
  657.     
  658.     def s_office_automatic_styles(self, tag, attrs):
  659.         if self.xmlfile == 'styles.xml':
  660.             self.autoprefix = 'A'
  661.         else:
  662.             self.autoprefix = ''
  663.  
  664.     
  665.     def s_office_document_content(self, tag, attrs):
  666.         self.writeout('<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" ')
  667.         self.writeout('"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n')
  668.         self.opentag('html', {
  669.             'xmlns': 'http://www.w3.org/1999/xhtml' }, True)
  670.         self.opentag('head', block = True)
  671.         self.emptytag('meta', {
  672.             'http-equiv': 'Content-Type',
  673.             'content': 'text/html;charset=UTF-8' })
  674.         for metaline in self.metatags:
  675.             self.writeout(metaline)
  676.         
  677.  
  678.     
  679.     def e_office_document_content(self, tag, attrs):
  680.         self.closetag('html')
  681.  
  682.     
  683.     def s_office_master_styles(self, tag, attrs):
  684.         pass
  685.  
  686.     
  687.     def s_office_presentation(self, tag, attrs):
  688.         self.styledict['p'] = {
  689.             (FONS, u'font-size'): u'24pt' }
  690.         self.styledict['presentation'] = {
  691.             (FONS, u'font-size'): u'24pt' }
  692.         self.html_body(tag, attrs)
  693.  
  694.     
  695.     def e_office_presentation(self, tag, attrs):
  696.         self.generate_footnotes()
  697.         self.closetag('body')
  698.  
  699.     
  700.     def s_office_spreadsheet(self, tag, attrs):
  701.         self.html_body(tag, attrs)
  702.  
  703.     
  704.     def e_office_spreadsheet(self, tag, attrs):
  705.         self.generate_footnotes()
  706.         self.closetag('body')
  707.  
  708.     
  709.     def s_office_styles(self, tag, attrs):
  710.         self.autoprefix = ''
  711.  
  712.     
  713.     def s_office_text(self, tag, attrs):
  714.         self.styledict['frame'] = {
  715.             (STYLENS, 'wrap'): u'parallel' }
  716.         self.html_body(tag, attrs)
  717.  
  718.     
  719.     def e_office_text(self, tag, attrs):
  720.         self.generate_footnotes()
  721.         self.closetag('body')
  722.  
  723.     
  724.     def s_style_handle_properties(self, tag, attrs):
  725.         if self.currentstyle is None:
  726.             return None
  727.         for key, attr in attrs.items():
  728.             self.styledict[self.currentstyle][key] = attr
  729.         
  730.  
  731.     familymap = {
  732.         'frame': 'frame',
  733.         'paragraph': 'p',
  734.         'presentation': 'presentation',
  735.         'text': 'span',
  736.         'section': 'div',
  737.         'table': 'table',
  738.         'table-cell': 'td',
  739.         'table-column': 'col',
  740.         'table-row': 'tr',
  741.         'graphic': 'graphic' }
  742.     
  743.     def s_style_default_style(self, tag, attrs):
  744.         family = attrs[(STYLENS, 'family')]
  745.         htmlfamily = self.familymap.get(family, 'unknown')
  746.         self.currentstyle = htmlfamily
  747.         self.styledict[self.currentstyle] = { }
  748.  
  749.     
  750.     def e_style_default_style(self, tag, attrs):
  751.         self.currentstyle = None
  752.  
  753.     
  754.     def s_style_font_face(self, tag, attrs):
  755.         name = attrs[(STYLENS, 'name')]
  756.         family = attrs[(SVGNS, 'font-family')]
  757.         generic = attrs.get((STYLENS, 'font-family-generic'), '')
  758.         self.cs.save_font(name, family, generic)
  759.  
  760.     
  761.     def s_style_footer(self, tag, attrs):
  762.         self.opentag('div', {
  763.             'id': 'footer' })
  764.         self.purgedata()
  765.  
  766.     
  767.     def e_style_footer(self, tag, attrs):
  768.         self.writedata()
  769.         self.closetag('div')
  770.         self.purgedata()
  771.  
  772.     
  773.     def s_style_footer_style(self, tag, attrs):
  774.         self.currentstyle = '@print #footer'
  775.         self.stylestack.append(self.currentstyle)
  776.         self.styledict[self.currentstyle] = { }
  777.  
  778.     
  779.     def s_style_header(self, tag, attrs):
  780.         self.opentag('div', {
  781.             'id': 'header' })
  782.         self.purgedata()
  783.  
  784.     
  785.     def e_style_header(self, tag, attrs):
  786.         self.writedata()
  787.         self.closetag('div')
  788.         self.purgedata()
  789.  
  790.     
  791.     def s_style_header_style(self, tag, attrs):
  792.         self.currentstyle = '@print #header'
  793.         self.stylestack.append(self.currentstyle)
  794.         self.styledict[self.currentstyle] = { }
  795.  
  796.     
  797.     def s_style_default_page_layout(self, tag, attrs):
  798.         self.currentstyle = '@page'
  799.         self.stylestack.append(self.currentstyle)
  800.         self.styledict[self.currentstyle] = { }
  801.  
  802.     
  803.     def s_style_page_layout(self, tag, attrs):
  804.         name = attrs[(STYLENS, 'name')]
  805.         name = name.replace('.', '_')
  806.         self.currentstyle = '@page ' + name
  807.         self.stylestack.append(self.currentstyle)
  808.         self.styledict[self.currentstyle] = { }
  809.  
  810.     
  811.     def e_style_page_layout(self, tag, attrs):
  812.         self.currentstyle = None
  813.  
  814.     
  815.     def s_style_master_page(self, tag, attrs):
  816.         name = attrs[(STYLENS, 'name')]
  817.         name = name.replace('.', '_')
  818.         self.currentstyle = '.MP-' + name
  819.         self.stylestack.append(self.currentstyle)
  820.         self.styledict[self.currentstyle] = {
  821.             ('', 'position'): 'relative' }
  822.         pagelayout = attrs.get((STYLENS, 'page-layout-name'), None)
  823.         if pagelayout:
  824.             pagelayout = '.PL-' + pagelayout
  825.             if self.styledict.has_key(pagelayout):
  826.                 styles = self.styledict[pagelayout]
  827.                 for style, val in styles.items():
  828.                     self.styledict[self.currentstyle][style] = val
  829.                 
  830.             else:
  831.                 self.styledict[self.currentstyle]['__parent-style-name'] = pagelayout
  832.         
  833.         self.s_ignorexml(tag, attrs)
  834.  
  835.     familyshort = {
  836.         'drawing-page': 'DP',
  837.         'paragraph': 'P',
  838.         'presentation': 'PR',
  839.         'text': 'S',
  840.         'section': 'D',
  841.         'table': 'T',
  842.         'table-cell': 'TD',
  843.         'table-column': 'TC',
  844.         'table-row': 'TR',
  845.         'graphic': 'G' }
  846.     
  847.     def s_style_style(self, tag, attrs):
  848.         name = attrs[(STYLENS, 'name')]
  849.         name = name.replace('.', '_')
  850.         family = attrs[(STYLENS, 'family')]
  851.         htmlfamily = self.familymap.get(family, 'unknown')
  852.         sfamily = self.familyshort.get(family, 'X')
  853.         name = '%s%s-%s' % (self.autoprefix, sfamily, name)
  854.         parent = attrs.get((STYLENS, 'parent-style-name'))
  855.         self.currentstyle = special_styles.get(name, '.' + name)
  856.         self.stylestack.append(self.currentstyle)
  857.         if not self.styledict.has_key(self.currentstyle):
  858.             self.styledict[self.currentstyle] = { }
  859.         
  860.         self.styledict[self.currentstyle]['__style-family'] = htmlfamily
  861.         if parent:
  862.             parent = '%s-%s' % (sfamily, parent)
  863.             parent = special_styles.get(parent, '.' + parent)
  864.             if self.styledict.has_key(parent):
  865.                 styles = self.styledict[parent]
  866.                 for style, val in styles.items():
  867.                     self.styledict[self.currentstyle][style] = val
  868.                 
  869.             else:
  870.                 self.styledict[self.currentstyle]['__parent-style-name'] = parent
  871.         
  872.  
  873.     
  874.     def e_style_style(self, tag, attrs):
  875.         self.currentstyle = None
  876.  
  877.     
  878.     def s_table_table(self, tag, attrs):
  879.         c = attrs.get((TABLENS, 'style-name'), None)
  880.         if c and self.generate_css:
  881.             c = c.replace('.', '_')
  882.             self.opentag('table', {
  883.                 'class': 'T-%s' % c })
  884.         else:
  885.             self.opentag('table')
  886.         self.purgedata()
  887.  
  888.     
  889.     def e_table_table(self, tag, attrs):
  890.         self.writedata()
  891.         self.closetag('table')
  892.         self.purgedata()
  893.  
  894.     
  895.     def s_table_table_cell(self, tag, attrs):
  896.         htmlattrs = { }
  897.         rowspan = attrs.get((TABLENS, 'number-rows-spanned'))
  898.         if rowspan:
  899.             htmlattrs['rowspan'] = rowspan
  900.         
  901.         colspan = attrs.get((TABLENS, 'number-columns-spanned'))
  902.         if colspan:
  903.             htmlattrs['colspan'] = colspan
  904.         
  905.         c = attrs.get((TABLENS, 'style-name'))
  906.         if c:
  907.             htmlattrs['class'] = 'TD-%s' % c.replace('.', '_')
  908.         
  909.         self.opentag('td', htmlattrs)
  910.         self.purgedata()
  911.  
  912.     
  913.     def e_table_table_cell(self, tag, attrs):
  914.         self.writedata()
  915.         self.closetag('td')
  916.         self.purgedata()
  917.  
  918.     
  919.     def s_table_table_column(self, tag, attrs):
  920.         c = attrs.get((TABLENS, 'style-name'), None)
  921.         repeated = int(attrs.get((TABLENS, 'number-columns-repeated'), 1))
  922.         htmlattrs = { }
  923.         if c:
  924.             htmlattrs['class'] = 'TC-%s' % c.replace('.', '_')
  925.         
  926.         for x in xrange(repeated):
  927.             self.emptytag('col', htmlattrs)
  928.         
  929.         self.purgedata()
  930.  
  931.     
  932.     def s_table_table_row(self, tag, attrs):
  933.         c = attrs.get((TABLENS, 'style-name'), None)
  934.         htmlattrs = { }
  935.         if c:
  936.             htmlattrs['class'] = 'TR-%s' % c.replace('.', '_')
  937.         
  938.         self.opentag('tr', htmlattrs)
  939.         self.purgedata()
  940.  
  941.     
  942.     def e_table_table_row(self, tag, attrs):
  943.         self.writedata()
  944.         self.closetag('tr')
  945.         self.purgedata()
  946.  
  947.     
  948.     def s_text_a(self, tag, attrs):
  949.         self.writedata()
  950.         href = attrs[(XLINKNS, 'href')].split('|')[0]
  951.         if href[0] == '#':
  952.             href = '#' + self.get_anchor(href[1:])
  953.         
  954.         self.opentag('a', {
  955.             'href': href })
  956.         self.purgedata()
  957.  
  958.     
  959.     def e_text_a(self, tag, attrs):
  960.         self.writedata()
  961.         self.closetag('a', False)
  962.         self.purgedata()
  963.  
  964.     
  965.     def s_text_h(self, tag, attrs):
  966.         level = int(attrs[(TEXTNS, 'outline-level')])
  967.         if level > 6:
  968.             level = 6
  969.         
  970.         if level < 1:
  971.             level = 1
  972.         
  973.         self.headinglevels[level] = self.headinglevels[level] + 1
  974.         name = self.classname(attrs)
  975.         for x in range(level + 1, 10):
  976.             self.headinglevels[x] = 0
  977.         
  978.         special = special_styles.get('P-' + name)
  979.         if special or not (self.generate_css):
  980.             self.opentag('h%s' % level)
  981.         else:
  982.             self.opentag('h%s' % level, {
  983.                 'class': 'P-%s' % name })
  984.         self.purgedata()
  985.  
  986.     
  987.     def e_text_h(self, tag, attrs):
  988.         self.writedata()
  989.         level = int(attrs[(TEXTNS, 'outline-level')])
  990.         if level > 6:
  991.             level = 6
  992.         
  993.         if level < 1:
  994.             level = 1
  995.         
  996.         lev = self.headinglevels[1:level + 1]
  997.         outline = '.'.join(map(str, lev))
  998.         anchor = self.get_anchor('%s.%s' % (outline, ''.join(self.data)))
  999.         self.opentag('a', {
  1000.             'id': anchor })
  1001.         self.closetag('a', False)
  1002.         self.closetag('h%s' % level)
  1003.         self.purgedata()
  1004.  
  1005.     
  1006.     def s_text_line_break(self, tag, attrs):
  1007.         self.writedata()
  1008.         self.emptytag('br')
  1009.         self.purgedata()
  1010.  
  1011.     
  1012.     def s_text_list(self, tag, attrs):
  1013.         name = attrs.get((TEXTNS, 'style-name'))
  1014.         level = self.tagstack.count_tags(tag) + 1
  1015.         if name:
  1016.             name = name.replace('.', '_')
  1017.         else:
  1018.             name = self.tagstack.rfindattr((TEXTNS, 'style-name'))
  1019.         list_class = '%s_%d' % (name, level)
  1020.         if self.generate_css:
  1021.             self.opentag('%s' % self.listtypes.get(list_class, 'UL'), {
  1022.                 'class': list_class })
  1023.         else:
  1024.             self.opentag('%s' % self.listtypes.get(list_class, 'UL'))
  1025.         self.purgedata()
  1026.  
  1027.     
  1028.     def e_text_list(self, tag, attrs):
  1029.         self.writedata()
  1030.         name = attrs.get((TEXTNS, 'style-name'))
  1031.         level = self.tagstack.count_tags(tag) + 1
  1032.         if name:
  1033.             name = name.replace('.', '_')
  1034.         else:
  1035.             name = self.tagstack.rfindattr((TEXTNS, 'style-name'))
  1036.         list_class = '%s_%d' % (name, level)
  1037.         self.closetag(self.listtypes.get(list_class, 'UL'))
  1038.         self.purgedata()
  1039.  
  1040.     
  1041.     def s_text_list_item(self, tag, attrs):
  1042.         self.opentag('li')
  1043.         self.purgedata()
  1044.  
  1045.     
  1046.     def e_text_list_item(self, tag, attrs):
  1047.         self.writedata()
  1048.         self.closetag('li')
  1049.         self.purgedata()
  1050.  
  1051.     
  1052.     def s_text_list_level_style_bullet(self, tag, attrs):
  1053.         name = self.tagstack.rfindattr((STYLENS, 'name'))
  1054.         level = attrs[(TEXTNS, 'level')]
  1055.         self.prevstyle = self.currentstyle
  1056.         list_class = '%s_%s' % (name, level)
  1057.         self.listtypes[list_class] = 'ul'
  1058.         self.currentstyle = '.%s_%s' % (name.replace('.', '_'), level)
  1059.         self.stylestack.append(self.currentstyle)
  1060.         self.styledict[self.currentstyle] = { }
  1061.         level = int(level)
  1062.         listtype = ('square', 'disc', 'circle')[level % 3]
  1063.         self.styledict[self.currentstyle][('', 'list-style-type')] = listtype
  1064.  
  1065.     
  1066.     def e_text_list_level_style_bullet(self, tag, attrs):
  1067.         self.currentstyle = self.prevstyle
  1068.         del self.prevstyle
  1069.  
  1070.     
  1071.     def s_text_list_level_style_number(self, tag, attrs):
  1072.         name = self.tagstack.stackparent()[(STYLENS, 'name')]
  1073.         level = attrs[(TEXTNS, 'level')]
  1074.         num_format = attrs.get((STYLENS, 'name'), '1')
  1075.         list_class = '%s_%s' % (name, level)
  1076.         self.prevstyle = self.currentstyle
  1077.         self.currentstyle = '.%s_%s' % (name.replace('.', '_'), level)
  1078.         self.listtypes[list_class] = 'ol'
  1079.         self.stylestack.append(self.currentstyle)
  1080.         self.styledict[self.currentstyle] = { }
  1081.         if num_format == '1':
  1082.             listtype = 'decimal'
  1083.         elif num_format == 'I':
  1084.             listtype = 'upper-roman'
  1085.         elif num_format == 'i':
  1086.             listtype = 'lower-roman'
  1087.         elif num_format == 'A':
  1088.             listtype = 'upper-alpha'
  1089.         elif num_format == 'a':
  1090.             listtype = 'lower-alpha'
  1091.         else:
  1092.             listtype = 'decimal'
  1093.         self.styledict[self.currentstyle][('', 'list-style-type')] = listtype
  1094.  
  1095.     
  1096.     def e_text_list_level_style_number(self, tag, attrs):
  1097.         self.currentstyle = self.prevstyle
  1098.         del self.prevstyle
  1099.  
  1100.     
  1101.     def s_text_note(self, tag, attrs):
  1102.         self.writedata()
  1103.         self.purgedata()
  1104.         self.currentnote = self.currentnote + 1
  1105.         self.notedict[self.currentnote] = { }
  1106.         self.notebody = []
  1107.  
  1108.     
  1109.     def e_text_note(self, tag, attrs):
  1110.         pass
  1111.  
  1112.     
  1113.     def collectnote(self, s):
  1114.         if s != '':
  1115.             self.notebody.append(s)
  1116.         
  1117.  
  1118.     
  1119.     def s_text_note_body(self, tag, attrs):
  1120.         self._orgwfunc = self._wfunc
  1121.         self._wfunc = self.collectnote
  1122.  
  1123.     
  1124.     def e_text_note_body(self, tag, attrs):
  1125.         self._wfunc = self._orgwfunc
  1126.         self.notedict[self.currentnote]['body'] = ''.join(self.notebody)
  1127.         self.notebody = ''
  1128.         del self._orgwfunc
  1129.  
  1130.     
  1131.     def e_text_note_citation(self, tag, attrs):
  1132.         mark = ''.join(self.data)
  1133.         self.notedict[self.currentnote]['citation'] = mark
  1134.         self.opentag('a', {
  1135.             'href': '#footnote-%s' % self.currentnote })
  1136.         self.opentag('sup')
  1137.         self.writeout(unicode(self.currentnote))
  1138.         self.closetag('sup')
  1139.         self.closetag('a')
  1140.  
  1141.     
  1142.     def s_text_p(self, tag, attrs):
  1143.         htmlattrs = { }
  1144.         specialtag = 'p'
  1145.         c = attrs.get((TEXTNS, 'style-name'), None)
  1146.         if c:
  1147.             c = c.replace('.', '_')
  1148.             specialtag = special_styles.get('P-' + c)
  1149.             if specialtag is None:
  1150.                 specialtag = 'p'
  1151.                 if self.generate_css:
  1152.                     htmlattrs['class'] = 'P-%s' % c
  1153.                 
  1154.             
  1155.         
  1156.         self.opentag(specialtag, htmlattrs)
  1157.         self.purgedata()
  1158.  
  1159.     
  1160.     def e_text_p(self, tag, attrs):
  1161.         specialtag = 'p'
  1162.         c = attrs.get((TEXTNS, 'style-name'), None)
  1163.         if c:
  1164.             c = c.replace('.', '_')
  1165.             specialtag = special_styles.get('P-' + c)
  1166.             if specialtag is None:
  1167.                 specialtag = 'p'
  1168.             
  1169.         
  1170.         self.writedata()
  1171.         if not self.data:
  1172.             self.writeout(' ')
  1173.         
  1174.         self.closetag(specialtag)
  1175.         self.purgedata()
  1176.  
  1177.     
  1178.     def s_text_s(self, tag, attrs):
  1179.         c = attrs.get((TEXTNS, 'c'), '1')
  1180.         for x in xrange(int(c)):
  1181.             self.writeout(' ')
  1182.         
  1183.  
  1184.     
  1185.     def s_text_span(self, tag, attrs):
  1186.         self.writedata()
  1187.         c = attrs.get((TEXTNS, 'style-name'), None)
  1188.         htmlattrs = { }
  1189.         if c:
  1190.             c = c.replace('.', '_')
  1191.             special = special_styles.get('S-' + c)
  1192.             if special is None and self.generate_css:
  1193.                 htmlattrs['class'] = 'S-%s' % c
  1194.             
  1195.         
  1196.         self.opentag('span', htmlattrs)
  1197.         self.purgedata()
  1198.  
  1199.     
  1200.     def e_text_span(self, tag, attrs):
  1201.         self.writedata()
  1202.         self.closetag('span', False)
  1203.         self.purgedata()
  1204.  
  1205.     
  1206.     def s_text_tab(self, tag, attrs):
  1207.         self.writedata()
  1208.         self.writeout(' ')
  1209.         self.purgedata()
  1210.  
  1211.     
  1212.     def s_text_x_source(self, tag, attrs):
  1213.         self.writedata()
  1214.         self.purgedata()
  1215.         self.s_ignorexml(tag, attrs)
  1216.  
  1217.     
  1218.     def e_text_x_source(self, tag, attrs):
  1219.         self.writedata()
  1220.         self.purgedata()
  1221.  
  1222.     
  1223.     def load(self, odffile):
  1224.         self._odffile = odffile
  1225.  
  1226.     
  1227.     def parseodf(self):
  1228.         self.xmlfile = ''
  1229.         self.title = ''
  1230.         self.data = []
  1231.         self.tagstack = TagStack()
  1232.         self.pstack = []
  1233.         self.processelem = True
  1234.         self.processcont = True
  1235.         self.listtypes = { }
  1236.         self.headinglevels = [
  1237.             0,
  1238.             0,
  1239.             0,
  1240.             0,
  1241.             0,
  1242.             0,
  1243.             0,
  1244.             0,
  1245.             0,
  1246.             0,
  1247.             0]
  1248.         self.cs = StyleToCSS()
  1249.         self.anchors = { }
  1250.         self.stylestack = []
  1251.         self.styledict = { }
  1252.         self.currentstyle = None
  1253.         self.notedict = { }
  1254.         self.currentnote = 0
  1255.         self.notebody = ''
  1256.         self.metatags = []
  1257.         z = zipfile.ZipFile(self._odffile)
  1258.         parser = expatreader.create_parser()
  1259.         parser.setFeature(handler.feature_namespaces, 1)
  1260.         parser.setContentHandler(self)
  1261.         parser.setErrorHandler(handler.ErrorHandler())
  1262.         inpsrc = InputSource()
  1263.         for xmlfile in ('meta.xml', 'styles.xml', 'content.xml'):
  1264.             self.xmlfile = xmlfile
  1265.             content = z.read(xmlfile)
  1266.             inpsrc.setByteStream(StringIO(content))
  1267.             parser.parse(inpsrc)
  1268.         
  1269.         z.close()
  1270.  
  1271.     
  1272.     def odf2xhtml(self, odffile):
  1273.         self.load(odffile)
  1274.         return self.xhtml()
  1275.  
  1276.     
  1277.     def _wlines(self, s):
  1278.         if s != '':
  1279.             self.lines.append(s)
  1280.         
  1281.  
  1282.     
  1283.     def xhtml(self):
  1284.         self.lines = []
  1285.         self._wfunc = self._wlines
  1286.         self.parseodf()
  1287.         return ''.join(self.lines)
  1288.  
  1289.     
  1290.     def _writecss(self, s):
  1291.         if s != '':
  1292.             self._csslines.append(s)
  1293.         
  1294.  
  1295.     
  1296.     def _writenothing(self, s):
  1297.         pass
  1298.  
  1299.     
  1300.     def css(self):
  1301.         self._wfunc = self._writenothing
  1302.         self.parseodf()
  1303.         self._csslines = []
  1304.         self._wfunc = self._writecss
  1305.         self.generate_stylesheet()
  1306.         res = ''.join(self._csslines)
  1307.         del self._csslines
  1308.         return res
  1309.  
  1310.  
  1311.