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

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __all__ = [
  5.     'CSSSerializer',
  6.     'Preferences']
  7. __docformat__ = 'restructuredtext'
  8. __version__ = '$Id: serialize.py 1898 2009-12-19 12:17:04Z cthedot $'
  9. import codecs
  10. import cssutils
  11. import helper
  12. import re
  13. import xml.dom as xml
  14.  
  15. def _escapecss(e):
  16.     s = e.object[e.start:e.end]
  17.     return ([]([ u'\\%s ' % str(hex(ord(x)))[2:].upper() for x in s ]), e.end)
  18.  
  19. codecs.register_error('escapecss', _escapecss)
  20.  
  21. class Preferences(object):
  22.     
  23.     def __init__(self, **initials):
  24.         self.useDefaults()
  25.         for key, value in initials.items():
  26.             if value:
  27.                 self.__setattr__(key, value)
  28.                 continue
  29.         
  30.  
  31.     
  32.     def __repr__(self):
  33.         return u', '.join % ([], []([ '\n    %s=%r' % (p, self.__getattribute__(p)) for p in self.__dict__ ]))
  34.  
  35.     
  36.     def __str__(self):
  37.         return u' '.join % ([], []([ '%s=%r' % (p, self.__getattribute__(p)) for p in self.__dict__ ]), id(self))
  38.  
  39.     
  40.     def useDefaults(self):
  41.         self.defaultAtKeyword = True
  42.         self.defaultPropertyName = True
  43.         self.defaultPropertyPriority = True
  44.         self.importHrefFormat = None
  45.         self.indent = u'    '
  46.         self.indentSpecificities = False
  47.         self.keepAllProperties = True
  48.         self.keepComments = True
  49.         self.keepEmptyRules = False
  50.         self.keepUnkownAtRules = True
  51.         self.keepUsedNamespaceRulesOnly = False
  52.         self.lineNumbers = False
  53.         self.lineSeparator = u'\n'
  54.         self.listItemSpacer = u' '
  55.         self.omitLastSemicolon = True
  56.         self.paranthesisSpacer = u' '
  57.         self.propertyNameSpacer = u' '
  58.         self.selectorCombinatorSpacer = u' '
  59.         self.spacer = u' '
  60.         self.validOnly = False
  61.  
  62.     
  63.     def useMinified(self):
  64.         self.importHrefFormat = 'string'
  65.         self.indent = u''
  66.         self.keepComments = False
  67.         self.keepEmptyRules = False
  68.         self.keepUnkownAtRules = False
  69.         self.keepUsedNamespaceRulesOnly = True
  70.         self.lineNumbers = False
  71.         self.lineSeparator = u''
  72.         self.listItemSpacer = u''
  73.         self.omitLastSemicolon = True
  74.         self.paranthesisSpacer = u''
  75.         self.propertyNameSpacer = u''
  76.         self.selectorCombinatorSpacer = u''
  77.         self.spacer = u''
  78.         self.validOnly = False
  79.  
  80.  
  81.  
  82. class Out(object):
  83.     
  84.     def __init__(self, ser):
  85.         self.ser = ser
  86.         self.out = []
  87.  
  88.     
  89.     def _remove_last_if_S(self):
  90.         if self.out and not self.out[-1].strip():
  91.             del self.out[-1]
  92.         
  93.  
  94.     
  95.     def append(self, val, typ = None, space = True, keepS = False, indent = False, lineSeparator = False):
  96.         prefspace = self.ser.prefs.spacer
  97.         if val or typ in ('STRING', 'URI'):
  98.             if 'COMMENT' == typ:
  99.                 if self.ser.prefs.keepComments:
  100.                     val = val.cssText
  101.                 else:
  102.                     return None
  103.             self.ser.prefs.keepComments
  104.             if hasattr(val, 'cssText'):
  105.                 val = val.cssText
  106.             elif 'S' == typ and not keepS:
  107.                 return None
  108.             if 'S' == typ and keepS:
  109.                 val = u' '
  110.             elif typ in ('NUMBER', 'DIMENSION', 'PERCENTAGE') and val == '0':
  111.                 if self.out and self.out[-1] in u'+-':
  112.                     del self.out[-1]
  113.                 
  114.             elif 'STRING' == typ:
  115.                 if val is None:
  116.                     return None
  117.                 val = helper.string(val)
  118.                 if not prefspace:
  119.                     self._remove_last_if_S()
  120.                 
  121.             elif 'URI' == typ:
  122.                 val = helper.uri(val)
  123.             elif 'HASH' == typ:
  124.                 val = self.ser._hash(val)
  125.             elif val in u'+>~,:{;)]/':
  126.                 self._remove_last_if_S()
  127.             
  128.             if indent:
  129.                 self.out.append(self.ser._indentblock(val, self.ser._level + 1))
  130.             elif val.endswith(u' '):
  131.                 self._remove_last_if_S()
  132.             
  133.             self.out.append(val)
  134.             if lineSeparator:
  135.                 pass
  136.             elif val in u'+>~':
  137.                 self.out.insert(-1, self.ser.prefs.selectorCombinatorSpacer)
  138.                 self.out.append(self.ser.prefs.selectorCombinatorSpacer)
  139.             elif u')' == val and not keepS:
  140.                 self.out.append(u' ')
  141.             elif u',' == val:
  142.                 self.out.append(self.ser.prefs.listItemSpacer)
  143.             elif u':' == val:
  144.                 self.out.append(self.ser.prefs.propertyNameSpacer)
  145.             elif u'{' == val:
  146.                 self.out.insert(-1, self.ser.prefs.paranthesisSpacer)
  147.                 self.out.append(self.ser.prefs.lineSeparator)
  148.             elif u';' == val:
  149.                 self.out.append(self.ser.prefs.lineSeparator)
  150.             elif val not in u'}[]()/' and typ != 'FUNCTION' and space:
  151.                 self.out.append(self.ser.prefs.spacer)
  152.                 if typ != 'STRING' and not (self.ser.prefs.spacer) and self.out and not self.out[-1].endswith(u' '):
  153.                     self.out.append(u' ')
  154.                 
  155.             
  156.         
  157.  
  158.     
  159.     def value(self, delim = u'', end = None, keepS = False):
  160.         if not keepS:
  161.             self._remove_last_if_S()
  162.         
  163.         if end:
  164.             self.out.append(end)
  165.         
  166.         return delim.join(self.out)
  167.  
  168.  
  169.  
  170. class CSSSerializer(object):
  171.     
  172.     def __init__(self, prefs = None):
  173.         if not prefs:
  174.             prefs = Preferences()
  175.         
  176.         self.prefs = prefs
  177.         self._level = 0
  178.         self._selectors = []
  179.         self._selectorlevel = 0
  180.  
  181.     
  182.     def _atkeyword(self, rule, default):
  183.         if self.prefs.defaultAtKeyword:
  184.             return default
  185.         return rule.atkeyword
  186.  
  187.     
  188.     def _indentblock(self, text, level):
  189.         if not self.prefs.lineSeparator:
  190.             return text
  191.         return []([ u'%s%s' % (level * self.prefs.indent, line) for line in text.split(self.prefs.lineSeparator) ])
  192.  
  193.     
  194.     def _propertyname(self, property, actual):
  195.         if self.prefs.defaultPropertyName and not (self.prefs.keepAllProperties):
  196.             return property.name
  197.         return actual
  198.  
  199.     
  200.     def _linenumnbers(self, text):
  201.         if self.prefs.lineNumbers:
  202.             pad = len(str(text.count(self.prefs.lineSeparator) + 1))
  203.             out = []
  204.             for i, line in enumerate(text.split(self.prefs.lineSeparator)):
  205.                 out.append(u'%*i: %s' % (pad, i + 1, line))
  206.             
  207.             text = self.prefs.lineSeparator.join(out)
  208.         
  209.         return text
  210.  
  211.     
  212.     def _hash(self, val, type_ = None):
  213.         if len(val) == 7 and val[1] == val[2] and val[3] == val[4] and val[5] == val[6]:
  214.             return u'#%s%s%s' % (val[1], val[3], val[5])
  215.         return val
  216.  
  217.     
  218.     def _valid(self, x):
  219.         if not (self.prefs.validOnly) and self.prefs.validOnly:
  220.             pass
  221.         return x.valid
  222.  
  223.     
  224.     def do_CSSStyleSheet(self, stylesheet):
  225.         useduris = stylesheet._getUsedURIs()
  226.         out = []
  227.         for rule in stylesheet.cssRules:
  228.             if self.prefs.keepUsedNamespaceRulesOnly and rule.NAMESPACE_RULE == rule.type and rule.namespaceURI not in useduris:
  229.                 if rule.prefix or None not in useduris:
  230.                     continue
  231.                 
  232.             cssText = rule.cssText
  233.             if cssText:
  234.                 out.append(cssText)
  235.                 continue
  236.         
  237.         text = self._linenumnbers(self.prefs.lineSeparator.join(out))
  238.         
  239.         try:
  240.             encoding = stylesheet.cssRules[0].encoding
  241.         except (IndexError, AttributeError):
  242.             encoding = 'UTF-8'
  243.  
  244.         return text.encode(encoding, 'escapecss')
  245.  
  246.     
  247.     def do_CSSComment(self, rule):
  248.         if rule._cssText and self.prefs.keepComments:
  249.             return rule._cssText
  250.         return u''
  251.  
  252.     
  253.     def do_CSSCharsetRule(self, rule):
  254.         if rule.wellformed:
  255.             return u'@charset %s;' % helper.string(rule.encoding)
  256.         return u''
  257.  
  258.     
  259.     def do_CSSVariablesRule(self, rule):
  260.         variablesText = rule.variables.cssText
  261.         if variablesText and rule.wellformed:
  262.             out = Out(self)
  263.             out.append(self._atkeyword(rule, u'@variables'))
  264.             for item in rule.seq:
  265.                 out.append(item.value, item.type)
  266.             
  267.             out.append(u'{')
  268.             out.append(u'%s%s}' % (variablesText, self.prefs.lineSeparator), indent = 1)
  269.             return out.value()
  270.         return u''
  271.  
  272.     
  273.     def do_CSSFontFaceRule(self, rule):
  274.         styleText = self.do_css_CSSStyleDeclaration(rule.style)
  275.         if styleText and rule.wellformed:
  276.             out = Out(self)
  277.             out.append(self._atkeyword(rule, u'@font-face'))
  278.             for item in rule.seq:
  279.                 out.append(item.value, item.type)
  280.             
  281.             out.append(u'{')
  282.             out.append(u'%s%s}' % (styleText, self.prefs.lineSeparator), indent = 1)
  283.             return out.value()
  284.         return u''
  285.  
  286.     
  287.     def do_CSSImportRule(self, rule):
  288.         if rule.wellformed:
  289.             out = Out(self)
  290.             out.append(self._atkeyword(rule, u'@import'))
  291.             for item in rule.seq:
  292.                 typ = item.type
  293.                 val = item.value
  294.                 if 'href' == typ:
  295.                     if (self.prefs.importHrefFormat == 'string' or self.prefs.importHrefFormat != 'uri') and rule.hreftype == 'string':
  296.                         out.append(val, 'STRING')
  297.                     else:
  298.                         out.append(val, 'URI')
  299.                 rule.hreftype == 'string'
  300.                 if 'media' == typ:
  301.                     mediaText = self.do_stylesheets_medialist(val)
  302.                     if mediaText and mediaText != u'all':
  303.                         out.append(mediaText)
  304.                     
  305.                 mediaText != u'all'
  306.                 if 'name' == typ:
  307.                     out.append(val, 'STRING')
  308.                     continue
  309.                 out.append(val, typ)
  310.             
  311.             return out.value(end = u';')
  312.         return u''
  313.  
  314.     
  315.     def do_CSSNamespaceRule(self, rule):
  316.         if rule.wellformed:
  317.             out = Out(self)
  318.             out.append(self._atkeyword(rule, u'@namespace'))
  319.             for item in rule.seq:
  320.                 typ = item.type
  321.                 val = item.value
  322.                 if 'namespaceURI' == typ:
  323.                     out.append(val, 'STRING')
  324.                     continue
  325.                 out.append(val, typ)
  326.             
  327.             return out.value(end = u';')
  328.         return u''
  329.  
  330.     
  331.     def do_CSSMediaRule(self, rule):
  332.         if not rule.media.wellformed:
  333.             return u''
  334.         out = [
  335.             self._atkeyword(rule, u'@media')]
  336.         if not len(self.prefs.spacer):
  337.             out.append(u' ')
  338.         else:
  339.             out.append(self.prefs.spacer)
  340.         out.append(self.do_stylesheets_medialist(rule.media))
  341.         if rule.name:
  342.             out.append(self.prefs.spacer)
  343.             nameout = Out(self)
  344.             nameout.append(helper.string(rule.name))
  345.             for item in rule.seq:
  346.                 nameout.append(item.value, item.type)
  347.             
  348.             out.append(nameout.value())
  349.         
  350.         out.append(self.prefs.paranthesisSpacer)
  351.         out.append(u'{')
  352.         out.append(self.prefs.lineSeparator)
  353.         rulesout = []
  354.         for r in rule.cssRules:
  355.             rtext = r.cssText
  356.             if rtext:
  357.                 rulesout.append(self._indentblock(rtext, self._level + 1))
  358.                 rulesout.append(self.prefs.lineSeparator)
  359.                 continue
  360.         
  361.         if not (self.prefs.keepEmptyRules) and not u''.join(rulesout).strip():
  362.             return u''
  363.         out.extend(rulesout)
  364.         out.append(u'%s}' % (self._level + 1) * self.prefs.indent)
  365.         return u''.join(out)
  366.  
  367.     
  368.     def do_CSSPageRule(self, rule):
  369.         styleText = self.do_css_CSSStyleDeclaration(rule.style)
  370.         if styleText and rule.wellformed:
  371.             out = Out(self)
  372.             out.append(self._atkeyword(rule, u'@page'))
  373.             out.append(rule.selectorText)
  374.             out.append(u'{')
  375.             out.append(u'%s%s}' % (styleText, self.prefs.lineSeparator), indent = 1)
  376.             return out.value()
  377.         return u''
  378.  
  379.     
  380.     def do_CSSPageRuleSelector(self, seq):
  381.         out = Out(self)
  382.         for item in seq:
  383.             if item.type == 'IDENT':
  384.                 out.append(item.value, item.type, space = False)
  385.                 continue
  386.             out.append(item.value, item.type)
  387.         
  388.         return out.value()
  389.  
  390.     
  391.     def do_CSSUnknownRule(self, rule):
  392.         if rule.wellformed and self.prefs.keepUnkownAtRules:
  393.             out = Out(self)
  394.             out.append(rule.atkeyword)
  395.             stacks = []
  396.             for item in rule.seq:
  397.                 typ = item.type
  398.                 val = item.value
  399.                 if u'}' == val:
  400.                     stackblock = stacks.pop().value()
  401.                     if stackblock:
  402.                         val = self._indentblock(stackblock + self.prefs.lineSeparator + val, min(1, len(stacks) + 1))
  403.                     else:
  404.                         val = self._indentblock(val, min(1, len(stacks) + 1))
  405.                 
  406.                 if stacks:
  407.                     stacks[-1].append(val, typ)
  408.                 else:
  409.                     out.append(val, typ)
  410.                 if u'{' == val:
  411.                     stacks.append(Out(self))
  412.                     continue
  413.             
  414.             return out.value()
  415.         return u''
  416.  
  417.     
  418.     def do_CSSStyleRule(self, rule):
  419.         selectorText = self.do_css_SelectorList(rule.selectorList)
  420.         if not selectorText or not (rule.wellformed):
  421.             return u''
  422.         self._level += 1
  423.         styleText = u''
  424.         
  425.         try:
  426.             styleText = self.do_css_CSSStyleDeclaration(rule.style)
  427.         finally:
  428.             self._level -= 1
  429.  
  430.         if not styleText:
  431.             if self.prefs.keepEmptyRules:
  432.                 return u'%s%s{}' % (selectorText, self.prefs.paranthesisSpacer)
  433.         else:
  434.             return self._indentblock(u'%s%s{%s%s%s%s}' % (selectorText, self.prefs.paranthesisSpacer, self.prefs.lineSeparator, self._indentblock(styleText, self._level + 1), self.prefs.lineSeparator, (self._level + 1) * self.prefs.indent), self._selectorlevel)
  435.         return self.prefs.keepEmptyRules
  436.  
  437.     
  438.     def do_css_SelectorList(self, selectorlist):
  439.         if selectorlist.wellformed:
  440.             out = []
  441.             for part in selectorlist.seq:
  442.                 if isinstance(part, cssutils.css.Selector):
  443.                     out.append(part.selectorText)
  444.                     continue
  445.                 out.append(part)
  446.             
  447.             sep = u',%s' % self.prefs.listItemSpacer
  448.             return sep.join(out)
  449.         return u''
  450.  
  451.     
  452.     def do_css_Selector(self, selector):
  453.         if selector.wellformed:
  454.             out = Out(self)
  455.             DEFAULTURI = selector._namespaces.get('', None)
  456.             for item in selector.seq:
  457.                 typ = item.type
  458.                 val = item.value
  459.                 if type(val) == tuple:
  460.                     (namespaceURI, name) = val
  461.                     if (DEFAULTURI == namespaceURI or not DEFAULTURI) and namespaceURI is None:
  462.                         out.append(name, typ, space = False)
  463.                     elif namespaceURI == cssutils._ANYNS:
  464.                         prefix = u'*'
  465.                     else:
  466.                         
  467.                         try:
  468.                             prefix = selector._namespaces.prefixForNamespaceURI(namespaceURI)
  469.                         except IndexError:
  470.                             prefix = u''
  471.  
  472.                     out.append(u'%s|%s' % (prefix, name), typ, space = False)
  473.                     continue
  474.                 out.append(val, typ, space = False, keepS = True)
  475.             
  476.             return out.value()
  477.         return u''
  478.  
  479.     
  480.     def do_css_CSSVariablesDeclaration(self, variables):
  481.         if len(variables.seq) > 0:
  482.             out = Out(self)
  483.             lastitem = len(variables.seq) - 1
  484.             for i, item in enumerate(variables.seq):
  485.                 type_ = item.type
  486.                 val = item.value
  487.                 if u'var' == type_:
  488.                     (name, cssvalue) = val
  489.                     out.append(name)
  490.                     out.append(u':')
  491.                     out.append(cssvalue.cssText)
  492.                     if i < lastitem or not (self.prefs.omitLastSemicolon):
  493.                         out.append(u';')
  494.                     
  495.                 not (self.prefs.omitLastSemicolon)
  496.                 if isinstance(val, cssutils.css.CSSComment):
  497.                     out.append(val, 'COMMENT')
  498.                     out.append(self.prefs.lineSeparator)
  499.                     continue
  500.                 out.append(val.cssText, type_)
  501.                 out.append(self.prefs.lineSeparator)
  502.             
  503.             return out.value().strip()
  504.         return u''
  505.  
  506.     
  507.     def do_css_CSSStyleDeclaration(self, style, separator = None):
  508.         if len(style.seq) > 0:
  509.             if separator is None:
  510.                 separator = self.prefs.lineSeparator
  511.             
  512.             out = []
  513.             for i, item in enumerate(seq):
  514.                 typ = item.type
  515.                 val = item.value
  516.                 if isinstance(val, cssutils.css.CSSComment):
  517.                     if self.prefs.keepComments:
  518.                         out.append(val.cssText)
  519.                         out.append(separator)
  520.                     
  521.                 self.prefs.keepComments
  522.                 if isinstance(val, cssutils.css.Property):
  523.                     if val.cssText:
  524.                         out.append(val.cssText)
  525.                         if not self.prefs.omitLastSemicolon and i == len(seq) - 1:
  526.                             out.append(u';')
  527.                         
  528.                         out.append(separator)
  529.                     
  530.                 val.cssText
  531.                 if isinstance(val, cssutils.css.CSSUnknownRule):
  532.                     out.append(val.cssText)
  533.                     out.append(separator)
  534.                     continue
  535.                 [] if self.prefs.keepAllProperties else []
  536.                 out.append(val)
  537.                 out.append(separator)
  538.             
  539.             if out and out[-1] == separator:
  540.                 del out[-1]
  541.             
  542.             return u''.join(out)
  543.         return u''
  544.  
  545.     
  546.     def do_Property(self, property):
  547.         out = []
  548.         if property.seqs[0] and property.wellformed and self._valid(property):
  549.             (nameseq, cssvalue, priorityseq) = property.seqs
  550.             for part in nameseq:
  551.                 if hasattr(part, 'cssText'):
  552.                     out.append(part.cssText)
  553.                     continue
  554.                 if property.literalname == part:
  555.                     out.append(self._propertyname(property, part))
  556.                     continue
  557.                 out.append(part)
  558.             
  559.             if out:
  560.                 if (not (property._mediaQuery) or property._mediaQuery) and cssvalue.cssText:
  561.                     out.append(u':')
  562.                     out.append(self.prefs.propertyNameSpacer)
  563.                 
  564.             out.append(cssvalue.cssText)
  565.             if out and priorityseq:
  566.                 out.append(u' ')
  567.                 for part in priorityseq:
  568.                     if hasattr(part, 'cssText'):
  569.                         out.append(part.cssText)
  570.                         continue
  571.                     if part == property.literalpriority and self.prefs.defaultPropertyPriority:
  572.                         out.append(property.priority)
  573.                         continue
  574.                     out.append(part)
  575.                 
  576.             
  577.         
  578.         return u''.join(out)
  579.  
  580.     
  581.     def do_Property_priority(self, priorityseq):
  582.         out = []
  583.         for part in priorityseq:
  584.             if hasattr(part, 'cssText'):
  585.                 out.append(u' ')
  586.                 out.append(part.cssText)
  587.                 out.append(u' ')
  588.                 continue
  589.             out.append(part)
  590.         
  591.         return u''.join(out).strip()
  592.  
  593.     
  594.     def do_css_CSSValue(self, cssvalue):
  595.         if not cssvalue:
  596.             return u''
  597.         out = Out(self)
  598.         for item in cssvalue.seq:
  599.             type_ = item.type
  600.             val = item.value
  601.             if hasattr(val, 'cssText'):
  602.                 out.append(val.cssText, type_)
  603.                 continue
  604.             cssvalue
  605.             if val and val[0] == val[-1] and val[0] in '\'"':
  606.                 val = helper.string(val[1:-1])
  607.             
  608.             out.append(val, type_)
  609.         
  610.         return out.value()
  611.  
  612.     
  613.     def do_css_CSSPrimitiveValue(self, cssvalue):
  614.         if not cssvalue:
  615.             return u''
  616.         out = Out(self)
  617.         for item in cssvalue.seq:
  618.             type_ = item.type
  619.             val = item.value
  620.             if type_ in ('DIMENSION', 'NUMBER', 'PERCENTAGE'):
  621.                 (n, d) = cssvalue._getNumDim(val)
  622.                 if 0 == n:
  623.                     if cssvalue.primitiveType in cssvalue._lengthtypes:
  624.                         val = u'0'
  625.                     else:
  626.                         val = u'0' + d
  627.                 else:
  628.                     val = unicode(n) + d
  629.             
  630.             out.append(val, type_)
  631.         
  632.         return out.value()
  633.  
  634.     
  635.     def do_css_CSSVariable(self, variable):
  636.         if not variable:
  637.             return u''
  638.         out = Out(self)
  639.         for item in variable.seq:
  640.             type_ = item.type
  641.             val = item.value
  642.             out.append(val, type_)
  643.         
  644.         return out.value()
  645.  
  646.     
  647.     def do_css_RGBColor(self, cssvalue):
  648.         if not cssvalue:
  649.             return u''
  650.         out = Out(self)
  651.         unary = None
  652.         for item in cssvalue.seq:
  653.             type_ = item.type
  654.             val = item.value
  655.             out.append(val, type_)
  656.         
  657.         return out.value()
  658.  
  659.     
  660.     def do_stylesheets_medialist(self, medialist):
  661.         if len(medialist) == 0:
  662.             return u'all'
  663.         sep = u',%s' % self.prefs.listItemSpacer
  664.         return sep.join((lambda .0: for mq in .0:
  665. mq.mediaText)(medialist))
  666.  
  667.     
  668.     def do_stylesheets_mediaquery(self, mediaquery):
  669.         if mediaquery.wellformed:
  670.             out = []
  671.             for part in mediaquery.seq:
  672.                 if isinstance(part, cssutils.css.Property):
  673.                     out.append(u'(%s)' % part.cssText)
  674.                     continue
  675.                 if hasattr(part, 'cssText'):
  676.                     out.append(part.cssText)
  677.                     continue
  678.                 out.append(part)
  679.             
  680.             return u' '.join(out)
  681.         return u''
  682.  
  683.     
  684.     def do_css_ExpressionValue(self, cssvalue):
  685.         if not cssvalue:
  686.             return u''
  687.         out = Out(self)
  688.         for item in cssvalue.seq:
  689.             type_ = item.type
  690.             val = item.value
  691.             if type_ in ('DIMENSION', 'NUMBER', 'PERCENTAGE'):
  692.                 (n, d) = cssvalue._getNumDim(val)
  693.                 if 0 == n:
  694.                     if cssvalue.primitiveType in cssvalue._lengthtypes:
  695.                         val = u'0'
  696.                     else:
  697.                         val = u'0' + d
  698.                 else:
  699.                     val = unicode(n) + d
  700.             
  701.             out.append(val, None, space = False)
  702.         
  703.         return out.value()
  704.  
  705.  
  706.