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

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import os
  5. import re
  6. import codecs
  7. import operator
  8. from xml.sax.saxutils import escape
  9. from datetime import date
  10.  
  11. try:
  12.     from elementtree.ElementTree import Element, SubElement
  13.     (Element, SubElement)
  14. except ImportError:
  15.     from xml.etree.ElementTree import Element, SubElement
  16.  
  17. from elements import ElementWriter
  18. from pylrf import LrfWriter, LrfObject, LrfTag, LrfToc, STREAM_COMPRESSED, LrfTagStream, LrfStreamBase, IMAGE_TYPE_ENCODING, BINDING_DIRECTION_ENCODING, LINE_TYPE_ENCODING, LrfFileStream, STREAM_FORCE_COMPRESSED
  19. from calibre.utils.date import isoformat
  20. DEFAULT_SOURCE_ENCODING = 'cp1252'
  21. DEFAULT_GENREADING = 'fs'
  22. from calibre import __appname__, __version__
  23. from calibre import entity_to_unicode
  24.  
  25. class LrsError(Exception):
  26.     pass
  27.  
  28.  
  29. class ContentError(Exception):
  30.     pass
  31.  
  32.  
  33. def _checkExists(filename):
  34.     if not os.path.exists(filename):
  35.         raise LrsError, "file '%s' not found" % filename
  36.     os.path.exists(filename)
  37.  
  38.  
  39. def _formatXml(root):
  40.     for elem in root.getiterator():
  41.         if len(elem) > 0:
  42.             if not (elem.text) or not elem.text.strip():
  43.                 elem.text = '\n'
  44.             
  45.         if not (elem.tail) or not elem.tail.strip():
  46.             elem.tail = '\n'
  47.             continue
  48.     
  49.  
  50.  
  51. def ElementWithText(tag, text, **extra):
  52.     e = Element(tag, **extra)
  53.     e.text = text
  54.     return e
  55.  
  56.  
  57. def ElementWithReading(tag, text, reading = False):
  58.     if text is None:
  59.         readingText = ''
  60.     elif isinstance(text, basestring):
  61.         readingText = text
  62.     else:
  63.         readingText = text[1]
  64.         text = text[0]
  65.     if not reading:
  66.         readingText = ''
  67.     
  68.     return ElementWithText(tag, text, reading = readingText)
  69.  
  70.  
  71. def appendTextElements(e, contentsList, se):
  72.     
  73.     def uconcat(text, newText, se):
  74.         if type(newText) != type(text):
  75.             if type(text) is str:
  76.                 text = text.decode(se)
  77.             else:
  78.                 newText = newText.decode(se)
  79.         
  80.         return text + newText
  81.  
  82.     e.text = ''
  83.     lastElement = None
  84.     for content in contentsList:
  85.         if not isinstance(content, Text):
  86.             newElement = content.toElement(se)
  87.             if newElement is None:
  88.                 continue
  89.             
  90.             lastElement = newElement
  91.             lastElement.tail = ''
  92.             e.append(lastElement)
  93.             continue
  94.         if lastElement is None:
  95.             e.text = uconcat(e.text, content.text, se)
  96.             continue
  97.         lastElement.tail = uconcat(lastElement.tail, content.text, se)
  98.     
  99.  
  100.  
  101. class Delegator(object):
  102.     
  103.     def __init__(self, delegates):
  104.         self.delegates = delegates
  105.         self.delegatedMethods = []
  106.         for d in delegates:
  107.             d.parent = self
  108.             methods = d.getMethods()
  109.             self.delegatedMethods += methods
  110.             for m in methods:
  111.                 setattr(self, m, getattr(d, m))
  112.             
  113.         
  114.  
  115.     
  116.     def applySetting(self, name, value, testValid = False):
  117.         applied = False
  118.         if name in self.getSettings():
  119.             setattr(self, name, value)
  120.             applied = True
  121.         
  122.         for d in self.delegates:
  123.             if hasattr(d, 'applySetting'):
  124.                 if not applied:
  125.                     pass
  126.                 applied = d.applySetting(name, value)
  127.                 continue
  128.             if name in d.getSettings():
  129.                 setattr(d, name, value)
  130.                 applied = True
  131.                 continue
  132.         
  133.         if testValid and not applied:
  134.             raise LrsError, 'setting %s not valid' % name
  135.         not applied
  136.         return applied
  137.  
  138.     
  139.     def applySettings(self, settings, testValid = False):
  140.         for setting, value in settings.items():
  141.             self.applySetting(setting, value, testValid)
  142.         
  143.  
  144.     
  145.     def appendDelegates(self, element, sourceEncoding):
  146.         for d in self.delegates:
  147.             e = d.toElement(sourceEncoding)
  148.             if e is not None:
  149.                 if isinstance(e, list):
  150.                     for e1 in e:
  151.                         element.append(e1)
  152.                     
  153.                 else:
  154.                     element.append(e)
  155.             isinstance(e, list)
  156.         
  157.  
  158.     
  159.     def appendReferencedObjects(self, parent):
  160.         for d in self.delegates:
  161.             d.appendReferencedObjects(parent)
  162.         
  163.  
  164.     
  165.     def getMethods(self):
  166.         return self.delegatedMethods
  167.  
  168.     
  169.     def getSettings(self):
  170.         return []
  171.  
  172.     
  173.     def toLrfDelegates(self, lrfWriter):
  174.         for d in self.delegates:
  175.             d.toLrf(lrfWriter)
  176.         
  177.  
  178.     
  179.     def toLrf(self, lrfWriter):
  180.         self.toLrfDelegates(lrfWriter)
  181.  
  182.  
  183.  
  184. class LrsAttributes(object):
  185.     
  186.     def __init__(self, defaults, alsoAllow = None, **settings):
  187.         if alsoAllow is None:
  188.             alsoAllow = []
  189.         
  190.         self.attrs = defaults.copy()
  191.         for name, value in settings.items():
  192.             if name not in self.attrs and name not in alsoAllow:
  193.                 raise LrsError, '%s does not support setting %s' % (self.__class__.__name__, name)
  194.             name not in alsoAllow
  195.             if type(value) is int:
  196.                 value = str(value)
  197.             
  198.             self.attrs[name] = value
  199.         
  200.  
  201.  
  202.  
  203. class LrsContainer(object):
  204.     
  205.     def __init__(self, validChildren):
  206.         self.parent = None
  207.         self.contents = []
  208.         self.validChildren = validChildren
  209.         self.must_append = False
  210.  
  211.     
  212.     def has_text(self):
  213.         if hasattr(self, 'text'):
  214.             if self.text.strip():
  215.                 return True
  216.         
  217.         if hasattr(self, 'contents'):
  218.             for child in self.contents:
  219.                 if child.has_text():
  220.                     return True
  221.             
  222.         
  223.         for item in self.contents:
  224.             if isinstance(item, (Plot, ImageBlock, Canvas, CR)):
  225.                 return True
  226.         
  227.         return False
  228.  
  229.     
  230.     def append_to(self, parent):
  231.         if self.contents or self.must_append:
  232.             parent.append(self)
  233.         
  234.  
  235.     
  236.     def appendReferencedObjects(self, parent):
  237.         for c in self.contents:
  238.             c.appendReferencedObjects(parent)
  239.         
  240.  
  241.     
  242.     def setParent(self, parent):
  243.         if self.parent is not None:
  244.             raise LrsError, 'object already has parent'
  245.         self.parent is not None
  246.         self.parent = parent
  247.  
  248.     
  249.     def append(self, content, convertText = True):
  250.         for validChild in self.validChildren:
  251.             if isinstance(content, validChild):
  252.                 break
  253.                 continue
  254.         else:
  255.             raise LrsError, "can't append %s to %s" % (content.__class__.__name__, self.__class__.__name__)
  256.         if None and isinstance(content, basestring):
  257.             content = Text(content)
  258.         
  259.         content.setParent(self)
  260.         if isinstance(content, LrsObject):
  261.             content.assignId()
  262.         
  263.         self.contents.append(content)
  264.         return self
  265.  
  266.     
  267.     def get_all(self, predicate = (lambda x: x)):
  268.         for child in self.contents:
  269.             if predicate(child):
  270.                 yield child
  271.             
  272.             if hasattr(child, 'get_all'):
  273.                 for grandchild in child.get_all(predicate):
  274.                     yield grandchild
  275.                 
  276.         
  277.  
  278.  
  279.  
  280. class LrsObject(object):
  281.     nextObjId = 0
  282.     
  283.     def getNextObjId(selfClass):
  284.         selfClass.nextObjId += 1
  285.         return selfClass.nextObjId
  286.  
  287.     getNextObjId = classmethod(getNextObjId)
  288.     
  289.     def __init__(self, assignId = False):
  290.         if assignId:
  291.             self.objId = LrsObject.getNextObjId()
  292.         else:
  293.             self.objId = 0
  294.  
  295.     
  296.     def assignId(self):
  297.         if self.objId != 0:
  298.             raise LrsError, 'id already assigned to ' + self.__class__.__name__
  299.         self.objId != 0
  300.         self.objId = LrsObject.getNextObjId()
  301.  
  302.     
  303.     def lrsObjectElement(self, name, objlabel = 'objlabel', labelName = None, labelDecorate = True, **settings):
  304.         element = Element(name)
  305.         element.attrib['objid'] = str(self.objId)
  306.         if labelName is None:
  307.             labelName = name
  308.         
  309.         if labelDecorate:
  310.             label = '%s.%d' % (labelName, self.objId)
  311.         else:
  312.             label = str(self.objId)
  313.         element.attrib[objlabel] = label
  314.         element.attrib.update(settings)
  315.         return element
  316.  
  317.  
  318.  
  319. class Book(Delegator):
  320.     
  321.     def __init__(self, textstyledefault = None, blockstyledefault = None, pagestyledefault = None, optimizeTags = False, optimizeCompression = False, **settings):
  322.         self.parent = None
  323.         if 'thumbnail' in settings:
  324.             _checkExists(settings['thumbnail'])
  325.         
  326.         self.optimizeTags = optimizeTags
  327.         self.optimizeCompression = optimizeCompression
  328.         pageStyle = PageStyle(**PageStyle.baseDefaults.copy())
  329.         blockStyle = BlockStyle(**BlockStyle.baseDefaults.copy())
  330.         textStyle = TextStyle(**TextStyle.baseDefaults.copy())
  331.         if textstyledefault is not None:
  332.             textStyle.update(textstyledefault)
  333.         
  334.         if blockstyledefault is not None:
  335.             blockStyle.update(blockstyledefault)
  336.         
  337.         if pagestyledefault is not None:
  338.             pageStyle.update(pagestyledefault)
  339.         
  340.         self.defaultPageStyle = pageStyle
  341.         self.defaultTextStyle = textStyle
  342.         self.defaultBlockStyle = blockStyle
  343.         LrsObject.nextObjId += 1
  344.         styledefault = StyleDefault()
  345.         if settings.has_key('setdefault'):
  346.             styledefault = settings.pop('setdefault')
  347.         
  348.         Delegator.__init__(self, [
  349.             BookInformation(),
  350.             Main(),
  351.             Template(),
  352.             Style(styledefault),
  353.             Solos(),
  354.             Objects()])
  355.         self.sourceencoding = None
  356.         self.applySetting('genreading', DEFAULT_GENREADING)
  357.         self.applySetting('sourceencoding', DEFAULT_SOURCE_ENCODING)
  358.         self.applySettings(settings, testValid = True)
  359.         self.allow_new_page = True
  360.         self.gc_count = 0
  361.  
  362.     
  363.     def set_title(self, title):
  364.         ot = self.delegates[0].delegates[0].delegates[0].title
  365.         self.delegates[0].delegates[0].delegates[0].title = (title, ot[1])
  366.  
  367.     
  368.     def set_author(self, author):
  369.         ot = self.delegates[0].delegates[0].delegates[0].author
  370.         self.delegates[0].delegates[0].delegates[0].author = (author, ot[1])
  371.  
  372.     
  373.     def create_text_style(self, **settings):
  374.         ans = TextStyle(**self.defaultTextStyle.attrs.copy())
  375.         ans.update(settings)
  376.         return ans
  377.  
  378.     
  379.     def create_block_style(self, **settings):
  380.         ans = BlockStyle(**self.defaultBlockStyle.attrs.copy())
  381.         ans.update(settings)
  382.         return ans
  383.  
  384.     
  385.     def create_page_style(self, **settings):
  386.         if not self.allow_new_page:
  387.             raise ContentError
  388.         self.allow_new_page
  389.         ans = PageStyle(**self.defaultPageStyle.attrs.copy())
  390.         ans.update(settings)
  391.         return ans
  392.  
  393.     
  394.     def create_page(self, pageStyle = None, **settings):
  395.         if not pageStyle:
  396.             pageStyle = self.defaultPageStyle
  397.         
  398.         return Page(pageStyle = pageStyle, **settings)
  399.  
  400.     
  401.     def create_text_block(self, textStyle = None, blockStyle = None, **settings):
  402.         if not textStyle:
  403.             textStyle = self.defaultTextStyle
  404.         
  405.         if not blockStyle:
  406.             blockStyle = self.defaultBlockStyle
  407.         
  408.         return TextBlock(textStyle = textStyle, blockStyle = blockStyle, **settings)
  409.  
  410.     
  411.     def pages(self):
  412.         ans = []
  413.         for item in self.delegates:
  414.             if isinstance(item, Main):
  415.                 for candidate in item.contents:
  416.                     if isinstance(candidate, Page):
  417.                         ans.append(candidate)
  418.                         continue
  419.                 
  420.                 break
  421.                 continue
  422.         
  423.         return ans
  424.  
  425.     
  426.     def last_page(self):
  427.         for item in self.delegates:
  428.             if isinstance(item, Main):
  429.                 temp = list(item.contents)
  430.                 temp.reverse()
  431.                 for candidate in temp:
  432.                     if isinstance(candidate, Page):
  433.                         return candidate
  434.                 
  435.             isinstance(candidate, Page)
  436.         
  437.  
  438.     
  439.     def embed_font(self, file, facename):
  440.         f = Font(file, facename)
  441.         self.append(f)
  442.  
  443.     
  444.     def getSettings(self):
  445.         return [
  446.             'sourceencoding']
  447.  
  448.     
  449.     def append(self, content):
  450.         className = content.__class__.__name__
  451.         
  452.         try:
  453.             method = getattr(self, 'append' + className)
  454.         except AttributeError:
  455.             raise LrsError, "can't append %s to Book" % className
  456.  
  457.         method(content)
  458.  
  459.     
  460.     def rationalize_font_sizes(self, base_font_size = 10):
  461.         base_font_size *= 10
  462.         main = None
  463.         for obj in self.delegates:
  464.             if isinstance(obj, Main):
  465.                 main = obj
  466.                 break
  467.                 continue
  468.         
  469.         fonts = { }
  470.         for text in main.get_all((lambda x: isinstance(x, Text))):
  471.             fs = base_font_size
  472.             ancestor = text.parent
  473.             while ancestor:
  474.                 
  475.                 try:
  476.                     fs = int(ancestor.attrs['fontsize'])
  477.                 except (AttributeError, KeyError):
  478.                     pass
  479.  
  480.                 
  481.                 try:
  482.                     fs = int(ancestor.textSettings['fontsize'])
  483.                 except (AttributeError, KeyError):
  484.                     pass
  485.  
  486.                 
  487.                 try:
  488.                     fs = int(ancestor.textStyle.attrs['fontsize'])
  489.                 except (AttributeError, KeyError):
  490.                     pass
  491.  
  492.                 ancestor = ancestor.parent
  493.             length = len(text.text)
  494.             fonts[fs] = fonts.get(fs, 0) + length
  495.         
  496.         if not fonts:
  497.             print 'WARNING: LRF seems to have no textual content. Cannot rationalize font sizes.'
  498.             return None
  499.         old_base_font_size = float(max(fonts.items(), key = operator.itemgetter(1))[0])
  500.         factor = base_font_size / old_base_font_size
  501.         
  502.         def rescale(old):
  503.             return str(int(int(old) * factor))
  504.  
  505.         text_blocks = list(main.get_all((lambda x: isinstance(x, TextBlock))))
  506.         for tb in text_blocks:
  507.             if tb.textSettings.has_key('fontsize'):
  508.                 tb.textSettings['fontsize'] = rescale(tb.textSettings['fontsize'])
  509.             
  510.             for span in tb.get_all((lambda x: isinstance(x, Span))):
  511.                 if span.attrs.has_key('fontsize'):
  512.                     span.attrs['fontsize'] = rescale(span.attrs['fontsize'])
  513.                 
  514.                 if span.attrs.has_key('baselineskip'):
  515.                     span.attrs['baselineskip'] = rescale(span.attrs['baselineskip'])
  516.                     continue
  517.             
  518.         
  519.         text_styles = set((lambda .0: for tb in .0:
  520. tb.textStyle)(text_blocks))
  521.         for ts in text_styles:
  522.             ts.attrs['fontsize'] = rescale(ts.attrs['fontsize'])
  523.             ts.attrs['baselineskip'] = rescale(ts.attrs['baselineskip'])
  524.         
  525.  
  526.     
  527.     def renderLrs(self, lrsFile, encoding = 'UTF-8'):
  528.         if isinstance(lrsFile, basestring):
  529.             lrsFile = codecs.open(lrsFile, 'wb', encoding = encoding)
  530.         
  531.         self.render(lrsFile, outputEncodingName = encoding)
  532.         lrsFile.close()
  533.  
  534.     
  535.     def renderLrf(self, lrfFile):
  536.         self.appendReferencedObjects(self)
  537.         if isinstance(lrfFile, basestring):
  538.             lrfFile = file(lrfFile, 'wb')
  539.         
  540.         lrfWriter = LrfWriter(self.sourceencoding)
  541.         lrfWriter.optimizeTags = self.optimizeTags
  542.         lrfWriter.optimizeCompression = self.optimizeCompression
  543.         self.toLrf(lrfWriter)
  544.         lrfWriter.writeFile(lrfFile)
  545.         lrfFile.close()
  546.  
  547.     
  548.     def toElement(self, se):
  549.         root = Element('BBeBXylog', version = '1.0')
  550.         root.append(Element('Property'))
  551.         self.appendDelegates(root, self.sourceencoding)
  552.         return root
  553.  
  554.     
  555.     def render(self, f, outputEncodingName = 'UTF-8'):
  556.         self.appendReferencedObjects(self)
  557.         root = self.toElement(self.sourceencoding)
  558.         _formatXml(root)
  559.         writer = ElementWriter(root, header = True, sourceEncoding = self.sourceencoding, spaceBeforeClose = False, outputEncodingName = outputEncodingName)
  560.         writer.write(f)
  561.  
  562.  
  563.  
  564. class BookInformation(Delegator):
  565.     
  566.     def __init__(self):
  567.         Delegator.__init__(self, [
  568.             Info(),
  569.             TableOfContents()])
  570.  
  571.     
  572.     def toElement(self, se):
  573.         bi = Element('BookInformation')
  574.         self.appendDelegates(bi, se)
  575.         return bi
  576.  
  577.  
  578.  
  579. class Info(Delegator):
  580.     
  581.     def __init__(self):
  582.         self.genreading = DEFAULT_GENREADING
  583.         Delegator.__init__(self, [
  584.             BookInfo(),
  585.             DocInfo()])
  586.  
  587.     
  588.     def getSettings(self):
  589.         return [
  590.             'genreading']
  591.  
  592.     
  593.     def toElement(self, se):
  594.         info = Element('Info', version = '1.1')
  595.         info.append(self.delegates[0].toElement(se, reading = 's' in self.genreading))
  596.         info.append(self.delegates[1].toElement(se))
  597.         return info
  598.  
  599.     
  600.     def toLrf(self, lrfWriter):
  601.         info = Element('Info', version = '1.1')
  602.         info.append(self.delegates[0].toElement(lrfWriter.getSourceEncoding(), reading = 'f' in self.genreading))
  603.         info.append(self.delegates[1].toElement(lrfWriter.getSourceEncoding()))
  604.         tnail = info.find('DocInfo/CThumbnail')
  605.         if tnail is not None:
  606.             lrfWriter.setThumbnailFile(tnail.get('file'))
  607.         
  608.         _formatXml(info)
  609.         xmlInfo = ElementWriter(info, header = True, sourceEncoding = lrfWriter.getSourceEncoding(), spaceBeforeClose = False).toString()
  610.         xmlInfo = re.sub('<CThumbnail.*?>\\n', '', xmlInfo)
  611.         xmlInfo = xmlInfo.replace('SumPage>', 'Page>')
  612.         lrfWriter.docInfoXml = xmlInfo
  613.  
  614.  
  615.  
  616. class TableOfContents(object):
  617.     
  618.     def __init__(self):
  619.         self.tocEntries = []
  620.  
  621.     
  622.     def appendReferencedObjects(self, parent):
  623.         pass
  624.  
  625.     
  626.     def getMethods(self):
  627.         return [
  628.             'addTocEntry']
  629.  
  630.     
  631.     def getSettings(self):
  632.         return []
  633.  
  634.     
  635.     def addTocEntry(self, tocLabel, textBlock):
  636.         if not isinstance(textBlock, (Canvas, TextBlock, ImageBlock, RuledLine)):
  637.             raise LrsError, 'TOC destination must be a Canvas, TextBlock, ImageBlock or RuledLine' + ' not a ' + str(type(textBlock))
  638.         isinstance(textBlock, (Canvas, TextBlock, ImageBlock, RuledLine))
  639.         if textBlock.parent is None:
  640.             raise LrsError, 'TOC text block must be already appended to a page'
  641.         textBlock.parent is None
  642.         if False and textBlock.parent.parent is None:
  643.             raise LrsError, 'TOC destination page must be already appended to a book'
  644.         textBlock.parent.parent is None
  645.         if not hasattr(textBlock.parent, 'objId'):
  646.             raise LrsError, 'TOC destination must be appended to a container with an objID'
  647.         hasattr(textBlock.parent, 'objId')
  648.         for tl in self.tocEntries:
  649.             if tl.label == tocLabel and tl.textBlock == textBlock:
  650.                 return None
  651.         
  652.         self.tocEntries.append(TocLabel(tocLabel, textBlock))
  653.         textBlock.tocLabel = tocLabel
  654.  
  655.     
  656.     def toElement(self, se):
  657.         if len(self.tocEntries) == 0:
  658.             return None
  659.         toc = Element('TOC')
  660.         for t in self.tocEntries:
  661.             toc.append(t.toElement(se))
  662.         
  663.         return toc
  664.  
  665.     
  666.     def toLrf(self, lrfWriter):
  667.         if len(self.tocEntries) == 0:
  668.             return None
  669.         toc = []
  670.         for t in self.tocEntries:
  671.             toc.append((t.textBlock.parent.objId, t.textBlock.objId, t.label))
  672.         
  673.         lrfToc = LrfToc(LrsObject.getNextObjId(), toc, lrfWriter.getSourceEncoding())
  674.         lrfWriter.append(lrfToc)
  675.         lrfWriter.setTocObject(lrfToc)
  676.  
  677.  
  678.  
  679. class TocLabel(object):
  680.     
  681.     def __init__(self, label, textBlock):
  682.         self.label = escape(re.sub('&(\\S+?);', entity_to_unicode, label))
  683.         self.textBlock = textBlock
  684.  
  685.     
  686.     def toElement(self, se):
  687.         return ElementWithText('TocLabel', self.label, refobj = str(self.textBlock.objId), refpage = str(self.textBlock.parent.objId))
  688.  
  689.  
  690.  
  691. class BookInfo(object):
  692.     
  693.     def __init__(self):
  694.         self.title = 'Untitled'
  695.         self.author = 'Anonymous'
  696.         self.bookid = None
  697.         self.pi = None
  698.         self.isbn = None
  699.         self.publisher = None
  700.         self.freetext = '\n\n'
  701.         self.label = None
  702.         self.category = None
  703.         self.classification = None
  704.  
  705.     
  706.     def appendReferencedObjects(self, parent):
  707.         pass
  708.  
  709.     
  710.     def getMethods(self):
  711.         return []
  712.  
  713.     
  714.     def getSettings(self):
  715.         return [
  716.             'author',
  717.             'title',
  718.             'bookid',
  719.             'isbn',
  720.             'publisher',
  721.             'freetext',
  722.             'label',
  723.             'category',
  724.             'classification']
  725.  
  726.     
  727.     def _appendISBN(self, bi):
  728.         pi = Element('ProductIdentifier')
  729.         isbnElement = ElementWithText('ISBNPrintable', self.isbn)
  730.         isbnValueElement = ElementWithText('ISBNValue', self.isbn.replace('-', ''))
  731.         pi.append(isbnElement)
  732.         pi.append(isbnValueElement)
  733.         bi.append(pi)
  734.  
  735.     
  736.     def toElement(self, se, reading = True):
  737.         bi = Element('BookInfo')
  738.         bi.append(ElementWithReading('Title', self.title, reading = reading))
  739.         bi.append(ElementWithReading('Author', self.author, reading = reading))
  740.         bi.append(ElementWithText('BookID', self.bookid))
  741.         if self.isbn is not None:
  742.             self._appendISBN(bi)
  743.         
  744.         if self.publisher is not None:
  745.             bi.append(ElementWithReading('Publisher', self.publisher))
  746.         
  747.         bi.append(ElementWithReading('Label', self.label, reading = reading))
  748.         bi.append(ElementWithText('Category', self.category))
  749.         bi.append(ElementWithText('Classification', self.classification))
  750.         bi.append(ElementWithText('FreeText', self.freetext))
  751.         return bi
  752.  
  753.  
  754.  
  755. class DocInfo(object):
  756.     
  757.     def __init__(self):
  758.         self.thumbnail = None
  759.         self.language = 'en'
  760.         self.creator = None
  761.         self.creationdate = str(isoformat(date.today()))
  762.         self.producer = '%s v%s' % (__appname__, __version__)
  763.         self.numberofpages = '0'
  764.  
  765.     
  766.     def appendReferencedObjects(self, parent):
  767.         pass
  768.  
  769.     
  770.     def getMethods(self):
  771.         return []
  772.  
  773.     
  774.     def getSettings(self):
  775.         return [
  776.             'thumbnail',
  777.             'language',
  778.             'creator',
  779.             'creationdate',
  780.             'producer',
  781.             'numberofpages']
  782.  
  783.     
  784.     def toElement(self, se):
  785.         docInfo = Element('DocInfo')
  786.         if self.thumbnail is not None:
  787.             docInfo.append(Element('CThumbnail', file = self.thumbnail))
  788.         
  789.         docInfo.append(ElementWithText('Language', self.language))
  790.         docInfo.append(ElementWithText('Creator', self.creator))
  791.         docInfo.append(ElementWithText('CreationDate', self.creationdate))
  792.         docInfo.append(ElementWithText('Producer', self.producer))
  793.         docInfo.append(ElementWithText('SumPage', str(self.numberofpages)))
  794.         return docInfo
  795.  
  796.  
  797.  
  798. class Main(LrsContainer):
  799.     
  800.     def __init__(self):
  801.         LrsContainer.__init__(self, [
  802.             Page])
  803.  
  804.     
  805.     def getMethods(self):
  806.         return [
  807.             'appendPage',
  808.             'Page']
  809.  
  810.     
  811.     def getSettings(self):
  812.         return []
  813.  
  814.     
  815.     def Page(self, *args, **kwargs):
  816.         p = Page(*args, **kwargs)
  817.         self.append(p)
  818.         return p
  819.  
  820.     
  821.     def appendPage(self, page):
  822.         self.append(page)
  823.  
  824.     
  825.     def toElement(self, sourceEncoding):
  826.         main = Element(self.__class__.__name__)
  827.         for page in self.contents:
  828.             main.append(page.toElement(sourceEncoding))
  829.         
  830.         return main
  831.  
  832.     
  833.     def toLrf(self, lrfWriter):
  834.         pageIds = []
  835.         pageTreeId = LrsObject.getNextObjId()
  836.         lrfWriter.setPageTreeId(pageTreeId)
  837.         for p in self.contents:
  838.             pageIds.append(p.objId)
  839.             p.toLrf(lrfWriter)
  840.         
  841.         pageTree = LrfObject('PageTree', pageTreeId)
  842.         pageTree.appendLrfTag(LrfTag('PageList', pageIds))
  843.         lrfWriter.append(pageTree)
  844.  
  845.  
  846.  
  847. class Solos(LrsContainer):
  848.     
  849.     def __init__(self):
  850.         LrsContainer.__init__(self, [
  851.             Solo])
  852.  
  853.     
  854.     def getMethods(self):
  855.         return [
  856.             'appendSolo',
  857.             'Solo']
  858.  
  859.     
  860.     def getSettings(self):
  861.         return []
  862.  
  863.     
  864.     def Solo(self, *args, **kwargs):
  865.         p = Solo(*args, **kwargs)
  866.         self.append(p)
  867.         return p
  868.  
  869.     
  870.     def appendSolo(self, solo):
  871.         self.append(solo)
  872.  
  873.     
  874.     def toLrf(self, lrfWriter):
  875.         for s in self.contents:
  876.             s.toLrf(lrfWriter)
  877.         
  878.  
  879.     
  880.     def toElement(self, se):
  881.         solos = []
  882.         for s in self.contents:
  883.             solos.append(s.toElement(se))
  884.         
  885.         if len(solos) == 0:
  886.             return None
  887.         return solos
  888.  
  889.  
  890.  
  891. class Solo(Main):
  892.     pass
  893.  
  894.  
  895. class Template(object):
  896.     
  897.     def appendReferencedObjects(self, parent):
  898.         pass
  899.  
  900.     
  901.     def getMethods(self):
  902.         return []
  903.  
  904.     
  905.     def getSettings(self):
  906.         return []
  907.  
  908.     
  909.     def toElement(self, se):
  910.         t = Element('Template')
  911.         t.attrib['version'] = '1.0'
  912.         return t
  913.  
  914.     
  915.     def toLrf(self, lrfWriter):
  916.         pass
  917.  
  918.  
  919.  
  920. class StyleDefault(LrsAttributes):
  921.     defaults = dict(rubyalign = 'start', rubyadjust = 'none', rubyoverhang = 'none', empdotsposition = 'before', empdotsfontname = 'Dutch801 Rm BT Roman', empdotscode = '0x002e', emplineposition = 'after', emplinetype = 'solid', setwaitprop = 'noreplay')
  922.     alsoAllow = [
  923.         'refempdotsfont',
  924.         'rubyAlignAndAdjust']
  925.     
  926.     def __init__(self, **settings):
  927.         LrsAttributes.__init__(self, self.defaults, alsoAllow = self.alsoAllow, **settings)
  928.  
  929.     
  930.     def toElement(self, se):
  931.         return Element('SetDefault', self.attrs)
  932.  
  933.  
  934.  
  935. class Style(LrsContainer, Delegator):
  936.     
  937.     def __init__(self, styledefault = StyleDefault()):
  938.         LrsContainer.__init__(self, [
  939.             PageStyle,
  940.             TextStyle,
  941.             BlockStyle])
  942.         Delegator.__init__(self, [
  943.             BookStyle(styledefault = styledefault)])
  944.         self.bookStyle = self.delegates[0]
  945.         self.appendPageStyle = self.appendTextStyle = self.appendBlockStyle = self.append
  946.  
  947.     
  948.     def appendReferencedObjects(self, parent):
  949.         LrsContainer.appendReferencedObjects(self, parent)
  950.  
  951.     
  952.     def getMethods(self):
  953.         return [
  954.             'PageStyle',
  955.             'TextStyle',
  956.             'BlockStyle',
  957.             'appendPageStyle',
  958.             'appendTextStyle',
  959.             'appendBlockStyle'] + self.delegatedMethods
  960.  
  961.     
  962.     def getSettings(self):
  963.         return [ (self.bookStyle, x) for x in self.bookStyle.getSettings() ]
  964.  
  965.     
  966.     def PageStyle(self, *args, **kwargs):
  967.         ps = PageStyle(*args, **kwargs)
  968.         self.append(ps)
  969.         return ps
  970.  
  971.     
  972.     def TextStyle(self, *args, **kwargs):
  973.         ts = TextStyle(*args, **kwargs)
  974.         self.append(ts)
  975.         return ts
  976.  
  977.     
  978.     def BlockStyle(self, *args, **kwargs):
  979.         bs = BlockStyle(*args, **kwargs)
  980.         self.append(bs)
  981.         return bs
  982.  
  983.     
  984.     def toElement(self, se):
  985.         style = Element('Style')
  986.         style.append(self.bookStyle.toElement(se))
  987.         for content in self.contents:
  988.             style.append(content.toElement(se))
  989.         
  990.         return style
  991.  
  992.     
  993.     def toLrf(self, lrfWriter):
  994.         self.bookStyle.toLrf(lrfWriter)
  995.         for s in self.contents:
  996.             s.toLrf(lrfWriter)
  997.         
  998.  
  999.  
  1000.  
  1001. class BookStyle(LrsObject, LrsContainer):
  1002.     
  1003.     def __init__(self, styledefault = StyleDefault()):
  1004.         LrsObject.__init__(self, assignId = True)
  1005.         LrsContainer.__init__(self, [
  1006.             Font])
  1007.         self.styledefault = styledefault
  1008.         self.booksetting = BookSetting()
  1009.         self.appendFont = self.append
  1010.  
  1011.     
  1012.     def getSettings(self):
  1013.         return [
  1014.             'styledefault',
  1015.             'booksetting']
  1016.  
  1017.     
  1018.     def getMethods(self):
  1019.         return [
  1020.             'Font',
  1021.             'appendFont']
  1022.  
  1023.     
  1024.     def Font(self, *args, **kwargs):
  1025.         f = Font(*args, **kwargs)
  1026.         self.append(f)
  1027.  
  1028.     
  1029.     def toElement(self, se):
  1030.         bookStyle = self.lrsObjectElement('BookStyle', objlabel = 'stylelabel', labelDecorate = False)
  1031.         bookStyle.append(self.styledefault.toElement(se))
  1032.         bookStyle.append(self.booksetting.toElement(se))
  1033.         for font in self.contents:
  1034.             bookStyle.append(font.toElement(se))
  1035.         
  1036.         return bookStyle
  1037.  
  1038.     
  1039.     def toLrf(self, lrfWriter):
  1040.         bookAtr = LrfObject('BookAtr', self.objId)
  1041.         bookAtr.appendLrfTag(LrfTag('ChildPageTree', lrfWriter.getPageTreeId()))
  1042.         bookAtr.appendTagDict(self.styledefault.attrs)
  1043.         self.booksetting.toLrf(lrfWriter)
  1044.         lrfWriter.append(bookAtr)
  1045.         lrfWriter.setRootObject(bookAtr)
  1046.         for font in self.contents:
  1047.             font.toLrf(lrfWriter)
  1048.         
  1049.  
  1050.  
  1051.  
  1052. class BookSetting(LrsAttributes):
  1053.     
  1054.     def __init__(self, **settings):
  1055.         defaults = dict(bindingdirection = 'Lr', dpi = '1660', screenheight = '800', screenwidth = '600', colordepth = '24')
  1056.         LrsAttributes.__init__(self, defaults, **settings)
  1057.  
  1058.     
  1059.     def toLrf(self, lrfWriter):
  1060.         a = self.attrs
  1061.         lrfWriter.dpi = int(a['dpi'])
  1062.         lrfWriter.bindingdirection = BINDING_DIRECTION_ENCODING[a['bindingdirection']]
  1063.         lrfWriter.height = int(a['screenheight'])
  1064.         lrfWriter.width = int(a['screenwidth'])
  1065.         lrfWriter.colorDepth = int(a['colordepth'])
  1066.  
  1067.     
  1068.     def toElement(self, se):
  1069.         return Element('BookSetting', self.attrs)
  1070.  
  1071.  
  1072.  
  1073. class LrsStyle(LrsObject, LrsAttributes, LrsContainer):
  1074.     
  1075.     def __init__(self, elementName, defaults = None, alsoAllow = None, **overrides):
  1076.         if defaults is None:
  1077.             defaults = { }
  1078.         
  1079.         LrsObject.__init__(self)
  1080.         LrsAttributes.__init__(self, defaults, alsoAllow = alsoAllow, **overrides)
  1081.         LrsContainer.__init__(self, [])
  1082.         self.elementName = elementName
  1083.         self.objectsAppended = False
  1084.  
  1085.     
  1086.     def update(self, settings):
  1087.         for name, value in settings.items():
  1088.             if name not in self.__class__.validSettings:
  1089.                 raise LrsError, '%s not a valid setting for %s' % (name, self.__class__.__name__)
  1090.             name not in self.__class__.validSettings
  1091.             self.attrs[name] = value
  1092.         
  1093.  
  1094.     
  1095.     def getLabel(self):
  1096.         return str(self.objId)
  1097.  
  1098.     
  1099.     def toElement(self, se):
  1100.         element = Element(self.elementName, stylelabel = self.getLabel(), objid = str(self.objId))
  1101.         element.attrib.update(self.attrs)
  1102.         return element
  1103.  
  1104.     
  1105.     def toLrf(self, lrfWriter):
  1106.         obj = LrfObject(self.elementName, self.objId)
  1107.         obj.appendTagDict(self.attrs, self.__class__.__name__)
  1108.         lrfWriter.append(obj)
  1109.  
  1110.     
  1111.     def __eq__(self, other):
  1112.         if hasattr(other, 'attrs'):
  1113.             if self.__class__ == other.__class__:
  1114.                 pass
  1115.             return self.attrs == other.attrs
  1116.         return False
  1117.  
  1118.  
  1119.  
  1120. class TextStyle(LrsStyle):
  1121.     baseDefaults = dict(columnsep = '0', charspace = '0', textlinewidth = '2', align = 'head', linecolor = '0x00000000', column = '1', fontsize = '100', fontwidth = '-10', fontescapement = '0', fontorientation = '0', fontweight = '400', fontfacename = 'Dutch801 Rm BT Roman', textcolor = '0x00000000', wordspace = '25', letterspace = '0', baselineskip = '120', linespace = '10', parindent = '0', parskip = '0', textbgcolor = '0xFF000000')
  1122.     alsoAllow = [
  1123.         'empdotscode',
  1124.         'empdotsfontname',
  1125.         'refempdotsfont',
  1126.         'rubyadjust',
  1127.         'rubyalign',
  1128.         'rubyoverhang',
  1129.         'empdotsposition',
  1130.         'emplinetype',
  1131.         'emplineposition']
  1132.     validSettings = baseDefaults.keys() + alsoAllow
  1133.     defaults = baseDefaults.copy()
  1134.     
  1135.     def __init__(self, **overrides):
  1136.         LrsStyle.__init__(self, 'TextStyle', self.defaults, alsoAllow = self.alsoAllow, **overrides)
  1137.  
  1138.     
  1139.     def copy(self):
  1140.         tb = TextStyle()
  1141.         tb.attrs = self.attrs.copy()
  1142.         return tb
  1143.  
  1144.  
  1145.  
  1146. class BlockStyle(LrsStyle):
  1147.     baseDefaults = dict(bgimagemode = 'fix', framemode = 'square', blockwidth = '560', blockheight = '100', blockrule = 'horz-adjustable', layout = 'LrTb', framewidth = '0', framecolor = '0x00000000', topskip = '0', sidemargin = '0', footskip = '0', bgcolor = '0xFF000000')
  1148.     validSettings = baseDefaults.keys()
  1149.     defaults = baseDefaults.copy()
  1150.     
  1151.     def __init__(self, **overrides):
  1152.         LrsStyle.__init__(self, 'BlockStyle', self.defaults, **overrides)
  1153.  
  1154.     
  1155.     def copy(self):
  1156.         tb = BlockStyle()
  1157.         tb.attrs = self.attrs.copy()
  1158.         return tb
  1159.  
  1160.  
  1161.  
  1162. class PageStyle(LrsStyle):
  1163.     baseDefaults = dict(topmargin = '20', headheight = '0', headsep = '0', oddsidemargin = '20', textheight = '747', textwidth = '575', footspace = '0', evensidemargin = '20', footheight = '0', layout = 'LrTb', bgimagemode = 'fix', pageposition = 'any', setwaitprop = 'noreplay', setemptyview = 'show')
  1164.     alsoAllow = [
  1165.         'header',
  1166.         'evenheader',
  1167.         'oddheader',
  1168.         'footer',
  1169.         'evenfooter',
  1170.         'oddfooter']
  1171.     validSettings = baseDefaults.keys() + alsoAllow
  1172.     defaults = baseDefaults.copy()
  1173.     
  1174.     def translateHeaderAndFooter(selfClass, parent, settings):
  1175.         selfClass._fixup(parent, 'header', settings)
  1176.         selfClass._fixup(parent, 'footer', settings)
  1177.  
  1178.     translateHeaderAndFooter = classmethod(translateHeaderAndFooter)
  1179.     
  1180.     def _fixup(selfClass, parent, basename, settings):
  1181.         evenbase = 'even' + basename
  1182.         oddbase = 'odd' + basename
  1183.         if basename in settings:
  1184.             baseObj = settings[basename]
  1185.             del settings[basename]
  1186.             settings[evenbase] = settings[oddbase] = baseObj
  1187.         
  1188.         if evenbase in settings:
  1189.             evenObj = settings[evenbase]
  1190.             del settings[evenbase]
  1191.             if evenObj.parent is None:
  1192.                 parent.append(evenObj)
  1193.             
  1194.             settings[evenbase + 'id'] = str(evenObj.objId)
  1195.         
  1196.         if oddbase in settings:
  1197.             oddObj = settings[oddbase]
  1198.             del settings[oddbase]
  1199.             if oddObj.parent is None:
  1200.                 parent.append(oddObj)
  1201.             
  1202.             settings[oddbase + 'id'] = str(oddObj.objId)
  1203.         
  1204.  
  1205.     _fixup = classmethod(_fixup)
  1206.     
  1207.     def appendReferencedObjects(self, parent):
  1208.         if self.objectsAppended:
  1209.             return None
  1210.         PageStyle.translateHeaderAndFooter(parent, self.attrs)
  1211.         self.objectsAppended = True
  1212.  
  1213.     
  1214.     def __init__(self, **settings):
  1215.         LrsStyle.__init__(self, 'PageStyle', self.defaults, alsoAllow = self.alsoAllow, **settings)
  1216.  
  1217.  
  1218.  
  1219. class Page(LrsObject, LrsContainer):
  1220.     defaultPageStyle = PageStyle()
  1221.     
  1222.     def __init__(self, pageStyle = defaultPageStyle, **settings):
  1223.         LrsObject.__init__(self)
  1224.         LrsContainer.__init__(self, [
  1225.             TextBlock,
  1226.             BlockSpace,
  1227.             RuledLine,
  1228.             ImageBlock,
  1229.             Canvas])
  1230.         self.pageStyle = pageStyle
  1231.         for settingName in settings.keys():
  1232.             if settingName not in PageStyle.defaults and settingName not in PageStyle.alsoAllow:
  1233.                 raise LrsError, 'setting %s not allowed on Page' % settingName
  1234.             settingName not in PageStyle.alsoAllow
  1235.         
  1236.         self.settings = settings.copy()
  1237.  
  1238.     
  1239.     def appendReferencedObjects(self, parent):
  1240.         PageStyle.translateHeaderAndFooter(parent, self.settings)
  1241.         self.pageStyle.appendReferencedObjects(parent)
  1242.         if self.pageStyle.parent is None:
  1243.             parent.append(self.pageStyle)
  1244.         
  1245.         LrsContainer.appendReferencedObjects(self, parent)
  1246.  
  1247.     
  1248.     def RuledLine(self, *args, **kwargs):
  1249.         rl = RuledLine(*args, **kwargs)
  1250.         self.append(rl)
  1251.         return rl
  1252.  
  1253.     
  1254.     def BlockSpace(self, *args, **kwargs):
  1255.         bs = BlockSpace(*args, **kwargs)
  1256.         self.append(bs)
  1257.         return bs
  1258.  
  1259.     
  1260.     def TextBlock(self, *args, **kwargs):
  1261.         tb = TextBlock(*args, **kwargs)
  1262.         self.append(tb)
  1263.         return tb
  1264.  
  1265.     
  1266.     def ImageBlock(self, *args, **kwargs):
  1267.         ib = ImageBlock(*args, **kwargs)
  1268.         self.append(ib)
  1269.         return ib
  1270.  
  1271.     
  1272.     def addLrfObject(self, objId):
  1273.         self.stream.appendLrfTag(LrfTag('Link', objId))
  1274.  
  1275.     
  1276.     def appendLrfTag(self, lrfTag):
  1277.         self.stream.appendLrfTag(lrfTag)
  1278.  
  1279.     
  1280.     def toLrf(self, lrfWriter):
  1281.         p = LrfObject('Page', self.objId)
  1282.         lrfWriter.append(p)
  1283.         pageContent = set()
  1284.         self.stream = LrfTagStream(0)
  1285.         for content in self.contents:
  1286.             content.toLrfContainer(lrfWriter, self)
  1287.             if hasattr(content, 'getReferencedObjIds'):
  1288.                 pageContent.update(content.getReferencedObjIds())
  1289.                 continue
  1290.         
  1291.         p.appendLrfTag(LrfTag('Link', self.pageStyle.objId))
  1292.         p.appendLrfTag(LrfTag('ParentPageTree', lrfWriter.getPageTreeId()))
  1293.         p.appendTagDict(self.settings)
  1294.         p.appendLrfTags(self.stream.getStreamTags(lrfWriter.getSourceEncoding()))
  1295.  
  1296.     
  1297.     def toElement(self, sourceEncoding):
  1298.         page = self.lrsObjectElement('Page')
  1299.         page.set('pagestyle', self.pageStyle.getLabel())
  1300.         page.attrib.update(self.settings)
  1301.         for content in self.contents:
  1302.             page.append(content.toElement(sourceEncoding))
  1303.         
  1304.         return page
  1305.  
  1306.  
  1307.  
  1308. class TextBlock(LrsObject, LrsContainer):
  1309.     defaultTextStyle = TextStyle()
  1310.     defaultBlockStyle = BlockStyle()
  1311.     
  1312.     def __init__(self, textStyle = defaultTextStyle, blockStyle = defaultBlockStyle, **settings):
  1313.         LrsObject.__init__(self)
  1314.         LrsContainer.__init__(self, [
  1315.             Paragraph,
  1316.             CR])
  1317.         self.textSettings = { }
  1318.         self.blockSettings = { }
  1319.         for name, value in settings.items():
  1320.             if name in TextStyle.validSettings:
  1321.                 self.textSettings[name] = value
  1322.                 continue
  1323.             if name in BlockStyle.validSettings:
  1324.                 self.blockSettings[name] = value
  1325.                 continue
  1326.             if name == 'toclabel':
  1327.                 self.tocLabel = value
  1328.                 continue
  1329.             raise LrsError, '%s not a valid setting for TextBlock' % name
  1330.         
  1331.         self.textStyle = textStyle
  1332.         self.blockStyle = blockStyle
  1333.         self.currentTextStyle = None if self.textSettings else textStyle
  1334.         self.currentTextStyle.attrs.update(self.textSettings)
  1335.  
  1336.     
  1337.     def appendReferencedObjects(self, parent):
  1338.         if self.textStyle.parent is None:
  1339.             parent.append(self.textStyle)
  1340.         
  1341.         if self.blockStyle.parent is None:
  1342.             parent.append(self.blockStyle)
  1343.         
  1344.         LrsContainer.appendReferencedObjects(self, parent)
  1345.  
  1346.     
  1347.     def Paragraph(self, *args, **kwargs):
  1348.         p = Paragraph(*args, **kwargs)
  1349.         self.append(p)
  1350.         self.append(CR())
  1351.         return p
  1352.  
  1353.     
  1354.     def toElement(self, sourceEncoding):
  1355.         tb = self.lrsObjectElement('TextBlock', labelName = 'Block')
  1356.         tb.attrib.update(self.textSettings)
  1357.         tb.attrib.update(self.blockSettings)
  1358.         tb.set('textstyle', self.textStyle.getLabel())
  1359.         tb.set('blockstyle', self.blockStyle.getLabel())
  1360.         if hasattr(self, 'tocLabel'):
  1361.             tb.set('toclabel', self.tocLabel)
  1362.         
  1363.         for content in self.contents:
  1364.             tb.append(content.toElement(sourceEncoding))
  1365.         
  1366.         return tb
  1367.  
  1368.     
  1369.     def getReferencedObjIds(self):
  1370.         ids = [
  1371.             self.objId,
  1372.             self.extraId,
  1373.             self.blockStyle.objId,
  1374.             self.textStyle.objId]
  1375.         for content in self.contents:
  1376.             if hasattr(content, 'getReferencedObjIds'):
  1377.                 ids.extend(content.getReferencedObjIds())
  1378.                 continue
  1379.         
  1380.         return ids
  1381.  
  1382.     
  1383.     def toLrf(self, lrfWriter):
  1384.         self.toLrfContainer(lrfWriter, lrfWriter)
  1385.  
  1386.     
  1387.     def toLrfContainer(self, lrfWriter, container):
  1388.         extraId = LrsObject.getNextObjId()
  1389.         b = LrfObject('Block', self.objId)
  1390.         b.appendLrfTag(LrfTag('Link', self.blockStyle.objId))
  1391.         b.appendLrfTags(LrfTagStream(0, [
  1392.             LrfTag('Link', extraId)]).getStreamTags(lrfWriter.getSourceEncoding()))
  1393.         b.appendTagDict(self.blockSettings)
  1394.         container.addLrfObject(b.objId)
  1395.         lrfWriter.append(b)
  1396.         tb = LrfObject('TextBlock', extraId)
  1397.         tb.appendLrfTag(LrfTag('Link', self.textStyle.objId))
  1398.         tb.appendTagDict(self.textSettings)
  1399.         stream = LrfTagStream(STREAM_COMPRESSED)
  1400.         for content in self.contents:
  1401.             content.toLrfContainer(lrfWriter, stream)
  1402.         
  1403.         if lrfWriter.saveStreamTags:
  1404.             tb.saveStreamTags = stream.tags
  1405.         
  1406.         tb.appendLrfTags(stream.getStreamTags(lrfWriter.getSourceEncoding(), optimizeTags = lrfWriter.optimizeTags, optimizeCompression = lrfWriter.optimizeCompression))
  1407.         lrfWriter.append(tb)
  1408.         self.extraId = extraId
  1409.  
  1410.  
  1411.  
  1412. class Paragraph(LrsContainer):
  1413.     
  1414.     def __init__(self, text = None):
  1415.         LrsContainer.__init__(self, [
  1416.             Text,
  1417.             CR,
  1418.             DropCaps,
  1419.             CharButton,
  1420.             LrsSimpleChar1,
  1421.             basestring])
  1422.         if text is not None:
  1423.             if isinstance(text, basestring):
  1424.                 text = Text(text)
  1425.             
  1426.             self.append(text)
  1427.         
  1428.  
  1429.     
  1430.     def CR(self):
  1431.         cr = CR()
  1432.         self.append(cr)
  1433.         return cr
  1434.  
  1435.     
  1436.     def getReferencedObjIds(self):
  1437.         ids = []
  1438.         for content in self.contents:
  1439.             if hasattr(content, 'getReferencedObjIds'):
  1440.                 ids.extend(content.getReferencedObjIds())
  1441.                 continue
  1442.         
  1443.         return ids
  1444.  
  1445.     
  1446.     def toLrfContainer(self, lrfWriter, parent):
  1447.         parent.appendLrfTag(LrfTag('pstart', 0))
  1448.         for content in self.contents:
  1449.             content.toLrfContainer(lrfWriter, parent)
  1450.         
  1451.         parent.appendLrfTag(LrfTag('pend'))
  1452.  
  1453.     
  1454.     def toElement(self, sourceEncoding):
  1455.         p = Element('P')
  1456.         appendTextElements(p, self.contents, sourceEncoding)
  1457.         return p
  1458.  
  1459.  
  1460.  
  1461. class LrsTextTag(LrsContainer):
  1462.     
  1463.     def __init__(self, text, validContents):
  1464.         LrsContainer.__init__(self, [
  1465.             Text,
  1466.             basestring] + validContents)
  1467.         if text is not None:
  1468.             self.append(text)
  1469.         
  1470.  
  1471.     
  1472.     def toLrfContainer(self, lrfWriter, parent):
  1473.         if hasattr(self, 'tagName'):
  1474.             tagName = self.tagName
  1475.         else:
  1476.             tagName = self.__class__.__name__
  1477.         parent.appendLrfTag(LrfTag(tagName))
  1478.         for content in self.contents:
  1479.             content.toLrfContainer(lrfWriter, parent)
  1480.         
  1481.         parent.appendLrfTag(LrfTag(tagName + 'End'))
  1482.  
  1483.     
  1484.     def toElement(self, se):
  1485.         if hasattr(self, 'tagName'):
  1486.             tagName = self.tagName
  1487.         else:
  1488.             tagName = self.__class__.__name__
  1489.         p = Element(tagName)
  1490.         appendTextElements(p, self.contents, se)
  1491.         return p
  1492.  
  1493.  
  1494.  
  1495. class LrsSimpleChar1(object):
  1496.     
  1497.     def isEmpty(self):
  1498.         for content in self.contents:
  1499.             if not content.isEmpty():
  1500.                 return False
  1501.         
  1502.         return True
  1503.  
  1504.     
  1505.     def hasFollowingContent(self):
  1506.         foundSelf = False
  1507.         for content in self.parent.contents:
  1508.             if content == self:
  1509.                 foundSelf = True
  1510.                 continue
  1511.             if foundSelf:
  1512.                 if not content.isEmpty():
  1513.                     return True
  1514.                 continue
  1515.             content.isEmpty()
  1516.         
  1517.         return False
  1518.  
  1519.  
  1520.  
  1521. class DropCaps(LrsTextTag):
  1522.     
  1523.     def __init__(self, line = 1):
  1524.         LrsTextTag.__init__(self, None, [
  1525.             LrsSimpleChar1])
  1526.         if int(line) <= 0:
  1527.             raise LrsError('A DrawChar must span at least one line.')
  1528.         int(line) <= 0
  1529.         self.line = int(line)
  1530.  
  1531.     
  1532.     def isEmpty(self):
  1533.         if not self.text == None:
  1534.             pass
  1535.         return not self.text.strip()
  1536.  
  1537.     
  1538.     def toElement(self, se):
  1539.         elem = Element('DrawChar', line = str(self.line))
  1540.         appendTextElements(elem, self.contents, se)
  1541.         return elem
  1542.  
  1543.     
  1544.     def toLrfContainer(self, lrfWriter, parent):
  1545.         parent.appendLrfTag(LrfTag('DrawChar', (int(self.line),)))
  1546.         for content in self.contents:
  1547.             content.toLrfContainer(lrfWriter, parent)
  1548.         
  1549.         parent.appendLrfTag(LrfTag('DrawCharEnd'))
  1550.  
  1551.  
  1552.  
  1553. class Button(LrsObject, LrsContainer):
  1554.     
  1555.     def __init__(self, **settings):
  1556.         LrsObject.__init__(self, **settings)
  1557.         LrsContainer.__init__(self, [
  1558.             PushButton])
  1559.  
  1560.     
  1561.     def findJumpToRefs(self):
  1562.         for sub1 in self.contents:
  1563.             if isinstance(sub1, PushButton):
  1564.                 for sub2 in sub1.contents:
  1565.                     if isinstance(sub2, JumpTo):
  1566.                         return (sub2.textBlock.objId, sub2.textBlock.parent.objId)
  1567.                 
  1568.             isinstance(sub2, JumpTo)
  1569.         
  1570.         raise LrsError, '%s has no PushButton or JumpTo subs' % self.__class__.__name__
  1571.  
  1572.     
  1573.     def toLrf(self, lrfWriter):
  1574.         (refobj, refpage) = self.findJumpToRefs()
  1575.         button = LrfObject('Button', self.objId)
  1576.         button.appendLrfTag(LrfTag('buttonflags', 16))
  1577.         button.appendLrfTag(LrfTag('PushButtonStart'))
  1578.         button.appendLrfTag(LrfTag('buttonactions'))
  1579.         button.appendLrfTag(LrfTag('jumpto', (int(refpage), int(refobj))))
  1580.         button.append(LrfTag('endbuttonactions'))
  1581.         button.appendLrfTag(LrfTag('PushButtonEnd'))
  1582.         lrfWriter.append(button)
  1583.  
  1584.     
  1585.     def toElement(self, se):
  1586.         b = self.lrsObjectElement('Button')
  1587.         for content in self.contents:
  1588.             b.append(content.toElement(se))
  1589.         
  1590.         return b
  1591.  
  1592.  
  1593.  
  1594. class ButtonBlock(Button):
  1595.     pass
  1596.  
  1597.  
  1598. class PushButton(LrsContainer):
  1599.     
  1600.     def __init__(self, **settings):
  1601.         LrsContainer.__init__(self, [
  1602.             JumpTo])
  1603.  
  1604.     
  1605.     def toElement(self, se):
  1606.         b = Element('PushButton')
  1607.         for content in self.contents:
  1608.             b.append(content.toElement(se))
  1609.         
  1610.         return b
  1611.  
  1612.  
  1613.  
  1614. class JumpTo(LrsContainer):
  1615.     
  1616.     def __init__(self, textBlock):
  1617.         LrsContainer.__init__(self, [])
  1618.         self.textBlock = textBlock
  1619.  
  1620.     
  1621.     def setTextBlock(self, textBlock):
  1622.         self.textBlock = textBlock
  1623.  
  1624.     
  1625.     def toElement(self, se):
  1626.         return Element('JumpTo', refpage = str(self.textBlock.parent.objId), refobj = str(self.textBlock.objId))
  1627.  
  1628.  
  1629.  
  1630. class Plot(LrsSimpleChar1, LrsContainer):
  1631.     ADJUSTMENT_VALUES = {
  1632.         'center': 1,
  1633.         'baseline': 2,
  1634.         'top': 3,
  1635.         'bottom': 4 }
  1636.     
  1637.     def __init__(self, obj, xsize = 0, ysize = 0, adjustment = None):
  1638.         LrsContainer.__init__(self, [])
  1639.         if obj != None:
  1640.             self.setObj(obj)
  1641.         
  1642.         if xsize < 0 or ysize < 0:
  1643.             raise LrsError('Sizes must be positive semi-definite')
  1644.         ysize < 0
  1645.         self.xsize = int(xsize)
  1646.         self.ysize = int(ysize)
  1647.         if adjustment and adjustment not in Plot.ADJUSTMENT_VALUES.keys():
  1648.             raise LrsError('adjustment must be one of' + Plot.ADJUSTMENT_VALUES.keys())
  1649.         adjustment not in Plot.ADJUSTMENT_VALUES.keys()
  1650.         self.adjustment = adjustment
  1651.  
  1652.     
  1653.     def setObj(self, obj):
  1654.         if not isinstance(obj, (Image, Button)):
  1655.             raise LrsError('Plot elements can only refer to Image or Button elements')
  1656.         isinstance(obj, (Image, Button))
  1657.         self.obj = obj
  1658.  
  1659.     
  1660.     def getReferencedObjIds(self):
  1661.         return [
  1662.             self.obj.objId]
  1663.  
  1664.     
  1665.     def appendReferencedObjects(self, parent):
  1666.         if self.obj.parent is None:
  1667.             parent.append(self.obj)
  1668.         
  1669.  
  1670.     
  1671.     def toElement(self, se):
  1672.         elem = Element('Plot', xsize = str(self.xsize), ysize = str(self.ysize), refobj = str(self.obj.objId))
  1673.         if self.adjustment:
  1674.             elem.set('adjustment', self.adjustment)
  1675.         
  1676.         return elem
  1677.  
  1678.     
  1679.     def toLrfContainer(self, lrfWriter, parent):
  1680.         adj = None if self.adjustment else 'bottom'
  1681.         params = (int(self.xsize), int(self.ysize), int(self.obj.objId), Plot.ADJUSTMENT_VALUES[adj])
  1682.         parent.appendLrfTag(LrfTag('Plot', params))
  1683.  
  1684.  
  1685.  
  1686. class Text(LrsContainer):
  1687.     
  1688.     def __init__(self, text):
  1689.         LrsContainer.__init__(self, [])
  1690.         self.text = text
  1691.  
  1692.     
  1693.     def isEmpty(self):
  1694.         if not not (self.text):
  1695.             pass
  1696.         return not self.text.strip()
  1697.  
  1698.     
  1699.     def toLrfContainer(self, lrfWriter, parent):
  1700.         if self.text:
  1701.             if isinstance(self.text, str):
  1702.                 parent.appendLrfTag(LrfTag('rawtext', self.text))
  1703.             else:
  1704.                 parent.appendLrfTag(LrfTag('textstring', self.text))
  1705.         
  1706.  
  1707.  
  1708.  
  1709. class CR(LrsSimpleChar1, LrsContainer):
  1710.     
  1711.     def __init__(self):
  1712.         LrsContainer.__init__(self, [])
  1713.  
  1714.     
  1715.     def toElement(self, se):
  1716.         return Element('CR')
  1717.  
  1718.     
  1719.     def toLrfContainer(self, lrfWriter, parent):
  1720.         parent.appendLrfTag(LrfTag('CR'))
  1721.  
  1722.  
  1723.  
  1724. class Italic(LrsSimpleChar1, LrsTextTag):
  1725.     
  1726.     def __init__(self, text = None):
  1727.         LrsTextTag.__init__(self, text, [
  1728.             LrsSimpleChar1])
  1729.  
  1730.  
  1731.  
  1732. class Sub(LrsSimpleChar1, LrsTextTag):
  1733.     
  1734.     def __init__(self, text = None):
  1735.         LrsTextTag.__init__(self, text, [])
  1736.  
  1737.  
  1738.  
  1739. class Sup(LrsSimpleChar1, LrsTextTag):
  1740.     
  1741.     def __init__(self, text = None):
  1742.         LrsTextTag.__init__(self, text, [])
  1743.  
  1744.  
  1745.  
  1746. class NoBR(LrsSimpleChar1, LrsTextTag):
  1747.     
  1748.     def __init__(self, text = None):
  1749.         LrsTextTag.__init__(self, text, [
  1750.             LrsSimpleChar1])
  1751.  
  1752.  
  1753.  
  1754. class Space(LrsSimpleChar1, LrsContainer):
  1755.     
  1756.     def __init__(self, xsize = 0, x = 0):
  1757.         LrsContainer.__init__(self, [])
  1758.         if xsize == 0 and x != 0:
  1759.             xsize = x
  1760.         
  1761.         self.xsize = xsize
  1762.  
  1763.     
  1764.     def toElement(self, se):
  1765.         if self.xsize == 0:
  1766.             return None
  1767.         return Element('Space', xsize = str(self.xsize))
  1768.  
  1769.     
  1770.     def toLrfContainer(self, lrfWriter, container):
  1771.         if self.xsize != 0:
  1772.             container.appendLrfTag(LrfTag('Space', self.xsize))
  1773.         
  1774.  
  1775.  
  1776.  
  1777. class Box(LrsSimpleChar1, LrsContainer):
  1778.     
  1779.     def __init__(self, linetype = 'solid'):
  1780.         LrsContainer.__init__(self, [
  1781.             Text,
  1782.             basestring])
  1783.         if linetype not in LINE_TYPE_ENCODING:
  1784.             raise LrsError, linetype + ' is not a valid line type'
  1785.         linetype not in LINE_TYPE_ENCODING
  1786.         self.linetype = linetype
  1787.  
  1788.     
  1789.     def toElement(self, se):
  1790.         e = Element('Box', linetype = self.linetype)
  1791.         appendTextElements(e, self.contents, se)
  1792.         return e
  1793.  
  1794.     
  1795.     def toLrfContainer(self, lrfWriter, container):
  1796.         container.appendLrfTag(LrfTag('Box', self.linetype))
  1797.         for content in self.contents:
  1798.             content.toLrfContainer(lrfWriter, container)
  1799.         
  1800.         container.appendLrfTag(LrfTag('BoxEnd'))
  1801.  
  1802.  
  1803.  
  1804. class Span(LrsSimpleChar1, LrsContainer):
  1805.     
  1806.     def __init__(self, text = None, **attrs):
  1807.         LrsContainer.__init__(self, [
  1808.             LrsSimpleChar1,
  1809.             Text,
  1810.             basestring])
  1811.         if text is not None:
  1812.             if isinstance(text, basestring):
  1813.                 text = Text(text)
  1814.             
  1815.             self.append(text)
  1816.         
  1817.         for attrname in attrs.keys():
  1818.             if attrname not in TextStyle.defaults and attrname not in TextStyle.alsoAllow:
  1819.                 raise LrsError, 'setting %s not allowed on Span' % attrname
  1820.             attrname not in TextStyle.alsoAllow
  1821.         
  1822.         self.attrs = attrs
  1823.  
  1824.     
  1825.     def findCurrentTextStyle(self):
  1826.         parent = self.parent
  1827.         while parent is None or hasattr(parent, 'currentTextStyle'):
  1828.             break
  1829.         parent = parent.parent
  1830.         continue
  1831.         if parent is None:
  1832.             raise LrsError, 'no enclosing current TextStyle found'
  1833.         parent is None
  1834.         return parent.currentTextStyle
  1835.  
  1836.     
  1837.     def toLrfContainer(self, lrfWriter, container):
  1838.         oldTextStyle = self.findCurrentTextStyle()
  1839.         for name, value in self.attrs.items():
  1840.             if name in oldTextStyle.attrs and oldTextStyle.attrs[name] == self.attrs[name]:
  1841.                 self.attrs.pop(name)
  1842.                 continue
  1843.             container.appendLrfTag(LrfTag(name, value))
  1844.         
  1845.         oldTextStyle = self.findCurrentTextStyle()
  1846.         self.currentTextStyle = oldTextStyle.copy()
  1847.         self.currentTextStyle.attrs.update(self.attrs)
  1848.         for content in self.contents:
  1849.             content.toLrfContainer(lrfWriter, container)
  1850.         
  1851.         for name in self.attrs.keys():
  1852.             container.appendLrfTag(LrfTag(name, oldTextStyle.attrs[name]))
  1853.         
  1854.  
  1855.     
  1856.     def toElement(self, se):
  1857.         element = Element('Span')
  1858.         for key, value in self.attrs.items():
  1859.             element.set(key, str(value))
  1860.         
  1861.         appendTextElements(element, self.contents, se)
  1862.         return element
  1863.  
  1864.  
  1865.  
  1866. class EmpLine(LrsTextTag, LrsSimpleChar1):
  1867.     emplinetypes = [
  1868.         'none',
  1869.         'solid',
  1870.         'dotted',
  1871.         'dashed',
  1872.         'double']
  1873.     emplinepositions = [
  1874.         'before',
  1875.         'after']
  1876.     
  1877.     def __init__(self, text = None, emplineposition = 'before', emplinetype = 'solid'):
  1878.         LrsTextTag.__init__(self, text, [
  1879.             LrsSimpleChar1])
  1880.         if emplineposition not in self.__class__.emplinepositions:
  1881.             raise LrsError('emplineposition for an EmpLine must be one of: ' + str(self.__class__.emplinepositions))
  1882.         emplineposition not in self.__class__.emplinepositions
  1883.         if emplinetype not in self.__class__.emplinetypes:
  1884.             raise LrsError('emplinetype for an EmpLine must be one of: ' + str(self.__class__.emplinetypes))
  1885.         emplinetype not in self.__class__.emplinetypes
  1886.         self.emplinetype = emplinetype
  1887.         self.emplineposition = emplineposition
  1888.  
  1889.     
  1890.     def toLrfContainer(self, lrfWriter, parent):
  1891.         parent.appendLrfTag(LrfTag(self.__class__.__name__, (self.emplineposition, self.emplinetype)))
  1892.         parent.appendLrfTag(LrfTag('emplineposition', self.emplineposition))
  1893.         parent.appendLrfTag(LrfTag('emplinetype', self.emplinetype))
  1894.         for content in self.contents:
  1895.             content.toLrfContainer(lrfWriter, parent)
  1896.         
  1897.         parent.appendLrfTag(LrfTag(self.__class__.__name__ + 'End'))
  1898.  
  1899.     
  1900.     def toElement(self, se):
  1901.         element = Element(self.__class__.__name__)
  1902.         element.set('emplineposition', self.emplineposition)
  1903.         element.set('emplinetype', self.emplinetype)
  1904.         appendTextElements(element, self.contents, se)
  1905.         return element
  1906.  
  1907.  
  1908.  
  1909. class Bold(Span):
  1910.     
  1911.     def __init__(self, text = None):
  1912.         Span.__init__(self, text, fontweight = 800)
  1913.  
  1914.     
  1915.     def toElement(self, se):
  1916.         e = Element('Bold')
  1917.         appendTextElements(e, self.contents, se)
  1918.         return e
  1919.  
  1920.  
  1921.  
  1922. class BlockSpace(LrsContainer):
  1923.     
  1924.     def __init__(self, xspace = 0, yspace = 0, x = 0, y = 0):
  1925.         LrsContainer.__init__(self, [])
  1926.         if xspace == 0 and x != 0:
  1927.             xspace = x
  1928.         
  1929.         if yspace == 0 and y != 0:
  1930.             yspace = y
  1931.         
  1932.         self.xspace = xspace
  1933.         self.yspace = yspace
  1934.  
  1935.     
  1936.     def toLrfContainer(self, lrfWriter, container):
  1937.         if self.xspace != 0:
  1938.             container.appendLrfTag(LrfTag('xspace', self.xspace))
  1939.         
  1940.         if self.yspace != 0:
  1941.             container.appendLrfTag(LrfTag('yspace', self.yspace))
  1942.         
  1943.  
  1944.     
  1945.     def toElement(self, se):
  1946.         element = Element('BlockSpace')
  1947.         if self.xspace != 0:
  1948.             element.attrib['xspace'] = str(self.xspace)
  1949.         
  1950.         if self.yspace != 0:
  1951.             element.attrib['yspace'] = str(self.yspace)
  1952.         
  1953.         return element
  1954.  
  1955.  
  1956.  
  1957. class CharButton(LrsSimpleChar1, LrsContainer):
  1958.     
  1959.     def __init__(self, button, text = None):
  1960.         LrsContainer.__init__(self, [
  1961.             basestring,
  1962.             Text,
  1963.             LrsSimpleChar1])
  1964.         self.button = None
  1965.         if button != None:
  1966.             self.setButton(button)
  1967.         
  1968.         if text is not None:
  1969.             self.append(text)
  1970.         
  1971.  
  1972.     
  1973.     def setButton(self, button):
  1974.         if not isinstance(button, (JumpButton, Button)):
  1975.             raise LrsError, 'CharButton button must be a JumpButton or Button'
  1976.         isinstance(button, (JumpButton, Button))
  1977.         self.button = button
  1978.  
  1979.     
  1980.     def appendReferencedObjects(self, parent):
  1981.         if self.button.parent is None:
  1982.             parent.append(self.button)
  1983.         
  1984.  
  1985.     
  1986.     def getReferencedObjIds(self):
  1987.         return [
  1988.             self.button.objId]
  1989.  
  1990.     
  1991.     def toLrfContainer(self, lrfWriter, container):
  1992.         container.appendLrfTag(LrfTag('CharButton', self.button.objId))
  1993.         for content in self.contents:
  1994.             content.toLrfContainer(lrfWriter, container)
  1995.         
  1996.         container.appendLrfTag(LrfTag('CharButtonEnd'))
  1997.  
  1998.     
  1999.     def toElement(self, se):
  2000.         cb = Element('CharButton', refobj = str(self.button.objId))
  2001.         appendTextElements(cb, self.contents, se)
  2002.         return cb
  2003.  
  2004.  
  2005.  
  2006. class Objects(LrsContainer):
  2007.     
  2008.     def __init__(self):
  2009.         LrsContainer.__init__(self, [
  2010.             JumpButton,
  2011.             TextBlock,
  2012.             HeaderOrFooter,
  2013.             ImageStream,
  2014.             Image,
  2015.             ImageBlock,
  2016.             Button,
  2017.             ButtonBlock])
  2018.         self.appendJumpButton = self.appendTextBlock = self.appendHeader = self.appendFooter = self.appendImageStream = self.appendImage = self.appendImageBlock = self.append
  2019.  
  2020.     
  2021.     def getMethods(self):
  2022.         return [
  2023.             'JumpButton',
  2024.             'appendJumpButton',
  2025.             'TextBlock',
  2026.             'appendTextBlock',
  2027.             'Header',
  2028.             'appendHeader',
  2029.             'Footer',
  2030.             'appendFooter',
  2031.             'ImageBlock',
  2032.             'ImageStream',
  2033.             'appendImageStream',
  2034.             'Image',
  2035.             'appendImage',
  2036.             'appendImageBlock']
  2037.  
  2038.     
  2039.     def getSettings(self):
  2040.         return []
  2041.  
  2042.     
  2043.     def ImageBlock(self, *args, **kwargs):
  2044.         ib = ImageBlock(*args, **kwargs)
  2045.         self.append(ib)
  2046.         return ib
  2047.  
  2048.     
  2049.     def JumpButton(self, textBlock):
  2050.         b = JumpButton(textBlock)
  2051.         self.append(b)
  2052.         return b
  2053.  
  2054.     
  2055.     def TextBlock(self, *args, **kwargs):
  2056.         tb = TextBlock(*args, **kwargs)
  2057.         self.append(tb)
  2058.         return tb
  2059.  
  2060.     
  2061.     def Header(self, *args, **kwargs):
  2062.         h = Header(*args, **kwargs)
  2063.         self.append(h)
  2064.         return h
  2065.  
  2066.     
  2067.     def Footer(self, *args, **kwargs):
  2068.         h = Footer(*args, **kwargs)
  2069.         self.append(h)
  2070.         return h
  2071.  
  2072.     
  2073.     def ImageStream(self, *args, **kwargs):
  2074.         i = ImageStream(*args, **kwargs)
  2075.         self.append(i)
  2076.         return i
  2077.  
  2078.     
  2079.     def Image(self, *args, **kwargs):
  2080.         i = Image(*args, **kwargs)
  2081.         self.append(i)
  2082.         return i
  2083.  
  2084.     
  2085.     def toElement(self, se):
  2086.         o = Element('Objects')
  2087.         for content in self.contents:
  2088.             o.append(content.toElement(se))
  2089.         
  2090.         return o
  2091.  
  2092.     
  2093.     def toLrf(self, lrfWriter):
  2094.         for content in self.contents:
  2095.             content.toLrf(lrfWriter)
  2096.         
  2097.  
  2098.  
  2099.  
  2100. class JumpButton(LrsObject, LrsContainer):
  2101.     
  2102.     def __init__(self, textBlock):
  2103.         LrsObject.__init__(self)
  2104.         LrsContainer.__init__(self, [])
  2105.         self.textBlock = textBlock
  2106.  
  2107.     
  2108.     def setTextBlock(self, textBlock):
  2109.         self.textBlock = textBlock
  2110.  
  2111.     
  2112.     def toLrf(self, lrfWriter):
  2113.         button = LrfObject('Button', self.objId)
  2114.         button.appendLrfTag(LrfTag('buttonflags', 16))
  2115.         button.appendLrfTag(LrfTag('PushButtonStart'))
  2116.         button.appendLrfTag(LrfTag('buttonactions'))
  2117.         button.appendLrfTag(LrfTag('jumpto', (self.textBlock.parent.objId, self.textBlock.objId)))
  2118.         button.append(LrfTag('endbuttonactions'))
  2119.         button.appendLrfTag(LrfTag('PushButtonEnd'))
  2120.         lrfWriter.append(button)
  2121.  
  2122.     
  2123.     def toElement(self, se):
  2124.         b = self.lrsObjectElement('Button')
  2125.         pb = SubElement(b, 'PushButton')
  2126.         SubElement(pb, 'JumpTo', refpage = str(self.textBlock.parent.objId), refobj = str(self.textBlock.objId))
  2127.         return b
  2128.  
  2129.  
  2130.  
  2131. class RuledLine(LrsContainer, LrsAttributes, LrsObject):
  2132.     defaults = dict(linelength = '500', linetype = 'solid', linewidth = '2', linecolor = '0x00000000')
  2133.     
  2134.     def __init__(self, **settings):
  2135.         LrsContainer.__init__(self, [])
  2136.         LrsAttributes.__init__(self, self.defaults, **settings)
  2137.         LrsObject.__init__(self)
  2138.  
  2139.     
  2140.     def toLrfContainer(self, lrfWriter, container):
  2141.         a = self.attrs
  2142.         container.appendLrfTag(LrfTag('RuledLine', (a['linelength'], a['linetype'], a['linewidth'], a['linecolor'])))
  2143.  
  2144.     
  2145.     def toElement(self, se):
  2146.         return Element('RuledLine', self.attrs)
  2147.  
  2148.  
  2149.  
  2150. class HeaderOrFooter(LrsObject, LrsContainer, LrsAttributes):
  2151.     defaults = dict(framemode = 'square', layout = 'LrTb', framewidth = '0', framecolor = '0x00000000', bgcolor = '0xFF000000')
  2152.     
  2153.     def __init__(self, **settings):
  2154.         LrsObject.__init__(self)
  2155.         LrsContainer.__init__(self, [
  2156.             PutObj])
  2157.         LrsAttributes.__init__(self, self.defaults, **settings)
  2158.  
  2159.     
  2160.     def put_object(self, obj, x1, y1):
  2161.         self.append(PutObj(obj, x1, y1))
  2162.  
  2163.     
  2164.     def PutObj(self, *args, **kwargs):
  2165.         p = PutObj(*args, **kwargs)
  2166.         self.append(p)
  2167.         return p
  2168.  
  2169.     
  2170.     def toLrf(self, lrfWriter):
  2171.         hd = LrfObject(self.__class__.__name__, self.objId)
  2172.         hd.appendTagDict(self.attrs)
  2173.         stream = LrfTagStream(0)
  2174.         for content in self.contents:
  2175.             content.toLrfContainer(lrfWriter, stream)
  2176.         
  2177.         hd.appendLrfTags(stream.getStreamTags(lrfWriter.getSourceEncoding()))
  2178.         lrfWriter.append(hd)
  2179.  
  2180.     
  2181.     def toElement(self, se):
  2182.         name = self.__class__.__name__
  2183.         labelName = name.lower() + 'label'
  2184.         hd = self.lrsObjectElement(name, objlabel = labelName)
  2185.         hd.attrib.update(self.attrs)
  2186.         for content in self.contents:
  2187.             hd.append(content.toElement(se))
  2188.         
  2189.         return hd
  2190.  
  2191.  
  2192.  
  2193. class Header(HeaderOrFooter):
  2194.     pass
  2195.  
  2196.  
  2197. class Footer(HeaderOrFooter):
  2198.     pass
  2199.  
  2200.  
  2201. class Canvas(LrsObject, LrsContainer, LrsAttributes):
  2202.     defaults = dict(framemode = 'square', layout = 'LrTb', framewidth = '0', framecolor = '0x00000000', bgcolor = '0xFF000000', canvasheight = 0, canvaswidth = 0, blockrule = 'block-adjustable')
  2203.     
  2204.     def __init__(self, width, height, **settings):
  2205.         LrsObject.__init__(self)
  2206.         LrsContainer.__init__(self, [
  2207.             PutObj])
  2208.         LrsAttributes.__init__(self, self.defaults, **settings)
  2209.         self.settings = self.defaults.copy()
  2210.         self.settings.update(settings)
  2211.         self.settings['canvasheight'] = int(height)
  2212.         self.settings['canvaswidth'] = int(width)
  2213.  
  2214.     
  2215.     def put_object(self, obj, x1, y1):
  2216.         self.append(PutObj(obj, x1, y1))
  2217.  
  2218.     
  2219.     def toElement(self, source_encoding):
  2220.         el = self.lrsObjectElement('Canvas', **self.settings)
  2221.         for po in self.contents:
  2222.             el.append(po.toElement(source_encoding))
  2223.         
  2224.         return el
  2225.  
  2226.     
  2227.     def toLrf(self, lrfWriter):
  2228.         self.toLrfContainer(lrfWriter, lrfWriter)
  2229.  
  2230.     
  2231.     def toLrfContainer(self, lrfWriter, container):
  2232.         c = LrfObject('Canvas', self.objId)
  2233.         c.appendTagDict(self.settings)
  2234.         stream = LrfTagStream(STREAM_COMPRESSED)
  2235.         for content in self.contents:
  2236.             content.toLrfContainer(lrfWriter, stream)
  2237.         
  2238.         if lrfWriter.saveStreamTags:
  2239.             c.saveStreamTags = stream.tags
  2240.         
  2241.         c.appendLrfTags(stream.getStreamTags(lrfWriter.getSourceEncoding(), optimizeTags = lrfWriter.optimizeTags, optimizeCompression = lrfWriter.optimizeCompression))
  2242.         container.addLrfObject(c.objId)
  2243.         lrfWriter.append(c)
  2244.  
  2245.     
  2246.     def has_text(self):
  2247.         return bool(self.contents)
  2248.  
  2249.  
  2250.  
  2251. class PutObj(LrsContainer):
  2252.     
  2253.     def __init__(self, content, x1 = 0, y1 = 0):
  2254.         LrsContainer.__init__(self, [
  2255.             TextBlock,
  2256.             ImageBlock])
  2257.         self.content = content
  2258.         self.x1 = int(x1)
  2259.         self.y1 = int(y1)
  2260.  
  2261.     
  2262.     def setContent(self, content):
  2263.         self.content = content
  2264.  
  2265.     
  2266.     def appendReferencedObjects(self, parent):
  2267.         if self.content.parent is None:
  2268.             parent.append(self.content)
  2269.         
  2270.  
  2271.     
  2272.     def toLrfContainer(self, lrfWriter, container):
  2273.         container.appendLrfTag(LrfTag('PutObj', (self.x1, self.y1, self.content.objId)))
  2274.  
  2275.     
  2276.     def toElement(self, se):
  2277.         el = Element('PutObj', x1 = str(self.x1), y1 = str(self.y1), refobj = str(self.content.objId))
  2278.         return el
  2279.  
  2280.  
  2281.  
  2282. class ImageStream(LrsObject, LrsContainer):
  2283.     VALID_ENCODINGS = [
  2284.         'JPEG',
  2285.         'GIF',
  2286.         'BMP',
  2287.         'PNG']
  2288.     
  2289.     def __init__(self, file = None, encoding = None, comment = None):
  2290.         LrsObject.__init__(self)
  2291.         LrsContainer.__init__(self, [])
  2292.         _checkExists(file)
  2293.         self.filename = file
  2294.         self.comment = comment
  2295.         if encoding is None:
  2296.             extension = os.path.splitext(file)[1]
  2297.             if not extension:
  2298.                 raise LrsError, 'file must have extension if encoding is not specified'
  2299.             extension
  2300.             extension = extension[1:].upper()
  2301.             if extension == 'JPG':
  2302.                 extension = 'JPEG'
  2303.             
  2304.             encoding = extension
  2305.         else:
  2306.             encoding = encoding.upper()
  2307.         if encoding not in self.VALID_ENCODINGS:
  2308.             raise LrsError, 'encoding or file extension not JPEG, GIF, BMP, or PNG'
  2309.         encoding not in self.VALID_ENCODINGS
  2310.         self.encoding = encoding
  2311.  
  2312.     
  2313.     def toLrf(self, lrfWriter):
  2314.         imageFile = file(self.filename, 'rb')
  2315.         imageData = imageFile.read()
  2316.         imageFile.close()
  2317.         isObj = LrfObject('ImageStream', self.objId)
  2318.         if self.comment is not None:
  2319.             isObj.appendLrfTag(LrfTag('comment', self.comment))
  2320.         
  2321.         streamFlags = IMAGE_TYPE_ENCODING[self.encoding]
  2322.         stream = LrfStreamBase(streamFlags, imageData)
  2323.         isObj.appendLrfTags(stream.getStreamTags())
  2324.         lrfWriter.append(isObj)
  2325.  
  2326.     
  2327.     def toElement(self, se):
  2328.         element = self.lrsObjectElement('ImageStream', objlabel = 'imagestreamlabel', encoding = self.encoding, file = self.filename)
  2329.         element.text = self.comment
  2330.         return element
  2331.  
  2332.  
  2333.  
  2334. class Image(LrsObject, LrsContainer, LrsAttributes):
  2335.     defaults = dict()
  2336.     
  2337.     def __init__(self, refstream, x0 = 0, x1 = 0, y0 = 0, y1 = 0, xsize = 0, ysize = 0, **settings):
  2338.         LrsObject.__init__(self)
  2339.         LrsContainer.__init__(self, [])
  2340.         LrsAttributes.__init__(self, self.defaults, settings)
  2341.         (self.x0, self.y0, self.x1, self.y1) = (int(x0), int(y0), int(x1), int(y1))
  2342.         self.xsize = int(xsize)
  2343.         self.ysize = int(ysize)
  2344.         self.setRefstream(refstream)
  2345.  
  2346.     
  2347.     def setRefstream(self, refstream):
  2348.         self.refstream = refstream
  2349.  
  2350.     
  2351.     def appendReferencedObjects(self, parent):
  2352.         if self.refstream.parent is None:
  2353.             parent.append(self.refstream)
  2354.         
  2355.  
  2356.     
  2357.     def getReferencedObjIds(self):
  2358.         return [
  2359.             self.objId,
  2360.             self.refstream.objId]
  2361.  
  2362.     
  2363.     def toElement(self, se):
  2364.         element = self.lrsObjectElement('Image', **self.attrs)
  2365.         element.set('refstream', str(self.refstream.objId))
  2366.         for name in [
  2367.             'x0',
  2368.             'y0',
  2369.             'x1',
  2370.             'y1',
  2371.             'xsize',
  2372.             'ysize']:
  2373.             element.set(name, str(getattr(self, name)))
  2374.         
  2375.         return element
  2376.  
  2377.     
  2378.     def toLrf(self, lrfWriter):
  2379.         ib = LrfObject('Image', self.objId)
  2380.         ib.appendLrfTag(LrfTag('ImageRect', (self.x0, self.y0, self.x1, self.y1)))
  2381.         ib.appendLrfTag(LrfTag('ImageSize', (self.xsize, self.ysize)))
  2382.         ib.appendLrfTag(LrfTag('RefObjId', self.refstream.objId))
  2383.         lrfWriter.append(ib)
  2384.  
  2385.  
  2386.  
  2387. class ImageBlock(LrsObject, LrsContainer, LrsAttributes):
  2388.     defaults = BlockStyle.baseDefaults.copy()
  2389.     
  2390.     def __init__(self, refstream, x0 = '0', y0 = '0', x1 = '600', y1 = '800', xsize = '600', ysize = '800', blockStyle = BlockStyle(blockrule = 'block-fixed'), alttext = None, **settings):
  2391.         LrsObject.__init__(self)
  2392.         LrsContainer.__init__(self, [
  2393.             Text,
  2394.             Image])
  2395.         LrsAttributes.__init__(self, self.defaults, **settings)
  2396.         (self.x0, self.y0, self.x1, self.y1) = (int(x0), int(y0), int(x1), int(y1))
  2397.         self.xsize = int(xsize)
  2398.         self.ysize = int(ysize)
  2399.         self.setRefstream(refstream)
  2400.         self.blockStyle = blockStyle
  2401.         self.alttext = alttext
  2402.  
  2403.     
  2404.     def setRefstream(self, refstream):
  2405.         self.refstream = refstream
  2406.  
  2407.     
  2408.     def appendReferencedObjects(self, parent):
  2409.         if self.refstream.parent is None:
  2410.             parent.append(self.refstream)
  2411.         
  2412.         if self.blockStyle is not None and self.blockStyle.parent is None:
  2413.             parent.append(self.blockStyle)
  2414.         
  2415.  
  2416.     
  2417.     def getReferencedObjIds(self):
  2418.         objects = [
  2419.             self.objId,
  2420.             self.extraId,
  2421.             self.refstream.objId]
  2422.         if self.blockStyle is not None:
  2423.             objects.append(self.blockStyle.objId)
  2424.         
  2425.         return objects
  2426.  
  2427.     
  2428.     def toLrf(self, lrfWriter):
  2429.         self.toLrfContainer(lrfWriter, lrfWriter)
  2430.  
  2431.     
  2432.     def toLrfContainer(self, lrfWriter, container):
  2433.         extraId = LrsObject.getNextObjId()
  2434.         b = LrfObject('Block', self.objId)
  2435.         if self.blockStyle is not None:
  2436.             b.appendLrfTag(LrfTag('Link', self.blockStyle.objId))
  2437.         
  2438.         b.appendTagDict(self.attrs)
  2439.         b.appendLrfTags(LrfTagStream(0, [
  2440.             LrfTag('Link', extraId)]).getStreamTags(lrfWriter.getSourceEncoding()))
  2441.         container.addLrfObject(b.objId)
  2442.         lrfWriter.append(b)
  2443.         ib = LrfObject('Image', extraId)
  2444.         ib.appendLrfTag(LrfTag('ImageRect', (self.x0, self.y0, self.x1, self.y1)))
  2445.         ib.appendLrfTag(LrfTag('ImageSize', (self.xsize, self.ysize)))
  2446.         ib.appendLrfTag(LrfTag('RefObjId', self.refstream.objId))
  2447.         if self.alttext:
  2448.             ib.appendLrfTag('Comment', self.alttext)
  2449.         
  2450.         lrfWriter.append(ib)
  2451.         self.extraId = extraId
  2452.  
  2453.     
  2454.     def toElement(self, se):
  2455.         element = self.lrsObjectElement('ImageBlock', **self.attrs)
  2456.         element.set('refstream', str(self.refstream.objId))
  2457.         for name in [
  2458.             'x0',
  2459.             'y0',
  2460.             'x1',
  2461.             'y1',
  2462.             'xsize',
  2463.             'ysize']:
  2464.             element.set(name, str(getattr(self, name)))
  2465.         
  2466.         element.text = self.alttext
  2467.         return element
  2468.  
  2469.  
  2470.  
  2471. class Font(LrsContainer):
  2472.     
  2473.     def __init__(self, file = None, fontname = None, fontfilename = None, encoding = None):
  2474.         LrsContainer.__init__(self, [])
  2475.         
  2476.         try:
  2477.             _checkExists(fontfilename)
  2478.             self.truefile = fontfilename
  2479.         except:
  2480.             
  2481.             try:
  2482.                 _checkExists(file)
  2483.                 self.truefile = file
  2484.             raise LrsError, "neither '%s' nor '%s' exists" % (fontfilename, file)
  2485.  
  2486.  
  2487.         self.file = file
  2488.         self.fontname = fontname
  2489.         self.fontfilename = fontfilename
  2490.         self.encoding = encoding
  2491.  
  2492.     
  2493.     def toLrf(self, lrfWriter):
  2494.         font = LrfObject('Font', LrsObject.getNextObjId())
  2495.         lrfWriter.registerFontId(font.objId)
  2496.         font.appendLrfTag(LrfTag('FontFilename', lrfWriter.toUnicode(self.truefile)))
  2497.         font.appendLrfTag(LrfTag('FontFacename', lrfWriter.toUnicode(self.fontname)))
  2498.         stream = LrfFileStream(STREAM_FORCE_COMPRESSED, self.truefile)
  2499.         font.appendLrfTags(stream.getStreamTags())
  2500.         lrfWriter.append(font)
  2501.  
  2502.     
  2503.     def toElement(self, se):
  2504.         element = Element('RegistFont', encoding = 'TTF', fontname = self.fontname, file = self.file, fontfilename = self.file)
  2505.         return element
  2506.  
  2507.  
  2508.