Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Unified Diff: third_party/pyscss/scss/parser.py

Issue 9111023: Pyscss is obsolete with Dart CSS complier; remove all pyscss code. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Remove pyparsing from .gitignore Created 8 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/pyscss/scss/grammar.py ('k') | third_party/pyscss/scss/tests/__init__.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/pyscss/scss/parser.py
diff --git a/third_party/pyscss/scss/parser.py b/third_party/pyscss/scss/parser.py
deleted file mode 100644
index c149769a7585d90748fe67215aa0b15675bcd94e..0000000000000000000000000000000000000000
--- a/third_party/pyscss/scss/parser.py
+++ /dev/null
@@ -1,736 +0,0 @@
-import cPickle
-import os.path
-import sys
-from collections import defaultdict
-
-from pyparsing import ParseBaseException
-
-from scss import SORTING
-from scss.base import Node, Empty, ParseNode, ContentNode, IncludeNode
-from scss.control import Variable, Expression, Function, Mixin, Include, MixinParam, Extend, Variables, Option, FunctionDefinition, FunctionReturn, If, For, SepValString, Stylet
-from scss.function import warn, _nest
-from scss.grammar import *
-from scss.value import NumberValue, StringValue, ColorValue, QuotedStringValue, PointValue, RepeatValue
-
-
-class Comment(Node):
- """ Comment node.
- """
- delim = ''
- def __str__(self):
- """ Clean comments if option `comments` disabled
- or enabled option `compress`
- """
- if self.root.get_opt('comments') and not self.root.get_opt('compress'):
- return super(Comment, self).__str__()
- return ''
-
-
-class Warn(Empty):
- """ Warning node @warn.
- """
- def parse(self, target):
- """ Write message to stderr.
- """
- if self.root.get_opt('warn'):
- warn(self.data[1])
-
-
-class Import(Node):
- """ Import node @import.
- """
- def __str__(self):
- """ Write @import to outstring.
- """
- return "%s;\n" % super(Import, self).__str__()
-
-# TODO(terry): Need to eliminate the { } as literal and consume with notion of
-# DECLARATION_BODY, ANIMATION_BODY, AnimationDecls, etc. This will
-# make the formatting code general and succinct.
-class AnimationDecls(ContentNode):
- def __str__(self):
- nl, ws, ts = self.root.cache['delims']
-
- # Formatting for animation declarations. Each declaration body is
- # wrapped by curly braces with one level of indentation (2 spaces).
- # Within a curly brace each declaration is indented 2 spaced and each
- # declaration ends with a semi-colon.
- declLen = len(self.data)
- if (declLen > 0):
- declLen -= 1
- assert self.data[0] == '{' and self.data[declLen] == '}'
- return ''.join(['%s{%s' % (ws, nl),
- '%s%s' % (ws, ws),
- '%s%s%s;' % (ws, ws,
- ''.join(str(decl) for decl in self.data[1:declLen])),
- '%s%s%s}%s%s%s' % (nl, ws, ws, nl, ws, ws)])
-
-class AnimationBody(ContentNode):
- def __str__(self):
- nl, ws, ts = self.root.cache['delims']
-
- # Formatting for the body of the animation. The body is surrounded by an
- # open curly brace and newline followed by a repeated field selector
- # (indented by 2 spaces) and the animation declaration. When all
- # animation declarations are emitted add the end curly brace for the
- # entire animation.
- bodyLen = len(self.data)
- if bodyLen > 0:
- bodyLen -= 1
- assert self.data[0] == '{' and self.data[bodyLen] == '}'
- return ''.join(['%s{%s' % (ws, nl),
- '%s%s' % (ws, ws),
- ''.join(str(body) for body in self.data[1:bodyLen]),
- '%s' % nl,
- '}%s%s' % (nl, nl)])
-
-class Ruleset(ContentNode):
- """ Rule node.
- """
- def parse(self, target):
- """ Parse nested rulesets
- and save it in cache.
- """
- if isinstance(target, ContentNode):
- if target.name:
- self.parent = target
- self.name.parse(self)
- self.name += target.name
- target.ruleset.append(self)
- self.root.cache['rset'][str(self.name).split()[0]].add(self)
- super(Ruleset, self).parse(target)
-
-
-class Declaration(ParseNode):
- """ Declaration node.
- """
- def __init__(self, s, n, t):
- """ Add self.name and self.expr to object.
- """
- super(Declaration, self).__init__(s, n, t)
- self.name = self.expr = ''
-
- def parse(self, target):
- """ Parse nested declaration.
- """
- if not isinstance(target, Node):
- parent = ContentNode(None, None, [])
- parent.parse(target)
- target = parent
-
- super(Declaration, self).parse(target)
- self.name = str(self.data[0])
- while isinstance(target, Declaration):
- self.name = '-'.join(( str(target.data[0]), self.name))
- target = target.parent
-
- self.expr = ' '.join(str(n) for n in self.data[2:] if not isinstance(n, Declaration))
- if self.expr:
- target.declareset.append(self)
-
- def __str__(self):
- """ Warning on unknown declaration
- and write current in outstring.
- """
- if ( not SORTING.has_key(self.name.strip('*_'))
- and self.root.get_opt('warn') ):
- warn("Unknown declaration: %s" % self.name)
-
- return (":%s" % self.root.cache['delims'][1] ).join(
- (self.name, self.expr))
-
-
-class DeclarationName(ParseNode):
- """ Name of declaration node.
- For spliting it in one string.
- """
- delim = ''
-
-
-class SelectorTree(ParseNode):
- """ Tree of selectors in ruleset.
- """
- delim = ', '
-
- def extend(self, target):
- """ @extend selectors tree.
- """
- self_test = ', '.join(map(str, self.data))
- target_test = ', '.join(map(str, target.data))
- self.data = (self_test + ', ' + self_test.replace(str(self.data[0].data[0]), target_test)).split(', ')
-
- def __add__(self, target):
- """ Add selectors from parent nodes.
- """
- if isinstance(target, SelectorTree):
- self_test = ', '.join(map(str, self.data))
- target_test = ', '.join(map(str, target.data))
- self.data = _nest(target_test, self_test).split(', ')
- return self
-
- def __str__(self):
- selOut = ''
- for entry in self.data:
- if (isinstance(entry, str)):
- # Combinator and commas are as raw strings.
- selOut += ' %s ' % entry
- else:
- for selEntry in entry.data:
- if (isinstance(selEntry, str)):
- selOut += ' %s ' % selEntry
- else:
- # Construct the pseudo elements etc. multiple regex tokens as str.
- selOut += ''.join(str(n) for n in selEntry.data);
- selOut += ' '
- return selOut
-
-
-class Selector(ParseNode):
- """ Simple selector node.
- """
- delim = ''
-
- def __str__(self):
- """ Write to output.
- """
- return ''.join(StringValue(n).value for n in self.data)
-
-
-class VarDefinition(ParseNode, Empty):
- """ Variable definition.
- """
- def __init__(self, s, n, t):
- """ Save self.name, self.default, self.expression
- """
- super(VarDefinition, self).__init__(s, n, t)
- self.name = t[0][1:]
- self.default = len(t) > 2
- self.expression = t[1]
-
- def parse(self, target):
- """ Update root and parent context.
- """
- super(VarDefinition, self).parse(target)
- if isinstance(self.parent, ParseNode):
- self.parent.ctx.update({ self.name: self.expression.value })
- self.root.set_var(self)
-
-
-class Media(ParseNode):
- def __str__(self):
- selOut = ''
- # TODO(terry): Need to retain parenthesis in expression for the media
- # selector. Parenthesis are important and need a better
- # grammar. For now hack is to wrap the 'and' operator and
- # comma operator to use emit parentheses around expressions.
- anyOper = False
- openParen = 0
- for entry in self.data:
- if isinstance(entry, str) and entry == 'and':
- if openParen > 0:
- selOut += ') and '
- openParen -= 1
- else:
- selOut += ' and '
- anyOper = True
- elif isinstance(entry, str) and entry == '{':
- selOut += ''.join([')' for n in xrange(openParen)])
- selOut += ' {\n'
- # Handle the expression.
- elif isinstance(entry, StringValue):
- if openParen > 0:
- selOut += ') , (%s' % entry
- elif anyOper:
- selOut += '(%s' % entry
- anyOper = False
- openParen += 1
- else:
- selOut += ' %s ' % entry
- else:
- selOut += ' %s ' % entry
-
- selOut += '}\n'
- return selOut
-
-class Stylesheet(object):
- """ Root stylesheet node.
- """
-
- def_delims = '\n', ' ', '\t'
-
- # Known stylet base classes.
- styletClasses = []
-
- # List of known CSS class names emitted. We only want to emit one constant
- # per CSS class.
- knownClassNames = []
-
- # Dart class to output only class name selectors with style properties.
- cssClass = []
-
- # Dart class to output only class name selectors with no style properties.
- cssStateSelectors = []
-
- currentOptions = []
- currentFile = ''
-
- scssIncludes = []
-
- exportedClassName = []
- classNameAsState = []
-
- def __init__(self, cache = None, options=None):
- self.cache = cache or dict(
-
- # Variables context
- ctx = dict(),
-
- # Mixin context
- mix = dict(),
-
- # Rules context
- rset = defaultdict(set),
-
- # Options context
- opts = dict(
- comments = True,
- warn = True,
- sort = True,
- path = os.getcwd(),
- ),
-
- # CSS delimeters
- delims = self.def_delims,
-
- )
-
- if options:
- self.currentOptions = options
- for option in options.items():
- self.set_opt(*option)
-
- self.setup()
- Node.root = self
-
- def setup(self):
-
- # Values
- OTHER_VALUE.setParseAction(NumberValue)
- PERCENTAGE_VALUE.setParseAction(NumberValue)
- IDENT.setParseAction(StringValue)
- PATH.setParseAction(StringValue)
- POINT.setParseAction(PointValue)
- COLOR_VALUE.setParseAction(ColorValue)
- REPEAT_VALUE.setParseAction(RepeatValue)
- quotedString.setParseAction(QuotedStringValue)
- EXPRESSION.setParseAction(Expression)
- SEP_VAL_STRING.setParseAction(SepValString)
-
- # Vars
- VARIABLE.setParseAction(Variable)
- VAR_DEFINITION.setParseAction(VarDefinition)
- VARIABLES.setParseAction(Variables)
- FUNCTION.setParseAction(Function)
- FUNCTION_DEFINITION.setParseAction(FunctionDefinition)
- FUNCTION_RETURN.setParseAction(FunctionReturn)
-
- # Coments
- SCSS_COMMENT.setParseAction(lambda x: '')
- CSS_COMMENT.setParseAction(Comment)
-
- # At rules
- IMPORT.setParseAction(Import)
- CHARSET.setParseAction(Import)
- MEDIA.setParseAction(Media)
- STYLET.setParseAction(Stylet)
- ANIMATION_DECLARATIONS.setParseAction(AnimationDecls)
- ANIMATION_BODY.setParseAction(AnimationBody)
-
- # Rules
- RULESET.setParseAction(Ruleset)
- DECLARATION.setParseAction(Declaration)
- DECLARATION_NAME.setParseAction(DeclarationName)
- SELECTOR.setParseAction(Selector)
- SELECTOR_GROUP.setParseAction(ParseNode)
- SELECTOR_TREE.setParseAction(SelectorTree)
- FONT_FACE.setParseAction(ContentNode)
-
- # SCSS Directives
- MIXIN.setParseAction(Mixin)
- MIXIN_PARAM.setParseAction(MixinParam)
- INCLUDE.setParseAction(Include)
- EXTEND.setParseAction(Extend)
- OPTION.setParseAction(Option)
- IF.setParseAction(If)
- IF_BODY.setParseAction(IncludeNode)
- ELSE.setParseAction(IncludeNode)
- FOR.setParseAction(For)
- FOR_BODY.setParseAction(IncludeNode)
- WARN.setParseAction(Warn)
-
- @property
- def ctx(self):
- return self.cache['ctx']
-
- def set_var(self, vardef):
- """ Set variable to global stylesheet context.
- """
- if not(vardef.default and self.cache['ctx'].get(vardef.name)):
- self.cache['ctx'][vardef.name] = vardef.expression.value
-
- def set_opt(self, name, value):
- """ Set option.
- """
- self.cache['opts'][name] = value
-
- if name == 'compress':
- self.cache['delims'] = self.def_delims if not value else ('', '', '')
-
- def get_opt(self, name):
- """ Get option.
- """
- return self.cache['opts'].get(name)
-
- def update(self, cache):
- """ Update self cache from other.
- """
- self.cache['delims'] = cache.get('delims')
- self.cache['opts'].update(cache.get('opts'))
- self.cache['rset'].update(cache.get('rset'))
- self.cache['mix'].update(cache.get('mix'))
- map(self.set_var, cache['ctx'].values())
-
- def scan(self, src):
- """ Scan scss from string and return nodes.
- """
- assert isinstance(src, basestring)
- try:
- nodes = STYLESHEET.parseString(src, parseAll=True)
- return nodes
- except ParseBaseException:
- err = sys.exc_info()[1]
- print >> sys.stderr, err.line
- print >> sys.stderr, " "*(err.column-1) + "^"
- print >> sys.stderr, err
- sys.exit(1)
-
- def parse(self, nodes):
- map(lambda n: n.parse(self) if isinstance(n, Node) else None, nodes)
-
- def loads(self, src):
- """ Compile css from scss string.
- """
- assert isinstance(src, basestring)
- nodes = self.scan(src.strip())
- self.parse(nodes)
- return ''.join(map(str, nodes))
-
- def load(self, f, precache=None):
- """ Compile scss from file.
- File is string path of file object.
- """
- precache = precache or self.get_opt('cache') or False
- nodes = None
- if isinstance(f, file):
- path = os.path.abspath(f.name)
-
- else:
- path = os.path.abspath(f.name)
- f = open(f)
-
- cache_path = os.path.splitext(path)[0] + '.ccss'
-
- if precache and os.path.exists(cache_path):
- ptime = os.path.getmtime(cache_path)
- ttime = os.path.getmtime(path)
- if ptime > ttime:
- dump = open(cache_path, 'rb').read()
- nodes = cPickle.loads(dump)
-
- if not nodes:
- src = f.read()
- nodes = self.scan(src.strip())
-
- if precache:
- f = open(cache_path, 'wb')
- cPickle.dump(nodes, f)
-
- self.parse(nodes)
- return ''.join(map(str, nodes))
-
- # TODO(terry): For now special function for returning nodes.
- def loadReturnNodes(self, f, precache=None):
- """ Compile scss from file.
- File is string path of file object.
- """
- self.currentFile = f
-
- precache = precache or self.get_opt('cache') or False
- nodes = None
- if isinstance(f, file):
- path = os.path.abspath(f.name)
-
- else:
- path = os.path.abspath(f.name)
- f = open(f)
-
- cache_path = os.path.splitext(path)[0] + '.ccss'
-
- if precache and os.path.exists(cache_path):
- ptime = os.path.getmtime(cache_path)
- ttime = os.path.getmtime(path)
- if ptime > ttime:
- dump = open(cache_path, 'rb').read()
- nodes = cPickle.loads(dump)
-
- if not nodes:
- src = f.read()
- nodes = self.scan(src.strip())
-
- if precache:
- f = open(cache_path, 'wb')
- cPickle.dump(nodes, f)
-
- self.parse(nodes)
- return nodes
-
- def __str__(self):
- return 'media';
-
- # Format of the Dart CSS class:
- #
- # class Layout1 {
- # // selector, properties<propertyName, value>
- # static final selectors = const {
- # '#elemId' : const {
- # 'left' : '20px'
- # },
- # '.className' : const {
- # 'color' : 'red'
- # }
- # };
- # }
- #
- # Emit pre-defined classes for Dart CSS.
- #
- def emitPreDefineDart(self, sourceFile):
- return ['// File generated by SCSS from source file %s\n' % sourceFile,
- '// Do not edit.\n\n'
- ]
-
- def emitCssClass(self, cssName):
- self.cssClass.append('class {0} {{\n'.format(cssName))
- self.cssClass.append(' // CSS class selectors:\n')
-
- # Emit stylet instance:
- #
- # static final CssLayout layout = new CssLayout();
- def emitStyletInstance(self, styletName):
- styletClass = 'STYLET_{0}'.format(styletName)
- return ' static final {0} {1} = new {0}();\n\n'.format(styletClass,
- styletName)
-
- # Emit each exported stylet.
- #
- # class {stylet name} {
- # // selector, properties<propertyName, value>
- # static final selectors = const {
- def emitStyletClass(self, stylet):
- self.styletClasses.append('class {0} {{\n'.
- format(stylet.name))
- self.styletClasses.append(' // selector, properties<propertyName, value>\n')
- self.styletClasses.append(' static final selectors = const {\n')
- return stylet.name
-
- def emitCloseCSSStyletSelector(self):
- self.styletClasses.append("\n }")
-
- # Emit the selector for this style:
- # where selectorValue is valid selector (e.g., #elemId, .className, etc.)
- #
- # 'selectorValue' : const {
- def emitCSSStyletSelector(self, selectorTree, anySelectors):
- if anySelectors:
- self.styletClasses.append(",\n");
- self.styletClasses.append(" '%s' : const {\n" % selectorTree.data[0])
-
- # Emit each property in the stylet property map:
- # 'propName' : 'propValue'
- def emitStyletProperty(self, decl, anyProps):
- if anyProps:
- self.styletClasses.append(',\n')
- propValues = len(decl)
- if propValues > 0:
- values = []
- first = True
- for value in decl[-(propValues - 2):]:
- values.append(('{0}' if first else ' {0}').format(value))
- first = False
- self.styletClasses.append(" '{0}' : \"{1}\"".
- format(decl[0], ''.join(values)))
- anyProps = True
- return anyProps
-
- def emitEndStyletClass(self):
- self.styletClasses.append('\n };\n')
- self.styletClasses.append('}\n\n')
-
- # Emit each CSS class name as a constant string in the generated Dart class,
- # but only once.
- def emitDartCSSClassName(self, selectorTree):
- # Only process selectors ignore declarations associated with the
- # selectors.
- for parseNode in selectorTree.data:
- if isinstance(parseNode, ParseNode):
- assert isinstance(parseNode.data[0], ParseNode)
-
- if len(parseNode.data) == 1:
- for selector in parseNode.data:
- # Tree will contain selector and strings (e.g., commas, etc.).
- if isinstance(selector, Selector):
- if len(selector.data) == 1:
- selectName = selector.data[0]
- if selectName[0] == '.' and selectName.rfind('.') == 0:
- # static final String ARTICLE = 'article';
- className = selectName[1:]
- if not(className in self.knownClassNames):
- # Class name hasn't been emitted; emit now.
-
- # TODO(terry): Better mechanism then replacing -
- # with _. Possibly add export name
- # attribute.
- exportedName = className.upper().replace('-', '_')
- self.cssClass.append(
- " static final String {0} = '{1}';\n".
- format(exportedName, className))
- # Add to list of known class names emitted.
- self.knownClassNames.append(className)
-
- # Decide if class selector should be as exported class name (that has a
- # a real CSS style) or as a class name used for state (no CSS style).
- def addToKnownClassList(self, selectorTree):
- for parseNode in selectorTree.data:
- if isinstance(parseNode, ParseNode):
- if len(parseNode.data) == 1:
- name = parseNode.data[0].data[0]
- if name[0] == '.':
- cssName = name[1:]
- if not(cssName in self.exportedClassName):
- self.exportedClassName.append(cssName)
- else:
- for node in parseNode.data:
- if isinstance(node, Selector):
- for name in node.data:
- if name[0] == '.':
- cssName = name[1:]
- if not(cssName in self.exportedClassName) and not(
- cssName in self.classNameAsState):
- self.classNameAsState.append(cssName)
-
- def emitCssSelector(self, name):
- exportedName = name.upper().replace('-', '_')
- self.cssClass.append(" static final String {0} = '{1}';\n".
- format(exportedName, name))
-
- def emitCssStateSelectors(self):
- self.cssStateSelectors.append('\n // CSS state class selectors:\n')
-
- def emitCssStateSelector(self, name):
- exportedName = name.upper().replace('-', '_')
- self.cssStateSelectors.append(" static final String {0} = '{1}';\n".
- format(exportedName, name))
-
- #class cssTest {
- # static final String FRONTVIEW = 'frontview';
- # static final String QUERY = 'query';
- #
- # static final CssLayout layout = new CssLayout();
- #}
- def dartClass(self, sourceFile, cssName, cssFiles):
- self.styletClasses = self.emitPreDefineDart(sourceFile)
- self.knownClassNames = []
- self.cssClass = []
-
- # One class per CSS file.
- self.emitCssClass(cssName)
-
- # Iterate though all rulesets.
- stylets = []
- anyProps = False
-
- for file in cssFiles:
- nodes = file[1]
- for node in nodes:
- if isinstance(node, Ruleset):
- ruleset = node
- for selectorTree in ruleset.data:
- if isinstance(selectorTree, SelectorTree):
- # Process both class selectors with style properties and class
- # selectors used as state.
- self.addToKnownClassList(selectorTree)
- elif isinstance(node, Stylet):
- # We've hit a stylet emit the stylet class definition.
- stylet = node
- stylets.append(self.emitStyletClass(stylet))
- styletRulesets = stylet.data[2:]
- styletSelectorOpen = False;
- anySelectors = False
- for styletRuleset in styletRulesets:
- assert isinstance(styletRuleset, Ruleset)
- for selectorTree in styletRuleset.data:
- if isinstance(selectorTree, SelectorTree):
- if styletSelectorOpen:
- self.emitCloseCSSStyletSelector();
- styletSelectorOpen = False;
- anyProps = False;
- self.emitCSSStyletSelector(selectorTree, anySelectors);
- anySelectors = True;
- styletSelectorOpen = True;
- elif isinstance(selectorTree, Declaration):
- anyProps = self.emitStyletProperty(selectorTree.data, anyProps)
-
- if styletSelectorOpen:
- self.emitCloseCSSStyletSelector();
- anySelectors = False;
- anyProps = False;
-
- # Close the CSSStylet properties array and the style class we've
- # been emitting.
- self.emitEndStyletClass()
- anyProps = False
-
- # Emit all CSS class selectors that have a real CSS properties.
- for cssClassSelector in self.exportedClassName:
- self.emitCssSelector(cssClassSelector)
-
- # Emit the CSS_State class for CSS class selectors that have not CSS
- # properties associated with the class name.
- self.emitCssStateSelectors()
- for cssStateName in self.classNameAsState:
- if not(cssStateName in self.exportedClassName):
- self.emitCssStateSelector(cssStateName)
-
- # Emit CSS selectors that have no CSS style properties (used for state).
- self.cssClass.extend(self.cssStateSelectors)
-
- # Close the CSS class we're done.
- self.cssClass.append('}\n')
-
- self.styletClasses.extend(self.cssClass)
- return "".join(self.styletClasses)
-
- def addInclude(self, filename, nodes):
- self.scssIncludes.append([filename, nodes])
-
-def parse( src, cache=None ):
- """ Parse from string.
- """
- parser = Stylesheet(cache)
- return parser.loads(src)
-
-
-def load(path, cache=None, precache=False):
- """ Parse from file.
- """
- parser = Stylesheet(cache)
- return parser.load(path, precache=precache)
« no previous file with comments | « third_party/pyscss/scss/grammar.py ('k') | third_party/pyscss/scss/tests/__init__.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698