mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Update bundled version of cssutils. Fixes #3162 (Calibre does not support complete font-face standard)
This commit is contained in:
parent
976b3139db
commit
b1c8d3d9a9
@ -88,7 +88,7 @@ _magick_error = None
|
|||||||
try:
|
try:
|
||||||
_magick = ctypes.CDLL(_lib)
|
_magick = ctypes.CDLL(_lib)
|
||||||
except Exception, err:
|
except Exception, err:
|
||||||
global _magick_error
|
#global _magick_error
|
||||||
_magick_error = str(err)
|
_magick_error = str(err)
|
||||||
|
|
||||||
_initialized = False
|
_initialized = False
|
||||||
|
@ -70,11 +70,11 @@ Usage may be::
|
|||||||
__all__ = ['css', 'stylesheets', 'CSSParser', 'CSSSerializer']
|
__all__ = ['css', 'stylesheets', 'CSSParser', 'CSSSerializer']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__author__ = 'Christof Hoeke with contributions by Walter Doerwald'
|
__author__ = 'Christof Hoeke with contributions by Walter Doerwald'
|
||||||
__date__ = '$LastChangedDate:: 2009-05-09 13:59:54 -0700 #$:'
|
__date__ = '$LastChangedDate:: 2009-08-01 16:10:11 -0600 #$:'
|
||||||
|
|
||||||
VERSION = '0.9.6a5'
|
VERSION = '0.9.6b3'
|
||||||
|
|
||||||
__version__ = '%s $Id: __init__.py 1747 2009-05-09 20:59:54Z cthedot $' % VERSION
|
__version__ = '%s $Id: __init__.py 1832 2009-08-01 22:10:11Z cthedot $' % VERSION
|
||||||
|
|
||||||
import codec
|
import codec
|
||||||
import xml.dom
|
import xml.dom
|
||||||
@ -165,6 +165,23 @@ def parse(*a, **k):
|
|||||||
return parseFile(*a, **k)
|
return parseFile(*a, **k)
|
||||||
parse.__doc__ = CSSParser.parse.__doc__
|
parse.__doc__ = CSSParser.parse.__doc__
|
||||||
|
|
||||||
|
def parseStyle(cssText, encoding='utf-8'):
|
||||||
|
"""Parse given `cssText` which is assumed to be the content of
|
||||||
|
a HTML style attribute.
|
||||||
|
|
||||||
|
:param cssText:
|
||||||
|
CSS string to parse
|
||||||
|
:param encoding:
|
||||||
|
It will be used to decode `cssText` if given as a (byte)
|
||||||
|
string.
|
||||||
|
:returns:
|
||||||
|
:class:`~cssutils.css.CSSStyleDeclaration`
|
||||||
|
"""
|
||||||
|
if isinstance(cssText, str):
|
||||||
|
cssText = cssText.decode(encoding)
|
||||||
|
style = css.CSSStyleDeclaration()
|
||||||
|
style.cssText = cssText
|
||||||
|
return style
|
||||||
|
|
||||||
# set "ser", default serializer
|
# set "ser", default serializer
|
||||||
def setSerializer(serializer):
|
def setSerializer(serializer):
|
||||||
@ -172,7 +189,6 @@ def setSerializer(serializer):
|
|||||||
global ser
|
global ser
|
||||||
ser = serializer
|
ser = serializer
|
||||||
|
|
||||||
|
|
||||||
def getUrls(sheet):
|
def getUrls(sheet):
|
||||||
"""Retrieve all ``url(urlstring)`` values (in e.g.
|
"""Retrieve all ``url(urlstring)`` values (in e.g.
|
||||||
:class:`cssutils.css.CSSImportRule` or :class:`cssutils.css.CSSValue`
|
:class:`cssutils.css.CSSImportRule` or :class:`cssutils.css.CSSValue`
|
||||||
@ -284,5 +300,6 @@ def resolveImports(sheet, target=None):
|
|||||||
target.add(rule)
|
target.add(rule)
|
||||||
return target
|
return target
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print __doc__
|
print __doc__
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
"""Default URL reading functions"""
|
"""Default URL reading functions"""
|
||||||
__all__ = ['_defaultFetcher', '_readUrl']
|
__all__ = ['_defaultFetcher']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: tokenize2.py 1547 2008-12-10 20:42:26Z cthedot $'
|
__version__ = '$Id: tokenize2.py 1547 2008-12-10 20:42:26Z cthedot $'
|
||||||
|
|
||||||
|
from cssutils import VERSION
|
||||||
import encutils
|
import encutils
|
||||||
import errorhandler
|
import errorhandler
|
||||||
import urllib2
|
import urllib2
|
||||||
@ -16,8 +17,11 @@ def _defaultFetcher(url):
|
|||||||
|
|
||||||
Returns ``(encoding, string)`` or ``None``
|
Returns ``(encoding, string)`` or ``None``
|
||||||
"""
|
"""
|
||||||
|
request = urllib2.Request(url)
|
||||||
|
request.add_header('User-agent',
|
||||||
|
'cssutils %s (http://www.cthedot.de/cssutils/)' % VERSION)
|
||||||
try:
|
try:
|
||||||
res = urllib2.urlopen(url)
|
res = urllib2.urlopen(request)
|
||||||
except OSError, e:
|
except OSError, e:
|
||||||
# e.g if file URL and not found
|
# e.g if file URL and not found
|
||||||
log.warn(e, error=OSError)
|
log.warn(e, error=OSError)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
"""GAE specific URL reading functions"""
|
"""GAE specific URL reading functions"""
|
||||||
__all__ = ['_defaultFetcher', '_readUrl']
|
__all__ = ['_defaultFetcher']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: tokenize2.py 1547 2008-12-10 20:42:26Z cthedot $'
|
__version__ = '$Id: tokenize2.py 1547 2008-12-10 20:42:26Z cthedot $'
|
||||||
|
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
"""CSSFontFaceRule implements DOM Level 2 CSS CSSFontFaceRule.
|
"""CSSFontFaceRule implements DOM Level 2 CSS CSSFontFaceRule.
|
||||||
|
|
||||||
|
From cssutils 0.9.6 additions from CSS Fonts Module Level 3 are
|
||||||
|
added http://www.w3.org/TR/css3-fonts/.
|
||||||
"""
|
"""
|
||||||
__all__ = ['CSSFontFaceRule']
|
__all__ = ['CSSFontFaceRule']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: cssfontfacerule.py 1638 2009-01-13 20:39:33Z cthedot $'
|
__version__ = '$Id: cssfontfacerule.py 1818 2009-07-30 21:39:00Z cthedot $'
|
||||||
|
|
||||||
from cssstyledeclaration import CSSStyleDeclaration
|
from cssstyledeclaration import CSSStyleDeclaration
|
||||||
import cssrule
|
import cssrule
|
||||||
@ -21,6 +24,11 @@ class CSSFontFaceRule(cssrule.CSSRule):
|
|||||||
: FONT_FACE_SYM S*
|
: FONT_FACE_SYM S*
|
||||||
'{' S* declaration [ ';' S* declaration ]* '}' S*
|
'{' S* declaration [ ';' S* declaration ]* '}' S*
|
||||||
;
|
;
|
||||||
|
|
||||||
|
cssutils uses a :class:`~cssutils.css.CSSStyleDeclaration` to
|
||||||
|
represent the font descriptions. For validation a specific profile
|
||||||
|
is used though were some properties have other valid values than
|
||||||
|
when used in e.g. a :class:`~cssutils.css.CSSStyleRule`.
|
||||||
"""
|
"""
|
||||||
def __init__(self, style=None, parentRule=None,
|
def __init__(self, style=None, parentRule=None,
|
||||||
parentStyleSheet=None, readonly=False):
|
parentStyleSheet=None, readonly=False):
|
||||||
@ -28,15 +36,15 @@ class CSSFontFaceRule(cssrule.CSSRule):
|
|||||||
If readonly allows setting of properties in constructor only.
|
If readonly allows setting of properties in constructor only.
|
||||||
|
|
||||||
:param style:
|
:param style:
|
||||||
CSSStyleDeclaration for this CSSStyleRule
|
CSSStyleDeclaration used to hold any font descriptions
|
||||||
|
for this CSSFontFaceRule
|
||||||
"""
|
"""
|
||||||
super(CSSFontFaceRule, self).__init__(parentRule=parentRule,
|
super(CSSFontFaceRule, self).__init__(parentRule=parentRule,
|
||||||
parentStyleSheet=parentStyleSheet)
|
parentStyleSheet=parentStyleSheet)
|
||||||
self._atkeyword = u'@font-face'
|
self._atkeyword = u'@font-face'
|
||||||
|
self._style = CSSStyleDeclaration(parentRule=self)
|
||||||
if style:
|
if style:
|
||||||
self.style = style
|
self.style = style
|
||||||
else:
|
|
||||||
self._style = CSSStyleDeclaration(parentRule=self)
|
|
||||||
|
|
||||||
self._readonly = readonly
|
self._readonly = readonly
|
||||||
|
|
||||||
@ -45,8 +53,9 @@ class CSSFontFaceRule(cssrule.CSSRule):
|
|||||||
self.__class__.__name__, self.style.cssText)
|
self.__class__.__name__, self.style.cssText)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return "<cssutils.css.%s object style=%r at 0x%x>" % (
|
return "<cssutils.css.%s object style=%r valid=%r at 0x%x>" % (
|
||||||
self.__class__.__name__, self.style.cssText, id(self))
|
self.__class__.__name__, self.style.cssText, self.valid,
|
||||||
|
id(self))
|
||||||
|
|
||||||
def _getCssText(self):
|
def _getCssText(self):
|
||||||
"""Return serialized property cssText."""
|
"""Return serialized property cssText."""
|
||||||
@ -112,15 +121,22 @@ class CSSFontFaceRule(cssrule.CSSRule):
|
|||||||
self._log.error(u'CSSFontFaceRule: Trailing content found.',
|
self._log.error(u'CSSFontFaceRule: Trailing content found.',
|
||||||
token=nonetoken)
|
token=nonetoken)
|
||||||
|
|
||||||
newstyle = CSSStyleDeclaration()
|
teststyle = CSSStyleDeclaration(parentRule=self)
|
||||||
if 'EOF' == typ:
|
if 'EOF' == typ:
|
||||||
# add again as style needs it
|
# add again as style needs it
|
||||||
styletokens.append(braceorEOFtoken)
|
styletokens.append(braceorEOFtoken)
|
||||||
newstyle.cssText = styletokens
|
# may raise:
|
||||||
|
teststyle.cssText = styletokens
|
||||||
|
|
||||||
if wellformed:
|
if wellformed:
|
||||||
self.style = newstyle
|
# contains probably comments only upto {
|
||||||
self._setSeq(newseq) # contains (probably comments) upto { only
|
self._setSeq(newseq)
|
||||||
|
|
||||||
|
# known as correct from before
|
||||||
|
cssutils.log.enabled = False
|
||||||
|
self.style.cssText = styletokens
|
||||||
|
cssutils.log.enabled = True
|
||||||
|
|
||||||
|
|
||||||
cssText = property(_getCssText, _setCssText,
|
cssText = property(_getCssText, _setCssText,
|
||||||
doc="(DOM) The parsable textual representation of this rule.")
|
doc="(DOM) The parsable textual representation of this rule.")
|
||||||
@ -132,9 +148,10 @@ class CSSFontFaceRule(cssrule.CSSRule):
|
|||||||
"""
|
"""
|
||||||
self._checkReadonly()
|
self._checkReadonly()
|
||||||
if isinstance(style, basestring):
|
if isinstance(style, basestring):
|
||||||
self._style = CSSStyleDeclaration(parentRule=self, cssText=style)
|
self._style.cssText = style
|
||||||
else:
|
else:
|
||||||
self._style._seq = style.seq
|
self._style = style
|
||||||
|
self._style.parentRule = self
|
||||||
|
|
||||||
style = property(lambda self: self._style, _setStyle,
|
style = property(lambda self: self._style, _setStyle,
|
||||||
doc="(DOM) The declaration-block of this rule set, "
|
doc="(DOM) The declaration-block of this rule set, "
|
||||||
@ -144,5 +161,20 @@ class CSSFontFaceRule(cssrule.CSSRule):
|
|||||||
doc="The type of this rule, as defined by a CSSRule "
|
doc="The type of this rule, as defined by a CSSRule "
|
||||||
"type constant.")
|
"type constant.")
|
||||||
|
|
||||||
|
def _getValid(self):
|
||||||
|
needed = ['font-family', 'src']
|
||||||
|
for p in self.style.getProperties(all=True):
|
||||||
|
if not p.valid:
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
needed.remove(p.name)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
return not bool(needed)
|
||||||
|
|
||||||
|
valid = property(_getValid, doc='CSSFontFace is valid if properties '
|
||||||
|
'`font-family` and `src` are set and all properties are '
|
||||||
|
'valid.')
|
||||||
|
|
||||||
# constant but needed:
|
# constant but needed:
|
||||||
wellformed = property(lambda self: True)
|
wellformed = property(lambda self: True)
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
"""CSSImportRule implements DOM Level 2 CSS CSSImportRule plus the
|
"""CSSImportRule implements DOM Level 2 CSS CSSImportRule plus the
|
||||||
``name`` property from http://www.w3.org/TR/css3-cascade/#cascading.
|
``name`` property from http://www.w3.org/TR/css3-cascade/#cascading."""
|
||||||
|
|
||||||
"""
|
|
||||||
__all__ = ['CSSImportRule']
|
__all__ = ['CSSImportRule']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: cssimportrule.py 1638 2009-01-13 20:39:33Z cthedot $'
|
__version__ = '$Id: cssimportrule.py 1824 2009-08-01 21:00:34Z cthedot $'
|
||||||
|
|
||||||
import cssrule
|
import cssrule
|
||||||
import cssutils
|
import cssutils
|
||||||
@ -320,7 +318,8 @@ class CSSImportRule(cssrule.CSSRule):
|
|||||||
parentHref = self.parentStyleSheet.href
|
parentHref = self.parentStyleSheet.href
|
||||||
if parentHref is None:
|
if parentHref is None:
|
||||||
# use cwd instead
|
# use cwd instead
|
||||||
parentHref = u'file:' + urllib.pathname2url(os.getcwd()) + '/'
|
#parentHref = u'file:' + urllib.pathname2url(os.getcwd()) + '/'
|
||||||
|
parentHref = cssutils.helper.path2url(os.getcwd()) + '/'
|
||||||
href = urlparse.urljoin(parentHref, self.href)
|
href = urlparse.urljoin(parentHref, self.href)
|
||||||
|
|
||||||
# all possible exceptions are ignored (styleSheet is None then)
|
# all possible exceptions are ignored (styleSheet is None then)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""CSSMediaRule implements DOM Level 2 CSS CSSMediaRule."""
|
"""CSSMediaRule implements DOM Level 2 CSS CSSMediaRule."""
|
||||||
__all__ = ['CSSMediaRule']
|
__all__ = ['CSSMediaRule']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: cssmediarule.py 1743 2009-05-09 20:33:15Z cthedot $'
|
__version__ = '$Id: cssmediarule.py 1820 2009-08-01 20:53:08Z cthedot $'
|
||||||
|
|
||||||
import cssrule
|
import cssrule
|
||||||
import cssutils
|
import cssutils
|
||||||
@ -34,15 +34,11 @@ class CSSMediaRule(cssrule.CSSRule):
|
|||||||
readonly=readonly)
|
readonly=readonly)
|
||||||
self.name = name
|
self.name = name
|
||||||
self.cssRules = cssutils.css.cssrulelist.CSSRuleList()
|
self.cssRules = cssutils.css.cssrulelist.CSSRuleList()
|
||||||
self.cssRules.append = self.insertRule
|
|
||||||
self.cssRules.extend = self.insertRule
|
|
||||||
self.cssRules.__delitem__ == self.deleteRule
|
|
||||||
|
|
||||||
self._readonly = readonly
|
self._readonly = readonly
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"""Generator iterating over these rule's cssRules."""
|
"""Generator iterating over these rule's cssRules."""
|
||||||
for rule in self.cssRules:
|
for rule in self._cssRules:
|
||||||
yield rule
|
yield rule
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -53,6 +49,20 @@ class CSSMediaRule(cssrule.CSSRule):
|
|||||||
return "<cssutils.css.%s object mediaText=%r at 0x%x>" % (
|
return "<cssutils.css.%s object mediaText=%r at 0x%x>" % (
|
||||||
self.__class__.__name__, self.media.mediaText, id(self))
|
self.__class__.__name__, self.media.mediaText, id(self))
|
||||||
|
|
||||||
|
def _setCssRules(self, cssRules):
|
||||||
|
"Set new cssRules and update contained rules refs."
|
||||||
|
cssRules.append = self.insertRule
|
||||||
|
cssRules.extend = self.insertRule
|
||||||
|
cssRules.__delitem__ == self.deleteRule
|
||||||
|
for rule in cssRules:
|
||||||
|
rule._parentStyleSheet = self.parentStyleSheet
|
||||||
|
rule._parentRule = self
|
||||||
|
self._cssRules = cssRules
|
||||||
|
|
||||||
|
cssRules = property(lambda self: self._cssRules, _setCssRules,
|
||||||
|
"All Rules in this style sheet, a "
|
||||||
|
":class:`~cssutils.css.CSSRuleList`.")
|
||||||
|
|
||||||
def _getCssText(self):
|
def _getCssText(self):
|
||||||
"""Return serialized property cssText."""
|
"""Return serialized property cssText."""
|
||||||
return cssutils.ser.do_CSSMediaRule(self)
|
return cssutils.ser.do_CSSMediaRule(self)
|
||||||
@ -204,9 +214,9 @@ class CSSMediaRule(cssrule.CSSRule):
|
|||||||
self._media.mediaText = newmedia.mediaText
|
self._media.mediaText = newmedia.mediaText
|
||||||
self.name = name
|
self.name = name
|
||||||
self._setSeq(nameseq)
|
self._setSeq(nameseq)
|
||||||
del self.cssRules[:]
|
del self._cssRules[:]
|
||||||
for r in newcssrules:
|
for r in newcssrules:
|
||||||
self.cssRules.append(r)
|
self._cssRules.append(r)
|
||||||
|
|
||||||
cssText = property(_getCssText, _setCssText,
|
cssText = property(_getCssText, _setCssText,
|
||||||
doc="(DOM) The parsable textual representation of this rule.")
|
doc="(DOM) The parsable textual representation of this rule.")
|
||||||
@ -245,12 +255,12 @@ class CSSMediaRule(cssrule.CSSRule):
|
|||||||
self._checkReadonly()
|
self._checkReadonly()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.cssRules[index]._parentRule = None # detach
|
self._cssRules[index]._parentRule = None # detach
|
||||||
del self.cssRules[index] # remove from @media
|
del self._cssRules[index] # remove from @media
|
||||||
except IndexError:
|
except IndexError:
|
||||||
raise xml.dom.IndexSizeErr(
|
raise xml.dom.IndexSizeErr(
|
||||||
u'CSSMediaRule: %s is not a valid index in the rulelist of length %i' % (
|
u'CSSMediaRule: %s is not a valid index in the rulelist of length %i' % (
|
||||||
index, self.cssRules.length))
|
index, self._cssRules.length))
|
||||||
|
|
||||||
def add(self, rule):
|
def add(self, rule):
|
||||||
"""Add `rule` to end of this mediarule.
|
"""Add `rule` to end of this mediarule.
|
||||||
@ -300,11 +310,11 @@ class CSSMediaRule(cssrule.CSSRule):
|
|||||||
|
|
||||||
# check position
|
# check position
|
||||||
if index is None:
|
if index is None:
|
||||||
index = len(self.cssRules)
|
index = len(self._cssRules)
|
||||||
elif index < 0 or index > self.cssRules.length:
|
elif index < 0 or index > self._cssRules.length:
|
||||||
raise xml.dom.IndexSizeErr(
|
raise xml.dom.IndexSizeErr(
|
||||||
u'CSSMediaRule: Invalid index %s for CSSRuleList with a length of %s.' % (
|
u'CSSMediaRule: Invalid index %s for CSSRuleList with a length of %s.' % (
|
||||||
index, self.cssRules.length))
|
index, self._cssRules.length))
|
||||||
|
|
||||||
# parse
|
# parse
|
||||||
if isinstance(rule, basestring):
|
if isinstance(rule, basestring):
|
||||||
@ -315,6 +325,13 @@ class CSSMediaRule(cssrule.CSSRule):
|
|||||||
self._log.error(u'CSSMediaRule: Invalid Rule: %s' % rule)
|
self._log.error(u'CSSMediaRule: Invalid Rule: %s' % rule)
|
||||||
return
|
return
|
||||||
rule = tempsheet.cssRules[0]
|
rule = tempsheet.cssRules[0]
|
||||||
|
|
||||||
|
elif isinstance(rule, cssutils.css.CSSRuleList):
|
||||||
|
# insert all rules
|
||||||
|
for i, r in enumerate(rule):
|
||||||
|
self.insertRule(r, index + i)
|
||||||
|
return index
|
||||||
|
|
||||||
elif not isinstance(rule, cssutils.css.CSSRule):
|
elif not isinstance(rule, cssutils.css.CSSRule):
|
||||||
self._log.error(u'CSSMediaRule: Not a CSSRule: %s' % rule)
|
self._log.error(u'CSSMediaRule: Not a CSSRule: %s' % rule)
|
||||||
return
|
return
|
||||||
@ -332,7 +349,7 @@ class CSSMediaRule(cssrule.CSSRule):
|
|||||||
error=xml.dom.HierarchyRequestErr)
|
error=xml.dom.HierarchyRequestErr)
|
||||||
return
|
return
|
||||||
|
|
||||||
self.cssRules.insert(index, rule)
|
self._cssRules.insert(index, rule)
|
||||||
rule._parentRule = self
|
rule._parentRule = self
|
||||||
rule._parentStyleSheet = self.parentStyleSheet
|
rule._parentStyleSheet = self.parentStyleSheet
|
||||||
return index
|
return index
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
"""CSSPageRule implements DOM Level 2 CSS CSSPageRule.
|
"""CSSPageRule implements DOM Level 2 CSS CSSPageRule."""
|
||||||
"""
|
|
||||||
__all__ = ['CSSPageRule']
|
__all__ = ['CSSPageRule']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: csspagerule.py 1658 2009-02-07 18:24:40Z cthedot $'
|
__version__ = '$Id: csspagerule.py 1824 2009-08-01 21:00:34Z cthedot $'
|
||||||
|
|
||||||
from cssstyledeclaration import CSSStyleDeclaration
|
from cssstyledeclaration import CSSStyleDeclaration
|
||||||
from selectorlist import SelectorList
|
from selectorlist import SelectorList
|
||||||
@ -45,11 +44,12 @@ class CSSPageRule(cssrule.CSSRule):
|
|||||||
tempseq.append(self.selectorText, 'selectorText')
|
tempseq.append(self.selectorText, 'selectorText')
|
||||||
else:
|
else:
|
||||||
self._selectorText = self._tempSeq()
|
self._selectorText = self._tempSeq()
|
||||||
|
|
||||||
|
self._style = CSSStyleDeclaration(parentRule=self)
|
||||||
if style:
|
if style:
|
||||||
self.style = style
|
self.style = style
|
||||||
tempseq.append(self.style, 'style')
|
tempseq.append(self.style, 'style')
|
||||||
else:
|
|
||||||
self._style = CSSStyleDeclaration(parentRule=self)
|
|
||||||
self._setSeq(tempseq)
|
self._setSeq(tempseq)
|
||||||
|
|
||||||
self._readonly = readonly
|
self._readonly = readonly
|
||||||
@ -192,7 +192,7 @@ class CSSPageRule(cssrule.CSSRule):
|
|||||||
|
|
||||||
wellformed, newselectorseq = self.__parseSelectorText(selectortokens)
|
wellformed, newselectorseq = self.__parseSelectorText(selectortokens)
|
||||||
|
|
||||||
newstyle = CSSStyleDeclaration()
|
teststyle = CSSStyleDeclaration(parentRule=self)
|
||||||
val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken)
|
val, typ = self._tokenvalue(braceorEOFtoken), self._type(braceorEOFtoken)
|
||||||
if val != u'}' and typ != 'EOF':
|
if val != u'}' and typ != 'EOF':
|
||||||
wellformed = False
|
wellformed = False
|
||||||
@ -203,12 +203,14 @@ class CSSPageRule(cssrule.CSSRule):
|
|||||||
if 'EOF' == typ:
|
if 'EOF' == typ:
|
||||||
# add again as style needs it
|
# add again as style needs it
|
||||||
styletokens.append(braceorEOFtoken)
|
styletokens.append(braceorEOFtoken)
|
||||||
newstyle.cssText = styletokens
|
teststyle.cssText = styletokens
|
||||||
|
|
||||||
if wellformed:
|
if wellformed:
|
||||||
self._selectorText = newselectorseq # already parsed
|
# known as correct from before
|
||||||
self.style = newstyle
|
cssutils.log.enabled = False
|
||||||
self._setSeq(newselectorseq) # contains upto style only
|
self._selectorText = newselectorseq # TODO: TEST and REFS
|
||||||
|
self.style.cssText = styletokens
|
||||||
|
cssutils.log.enabled = True
|
||||||
|
|
||||||
cssText = property(_getCssText, _setCssText,
|
cssText = property(_getCssText, _setCssText,
|
||||||
doc="(DOM) The parsable textual representation of this rule.")
|
doc="(DOM) The parsable textual representation of this rule.")
|
||||||
@ -239,7 +241,7 @@ class CSSPageRule(cssrule.CSSRule):
|
|||||||
|
|
||||||
# may raise SYNTAX_ERR
|
# may raise SYNTAX_ERR
|
||||||
wellformed, newseq = self.__parseSelectorText(selectorText)
|
wellformed, newseq = self.__parseSelectorText(selectorText)
|
||||||
if wellformed and newseq:
|
if wellformed:
|
||||||
self._selectorText = newseq
|
self._selectorText = newseq
|
||||||
|
|
||||||
selectorText = property(_getSelectorText, _setSelectorText,
|
selectorText = property(_getSelectorText, _setSelectorText,
|
||||||
@ -251,19 +253,16 @@ class CSSPageRule(cssrule.CSSRule):
|
|||||||
a CSSStyleDeclaration or string
|
a CSSStyleDeclaration or string
|
||||||
"""
|
"""
|
||||||
self._checkReadonly()
|
self._checkReadonly()
|
||||||
|
|
||||||
if isinstance(style, basestring):
|
if isinstance(style, basestring):
|
||||||
self._style.cssText = style
|
self._style.cssText = style
|
||||||
else:
|
else:
|
||||||
# cssText would be serialized with optional preferences
|
self._style = style
|
||||||
# so use seq!
|
self._style.parentRule = self
|
||||||
self._style._seq = style.seq
|
|
||||||
|
|
||||||
style = property(lambda self: self._style, _setStyle,
|
style = property(lambda self: self._style, _setStyle,
|
||||||
doc="(DOM) The declaration-block of this rule set, "
|
doc="(DOM) The declaration-block of this rule set, "
|
||||||
"a :class:`~cssutils.css.CSSStyleDeclaration`.")
|
"a :class:`~cssutils.css.CSSStyleDeclaration`.")
|
||||||
|
|
||||||
|
|
||||||
type = property(lambda self: self.PAGE_RULE,
|
type = property(lambda self: self.PAGE_RULE,
|
||||||
doc="The type of this rule, as defined by a CSSRule "
|
doc="The type of this rule, as defined by a CSSRule "
|
||||||
"type constant.")
|
"type constant.")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""CSSRule implements DOM Level 2 CSS CSSRule."""
|
"""CSSRule implements DOM Level 2 CSS CSSRule."""
|
||||||
__all__ = ['CSSRule']
|
__all__ = ['CSSRule']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: cssrule.py 1638 2009-01-13 20:39:33Z cthedot $'
|
__version__ = '$Id: cssrule.py 1808 2009-07-29 13:09:36Z cthedot $'
|
||||||
|
|
||||||
import cssutils
|
import cssutils
|
||||||
import xml.dom
|
import xml.dom
|
||||||
@ -35,6 +35,7 @@ class CSSRule(cssutils.util.Base2):
|
|||||||
def __init__(self, parentRule=None, parentStyleSheet=None, readonly=False):
|
def __init__(self, parentRule=None, parentStyleSheet=None, readonly=False):
|
||||||
"""Set common attributes for all rules."""
|
"""Set common attributes for all rules."""
|
||||||
super(CSSRule, self).__init__()
|
super(CSSRule, self).__init__()
|
||||||
|
self._parent = parentRule
|
||||||
self._parentRule = parentRule
|
self._parentRule = parentRule
|
||||||
self._parentStyleSheet = parentStyleSheet
|
self._parentStyleSheet = parentStyleSheet
|
||||||
self._setSeq(self._tempSeq())
|
self._setSeq(self._tempSeq())
|
||||||
@ -78,6 +79,10 @@ class CSSRule(cssutils.util.Base2):
|
|||||||
"rule. This reflects the current state of the rule "
|
"rule. This reflects the current state of the rule "
|
||||||
"and not its initial value.")
|
"and not its initial value.")
|
||||||
|
|
||||||
|
parent = property(lambda self: self._parent,
|
||||||
|
doc="The Parent Node of this CSSRule (currently if a "
|
||||||
|
"CSSStyleDeclaration only!) or None.")
|
||||||
|
|
||||||
parentRule = property(lambda self: self._parentRule,
|
parentRule = property(lambda self: self._parentRule,
|
||||||
doc="If this rule is contained inside "
|
doc="If this rule is contained inside "
|
||||||
"another rule (e.g. a style rule inside "
|
"another rule (e.g. a style rule inside "
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
"""CSSRuleList implements DOM Level 2 CSS CSSRuleList.
|
"""CSSRuleList implements DOM Level 2 CSS CSSRuleList.
|
||||||
Partly also http://dev.w3.org/csswg/cssom/#the-cssrulelist
|
Partly also http://dev.w3.org/csswg/cssom/#the-cssrulelist."""
|
||||||
"""
|
|
||||||
__all__ = ['CSSRuleList']
|
__all__ = ['CSSRuleList']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: cssrulelist.py 1641 2009-01-13 21:05:37Z cthedot $'
|
__version__ = '$Id: cssrulelist.py 1824 2009-08-01 21:00:34Z cthedot $'
|
||||||
|
|
||||||
class CSSRuleList(list):
|
class CSSRuleList(list):
|
||||||
"""The CSSRuleList object represents an (ordered) list of statements.
|
"""The CSSRuleList object represents an (ordered) list of statements.
|
||||||
|
@ -51,7 +51,7 @@ TODO:
|
|||||||
"""
|
"""
|
||||||
__all__ = ['CSSStyleDeclaration', 'Property']
|
__all__ = ['CSSStyleDeclaration', 'Property']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: cssstyledeclaration.py 1710 2009-04-18 15:46:20Z cthedot $'
|
__version__ = '$Id: cssstyledeclaration.py 1819 2009-08-01 20:52:43Z cthedot $'
|
||||||
|
|
||||||
from cssproperties import CSS2Properties
|
from cssproperties import CSS2Properties
|
||||||
from property import Property
|
from property import Property
|
||||||
@ -128,6 +128,11 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
|||||||
yield self.getProperty(name)
|
yield self.getProperty(name)
|
||||||
return properties()
|
return properties()
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
"""Analoguous to standard dict returns property names which are set in
|
||||||
|
this declaration."""
|
||||||
|
return list(self.__nnames())
|
||||||
|
|
||||||
def __getitem__(self, CSSName):
|
def __getitem__(self, CSSName):
|
||||||
"""Retrieve the value of property ``CSSName`` from this declaration.
|
"""Retrieve the value of property ``CSSName`` from this declaration.
|
||||||
|
|
||||||
@ -247,6 +252,13 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
|||||||
"""
|
"""
|
||||||
self.removeProperty(CSSName)
|
self.removeProperty(CSSName)
|
||||||
|
|
||||||
|
def children(self):
|
||||||
|
"""Generator yielding any known child in this declaration including
|
||||||
|
*all* properties, comments or CSSUnknownrules.
|
||||||
|
"""
|
||||||
|
for item in self._seq:
|
||||||
|
yield item.value
|
||||||
|
|
||||||
def _getCssText(self):
|
def _getCssText(self):
|
||||||
"""Return serialized property cssText."""
|
"""Return serialized property cssText."""
|
||||||
return cssutils.ser.do_css_CSSStyleDeclaration(self)
|
return cssutils.ser.do_css_CSSStyleDeclaration(self)
|
||||||
@ -275,7 +287,7 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
|||||||
semicolon=True)
|
semicolon=True)
|
||||||
if self._tokenvalue(tokens[-1]) == u';':
|
if self._tokenvalue(tokens[-1]) == u';':
|
||||||
tokens.pop()
|
tokens.pop()
|
||||||
property = Property()
|
property = Property(parent=self)
|
||||||
property.cssText = tokens
|
property.cssText = tokens
|
||||||
if property.wellformed:
|
if property.wellformed:
|
||||||
seq.append(property, 'Property')
|
seq.append(property, 'Property')
|
||||||
@ -301,10 +313,11 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
|||||||
productions={'IDENT': ident},#, 'CHAR': char},
|
productions={'IDENT': ident},#, 'CHAR': char},
|
||||||
default=unexpected)
|
default=unexpected)
|
||||||
# wellformed set by parse
|
# wellformed set by parse
|
||||||
# post conditions
|
|
||||||
|
for item in newseq:
|
||||||
|
item.value._parent = self
|
||||||
|
|
||||||
# do not check wellformed as invalid things are removed anyway
|
# do not check wellformed as invalid things are removed anyway
|
||||||
#if wellformed:
|
|
||||||
self._setSeq(newseq)
|
self._setSeq(newseq)
|
||||||
|
|
||||||
cssText = property(_getCssText, _setCssText,
|
cssText = property(_getCssText, _setCssText,
|
||||||
@ -322,13 +335,12 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
|||||||
"""
|
"""
|
||||||
return cssutils.ser.do_css_CSSStyleDeclaration(self, separator)
|
return cssutils.ser.do_css_CSSStyleDeclaration(self, separator)
|
||||||
|
|
||||||
def _getParentRule(self):
|
|
||||||
return self._parentRule
|
|
||||||
|
|
||||||
def _setParentRule(self, parentRule):
|
def _setParentRule(self, parentRule):
|
||||||
self._parentRule = parentRule
|
self._parentRule = parentRule
|
||||||
|
for x in self.children():
|
||||||
|
x.parent = self
|
||||||
|
|
||||||
parentRule = property(_getParentRule, _setParentRule,
|
parentRule = property(lambda self: self._parentRule, _setParentRule,
|
||||||
doc="(DOM) The CSS rule that contains this declaration block or "
|
doc="(DOM) The CSS rule that contains this declaration block or "
|
||||||
"None if this CSSStyleDeclaration is not attached to a CSSRule.")
|
"None if this CSSStyleDeclaration is not attached to a CSSRule.")
|
||||||
|
|
||||||
@ -581,6 +593,7 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
|
|||||||
property.priority = newp.priority
|
property.priority = newp.priority
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
newp.parent = self
|
||||||
self.seq._readonly = False
|
self.seq._readonly = False
|
||||||
self.seq.append(newp, 'Property')
|
self.seq.append(newp, 'Property')
|
||||||
self.seq._readonly = True
|
self.seq._readonly = True
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""CSSStyleRule implements DOM Level 2 CSS CSSStyleRule."""
|
"""CSSStyleRule implements DOM Level 2 CSS CSSStyleRule."""
|
||||||
__all__ = ['CSSStyleRule']
|
__all__ = ['CSSStyleRule']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: cssstylerule.py 1638 2009-01-13 20:39:33Z cthedot $'
|
__version__ = '$Id: cssstylerule.py 1815 2009-07-29 16:51:58Z cthedot $'
|
||||||
|
|
||||||
from cssstyledeclaration import CSSStyleDeclaration
|
from cssstyledeclaration import CSSStyleDeclaration
|
||||||
from selectorlist import SelectorList
|
from selectorlist import SelectorList
|
||||||
@ -107,6 +107,8 @@ class CSSStyleRule(cssrule.CSSRule):
|
|||||||
else:
|
else:
|
||||||
wellformed = True
|
wellformed = True
|
||||||
|
|
||||||
|
testselectorlist, teststyle = None, None
|
||||||
|
|
||||||
bracetoken = selectortokens.pop()
|
bracetoken = selectortokens.pop()
|
||||||
if self._tokenvalue(bracetoken) != u'{':
|
if self._tokenvalue(bracetoken) != u'{':
|
||||||
wellformed = False
|
wellformed = False
|
||||||
@ -117,11 +119,11 @@ class CSSStyleRule(cssrule.CSSRule):
|
|||||||
wellformed = False
|
wellformed = False
|
||||||
self._log.error(u'CSSStyleRule: No selector found: %r.' %
|
self._log.error(u'CSSStyleRule: No selector found: %r.' %
|
||||||
self._valuestr(cssText), bracetoken)
|
self._valuestr(cssText), bracetoken)
|
||||||
newselectorlist = SelectorList(selectorText=(selectortokens,
|
|
||||||
|
testselectorlist = SelectorList(selectorText=(selectortokens,
|
||||||
namespaces),
|
namespaces),
|
||||||
parentRule=self)
|
parentRule=self)
|
||||||
|
|
||||||
newstyle = CSSStyleDeclaration()
|
|
||||||
if not styletokens:
|
if not styletokens:
|
||||||
wellformed = False
|
wellformed = False
|
||||||
self._log.error(
|
self._log.error(
|
||||||
@ -139,11 +141,14 @@ class CSSStyleRule(cssrule.CSSRule):
|
|||||||
if 'EOF' == typ:
|
if 'EOF' == typ:
|
||||||
# add again as style needs it
|
# add again as style needs it
|
||||||
styletokens.append(braceorEOFtoken)
|
styletokens.append(braceorEOFtoken)
|
||||||
newstyle.cssText = styletokens
|
teststyle = CSSStyleDeclaration(styletokens, parentRule=self)
|
||||||
|
|
||||||
if wellformed:
|
if wellformed and testselectorlist and teststyle:
|
||||||
self._selectorList = newselectorlist
|
# known as correct from before
|
||||||
self.style = newstyle
|
cssutils.log.enabled = False
|
||||||
|
self.style.cssText = styletokens
|
||||||
|
self.selectorList.selectorText=(selectortokens, namespaces)
|
||||||
|
cssutils.log.enabled = True
|
||||||
|
|
||||||
cssText = property(_getCssText, _setCssText,
|
cssText = property(_getCssText, _setCssText,
|
||||||
doc="(DOM) The parsable textual representation of this rule.")
|
doc="(DOM) The parsable textual representation of this rule.")
|
||||||
@ -164,11 +169,12 @@ class CSSStyleRule(cssrule.CSSRule):
|
|||||||
|
|
||||||
def _setSelectorList(self, selectorList):
|
def _setSelectorList(self, selectorList):
|
||||||
"""
|
"""
|
||||||
:param selectorList: selectorList, only content is used, not the actual
|
:param selectorList: A SelectorList which replaces the current
|
||||||
object
|
selectorList object
|
||||||
"""
|
"""
|
||||||
self._checkReadonly()
|
self._checkReadonly()
|
||||||
self.selectorText = selectorList.selectorText
|
selectorList._parentRule = self
|
||||||
|
self._selectorList = selectorList
|
||||||
|
|
||||||
selectorList = property(lambda self: self._selectorList, _setSelectorList,
|
selectorList = property(lambda self: self._selectorList, _setSelectorList,
|
||||||
doc="The SelectorList of this rule.")
|
doc="The SelectorList of this rule.")
|
||||||
@ -200,16 +206,15 @@ class CSSStyleRule(cssrule.CSSRule):
|
|||||||
|
|
||||||
def _setStyle(self, style):
|
def _setStyle(self, style):
|
||||||
"""
|
"""
|
||||||
:param style: CSSStyleDeclaration or string, only the cssText of a
|
:param style: A string or CSSStyleDeclaration which replaces the
|
||||||
declaration is used, not the actual object
|
current style object.
|
||||||
"""
|
"""
|
||||||
self._checkReadonly()
|
self._checkReadonly()
|
||||||
if isinstance(style, basestring):
|
if isinstance(style, basestring):
|
||||||
self._style.cssText = style
|
self._style.cssText = style
|
||||||
else:
|
else:
|
||||||
# cssText would be serialized with optional preferences
|
style._parentRule = self
|
||||||
# so use _seq!
|
self._style = style
|
||||||
self._style._seq = style._seq
|
|
||||||
|
|
||||||
style = property(lambda self: self._style, _setStyle,
|
style = property(lambda self: self._style, _setStyle,
|
||||||
doc="(DOM) The declaration-block of this rule set.")
|
doc="(DOM) The declaration-block of this rule set.")
|
||||||
|
@ -9,7 +9,7 @@ TODO:
|
|||||||
"""
|
"""
|
||||||
__all__ = ['CSSStyleSheet']
|
__all__ = ['CSSStyleSheet']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: cssstylesheet.py 1641 2009-01-13 21:05:37Z cthedot $'
|
__version__ = '$Id: cssstylesheet.py 1820 2009-08-01 20:53:08Z cthedot $'
|
||||||
|
|
||||||
from cssutils.helper import Deprecated
|
from cssutils.helper import Deprecated
|
||||||
from cssutils.util import _Namespaces, _SimpleNamespaces, _readUrl
|
from cssutils.util import _Namespaces, _SimpleNamespaces, _readUrl
|
||||||
@ -42,8 +42,6 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
|
|
||||||
self._ownerRule = ownerRule
|
self._ownerRule = ownerRule
|
||||||
self.cssRules = cssutils.css.CSSRuleList()
|
self.cssRules = cssutils.css.CSSRuleList()
|
||||||
self.cssRules.append = self.insertRule
|
|
||||||
self.cssRules.extend = self.insertRule
|
|
||||||
self._namespaces = _Namespaces(parentStyleSheet=self, log=self._log)
|
self._namespaces = _Namespaces(parentStyleSheet=self, log=self._log)
|
||||||
self._readonly = readonly
|
self._readonly = readonly
|
||||||
|
|
||||||
@ -53,7 +51,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"Generator which iterates over cssRules."
|
"Generator which iterates over cssRules."
|
||||||
for rule in self.cssRules:
|
for rule in self._cssRules:
|
||||||
yield rule
|
yield rule
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
@ -78,7 +76,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
|
|
||||||
def _cleanNamespaces(self):
|
def _cleanNamespaces(self):
|
||||||
"Remove all namespace rules with same namespaceURI but last one set."
|
"Remove all namespace rules with same namespaceURI but last one set."
|
||||||
rules = self.cssRules
|
rules = self._cssRules
|
||||||
namespaceitems = self.namespaces.items()
|
namespaceitems = self.namespaces.items()
|
||||||
i = 0
|
i = 0
|
||||||
while i < len(rules):
|
while i < len(rules):
|
||||||
@ -101,6 +99,19 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
useduris.update(r2.selectorList._getUsedUris())
|
useduris.update(r2.selectorList._getUsedUris())
|
||||||
return useduris
|
return useduris
|
||||||
|
|
||||||
|
def _setCssRules(self, cssRules):
|
||||||
|
"Set new cssRules and update contained rules refs."
|
||||||
|
cssRules.append = self.insertRule
|
||||||
|
cssRules.extend = self.insertRule
|
||||||
|
cssRules.__delitem__ == self.deleteRule
|
||||||
|
for rule in cssRules:
|
||||||
|
rule._parentStyleSheet = self
|
||||||
|
self._cssRules = cssRules
|
||||||
|
|
||||||
|
cssRules = property(lambda self: self._cssRules, _setCssRules,
|
||||||
|
"All Rules in this style sheet, a "
|
||||||
|
":class:`~cssutils.css.CSSRuleList`.")
|
||||||
|
|
||||||
def _getCssText(self):
|
def _getCssText(self):
|
||||||
"Textual representation of the stylesheet (a byte string)."
|
"Textual representation of the stylesheet (a byte string)."
|
||||||
return cssutils.ser.do_CSSStyleSheet(self)
|
return cssutils.ser.do_CSSStyleSheet(self)
|
||||||
@ -260,7 +271,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
default=ruleset)
|
default=ruleset)
|
||||||
|
|
||||||
if wellformed:
|
if wellformed:
|
||||||
del self.cssRules[:]
|
del self._cssRules[:]
|
||||||
for rule in newseq:
|
for rule in newseq:
|
||||||
self.insertRule(rule, _clean=False)
|
self.insertRule(rule, _clean=False)
|
||||||
self._cleanNamespaces()
|
self._cleanNamespaces()
|
||||||
@ -277,7 +288,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
try:
|
try:
|
||||||
# explicit @charset
|
# explicit @charset
|
||||||
selfAsParentEncoding = self.cssRules[0].encoding
|
selfAsParentEncoding = self._cssRules[0].encoding
|
||||||
except (IndexError, AttributeError):
|
except (IndexError, AttributeError):
|
||||||
# default not UTF-8 but None!
|
# default not UTF-8 but None!
|
||||||
selfAsParentEncoding = None
|
selfAsParentEncoding = None
|
||||||
@ -312,6 +323,14 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
"""Set @import URL loader, if None the default is used."""
|
"""Set @import URL loader, if None the default is used."""
|
||||||
self._fetcher = fetcher
|
self._fetcher = fetcher
|
||||||
|
|
||||||
|
def _getEncoding(self):
|
||||||
|
"""Encoding set in :class:`~cssutils.css.CSSCharsetRule` or if ``None``
|
||||||
|
resulting in default ``utf-8`` encoding being used."""
|
||||||
|
try:
|
||||||
|
return self._cssRules[0].encoding
|
||||||
|
except (IndexError, AttributeError):
|
||||||
|
return 'utf-8'
|
||||||
|
|
||||||
def _setEncoding(self, encoding):
|
def _setEncoding(self, encoding):
|
||||||
"""Set `encoding` of charset rule if present in sheet or insert a new
|
"""Set `encoding` of charset rule if present in sheet or insert a new
|
||||||
:class:`~cssutils.css.CSSCharsetRule` with given `encoding`.
|
:class:`~cssutils.css.CSSCharsetRule` with given `encoding`.
|
||||||
@ -319,7 +338,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
default encoding of utf-8.
|
default encoding of utf-8.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
rule = self.cssRules[0]
|
rule = self._cssRules[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
rule = None
|
rule = None
|
||||||
if rule and rule.CHARSET_RULE == rule.type:
|
if rule and rule.CHARSET_RULE == rule.type:
|
||||||
@ -330,14 +349,6 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
elif encoding:
|
elif encoding:
|
||||||
self.insertRule(cssutils.css.CSSCharsetRule(encoding=encoding), 0)
|
self.insertRule(cssutils.css.CSSCharsetRule(encoding=encoding), 0)
|
||||||
|
|
||||||
def _getEncoding(self):
|
|
||||||
"""Encoding set in :class:`~cssutils.css.CSSCharsetRule` or if ``None``
|
|
||||||
resulting in default ``utf-8`` encoding being used."""
|
|
||||||
try:
|
|
||||||
return self.cssRules[0].encoding
|
|
||||||
except (IndexError, AttributeError):
|
|
||||||
return 'utf-8'
|
|
||||||
|
|
||||||
encoding = property(_getEncoding, _setEncoding,
|
encoding = property(_getEncoding, _setEncoding,
|
||||||
"(cssutils) Reflect encoding of an @charset rule or 'utf-8' "
|
"(cssutils) Reflect encoding of an @charset rule or 'utf-8' "
|
||||||
"(default) if set to ``None``")
|
"(default) if set to ``None``")
|
||||||
@ -371,11 +382,11 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
self._checkReadonly()
|
self._checkReadonly()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
rule = self.cssRules[index]
|
rule = self._cssRules[index]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
raise xml.dom.IndexSizeErr(
|
raise xml.dom.IndexSizeErr(
|
||||||
u'CSSStyleSheet: %s is not a valid index in the rulelist of length %i' % (
|
u'CSSStyleSheet: %s is not a valid index in the rulelist of length %i' % (
|
||||||
index, self.cssRules.length))
|
index, self._cssRules.length))
|
||||||
else:
|
else:
|
||||||
if rule.type == rule.NAMESPACE_RULE:
|
if rule.type == rule.NAMESPACE_RULE:
|
||||||
# check all namespacerules if used
|
# check all namespacerules if used
|
||||||
@ -388,7 +399,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
return
|
return
|
||||||
|
|
||||||
rule._parentStyleSheet = None # detach
|
rule._parentStyleSheet = None # detach
|
||||||
del self.cssRules[index] # delete from StyleSheet
|
del self._cssRules[index] # delete from StyleSheet
|
||||||
|
|
||||||
def insertRule(self, rule, index=None, inOrder=False, _clean=True):
|
def insertRule(self, rule, index=None, inOrder=False, _clean=True):
|
||||||
"""
|
"""
|
||||||
@ -427,11 +438,11 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
|
|
||||||
# check position
|
# check position
|
||||||
if index is None:
|
if index is None:
|
||||||
index = len(self.cssRules)
|
index = len(self._cssRules)
|
||||||
elif index < 0 or index > self.cssRules.length:
|
elif index < 0 or index > self._cssRules.length:
|
||||||
raise xml.dom.IndexSizeErr(
|
raise xml.dom.IndexSizeErr(
|
||||||
u'CSSStyleSheet: Invalid index %s for CSSRuleList with a length of %s.' % (
|
u'CSSStyleSheet: Invalid index %s for CSSRuleList with a length of %s.' % (
|
||||||
index, self.cssRules.length))
|
index, self._cssRules.length))
|
||||||
return
|
return
|
||||||
|
|
||||||
if isinstance(rule, basestring):
|
if isinstance(rule, basestring):
|
||||||
@ -447,11 +458,11 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
# prepend encoding if in this sheet to be able to use it in
|
# prepend encoding if in this sheet to be able to use it in
|
||||||
# @import rules encoding resolution
|
# @import rules encoding resolution
|
||||||
# do not add if new rule startswith "@charset" (which is exact!)
|
# do not add if new rule startswith "@charset" (which is exact!)
|
||||||
if not rule.startswith(u'@charset') and (self.cssRules and
|
if not rule.startswith(u'@charset') and (self._cssRules and
|
||||||
self.cssRules[0].type == self.cssRules[0].CHARSET_RULE):
|
self._cssRules[0].type == self._cssRules[0].CHARSET_RULE):
|
||||||
# rule 0 is @charset!
|
# rule 0 is @charset!
|
||||||
newrulescount, newruleindex = 2, 1
|
newrulescount, newruleindex = 2, 1
|
||||||
rule = self.cssRules[0].cssText + rule
|
rule = self._cssRules[0].cssText + rule
|
||||||
else:
|
else:
|
||||||
newrulescount, newruleindex = 1, 0
|
newrulescount, newruleindex = 1, 0
|
||||||
|
|
||||||
@ -484,29 +495,29 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
if inOrder:
|
if inOrder:
|
||||||
index = 0
|
index = 0
|
||||||
# always first and only
|
# always first and only
|
||||||
if (self.cssRules and self.cssRules[0].type == rule.CHARSET_RULE):
|
if (self._cssRules and self._cssRules[0].type == rule.CHARSET_RULE):
|
||||||
self.cssRules[0].encoding = rule.encoding
|
self._cssRules[0].encoding = rule.encoding
|
||||||
else:
|
else:
|
||||||
self.cssRules.insert(0, rule)
|
self._cssRules.insert(0, rule)
|
||||||
elif index != 0 or (self.cssRules and
|
elif index != 0 or (self._cssRules and
|
||||||
self.cssRules[0].type == rule.CHARSET_RULE):
|
self._cssRules[0].type == rule.CHARSET_RULE):
|
||||||
self._log.error(
|
self._log.error(
|
||||||
u'CSSStylesheet: @charset only allowed once at the beginning of a stylesheet.',
|
u'CSSStylesheet: @charset only allowed once at the beginning of a stylesheet.',
|
||||||
error=xml.dom.HierarchyRequestErr)
|
error=xml.dom.HierarchyRequestErr)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.cssRules.insert(index, rule)
|
self._cssRules.insert(index, rule)
|
||||||
|
|
||||||
# @unknown or comment
|
# @unknown or comment
|
||||||
elif rule.type in (rule.UNKNOWN_RULE, rule.COMMENT) and not inOrder:
|
elif rule.type in (rule.UNKNOWN_RULE, rule.COMMENT) and not inOrder:
|
||||||
if index == 0 and self.cssRules and\
|
if index == 0 and self._cssRules and\
|
||||||
self.cssRules[0].type == rule.CHARSET_RULE:
|
self._cssRules[0].type == rule.CHARSET_RULE:
|
||||||
self._log.error(
|
self._log.error(
|
||||||
u'CSSStylesheet: @charset must be the first rule.',
|
u'CSSStylesheet: @charset must be the first rule.',
|
||||||
error=xml.dom.HierarchyRequestErr)
|
error=xml.dom.HierarchyRequestErr)
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
self.cssRules.insert(index, rule)
|
self._cssRules.insert(index, rule)
|
||||||
|
|
||||||
# @import
|
# @import
|
||||||
elif rule.type == rule.IMPORT_RULE:
|
elif rule.type == rule.IMPORT_RULE:
|
||||||
@ -514,27 +525,27 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
# automatic order
|
# automatic order
|
||||||
if rule.type in (r.type for r in self):
|
if rule.type in (r.type for r in self):
|
||||||
# find last of this type
|
# find last of this type
|
||||||
for i, r in enumerate(reversed(self.cssRules)):
|
for i, r in enumerate(reversed(self._cssRules)):
|
||||||
if r.type == rule.type:
|
if r.type == rule.type:
|
||||||
index = len(self.cssRules) - i
|
index = len(self._cssRules) - i
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# find first point to insert
|
# find first point to insert
|
||||||
if self.cssRules and self.cssRules[0].type in (rule.CHARSET_RULE,
|
if self._cssRules and self._cssRules[0].type in (rule.CHARSET_RULE,
|
||||||
rule.COMMENT):
|
rule.COMMENT):
|
||||||
index = 1
|
index = 1
|
||||||
else:
|
else:
|
||||||
index = 0
|
index = 0
|
||||||
else:
|
else:
|
||||||
# after @charset
|
# after @charset
|
||||||
if index == 0 and self.cssRules and\
|
if index == 0 and self._cssRules and\
|
||||||
self.cssRules[0].type == rule.CHARSET_RULE:
|
self._cssRules[0].type == rule.CHARSET_RULE:
|
||||||
self._log.error(
|
self._log.error(
|
||||||
u'CSSStylesheet: Found @charset at index 0.',
|
u'CSSStylesheet: Found @charset at index 0.',
|
||||||
error=xml.dom.HierarchyRequestErr)
|
error=xml.dom.HierarchyRequestErr)
|
||||||
return
|
return
|
||||||
# before @namespace, @page, @font-face, @media and stylerule
|
# before @namespace, @page, @font-face, @media and stylerule
|
||||||
for r in self.cssRules[:index]:
|
for r in self._cssRules[:index]:
|
||||||
if r.type in (r.NAMESPACE_RULE, r.MEDIA_RULE, r.PAGE_RULE,
|
if r.type in (r.NAMESPACE_RULE, r.MEDIA_RULE, r.PAGE_RULE,
|
||||||
r.STYLE_RULE, r.FONT_FACE_RULE):
|
r.STYLE_RULE, r.FONT_FACE_RULE):
|
||||||
self._log.error(
|
self._log.error(
|
||||||
@ -542,27 +553,27 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
index,
|
index,
|
||||||
error=xml.dom.HierarchyRequestErr)
|
error=xml.dom.HierarchyRequestErr)
|
||||||
return
|
return
|
||||||
self.cssRules.insert(index, rule)
|
self._cssRules.insert(index, rule)
|
||||||
|
|
||||||
# @namespace
|
# @namespace
|
||||||
elif rule.type == rule.NAMESPACE_RULE:
|
elif rule.type == rule.NAMESPACE_RULE:
|
||||||
if inOrder:
|
if inOrder:
|
||||||
if rule.type in (r.type for r in self):
|
if rule.type in (r.type for r in self):
|
||||||
# find last of this type
|
# find last of this type
|
||||||
for i, r in enumerate(reversed(self.cssRules)):
|
for i, r in enumerate(reversed(self._cssRules)):
|
||||||
if r.type == rule.type:
|
if r.type == rule.type:
|
||||||
index = len(self.cssRules) - i
|
index = len(self._cssRules) - i
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# find first point to insert
|
# find first point to insert
|
||||||
for i, r in enumerate(self.cssRules):
|
for i, r in enumerate(self._cssRules):
|
||||||
if r.type in (r.MEDIA_RULE, r.PAGE_RULE, r.STYLE_RULE,
|
if r.type in (r.MEDIA_RULE, r.PAGE_RULE, r.STYLE_RULE,
|
||||||
r.FONT_FACE_RULE, r.UNKNOWN_RULE, r.COMMENT):
|
r.FONT_FACE_RULE, r.UNKNOWN_RULE, r.COMMENT):
|
||||||
index = i # before these
|
index = i # before these
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
# after @charset and @import
|
# after @charset and @import
|
||||||
for r in self.cssRules[index:]:
|
for r in self._cssRules[index:]:
|
||||||
if r.type in (r.CHARSET_RULE, r.IMPORT_RULE):
|
if r.type in (r.CHARSET_RULE, r.IMPORT_RULE):
|
||||||
self._log.error(
|
self._log.error(
|
||||||
u'CSSStylesheet: Cannot insert @namespace here, found @charset or @import after index %s.' %
|
u'CSSStylesheet: Cannot insert @namespace here, found @charset or @import after index %s.' %
|
||||||
@ -570,7 +581,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
error=xml.dom.HierarchyRequestErr)
|
error=xml.dom.HierarchyRequestErr)
|
||||||
return
|
return
|
||||||
# before @media and stylerule
|
# before @media and stylerule
|
||||||
for r in self.cssRules[:index]:
|
for r in self._cssRules[:index]:
|
||||||
if r.type in (r.MEDIA_RULE, r.PAGE_RULE, r.STYLE_RULE,
|
if r.type in (r.MEDIA_RULE, r.PAGE_RULE, r.STYLE_RULE,
|
||||||
r.FONT_FACE_RULE):
|
r.FONT_FACE_RULE):
|
||||||
self._log.error(
|
self._log.error(
|
||||||
@ -582,7 +593,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
if not (rule.prefix in self.namespaces and
|
if not (rule.prefix in self.namespaces and
|
||||||
self.namespaces[rule.prefix] == rule.namespaceURI):
|
self.namespaces[rule.prefix] == rule.namespaceURI):
|
||||||
# no doublettes
|
# no doublettes
|
||||||
self.cssRules.insert(index, rule)
|
self._cssRules.insert(index, rule)
|
||||||
if _clean:
|
if _clean:
|
||||||
self._cleanNamespaces()
|
self._cleanNamespaces()
|
||||||
|
|
||||||
@ -590,17 +601,17 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
|
|||||||
else:
|
else:
|
||||||
if inOrder:
|
if inOrder:
|
||||||
# simply add to end as no specific order
|
# simply add to end as no specific order
|
||||||
self.cssRules.append(rule)
|
self._cssRules.append(rule)
|
||||||
index = len(self.cssRules) - 1
|
index = len(self._cssRules) - 1
|
||||||
else:
|
else:
|
||||||
for r in self.cssRules[index:]:
|
for r in self._cssRules[index:]:
|
||||||
if r.type in (r.CHARSET_RULE, r.IMPORT_RULE, r.NAMESPACE_RULE):
|
if r.type in (r.CHARSET_RULE, r.IMPORT_RULE, r.NAMESPACE_RULE):
|
||||||
self._log.error(
|
self._log.error(
|
||||||
u'CSSStylesheet: Cannot insert rule here, found @charset, @import or @namespace before index %s.' %
|
u'CSSStylesheet: Cannot insert rule here, found @charset, @import or @namespace before index %s.' %
|
||||||
index,
|
index,
|
||||||
error=xml.dom.HierarchyRequestErr)
|
error=xml.dom.HierarchyRequestErr)
|
||||||
return
|
return
|
||||||
self.cssRules.insert(index, rule)
|
self._cssRules.insert(index, rule)
|
||||||
|
|
||||||
# post settings, TODO: for other rules which contain @rules
|
# post settings, TODO: for other rules which contain @rules
|
||||||
rule._parentStyleSheet = self
|
rule._parentStyleSheet = self
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"""
|
"""
|
||||||
__all__ = ['CSSValue', 'CSSPrimitiveValue', 'CSSValueList', 'RGBColor']
|
__all__ = ['CSSValue', 'CSSPrimitiveValue', 'CSSValueList', 'RGBColor']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: cssvalue.py 1684 2009-03-01 18:26:21Z cthedot $'
|
__version__ = '$Id: cssvalue.py 1834 2009-08-02 12:20:21Z cthedot $'
|
||||||
|
|
||||||
from cssutils.prodparser import *
|
from cssutils.prodparser import *
|
||||||
import cssutils
|
import cssutils
|
||||||
@ -81,6 +81,7 @@ class CSSValue(cssutils.util._NewBase):
|
|||||||
[ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* |
|
[ NUMBER S* | PERCENTAGE S* | LENGTH S* | EMS S* | EXS S* | ANGLE S* |
|
||||||
TIME S* | FREQ S* ]
|
TIME S* | FREQ S* ]
|
||||||
| STRING S* | IDENT S* | URI S* | hexcolor | function
|
| STRING S* | IDENT S* | URI S* | hexcolor | function
|
||||||
|
| UNICODE-RANGE S*
|
||||||
;
|
;
|
||||||
function
|
function
|
||||||
: FUNCTION S* expr ')' S*
|
: FUNCTION S* expr ')' S*
|
||||||
@ -117,22 +118,25 @@ class CSSValue(cssutils.util._NewBase):
|
|||||||
PreDef.ident(nextSor=nextSor),
|
PreDef.ident(nextSor=nextSor),
|
||||||
PreDef.uri(nextSor=nextSor),
|
PreDef.uri(nextSor=nextSor),
|
||||||
PreDef.hexcolor(nextSor=nextSor),
|
PreDef.hexcolor(nextSor=nextSor),
|
||||||
|
PreDef.unicode_range(nextSor=nextSor),
|
||||||
# special case IE only expression
|
# special case IE only expression
|
||||||
Prod(name='expression',
|
Prod(name='expression',
|
||||||
match=lambda t, v: t == self._prods.FUNCTION and
|
match=lambda t, v: t == self._prods.FUNCTION and (
|
||||||
cssutils.helper.normalize(v) in (u'expression(',
|
cssutils.helper.normalize(v) in (u'expression(',
|
||||||
u'alpha('),
|
u'alpha(') or
|
||||||
|
v.startswith(u'progid:DXImageTransform.Microsoft.') ),
|
||||||
nextSor=nextSor,
|
nextSor=nextSor,
|
||||||
toSeq=lambda t, tokens: (ExpressionValue.name,
|
toSeq=lambda t, tokens: (ExpressionValue.name,
|
||||||
ExpressionValue(cssutils.helper.pushtoken(t,
|
ExpressionValue(cssutils.helper.pushtoken(t,
|
||||||
tokens)))),
|
tokens)))
|
||||||
|
),
|
||||||
PreDef.function(nextSor=nextSor,
|
PreDef.function(nextSor=nextSor,
|
||||||
toSeq=lambda t, tokens: ('FUNCTION',
|
toSeq=lambda t, tokens: ('FUNCTION',
|
||||||
CSSFunction(cssutils.helper.pushtoken(t,
|
CSSFunction(cssutils.helper.pushtoken(t,
|
||||||
tokens)))))
|
tokens)))))
|
||||||
operator = Choice(PreDef.S(optional=False, mayEnd=True),
|
operator = Choice(PreDef.S(),
|
||||||
PreDef.CHAR('comma', ',', toSeq=lambda t, tokens: ('operator', t[1])),
|
PreDef.char('comma', ',', toSeq=lambda t, tokens: ('operator', t[1])),
|
||||||
PreDef.CHAR('slash', '/', toSeq=lambda t, tokens: ('operator', t[1])),
|
PreDef.char('slash', '/', toSeq=lambda t, tokens: ('operator', t[1])),
|
||||||
optional=True)
|
optional=True)
|
||||||
# CSSValue PRODUCTIONS
|
# CSSValue PRODUCTIONS
|
||||||
valueprods = Sequence(term,
|
valueprods = Sequence(term,
|
||||||
@ -154,19 +158,22 @@ class CSSValue(cssutils.util._NewBase):
|
|||||||
item = seq[i]
|
item = seq[i]
|
||||||
if item.type == self._prods.S:
|
if item.type == self._prods.S:
|
||||||
pass
|
pass
|
||||||
elif item.value == u',' and item.type not in (self._prods.URI, self._prods.STRING):
|
|
||||||
# counts as a single one
|
elif (item.value, item.type) == (u',', 'operator'):
|
||||||
|
# , separared counts as a single STRING for now
|
||||||
|
# URI or STRING value might be a single CHAR too!
|
||||||
newseq.appendItem(item)
|
newseq.appendItem(item)
|
||||||
if firstvalue:
|
|
||||||
# may be IDENT or STRING but with , it is always STRING
|
|
||||||
firstvalue = firstvalue[0], 'STRING'
|
|
||||||
# each comma separated list counts as a single one only
|
|
||||||
count -= 1
|
count -= 1
|
||||||
|
if firstvalue:
|
||||||
|
# list of IDENTs is handled as STRING!
|
||||||
|
if firstvalue[1] == self._prods.IDENT:
|
||||||
|
firstvalue = firstvalue[0], 'STRING'
|
||||||
|
|
||||||
elif item.value == u'/':
|
elif item.value == u'/':
|
||||||
# counts as a single one
|
# / separated items count as one
|
||||||
newseq.appendItem(item)
|
newseq.appendItem(item)
|
||||||
|
|
||||||
elif item.value == u'+' or item.value == u'-':
|
elif item.value == u'-' or item.value == u'+':
|
||||||
# combine +- and following number or other
|
# combine +- and following number or other
|
||||||
i += 1
|
i += 1
|
||||||
try:
|
try:
|
||||||
@ -228,6 +235,8 @@ class CSSValue(cssutils.util._NewBase):
|
|||||||
return cssutils.helper.string(item.value)
|
return cssutils.helper.string(item.value)
|
||||||
elif self._prods.URI == item.type:
|
elif self._prods.URI == item.type:
|
||||||
return cssutils.helper.uri(item.value)
|
return cssutils.helper.uri(item.value)
|
||||||
|
elif self._prods.FUNCTION == item.type:
|
||||||
|
return item.value.cssText
|
||||||
else:
|
else:
|
||||||
return item.value
|
return item.value
|
||||||
|
|
||||||
@ -253,7 +262,8 @@ class CSSValue(cssutils.util._NewBase):
|
|||||||
self._prods.NUMBER,
|
self._prods.NUMBER,
|
||||||
self._prods.PERCENTAGE,
|
self._prods.PERCENTAGE,
|
||||||
self._prods.STRING,
|
self._prods.STRING,
|
||||||
self._prods.URI):
|
self._prods.URI,
|
||||||
|
self._prods.UNICODE_RANGE):
|
||||||
if nexttocommalist:
|
if nexttocommalist:
|
||||||
# wait until complete
|
# wait until complete
|
||||||
commalist.append(itemValue(item))
|
commalist.append(itemValue(item))
|
||||||
@ -353,6 +363,7 @@ class CSSPrimitiveValue(CSSValue):
|
|||||||
CSS_RGBCOLOR = 25
|
CSS_RGBCOLOR = 25
|
||||||
# NOT OFFICIAL:
|
# NOT OFFICIAL:
|
||||||
CSS_RGBACOLOR = 26
|
CSS_RGBACOLOR = 26
|
||||||
|
CSS_UNICODE_RANGE = 27
|
||||||
|
|
||||||
_floattypes = (CSS_NUMBER, CSS_PERCENTAGE, CSS_EMS, CSS_EXS,
|
_floattypes = (CSS_NUMBER, CSS_PERCENTAGE, CSS_EMS, CSS_EXS,
|
||||||
CSS_PX, CSS_CM, CSS_MM, CSS_IN, CSS_PT, CSS_PC,
|
CSS_PX, CSS_CM, CSS_MM, CSS_IN, CSS_PT, CSS_PC,
|
||||||
@ -429,6 +440,7 @@ class CSSPrimitiveValue(CSSValue):
|
|||||||
'CSS_STRING', 'CSS_URI', 'CSS_IDENT',
|
'CSS_STRING', 'CSS_URI', 'CSS_IDENT',
|
||||||
'CSS_ATTR', 'CSS_COUNTER', 'CSS_RECT',
|
'CSS_ATTR', 'CSS_COUNTER', 'CSS_RECT',
|
||||||
'CSS_RGBCOLOR', 'CSS_RGBACOLOR',
|
'CSS_RGBCOLOR', 'CSS_RGBACOLOR',
|
||||||
|
'CSS_UNICODE_RANGE'
|
||||||
]
|
]
|
||||||
|
|
||||||
_reNumDim = re.compile(ur'([+-]?\d*\.\d+|[+-]?\d+)(.*)$', re.I| re.U|re.X)
|
_reNumDim = re.compile(ur'([+-]?\d*\.\d+|[+-]?\d+)(.*)$', re.I| re.U|re.X)
|
||||||
@ -464,6 +476,7 @@ class CSSPrimitiveValue(CSSValue):
|
|||||||
__types.NUMBER: 'CSS_NUMBER',
|
__types.NUMBER: 'CSS_NUMBER',
|
||||||
__types.PERCENTAGE: 'CSS_PERCENTAGE',
|
__types.PERCENTAGE: 'CSS_PERCENTAGE',
|
||||||
__types.STRING: 'CSS_STRING',
|
__types.STRING: 'CSS_STRING',
|
||||||
|
__types.UNICODE_RANGE: 'CSS_UNICODE_RANGE',
|
||||||
__types.URI: 'CSS_URI',
|
__types.URI: 'CSS_URI',
|
||||||
__types.IDENT: 'CSS_IDENT',
|
__types.IDENT: 'CSS_IDENT',
|
||||||
__types.HASH: 'CSS_RGBCOLOR',
|
__types.HASH: 'CSS_RGBCOLOR',
|
||||||
@ -474,7 +487,6 @@ class CSSPrimitiveValue(CSSValue):
|
|||||||
def __set_primitiveType(self):
|
def __set_primitiveType(self):
|
||||||
"""primitiveType is readonly but is set lazy if accessed"""
|
"""primitiveType is readonly but is set lazy if accessed"""
|
||||||
# TODO: check unary and font-family STRING a, b, "c"
|
# TODO: check unary and font-family STRING a, b, "c"
|
||||||
|
|
||||||
val, type_ = self._value
|
val, type_ = self._value
|
||||||
# try get by type_
|
# try get by type_
|
||||||
pt = self.__unitbytype.get(type_, 'CSS_UNKNOWN')
|
pt = self.__unitbytype.get(type_, 'CSS_UNKNOWN')
|
||||||
@ -969,23 +981,31 @@ class RGBColor(CSSPrimitiveValue):
|
|||||||
|
|
||||||
class ExpressionValue(CSSFunction):
|
class ExpressionValue(CSSFunction):
|
||||||
"""Special IE only CSSFunction which may contain *anything*.
|
"""Special IE only CSSFunction which may contain *anything*.
|
||||||
Used for expressions and ``alpha(opacity=100)`` currently"""
|
Used for expressions and ``alpha(opacity=100)`` currently."""
|
||||||
name = u'Expression (IE only)'
|
name = u'Expression (IE only)'
|
||||||
|
|
||||||
def _productiondefinition(self):
|
def _productiondefinition(self):
|
||||||
"""Return defintion used for parsing."""
|
"""Return defintion used for parsing."""
|
||||||
types = self._prods # rename!
|
types = self._prods # rename!
|
||||||
|
|
||||||
|
def toSeq(t, tokens):
|
||||||
|
"Do not normalize function name!"
|
||||||
|
return t[0], t[1]
|
||||||
|
|
||||||
funcProds = Sequence(Prod(name='expression',
|
funcProds = Sequence(Prod(name='expression',
|
||||||
match=lambda t, v: t == types.FUNCTION,
|
match=lambda t, v: t == types.FUNCTION,
|
||||||
toSeq=lambda t, tokens: (t[0], cssutils.helper.normalize(t[1]))),
|
toSeq=toSeq
|
||||||
|
),
|
||||||
Sequence(Choice(Prod(name='nested function',
|
Sequence(Choice(Prod(name='nested function',
|
||||||
match=lambda t, v: t == self._prods.FUNCTION,
|
match=lambda t, v: t == self._prods.FUNCTION,
|
||||||
toSeq=lambda t, tokens: (CSSFunction.name,
|
toSeq=lambda t, tokens: (CSSFunction.name,
|
||||||
CSSFunction(cssutils.helper.pushtoken(t,
|
CSSFunction(cssutils.helper.pushtoken(t,
|
||||||
tokens)))),
|
tokens)))
|
||||||
|
),
|
||||||
Prod(name='part',
|
Prod(name='part',
|
||||||
match=lambda t, v: v != u')',
|
match=lambda t, v: v != u')',
|
||||||
toSeq=lambda t, tokens: (t[0], t[1])), ),
|
toSeq=lambda t, tokens: (t[0], t[1])),
|
||||||
|
),
|
||||||
minmax=lambda: (0, None)),
|
minmax=lambda: (0, None)),
|
||||||
PreDef.funcEnd(stop=True))
|
PreDef.funcEnd(stop=True))
|
||||||
return funcProds
|
return funcProds
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"""Property is a single CSS property in a CSSStyleDeclaration."""
|
"""Property is a single CSS property in a CSSStyleDeclaration."""
|
||||||
__all__ = ['Property']
|
__all__ = ['Property']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: property.py 1685 2009-03-01 18:26:48Z cthedot $'
|
__version__ = '$Id: property.py 1811 2009-07-29 13:11:15Z cthedot $'
|
||||||
|
|
||||||
from cssutils.helper import Deprecated
|
from cssutils.helper import Deprecated
|
||||||
from cssvalue import CSSValue
|
from cssvalue import CSSValue
|
||||||
@ -44,7 +44,7 @@ class Property(cssutils.util.Base):
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, name=None, value=None, priority=u'',
|
def __init__(self, name=None, value=None, priority=u'',
|
||||||
_mediaQuery=False, _parent=None):
|
_mediaQuery=False, parent=None, parentStyle=None):
|
||||||
"""
|
"""
|
||||||
:param name:
|
:param name:
|
||||||
a property name string (will be normalized)
|
a property name string (will be normalized)
|
||||||
@ -55,16 +55,17 @@ class Property(cssutils.util.Base):
|
|||||||
u'!important' or u'important'
|
u'!important' or u'important'
|
||||||
:param _mediaQuery:
|
:param _mediaQuery:
|
||||||
if ``True`` value is optional (used by MediaQuery)
|
if ``True`` value is optional (used by MediaQuery)
|
||||||
:param _parent:
|
:param parent:
|
||||||
the parent object, normally a
|
the parent object, normally a
|
||||||
:class:`cssutils.css.CSSStyleDeclaration`
|
:class:`cssutils.css.CSSStyleDeclaration`
|
||||||
|
:param parentStyle:
|
||||||
|
DEPRECATED: Use ``parent`` instead
|
||||||
"""
|
"""
|
||||||
super(Property, self).__init__()
|
super(Property, self).__init__()
|
||||||
|
|
||||||
self.seqs = [[], None, []]
|
self.seqs = [[], None, []]
|
||||||
self.wellformed = False
|
self.wellformed = False
|
||||||
self._mediaQuery = _mediaQuery
|
self._mediaQuery = _mediaQuery
|
||||||
self._parent = _parent
|
self.parent = parent
|
||||||
|
|
||||||
self.__nametoken = None
|
self.__nametoken = None
|
||||||
self._name = u''
|
self._name = u''
|
||||||
@ -363,12 +364,17 @@ class Property(cssutils.util.Base):
|
|||||||
literalpriority = property(lambda self: self._literalpriority,
|
literalpriority = property(lambda self: self._literalpriority,
|
||||||
doc="Readonly literal (not normalized) priority of this property")
|
doc="Readonly literal (not normalized) priority of this property")
|
||||||
|
|
||||||
def validate(self, profiles=None):
|
def _setParent(self, parent):
|
||||||
"""Validate value against `profiles`.
|
self._parent = parent
|
||||||
|
|
||||||
:param profiles:
|
parent = property(lambda self: self._parent, _setParent,
|
||||||
A list of profile names used for validating. If no `profiles`
|
doc="The Parent Node (normally a CSSStyledeclaration) of this "
|
||||||
is given ``cssutils.profile.defaultProfiles`` is used
|
"Property")
|
||||||
|
|
||||||
|
def validate(self):
|
||||||
|
"""Validate value against `profiles` which are checked dynamically.
|
||||||
|
properties in e.g. @font-face rules are checked against
|
||||||
|
``cssutils.profile.CSS3_FONT_FACE`` only.
|
||||||
|
|
||||||
For each of the following cases a message is reported:
|
For each of the following cases a message is reported:
|
||||||
|
|
||||||
@ -424,6 +430,16 @@ class Property(cssutils.util.Base):
|
|||||||
"""
|
"""
|
||||||
valid = False
|
valid = False
|
||||||
|
|
||||||
|
profiles = None
|
||||||
|
try:
|
||||||
|
# if @font-face use that profile
|
||||||
|
rule = self.parent.parentRule
|
||||||
|
if rule.type == rule.FONT_FACE_RULE:
|
||||||
|
profiles = [cssutils.profile.CSS3_FONT_FACE]
|
||||||
|
#TODO: same for @page
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
if self.name and self.value:
|
if self.name and self.value:
|
||||||
|
|
||||||
if self.name in cssutils.profile.knownNames:
|
if self.name in cssutils.profile.knownNames:
|
||||||
@ -467,3 +483,12 @@ class Property(cssutils.util.Base):
|
|||||||
|
|
||||||
valid = property(validate, doc="Check if value of this property is valid "
|
valid = property(validate, doc="Check if value of this property is valid "
|
||||||
"in the properties context.")
|
"in the properties context.")
|
||||||
|
|
||||||
|
|
||||||
|
@Deprecated('Use ``parent`` attribute instead.')
|
||||||
|
def _getParentStyle(self):
|
||||||
|
return self._parent
|
||||||
|
|
||||||
|
parentStyle = property(_getParentStyle, _setParent,
|
||||||
|
doc="DEPRECATED: Use ``parent`` instead")
|
||||||
|
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
"""productions for CSS 3
|
|
||||||
|
|
||||||
CSS3_MACROS and CSS3_PRODUCTIONS are from http://www.w3.org/TR/css3-syntax
|
|
||||||
"""
|
|
||||||
__all__ = ['CSSProductions', 'MACROS', 'PRODUCTIONS']
|
|
||||||
__docformat__ = 'restructuredtext'
|
|
||||||
__version__ = '$Id: css3productions.py 1116 2008-03-05 13:52:23Z cthedot $'
|
|
||||||
|
|
||||||
# a complete list of css3 macros
|
|
||||||
MACROS = {
|
|
||||||
'ident': r'[-]?{nmstart}{nmchar}*',
|
|
||||||
'name': r'{nmchar}+',
|
|
||||||
'nmstart': r'[_a-zA-Z]|{nonascii}|{escape}',
|
|
||||||
'nonascii': r'[^\0-\177]',
|
|
||||||
'unicode': r'\\[0-9a-f]{1,6}{wc}?',
|
|
||||||
'escape': r'{unicode}|\\[ -~\200-\777]',
|
|
||||||
# 'escape': r'{unicode}|\\[ -~\200-\4177777]',
|
|
||||||
'nmchar': r'[-_a-zA-Z0-9]|{nonascii}|{escape}',
|
|
||||||
|
|
||||||
# CHANGED TO SPEC: added "-?"
|
|
||||||
'num': r'-?[0-9]*\.[0-9]+|[0-9]+', #r'[-]?\d+|[-]?\d*\.\d+',
|
|
||||||
'string': r'''\'({stringchar}|\")*\'|\"({stringchar}|\')*\"''',
|
|
||||||
'stringchar': r'{urlchar}| |\\{nl}',
|
|
||||||
'urlchar': r'[\x09\x21\x23-\x26\x27-\x7E]|{nonascii}|{escape}',
|
|
||||||
# what if \r\n, \n matches first?
|
|
||||||
'nl': r'\n|\r\n|\r|\f',
|
|
||||||
'w': r'{wc}*',
|
|
||||||
'wc': r'\t|\r|\n|\f|\x20'
|
|
||||||
}
|
|
||||||
|
|
||||||
# The following productions are the complete list of tokens in CSS3, the productions are **ordered**:
|
|
||||||
PRODUCTIONS = [
|
|
||||||
('BOM', r'\xFEFF'),
|
|
||||||
('URI', r'url\({w}({string}|{urlchar}*){w}\)'),
|
|
||||||
('FUNCTION', r'{ident}\('),
|
|
||||||
('ATKEYWORD', r'\@{ident}'),
|
|
||||||
('IDENT', r'{ident}'),
|
|
||||||
('STRING', r'{string}'),
|
|
||||||
('HASH', r'\#{name}'),
|
|
||||||
('PERCENTAGE', r'{num}\%'),
|
|
||||||
('DIMENSION', r'{num}{ident}'),
|
|
||||||
('NUMBER', r'{num}'),
|
|
||||||
#???
|
|
||||||
('UNICODE-RANGE', ur'[0-9A-F?]{1,6}(\-[0-9A-F]{1,6})?'),
|
|
||||||
('CDO', r'\<\!\-\-'),
|
|
||||||
('CDC', r'\-\-\>'),
|
|
||||||
('S', r'{wc}+'),
|
|
||||||
('INCLUDES', '\~\='),
|
|
||||||
('DASHMATCH', r'\|\='),
|
|
||||||
('PREFIXMATCH', r'\^\='),
|
|
||||||
('SUFFIXMATCH', r'\$\='),
|
|
||||||
('SUBSTRINGMATCH', r'\*\='),
|
|
||||||
('COMMENT', r'\/\*[^*]*\*+([^/][^*]*\*+)*\/'),
|
|
||||||
('CHAR', r'[^"\']'),
|
|
||||||
]
|
|
||||||
|
|
||||||
class CSSProductions(object):
|
|
||||||
"has attributes for all PRODUCTIONS"
|
|
||||||
pass
|
|
||||||
|
|
||||||
for i, t in enumerate(PRODUCTIONS):
|
|
||||||
setattr(CSSProductions, t[0].replace('-', '_'), t[0])
|
|
@ -12,12 +12,12 @@ open issues
|
|||||||
"""
|
"""
|
||||||
__all__ = ['CSSProductions', 'MACROS', 'PRODUCTIONS']
|
__all__ = ['CSSProductions', 'MACROS', 'PRODUCTIONS']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: cssproductions.py 1738 2009-05-02 13:03:28Z cthedot $'
|
__version__ = '$Id: cssproductions.py 1835 2009-08-02 16:47:27Z cthedot $'
|
||||||
|
|
||||||
# a complete list of css3 macros
|
# a complete list of css3 macros
|
||||||
MACROS = {
|
MACROS = {
|
||||||
'nonascii': r'[^\0-\177]',
|
'nonascii': r'[^\0-\177]',
|
||||||
'unicode': r'\\[0-9a-f]{1,6}(?:{nl}|{s})?',
|
'unicode': r'\\[0-9A-Fa-f]{1,6}(?:{nl}|{s})?',
|
||||||
#'escape': r'{unicode}|\\[ -~\200-\777]',
|
#'escape': r'{unicode}|\\[ -~\200-\777]',
|
||||||
'escape': r'{unicode}|\\[^\n\r\f0-9a-f]',
|
'escape': r'{unicode}|\\[^\n\r\f0-9a-f]',
|
||||||
'nmstart': r'[_a-zA-Z]|{nonascii}|{escape}',
|
'nmstart': r'[_a-zA-Z]|{nonascii}|{escape}',
|
||||||
@ -71,6 +71,7 @@ PRODUCTIONS = [
|
|||||||
('S', r'{s}+'), # 1st in list of general productions
|
('S', r'{s}+'), # 1st in list of general productions
|
||||||
('URI', r'{U}{R}{L}\({w}({string}|{url}*){w}\)'),
|
('URI', r'{U}{R}{L}\({w}({string}|{url}*){w}\)'),
|
||||||
('FUNCTION', r'{ident}\('),
|
('FUNCTION', r'{ident}\('),
|
||||||
|
('UNICODE-RANGE', r'{U}\+[0-9A-Fa-f?]{1,6}(\-[0-9A-Fa-f]{1,6})?'),
|
||||||
('IDENT', r'{ident}'),
|
('IDENT', r'{ident}'),
|
||||||
('STRING', r'{string}'),
|
('STRING', r'{string}'),
|
||||||
('INVALID', r'{invalid}'), # from CSS2.1
|
('INVALID', r'{invalid}'), # from CSS2.1
|
||||||
@ -80,8 +81,9 @@ PRODUCTIONS = [
|
|||||||
('NUMBER', r'{num}'),
|
('NUMBER', r'{num}'),
|
||||||
# valid ony at start so not checked everytime
|
# valid ony at start so not checked everytime
|
||||||
#('CHARSET_SYM', r'@charset '), # from Errata includes ending space!
|
#('CHARSET_SYM', r'@charset '), # from Errata includes ending space!
|
||||||
|
# checked specially if fullsheet is parsed
|
||||||
|
('COMMENT', r'{comment}'), #r'\/\*[^*]*\*+([^/][^*]*\*+)*\/'),
|
||||||
('ATKEYWORD', r'@{ident}'), # other keywords are done in the tokenizer
|
('ATKEYWORD', r'@{ident}'), # other keywords are done in the tokenizer
|
||||||
#('UNICODE-RANGE', r'[0-9A-F?]{1,6}(\-[0-9A-F]{1,6})?'), #???
|
|
||||||
('CDO', r'\<\!\-\-'),
|
('CDO', r'\<\!\-\-'),
|
||||||
('CDC', r'\-\-\>'),
|
('CDC', r'\-\-\>'),
|
||||||
('INCLUDES', '\~\='),
|
('INCLUDES', '\~\='),
|
||||||
@ -89,8 +91,6 @@ PRODUCTIONS = [
|
|||||||
('PREFIXMATCH', r'\^\='),
|
('PREFIXMATCH', r'\^\='),
|
||||||
('SUFFIXMATCH', r'\$\='),
|
('SUFFIXMATCH', r'\$\='),
|
||||||
('SUBSTRINGMATCH', r'\*\='),
|
('SUBSTRINGMATCH', r'\*\='),
|
||||||
# checked specially if fullsheet is parsed
|
|
||||||
('COMMENT', r'{comment}'), #r'\/\*[^*]*\*+([^/][^*]*\*+)*\/'),
|
|
||||||
('CHAR', r'[^"\']') # MUST always be last
|
('CHAR', r'[^"\']') # MUST always be last
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -110,3 +110,9 @@ class CSSProductions(object):
|
|||||||
|
|
||||||
for i, t in enumerate(PRODUCTIONS):
|
for i, t in enumerate(PRODUCTIONS):
|
||||||
setattr(CSSProductions, t[0].replace('-', '_'), t[0])
|
setattr(CSSProductions, t[0].replace('-', '_'), t[0])
|
||||||
|
|
||||||
|
|
||||||
|
# may be enabled by settings.set
|
||||||
|
_DXImageTransform = ('FUNCTION',
|
||||||
|
r'progid\:DXImageTransform\.Microsoft\..+\('
|
||||||
|
)
|
||||||
|
@ -16,7 +16,7 @@ log
|
|||||||
"""
|
"""
|
||||||
__all__ = ['ErrorHandler']
|
__all__ = ['ErrorHandler']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: errorhandler.py 1728 2009-05-01 20:35:25Z cthedot $'
|
__version__ = '$Id: errorhandler.py 1812 2009-07-29 13:11:49Z cthedot $'
|
||||||
|
|
||||||
from helper import Deprecated
|
from helper import Deprecated
|
||||||
import logging
|
import logging
|
||||||
@ -41,6 +41,9 @@ class _ErrorHandler(object):
|
|||||||
- False: Errors will be written to the log, this is the
|
- False: Errors will be written to the log, this is the
|
||||||
default behaviour when parsing
|
default behaviour when parsing
|
||||||
"""
|
"""
|
||||||
|
# may be disabled during setting of known valid items
|
||||||
|
self.enabled = True
|
||||||
|
|
||||||
if log:
|
if log:
|
||||||
self._log = log
|
self._log = log
|
||||||
else:
|
else:
|
||||||
@ -74,6 +77,7 @@ class _ErrorHandler(object):
|
|||||||
handles all calls
|
handles all calls
|
||||||
logs or raises exception
|
logs or raises exception
|
||||||
"""
|
"""
|
||||||
|
if self.enabled:
|
||||||
line, col = None, None
|
line, col = None, None
|
||||||
if token:
|
if token:
|
||||||
if isinstance(token, tuple):
|
if isinstance(token, tuple):
|
||||||
@ -89,8 +93,8 @@ class _ErrorHandler(object):
|
|||||||
elif issubclass(error, xml.dom.DOMException):
|
elif issubclass(error, xml.dom.DOMException):
|
||||||
error.line = line
|
error.line = line
|
||||||
error.col = col
|
error.col = col
|
||||||
# raise error(msg, line, col)
|
# raise error(msg, line, col)
|
||||||
# else:
|
# else:
|
||||||
raise error(msg)
|
raise error(msg)
|
||||||
else:
|
else:
|
||||||
self._logcall(msg)
|
self._logcall(msg)
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: errorhandler.py 1234 2008-05-22 20:26:12Z cthedot $'
|
__version__ = '$Id: errorhandler.py 1234 2008-05-22 20:26:12Z cthedot $'
|
||||||
|
|
||||||
|
import os
|
||||||
import re
|
import re
|
||||||
|
import sys
|
||||||
|
import urllib
|
||||||
|
|
||||||
class Deprecated(object):
|
class Deprecated(object):
|
||||||
"""This is a decorator which can be used to mark functions
|
"""This is a decorator which can be used to mark functions
|
||||||
@ -48,6 +51,10 @@ def normalize(x):
|
|||||||
else:
|
else:
|
||||||
return x
|
return x
|
||||||
|
|
||||||
|
def path2url(path):
|
||||||
|
"""Return file URL of `path`"""
|
||||||
|
return u'file:' + urllib.pathname2url(os.path.abspath(path))
|
||||||
|
|
||||||
def pushtoken(token, tokens):
|
def pushtoken(token, tokens):
|
||||||
"""Return new generator starting with token followed by all tokens in
|
"""Return new generator starting with token followed by all tokens in
|
||||||
``tokens``"""
|
``tokens``"""
|
||||||
@ -107,24 +114,24 @@ def urivalue(uri):
|
|||||||
else:
|
else:
|
||||||
return uri
|
return uri
|
||||||
|
|
||||||
def normalnumber(num):
|
#def normalnumber(num):
|
||||||
"""
|
# """
|
||||||
Return normalized number as string.
|
# Return normalized number as string.
|
||||||
"""
|
# """
|
||||||
sign = ''
|
# sign = ''
|
||||||
if num.startswith('-'):
|
# if num.startswith('-'):
|
||||||
sign = '-'
|
# sign = '-'
|
||||||
num = num[1:]
|
# num = num[1:]
|
||||||
elif num.startswith('+'):
|
# elif num.startswith('+'):
|
||||||
num = num[1:]
|
# num = num[1:]
|
||||||
|
#
|
||||||
if float(num) == 0.0:
|
# if float(num) == 0.0:
|
||||||
return '0'
|
# return '0'
|
||||||
else:
|
# else:
|
||||||
if num.find('.') == -1:
|
# if num.find('.') == -1:
|
||||||
return sign + str(int(num))
|
# return sign + str(int(num))
|
||||||
else:
|
# else:
|
||||||
a, b = num.split('.')
|
# a, b = num.split('.')
|
||||||
if not a:
|
# if not a:
|
||||||
a = '0'
|
# a = '0'
|
||||||
return '%s%s.%s' % (sign, int(a), b)
|
# return '%s%s.%s' % (sign, int(a), b)
|
||||||
|
@ -2,9 +2,9 @@
|
|||||||
"""A validating CSSParser"""
|
"""A validating CSSParser"""
|
||||||
__all__ = ['CSSParser']
|
__all__ = ['CSSParser']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: parse.py 1656 2009-02-03 20:31:06Z cthedot $'
|
__version__ = '$Id: parse.py 1754 2009-05-30 14:50:13Z cthedot $'
|
||||||
|
|
||||||
from helper import Deprecated
|
from helper import Deprecated, path2url
|
||||||
import codecs
|
import codecs
|
||||||
import cssutils
|
import cssutils
|
||||||
import os
|
import os
|
||||||
@ -124,7 +124,8 @@ class CSSParser(object):
|
|||||||
"""
|
"""
|
||||||
if not href:
|
if not href:
|
||||||
# prepend // for file URL, urllib does not do this?
|
# prepend // for file URL, urllib does not do this?
|
||||||
href = u'file:' + urllib.pathname2url(os.path.abspath(filename))
|
#href = u'file:' + urllib.pathname2url(os.path.abspath(filename))
|
||||||
|
href = path2url(filename)
|
||||||
|
|
||||||
return self.parseString(open(filename, 'rb').read(),
|
return self.parseString(open(filename, 'rb').read(),
|
||||||
encoding=encoding, # read returns a str
|
encoding=encoding, # read returns a str
|
||||||
|
@ -533,105 +533,98 @@ class PreDef(object):
|
|||||||
types = cssutils.cssproductions.CSSProductions
|
types = cssutils.cssproductions.CSSProductions
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def CHAR(name='char', char=u',', toSeq=None, toStore=None, stop=False,
|
def char(name='char', char=u',', toSeq=None, stop=False,
|
||||||
nextSor=False):
|
nextSor=False):
|
||||||
"any CHAR"
|
"any CHAR"
|
||||||
return Prod(name=name, match=lambda t, v: v == char,
|
return Prod(name=name, match=lambda t, v: v == char,
|
||||||
toSeq=toSeq,
|
toSeq=toSeq,
|
||||||
toStore=toStore,
|
|
||||||
stop=stop,
|
stop=stop,
|
||||||
nextSor=nextSor)
|
nextSor=nextSor)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def comma(toStore=None):
|
def comma():
|
||||||
return PreDef.CHAR(u'comma', u',', toStore=toStore)
|
return PreDef.char(u'comma', u',')
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def dimension(toStore=None, nextSor=False):
|
def dimension(nextSor=False):
|
||||||
return Prod(name=u'dimension',
|
return Prod(name=u'dimension',
|
||||||
match=lambda t, v: t == PreDef.types.DIMENSION,
|
match=lambda t, v: t == PreDef.types.DIMENSION,
|
||||||
toStore=toStore,
|
|
||||||
toSeq=lambda t, tokens: (t[0], cssutils.helper.normalize(t[1])),
|
toSeq=lambda t, tokens: (t[0], cssutils.helper.normalize(t[1])),
|
||||||
nextSor=nextSor)
|
nextSor=nextSor)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def function(toSeq=None, toStore=None, nextSor=False):
|
def function(toSeq=None, nextSor=False):
|
||||||
return Prod(name=u'function',
|
return Prod(name=u'function',
|
||||||
match=lambda t, v: t == PreDef.types.FUNCTION,
|
match=lambda t, v: t == PreDef.types.FUNCTION,
|
||||||
toSeq=toSeq,
|
toSeq=toSeq,
|
||||||
toStore=toStore,
|
|
||||||
nextSor=nextSor)
|
nextSor=nextSor)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def funcEnd(toStore=None, stop=False, nextSor=False):
|
def funcEnd(stop=False):
|
||||||
")"
|
")"
|
||||||
return PreDef.CHAR(u'end FUNC ")"', u')',
|
return PreDef.char(u'end FUNC ")"', u')',
|
||||||
toStore=toStore,
|
stop=stop)
|
||||||
stop=stop,
|
|
||||||
nextSor=nextSor)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def ident(toStore=None, nextSor=False):
|
def ident(nextSor=False):
|
||||||
return Prod(name=u'ident',
|
return Prod(name=u'ident',
|
||||||
match=lambda t, v: t == PreDef.types.IDENT,
|
match=lambda t, v: t == PreDef.types.IDENT,
|
||||||
toStore=toStore,
|
|
||||||
nextSor=nextSor)
|
nextSor=nextSor)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def number(toStore=None, nextSor=False):
|
def number(nextSor=False):
|
||||||
return Prod(name=u'number',
|
return Prod(name=u'number',
|
||||||
match=lambda t, v: t == PreDef.types.NUMBER,
|
match=lambda t, v: t == PreDef.types.NUMBER,
|
||||||
toStore=toStore,
|
|
||||||
nextSor=nextSor)
|
nextSor=nextSor)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def string(toStore=None, nextSor=False):
|
def string(nextSor=False):
|
||||||
"string delimiters are removed by default"
|
"string delimiters are removed by default"
|
||||||
return Prod(name=u'string',
|
return Prod(name=u'string',
|
||||||
match=lambda t, v: t == PreDef.types.STRING,
|
match=lambda t, v: t == PreDef.types.STRING,
|
||||||
toStore=toStore,
|
|
||||||
toSeq=lambda t, tokens: (t[0], cssutils.helper.stringvalue(t[1])),
|
toSeq=lambda t, tokens: (t[0], cssutils.helper.stringvalue(t[1])),
|
||||||
nextSor=nextSor)
|
nextSor=nextSor)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def percentage(toStore=None, nextSor=False):
|
def percentage(nextSor=False):
|
||||||
return Prod(name=u'percentage',
|
return Prod(name=u'percentage',
|
||||||
match=lambda t, v: t == PreDef.types.PERCENTAGE,
|
match=lambda t, v: t == PreDef.types.PERCENTAGE,
|
||||||
toStore=toStore,
|
|
||||||
nextSor=nextSor)
|
nextSor=nextSor)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def S(name=u'whitespace', optional=True, toSeq=None, toStore=None, nextSor=False,
|
def S():
|
||||||
mayEnd=False):
|
return Prod(name=u'whitespace',
|
||||||
return Prod(name=name,
|
|
||||||
match=lambda t, v: t == PreDef.types.S,
|
match=lambda t, v: t == PreDef.types.S,
|
||||||
optional=optional,
|
mayEnd=True)
|
||||||
toSeq=toSeq,
|
|
||||||
toStore=toStore,
|
|
||||||
mayEnd=mayEnd)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def unary(optional=True, toStore=None):
|
def unary():
|
||||||
"+ or -"
|
"+ or -"
|
||||||
return Prod(name=u'unary +-', match=lambda t, v: v in (u'+', u'-'),
|
return Prod(name=u'unary +-', match=lambda t, v: v in (u'+', u'-'),
|
||||||
optional=optional,
|
optional=True)
|
||||||
toStore=toStore)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def uri(toStore=None, nextSor=False):
|
def uri(nextSor=False):
|
||||||
"'url(' and ')' are removed and URI is stripped"
|
"'url(' and ')' are removed and URI is stripped"
|
||||||
return Prod(name=u'URI',
|
return Prod(name=u'URI',
|
||||||
match=lambda t, v: t == PreDef.types.URI,
|
match=lambda t, v: t == PreDef.types.URI,
|
||||||
toStore=toStore,
|
|
||||||
toSeq=lambda t, tokens: (t[0], cssutils.helper.urivalue(t[1])),
|
toSeq=lambda t, tokens: (t[0], cssutils.helper.urivalue(t[1])),
|
||||||
nextSor=nextSor)
|
nextSor=nextSor)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def hexcolor(toStore=None, toSeq=None, nextSor=False):
|
def hexcolor(nextSor=False):
|
||||||
|
"#123456"
|
||||||
return Prod(name='HEX color',
|
return Prod(name='HEX color',
|
||||||
match=lambda t, v: t == PreDef.types.HASH and
|
match=lambda t, v: t == PreDef.types.HASH and (
|
||||||
len(v) == 4 or len(v) == 7,
|
len(v) == 4 or len(v) == 7),
|
||||||
toStore=toStore,
|
nextSor=nextSor
|
||||||
toSeq=toSeq,
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def unicode_range(nextSor=False):
|
||||||
|
"u+123456-abc normalized to lower `u`"
|
||||||
|
return Prod(name='unicode-range',
|
||||||
|
match=lambda t, v: t == PreDef.types.UNICODE_RANGE,
|
||||||
|
toSeq=lambda t, tokens: (t[0], t[1].lower()),
|
||||||
nextSor=nextSor
|
nextSor=nextSor
|
||||||
)
|
)
|
||||||
|
@ -43,8 +43,10 @@ class Profiles(object):
|
|||||||
macros.
|
macros.
|
||||||
"""
|
"""
|
||||||
CSS_LEVEL_2 = 'CSS Level 2.1'
|
CSS_LEVEL_2 = 'CSS Level 2.1'
|
||||||
CSS3_COLOR = CSS_COLOR_LEVEL_3 = 'CSS Color Module Level 3'
|
|
||||||
CSS3_BOX = CSS_BOX_LEVEL_3 = 'CSS Box Module Level 3'
|
CSS3_BOX = CSS_BOX_LEVEL_3 = 'CSS Box Module Level 3'
|
||||||
|
CSS3_COLOR = CSS_COLOR_LEVEL_3 = 'CSS Color Module Level 3'
|
||||||
|
CSS3_FONTS = 'CSS Fonts Module Level 3'
|
||||||
|
CSS3_FONT_FACE = 'CSS Fonts Module Level 3 @font-face properties'
|
||||||
CSS3_PAGED_MEDIA = 'CSS3 Paged Media Module'
|
CSS3_PAGED_MEDIA = 'CSS3 Paged Media Module'
|
||||||
|
|
||||||
_TOKEN_MACROS = {
|
_TOKEN_MACROS = {
|
||||||
@ -58,6 +60,7 @@ class Profiles(object):
|
|||||||
'int': r'[-]?\d+',
|
'int': r'[-]?\d+',
|
||||||
'nmchar': r'[\w-]|{nonascii}|{escape}',
|
'nmchar': r'[\w-]|{nonascii}|{escape}',
|
||||||
'num': r'[-]?\d+|[-]?\d*\.\d+',
|
'num': r'[-]?\d+|[-]?\d*\.\d+',
|
||||||
|
'positivenum': r'\d+|[-]?\d*\.\d+',
|
||||||
'number': r'{num}',
|
'number': r'{num}',
|
||||||
'string': r'{string1}|{string2}',
|
'string': r'{string1}|{string2}',
|
||||||
'string1': r'"(\\\"|[^\"])*"',
|
'string1': r'"(\\\"|[^\"])*"',
|
||||||
@ -75,6 +78,7 @@ class Profiles(object):
|
|||||||
#'color': r'(maroon|red|orange|yellow|olive|purple|fuchsia|white|lime|green|navy|blue|aqua|teal|black|silver|gray|ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText)|#[0-9a-f]{3}|#[0-9a-f]{6}|rgb\({w}{int}{w},{w}{int}{w},{w}{int}{w}\)|rgb\({w}{num}%{w},{w}{num}%{w},{w}{num}%{w}\)',
|
#'color': r'(maroon|red|orange|yellow|olive|purple|fuchsia|white|lime|green|navy|blue|aqua|teal|black|silver|gray|ActiveBorder|ActiveCaption|AppWorkspace|Background|ButtonFace|ButtonHighlight|ButtonShadow|ButtonText|CaptionText|GrayText|Highlight|HighlightText|InactiveBorder|InactiveCaption|InactiveCaptionText|InfoBackground|InfoText|Menu|MenuText|Scrollbar|ThreeDDarkShadow|ThreeDFace|ThreeDHighlight|ThreeDLightShadow|ThreeDShadow|Window|WindowFrame|WindowText)|#[0-9a-f]{3}|#[0-9a-f]{6}|rgb\({w}{int}{w},{w}{int}{w},{w}{int}{w}\)|rgb\({w}{num}%{w},{w}{num}%{w},{w}{num}%{w}\)',
|
||||||
'integer': r'{int}',
|
'integer': r'{int}',
|
||||||
'length': r'0|{num}(em|ex|px|in|cm|mm|pt|pc)',
|
'length': r'0|{num}(em|ex|px|in|cm|mm|pt|pc)',
|
||||||
|
'positivelength': r'0|{positivenum}(em|ex|px|in|cm|mm|pt|pc)',
|
||||||
'angle': r'0|{num}(deg|grad|rad)',
|
'angle': r'0|{num}(deg|grad|rad)',
|
||||||
'time': r'0|{num}m?s',
|
'time': r'0|{num}m?s',
|
||||||
'frequency': r'0|{num}k?Hz',
|
'frequency': r'0|{num}k?Hz',
|
||||||
@ -97,6 +101,16 @@ class Profiles(object):
|
|||||||
self.addProfile(self.CSS3_COLOR,
|
self.addProfile(self.CSS3_COLOR,
|
||||||
properties[self.CSS3_COLOR],
|
properties[self.CSS3_COLOR],
|
||||||
macros[self.CSS3_COLOR])
|
macros[self.CSS3_COLOR])
|
||||||
|
|
||||||
|
self.addProfile(self.CSS3_FONTS,
|
||||||
|
properties[self.CSS3_FONTS],
|
||||||
|
macros[self.CSS3_FONTS])
|
||||||
|
|
||||||
|
# new object for font-face only?
|
||||||
|
self.addProfile(self.CSS3_FONT_FACE,
|
||||||
|
properties[self.CSS3_FONT_FACE],
|
||||||
|
macros[self.CSS3_FONTS]) # same
|
||||||
|
|
||||||
self.addProfile(self.CSS3_PAGED_MEDIA,
|
self.addProfile(self.CSS3_PAGED_MEDIA,
|
||||||
properties[self.CSS3_PAGED_MEDIA],
|
properties[self.CSS3_PAGED_MEDIA],
|
||||||
macros[self.CSS3_PAGED_MEDIA])
|
macros[self.CSS3_PAGED_MEDIA])
|
||||||
@ -132,7 +146,7 @@ class Profiles(object):
|
|||||||
def _getDefaultProfiles(self):
|
def _getDefaultProfiles(self):
|
||||||
"If not explicitly set same as Profiles.profiles but in reverse order."
|
"If not explicitly set same as Profiles.profiles but in reverse order."
|
||||||
if not self._defaultProfiles:
|
if not self._defaultProfiles:
|
||||||
return self.profiles#list(reversed(self.profiles))
|
return self.profiles
|
||||||
else:
|
else:
|
||||||
return self._defaultProfiles
|
return self._defaultProfiles
|
||||||
|
|
||||||
@ -338,12 +352,12 @@ macros[Profiles.CSS_LEVEL_2] = {
|
|||||||
'shape': r'rect\(({w}({length}|auto}){w},){3}{w}({length}|auto){w}\)',
|
'shape': r'rect\(({w}({length}|auto}){w},){3}{w}({length}|auto){w}\)',
|
||||||
'counter': r'counter\({w}{identifier}{w}(?:,{w}{list-style-type}{w})?\)',
|
'counter': r'counter\({w}{identifier}{w}(?:,{w}{list-style-type}{w})?\)',
|
||||||
'identifier': r'{ident}',
|
'identifier': r'{ident}',
|
||||||
'family-name': r'{string}|{identifier}',
|
'family-name': r'{string}|{identifier}({w}{identifier})*',
|
||||||
'generic-family': r'serif|sans-serif|cursive|fantasy|monospace',
|
'generic-family': r'serif|sans-serif|cursive|fantasy|monospace',
|
||||||
'absolute-size': r'(x?x-)?(small|large)|medium',
|
'absolute-size': r'(x?x-)?(small|large)|medium',
|
||||||
'relative-size': r'smaller|larger',
|
'relative-size': r'smaller|larger',
|
||||||
'font-family': r'(({family-name}|{generic-family}){w},{w})*({family-name}|{generic-family})|inherit',
|
'font-family': r'(({family-name}|{generic-family}){w},{w})*({family-name}|{generic-family})|inherit',
|
||||||
'font-size': r'{absolute-size}|{relative-size}|{length}|{percentage}|inherit',
|
'font-size': r'{absolute-size}|{relative-size}|{positivelength}|{percentage}|inherit',
|
||||||
'font-style': r'normal|italic|oblique|inherit',
|
'font-style': r'normal|italic|oblique|inherit',
|
||||||
'font-variant': r'normal|small-caps|inherit',
|
'font-variant': r'normal|small-caps|inherit',
|
||||||
'font-weight': r'normal|bold|bolder|lighter|[1-9]00|inherit',
|
'font-weight': r'normal|bold|bolder|lighter|[1-9]00|inherit',
|
||||||
@ -495,7 +509,7 @@ macros[Profiles.CSS3_BOX] = {
|
|||||||
'overflow': macros[Profiles.CSS_LEVEL_2]['overflow']
|
'overflow': macros[Profiles.CSS_LEVEL_2]['overflow']
|
||||||
}
|
}
|
||||||
properties[Profiles.CSS3_BOX] = {
|
properties[Profiles.CSS3_BOX] = {
|
||||||
'overflow': '{overflow}\s?{overflow}?|inherit',
|
'overflow': '{overflow}{w}{overflow}?|inherit',
|
||||||
'overflow-x': '{overflow}|inherit',
|
'overflow-x': '{overflow}|inherit',
|
||||||
'overflow-y': '{overflow}|inherit'
|
'overflow-y': '{overflow}|inherit'
|
||||||
}
|
}
|
||||||
@ -515,6 +529,28 @@ properties[Profiles.CSS3_COLOR] = {
|
|||||||
'opacity': r'{num}|inherit'
|
'opacity': r'{num}|inherit'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# CSS Fonts Module Level 3 http://www.w3.org/TR/css3-fonts/
|
||||||
|
macros[Profiles.CSS3_FONTS] = {
|
||||||
|
'family-name': r'{string}|{ident}', # but STRING is effectively an IDENT???
|
||||||
|
'font-face-name': 'local\({w}{ident}{w}\)',
|
||||||
|
'font-stretch-names': r'(ultra-condensed|extra-condensed|condensed|semi-condensed|semi-expanded|expanded|extra-expanded|ultra-expanded)',
|
||||||
|
'unicode-range': r'[uU]\+[0-9A-Fa-f?]{1,6}(\-[0-9A-Fa-f]{1,6})?'
|
||||||
|
}
|
||||||
|
properties[Profiles.CSS3_FONTS] = {
|
||||||
|
'font-size-adjust': r'{number}|none|inherit',
|
||||||
|
'font-stretch': r'normal|wider|narrower|{font-stretch-names}|inherit'
|
||||||
|
}
|
||||||
|
properties[Profiles.CSS3_FONT_FACE] = {
|
||||||
|
'font-family': '{family-name}',
|
||||||
|
'font-stretch': r'{font-stretch-names}',
|
||||||
|
'font-style': r'normal|italic|oblique',
|
||||||
|
'font-weight': r'normal|bold|[1-9]00',
|
||||||
|
'src': r'({uri}{w}(format\({w}{string}{w}(\,{w}{string}{w})*\))?|{font-face-name})({w},{w}({uri}{w}(format\({w}{string}{w}(\,{w}{string}{w})*\))?|{font-face-name}))*',
|
||||||
|
'unicode-range': '{unicode-range}({w},{w}{unicode-range})*'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# CSS3 Paged Media
|
# CSS3 Paged Media
|
||||||
macros[Profiles.CSS3_PAGED_MEDIA] = {
|
macros[Profiles.CSS3_PAGED_MEDIA] = {
|
||||||
'pagesize': 'a5|a4|a3|b5|b4|letter|legal|ledger',
|
'pagesize': 'a5|a4|a3|b5|b4|letter|legal|ledger',
|
||||||
|
13
src/cssutils/settings.py
Normal file
13
src/cssutils/settings.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
"""Experimental settings for special stuff."""
|
||||||
|
|
||||||
|
def set(key, value):
|
||||||
|
"""Call to enable special settings:
|
||||||
|
|
||||||
|
('DXImageTransform.Microsoft', True)
|
||||||
|
enable support for parsing special MS only filter values
|
||||||
|
|
||||||
|
"""
|
||||||
|
if key == 'DXImageTransform.Microsoft' and value == True:
|
||||||
|
import cssproductions
|
||||||
|
cssproductions.PRODUCTIONS.insert(1, cssproductions._DXImageTransform)
|
||||||
|
|
@ -4,7 +4,7 @@
|
|||||||
"""
|
"""
|
||||||
__all__ = ['Tokenizer', 'CSSProductions']
|
__all__ = ['Tokenizer', 'CSSProductions']
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: tokenize2.py 1547 2008-12-10 20:42:26Z cthedot $'
|
__version__ = '$Id: tokenize2.py 1834 2009-08-02 12:20:21Z cthedot $'
|
||||||
|
|
||||||
from cssproductions import *
|
from cssproductions import *
|
||||||
from helper import normalize
|
from helper import normalize
|
||||||
@ -147,7 +147,8 @@ class Tokenizer(object):
|
|||||||
break
|
break
|
||||||
|
|
||||||
if name in ('DIMENSION', 'IDENT', 'STRING', 'URI',
|
if name in ('DIMENSION', 'IDENT', 'STRING', 'URI',
|
||||||
'HASH', 'COMMENT', 'FUNCTION', 'INVALID'):
|
'HASH', 'COMMENT', 'FUNCTION', 'INVALID',
|
||||||
|
'UNICODE-RANGE'):
|
||||||
# may contain unicode escape, replace with normal char
|
# may contain unicode escape, replace with normal char
|
||||||
# but do not _normalize (?)
|
# but do not _normalize (?)
|
||||||
value = self.unicodesub(_repl, found)
|
value = self.unicodesub(_repl, found)
|
||||||
@ -166,7 +167,6 @@ class Tokenizer(object):
|
|||||||
name = self._atkeywords.get(_normalize(found), 'ATKEYWORD')
|
name = self._atkeywords.get(_normalize(found), 'ATKEYWORD')
|
||||||
|
|
||||||
value = found # should not contain unicode escape (?)
|
value = found # should not contain unicode escape (?)
|
||||||
|
|
||||||
yield (name, value, line, col)
|
yield (name, value, line, col)
|
||||||
text = text[len(found):]
|
text = text[len(found):]
|
||||||
nls = found.count(self._linesep)
|
nls = found.count(self._linesep)
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
"""
|
"""
|
||||||
__all__ = []
|
__all__ = []
|
||||||
__docformat__ = 'restructuredtext'
|
__docformat__ = 'restructuredtext'
|
||||||
__version__ = '$Id: util.py 1743 2009-05-09 20:33:15Z cthedot $'
|
__version__ = '$Id: util.py 1781 2009-07-19 12:30:49Z cthedot $'
|
||||||
|
|
||||||
from helper import normalize
|
from helper import normalize
|
||||||
from itertools import ifilter
|
from itertools import ifilter
|
||||||
@ -663,6 +663,9 @@ class _Namespaces(object):
|
|||||||
self.parentStyleSheet = parentStyleSheet
|
self.parentStyleSheet = parentStyleSheet
|
||||||
self._log = log
|
self._log = log
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "%r" % self.namespaces
|
||||||
|
|
||||||
def __contains__(self, prefix):
|
def __contains__(self, prefix):
|
||||||
return prefix in self.namespaces
|
return prefix in self.namespaces
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user