This commit is contained in:
jtm
2012-02-19 20:38:19 +00:00
parent 54ea212402
commit aaedc6bcfc
111 changed files with 440 additions and 3487 deletions

View File

@@ -19,7 +19,7 @@ class LessLexer:
states = (
('parn', 'inclusive'),
)
literals = ',{}>=%!/*-+:;()~';
literals = ',>{}=%!/*-+:;~&';
tokens = [
'css_ident',
'css_dom',
@@ -32,7 +32,6 @@ class LessLexer:
'css_color',
'css_filter',
'css_number',
'css_number_unit',
'css_important',
'css_vendor_hack',
'css_uri',
@@ -41,7 +40,6 @@ class LessLexer:
'less_comment',
'less_string',
'less_open_format',
'less_combine',
't_ws',
't_popen',
@@ -60,10 +58,23 @@ class LessLexer:
'@arguments': 'less_arguments',
}
tokens = tokens + list(set(reserved.values()))
tokens += list(set(reserved.values()))
significant_ws = [
'css_class',
'css_id',
'css_dom',
'css_property',
'css_vendor_property',
'css_ident',
'css_number',
'>',
'&',
]
significant_ws += list(set(reserved.values()))
def __init__(self):
self.build(reflags=re.UNICODE|re.IGNORECASE)
self.last = None
def t_css_filter(self, t):
(r'\[[^\]]*\]'
@@ -76,11 +87,11 @@ class LessLexer:
'|@[@\-]?)'
'([_a-z]'
'|[\200-\377]'
'|\\\[0-9a-f]{1,6}([ \t\f])?'
'|\\\[^\s\r\n0-9a-f])'
'|\\\[0-9a-f]{1,6}'
'|\\\[^\s\r\n0-9a-f])[ \t\f\v]?'
'([_a-z0-9\-]|[\200-\377]'
'|\\\[0-9a-f]{1,6}([ \t\f])?'
'|\\\[^\s\r\n0-9a-f])*[ \t]?')
'|\\\[0-9a-f]{1,6}'
'|\\\[^\s\r\n0-9a-f])*')
v = t.value.strip()
c = v[0]
if c == '.':
@@ -97,7 +108,6 @@ class LessLexer:
t.value = t.value.strip()
elif v.lower() in dom.html:
t.type = 'css_dom'
t.value = t.value
elif c == '@':
v = v.lower()
if v in LessLexer.reserved:
@@ -106,6 +116,7 @@ class LessLexer:
t.type = 'less_variable'
elif c == '-':
t.type = 'css_vendor_property'
t.value = t.value.strip()
return t
def t_css_color(self, t):
@@ -125,10 +136,10 @@ class LessLexer:
def t_parn_css_ident(self, t):
(r'(([_a-z]'
'|[\200-\377]'
'|\\\[0-9a-f]{1,6}([ \t\f])?'
'|\\\[0-9a-f]{1,6}'
'|\\\[^\r\n\s0-9a-f])'
'([_a-z0-9\-]|[\200-\377]'
'|\\\[0-9a-f]{1,6}([ \t\f])?'
'|\\\[0-9a-f]{1,6}'
'|\\\[^\r\n\s0-9a-f])*)')
return t
@@ -137,11 +148,11 @@ class LessLexer:
return t
def t_newline(self, t):
r'\n+'
t.lexer.lineno += len(t.value)
r'[\n\r]+'
t.lexer.lineno += t.value.count('\n')
def t_css_comment(self, t):
r'(/\*(.|\n)*?\*/)'
r'(/\*(.|\n|\r)*?\*/)'
t.lexer.lineno += t.value.count('\n')
pass
@@ -155,8 +166,8 @@ class LessLexer:
return t
def t_t_ws(self, t):
r'[ \t]+'
pass
r'[ \t\f\v]+'
return t
def t_t_popen(self, t):
r'\('
@@ -173,13 +184,16 @@ class LessLexer:
t.lexer.pop_state()
return t
def t_less_combine(self, t):
r'&[ \t]?'
def t_less_string(self, t):
(r'"([^"@]*@\{[^"\}]+\}[^"]*)+"'
'|\'([^\'@]*@\{[^\'\}]+\}[^\']*)+\'')
t.lexer.lineno += t.value.count('\n')
return t
t_less_string = (r'"([^"@]*@\{[^"\}]+\}[^"]*)+"'
'|\'([^\'@]*@\{[^\'\}]+\}[^\']*)+\'')
t_css_string = r'"[^"]*"|\'[^\']*\''
def t_css_string(self, t):
r'"[^"]*"|\'[^\']*\''
t.lexer.lineno += t.value.count('\n')
return t
# Error handling rule
def t_error(self, t):
@@ -193,11 +207,18 @@ class LessLexer:
def file(self, filename):
with open(filename) as f:
self.lexer.input(f.read())
return self.lexer
return self
def input(self, filename):
with open(filename) as f:
self.lexer.input(f.read())
def token(self):
return self.lexer.token()
while True:
t = self.lexer.token()
if not t: return t
if t.type == 't_ws' and self.last and self.last.type not in self.significant_ws:
continue
self.last = t
break
return t

View File

@@ -1,5 +1,6 @@
"""
LESSCSS Parser.
.. module:: parser
:synopsis: Lesscss parser.
http://www.dabeaz.com/ply/ply.html
http://www.w3.org/TR/CSS21/grammar.html#scanner
@@ -7,7 +8,7 @@
Copyright (c)
See LICENSE for details.
<jtm@robot.is>
.. moduleauthor:: Jóhann T. Maríusson <jtm@robot.is>
"""
import os
import ply.yacc
@@ -25,36 +26,41 @@ class LessParser(object):
def __init__(self,
lex_optimize=True,
yacc_optimize=True,
yacctab='yacctab',
tabfile='yacctab',
yacc_debug=False,
scope=None,
outputdir='/tmp',
importlvl=0,
verbose=False):
""" Parser object
@param bool: Optimized lexer
@param bool: Optimized parser
@param string: Yacc tables file
@param bool: Debug mode
@param dict: Included scope
Kwargs:
lex_optimize (bool): Optimize lexer
yacc_optimize (bool): Optimize parser
tabfile (str): Yacc tab filename
yacc_debug (bool): yacc debug mode
scope (Scope): Inherited scope
outputdir (str): Output (debugging)
importlvl (int): Import depth
verbose (bool): Verbose mode
"""
self.verbose = verbose
self.importlvl = importlvl
self.lex = lexer.LessLexer()
if not yacctab:
yacctab = 'yacctab'
if not tabfile:
tabfile = 'yacctab'
self.ignored = ('t_ws', 'css_comment', 'less_comment',
self.ignored = ('css_comment', 'less_comment',
'css_vendor_hack', 'css_keyframes')
self.tokens = [t for t in self.lex.tokens
if t not in self.ignored]
self.parser = ply.yacc.yacc(
module=self,
start='unit',
start='tunit',
debug=yacc_debug,
optimize=yacc_optimize,
tabmodule=yacctab,
tabmodule=tabfile,
outputdir=outputdir
)
self.scope = scope if scope else Scope()
@@ -76,49 +82,55 @@ class LessParser(object):
"""
if self.result:
utility.print_recursive(self.result)
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_tunit(self, p):
""" tunit : unit_list
"""
p[0] = p[1]
def p_unit_list(self, p):
""" unit_list : unit_list unit
| unit
"""
if len(p) == 3:
p[1].append(p[2])
p[0] = p[1]
def p_unit(self, p):
""" unit : statement_list
"""
p[0] = p[1]
def p_statement_list_aux(self, p):
""" statement_list : statement_list statement
"""
p[1].extend([p[2]])
p[0] = p[1]
def p_statement_list(self, p):
""" statement_list : statement
""" unit : statement
| variable_decl
| block_decl
| mixin_decl
"""
p[0] = [p[1]]
def p_statement(self, p):
""" statement : block_decl
| variable_decl
| mixin_decl
"""
p[0] = p[1]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_statement_aux(self, p):
""" statement : css_charset css_string ';'
| css_namespace css_string ';'
""" statement : css_charset t_ws css_string ';'
| css_namespace t_ws css_string ';'
"""
p[0] = Statement(p)
p[0] = Statement(list(p)[1:])
p[0].parse(None)
def p_statement_namespace(self, p):
""" statement : css_namespace css_ident css_string ';'
""" statement : css_namespace t_ws word css_string ';'
"""
p[0] = Statement(p)
p[0] = Statement(list(p)[1:])
p[0].parse(None)
def p_statement_import(self, p):
""" statement : css_import css_string ';'
""" statement : css_import t_ws css_string ';'
"""
if self.importlvl > 8:
raise ImportError('Recrusive import level too deep > 8 (circular import ?)')
ipath = utility.destring(p[2])
ipath = utility.destring(p[3])
fn, fe = os.path.splitext(ipath)
if not fe or fe.lower() == '.less':
try:
@@ -126,7 +138,7 @@ class LessParser(object):
if not fe: ipath += '.less'
filename = "%s%s%s" % (cpath, os.sep, ipath)
if os.path.exists(filename):
recurse = LessParser(importlvl=self.importlvl+1)
recurse = LessParser(importlvl=self.importlvl+1, verbose=self.verbose)
recurse.parse(filename=filename, debuglevel=0)
self.scope.update(recurse.scope)
else:
@@ -138,25 +150,16 @@ class LessParser(object):
else:
p[0] = Statement(p)
p[0].parse(None)
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_mixin_decl(self, p):
""" mixin_decl : block_open_mixin declaration_list brace_close
"""
try:
mixin = Mixin(p)
mixin.parse(self.scope, self.stash)
self.scope.add_mixin(mixin)
except SyntaxError as e:
self.handle_error(e, p)
p[0] = None
#
def p_block_decl(self, p):
""" block_decl : block_open declaration_list brace_close
def p_block(self, p):
""" block_decl : block_open declaration_list brace_close
"""
try:
block = Block(p)
block = Block(list(p)[1:-1])
if not self.scope.in_mixin():
block.parse(self.scope)
self.scope.add_block(block)
@@ -165,176 +168,102 @@ class LessParser(object):
self.handle_error(e, p)
p[0] = None
def p_block_empty(self, p):
""" block_decl : block_open brace_close
def p_block_replace(self, p):
""" block_decl : identifier ';'
"""
p[0] = None
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_block_open_mixin(self, p):
""" block_open_mixin : css_class t_popen block_mixin_args t_pclose brace_open
"""
self.scope.current = '__mixin__'
p[0] = list(p)[1:5]
def p_block_open_mixin_aux(self, p):
""" block_open_mixin : css_class t_popen less_arguments t_pclose brace_open
"""
self.scope.current = '__mixin__'
p[0] = list(p)[1:5]
def p_block_open_mixin_empty(self, p):
""" block_open_mixin : css_class t_popen t_pclose brace_open
"""
self.scope.current = '__mixin__'
p[0] = [p[1]]
def p_block_mixin_args_aux(self, p):
""" block_mixin_args : block_mixin_args ',' block_mixin_arg
"""
p[1].extend([p[2], p[3]])
p[0] = p[1]
def p_block_mixin_args(self, p):
""" block_mixin_args : block_mixin_arg
"""
p[0] = [p[1]]
def p_block_mixin_arg_def(self, p):
""" block_mixin_arg : less_variable ':' block_mixin_factor
| less_variable ':' less_variable
"""
p[0] = list(p)[1:4]
def p_block_mixin_arg(self, p):
""" block_mixin_arg : block_mixin_factor
| less_variable
"""
p[0] = p[1]
def p_block_mixin_factor(self, p):
""" block_mixin_factor : css_number
| css_color
| css_ident
| css_string
"""
p[0] = p[1]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_block_open(self, p):
""" block_open : identifier_list brace_open
""" block_open : identifier brace_open
"""
name = ["%s " % t
if t in '>+'
else t
for t in utility.flatten(p[1])]
self.scope.current = ''.join(name).strip()
p[0] = p[1]
def p_identifier_list_mixin(self, p):
""" mixin : identifier_list ';'
def p_media_open(self, p):
""" block_open : css_media t_ws identifier brace_open
"""
p[0] = [p[1], p[3]]
def p_font_face_open(self, p):
""" block_open : css_font_face t_ws brace_open
"""
p[0] = p[1]
def p_identifier_list(self, p):
""" identifier_list : identifier_group
| identifier_page
| css_font_face
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_mixin(self, p):
""" mixin_decl : open_mixin declaration_list brace_close
"""
if type(p[1]) is list:
p[0] = p[1]
else:
p[0] = [p[1]]
def p_identifier_page_aux(self, p):
""" identifier_page : identifier_page dom_filter
p[0] = None
def p_open_mixin(self, p):
""" open_mixin : class t_popen mixin_args t_pclose brace_open
| id t_popen mixin_args t_pclose brace_open
"""
p[1].extend(p[2])
p[0] = p[1]
def p_identifier_page(self, p):
""" identifier_page : css_page
"""
p[0] = [p[1]]
p[0] = None
def p_identifier_group_op(self, p):
""" identifier_group : identifier_group ',' identifier
| identifier_group '+' identifier
def p_call_mixin(self, p):
""" call_mixin : class t_popen mixin_args t_pclose ';'
| id t_popen mixin_args t_pclose ';'
"""
p[1].extend([p[2], p[3]])
p[0] = None
def p_mixin_args_aux(self, p):
""" mixin_args : mixin_args ',' argument
| mixin_args ',' mixin_kwarg
"""
p[1].append(p[2])
p[1].append(p[3])
p[0] = p[1]
def p_identifier_group_aux(self, p):
""" identifier_group : identifier_group identifier
"""
p[1].extend([p[2]])
p[0] = p[1]
def p_identifier_group(self, p):
""" identifier_group : identifier
def p_mixin_args(self, p):
""" mixin_args : argument
| mixin_kwarg
| empty
"""
p[0] = [p[1]]
def p_identifier_group_media(self, p):
""" identifier_group : css_media
def p_mixin_kwarg(self, p):
""" mixin_kwarg : variable ':' argument
"""
p[0] = [p[1]]
def p_identifier(self, p):
""" identifier : css_dom
| css_id
| css_class
| dom_filter
| filter_group
| css_color
| less_combine
| '*'
| '>'
"""
p[0] = p[1]
p[0] = list(p)[1:]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_declaration_list_aux(self, p):
""" declaration_list : declaration_list declaration
#
def p_declaration_list(self, p):
""" declaration_list : declaration_list declaration
| declaration
| empty
"""
p[1].extend([p[2]])
if len(p) > 2:
p[1].extend(p[2])
p[0] = p[1]
def p_declaration_list(self, p):
""" declaration_list : declaration
def p_declaration(self, p):
""" declaration : variable_decl
| property_decl
| block_decl
| mixin_decl
| call_mixin
"""
p[0] = [p[1]]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_declaration(self, p):
""" declaration : property_decl
"""
p[0] = p[1]
def p_declaration_block(self, p):
""" declaration : block_decl
| variable_decl
"""
p[0] = p[1]
def p_variable_decl(self, p):
""" variable_decl : less_variable ':' style_list ';'
""" variable_decl : variable ':' style_list ';'
"""
try:
v = Variable(p)
v.parse(self.scope)
if self.scope.current == '__mixin__':
self.stash[v.name()] = v
else:
self.scope.add_variable(v)
# v.parse(self.scope)
# if self.scope.current == '__mixin__':
# self.stash[v.name()] = v
# else:
# self.scope.add_variable(v)
except SyntaxError as e:
self.handle_error(e, p)
p[0] = None
@@ -342,62 +271,13 @@ class LessParser(object):
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_property_mixin_call(self, p):
""" property_decl : identifier_list t_popen argument_list t_pclose ';'
"""
n = p[1][0]
mixin = self.scope.mixins(n)
if mixin:
if not self.scope.in_mixin():
try:
p[0] = mixin.call(p[3], self.scope)
except SyntaxError as e:
self.handle_error(e, p)
p[0] = None
else:
p[0] = mixin
else:
self.handle_error('Mixin not found in scope: ´%s´' % n, p)
p[0] = None
def p_property_mixin_call_empty(self, p):
""" property_decl : identifier_list t_popen t_pclose ';'
"""
n = p[1][0]
mixin = self.scope.mixins(n)
if mixin:
try:
p[0] = mixin.call(None, self.scope)
except SyntaxError as e:
self.handle_error(e, p)
p[0] = None
else:
p[0] = None
def p_property_mixin(self, p):
""" property_decl : mixin
"""
m = ''.join([u.strip() for u in p[1]])
l = utility.block_search(m, self.scope)
mixin = self.scope.mixins(m)
if l:
p[0] = [b.parsed['proplist'] for b in l]
elif mixin:
try:
p[0] = mixin.call(None, self.scope)
except SyntaxError as e:
self.handle_error(e, p)
p[0] = None
else:
p[0] = []
def p_property_decl(self, p):
""" property_decl : property ':' style_list ';'
| property ':' style_list
""" property_decl : prop_open style_list ';'
| prop_open empty ';'
| prop_open less_arguments ';'
"""
p[0] = Property(p)
p[0] = Property(list(p)[1:-1])
if not self.scope.in_mixin():
try:
p[0].parse(self.scope)
@@ -405,165 +285,158 @@ class LessParser(object):
self.handle_error(e, p)
p[0] = None
def p_prop_decl_bad(self, p):
""" property_decl : property ':' ';'
"""
p[0] = None
def p_property_ie_hack(self, p):
""" property : '*' property
"""
p[0] = "%s%s" % (p[1], p[2])
def p_property(self, p):
""" property : css_property
| css_vendor_property
| css_ident
def p_prop_open(self, p):
""" prop_open : property ':'
| vendor_property ':'
| word ':'
"""
p[0] = p[1]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_style_list_aux(self, p):
""" style_list : style_list style
| style_list ',' style
| style_list css_important
"""
p[1].extend(list(p)[2:])
p[0] = p[1]
def p_style_list(self, p):
""" style_list : style_group
"""
p[0] = p[1]
def p_less_style_list(self, p):
""" style_list : less_arguments
"""
p[0] = p[1]
def p_style_group_sep(self, p):
""" style_group : style_group ',' style
"""
p[1].extend([p[2], p[3]])
p[0] = p[1]
def p_style_group_aux(self, p):
""" style_group : style_group style
"""
p[1].extend([p[2]])
p[0] = p[1]
def p_style_group(self, p):
""" style_group : style
""" style_list : style
"""
p[0] = [p[1]]
def p_style(self, p):
""" style : expression
| css_important
| css_string
| istring
| css_vendor_property
| css_property
| css_ident
""" style : expression
| css_string
| word
| property
| vendor_property
| istring
| fcall
"""
p[0] = p[1]
def p_style_escape(self, p):
""" style : '~' istring
| '~' css_string
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_identifier(self, p):
""" identifier : identifier_list
"""
p[0] = Call(p)
p[0] = Identifier(p[1])
def p_identifier_list_aux(self, p):
""" identifier_list : identifier_list ',' identifier_group
"""
p[1].extend([p[2]])
p[1].extend(p[3])
p[0] = p[1]
def p_identifier_list(self, p):
""" identifier_list : identifier_group
"""
p[0] = p[1]
def p_identifier_group_op(self, p):
""" identifier_group : identifier_group child_selector ident_parts
| identifier_group '+' ident_parts
"""
p[1].extend([p[2]])
p[1].extend(p[3])
p[0] = p[1]
def p_identifier_group(self, p):
""" identifier_group : ident_parts
"""
p[0] = p[1]
def p_ident_parts_aux(self, p):
""" ident_parts : ident_parts ident_part
| ident_parts filter_group
"""
if type(p[2]) is list:
p[1].extend(p[2])
else: p[1].append(p[2])
p[0] = p[1]
def p_ident_parts(self, p):
""" ident_parts : ident_part
| selector
| filter_group
"""
if type(p[1]) is not list:
p[1] = [p[1]]
p[0] = p[1]
def p_selector(self, p):
""" selector : child_selector ident_part
| '+' ident_part
| '*' ident_part
"""
p[0] = [p[1], p[2]]
def p_selector_comb(self, p):
""" selector : combinator
| '*'
"""
p[0] = p[1]
def p_ident_part(self, p):
""" ident_part : class
| id
| dom
"""
p[0] = p[1]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_dom_filter(self, p):
""" dom_filter : css_dom filter_group
| css_id filter_group
| css_class filter_group
| less_combine filter_group
"""
p[0] = [p[1], p[2]]
def p_filter_group_aux(self, p):
""" filter_group : filter filter
""" filter_group : filter_group filter
"""
p[1].extend([p[2]])
p[1].extend(p[2])
p[0] = p[1]
def p_filter_group(self, p):
""" filter_group : filter
""" filter_group : filter
"""
p[0] = [p[1]]
p[0] = p[1]
def p_filter(self, p):
""" filter : css_filter
| ':' css_ident
| ':' css_vendor_property
| ':' css_filter
| ':' ':' css_ident
| ':' ':' css_vendor_property
""" filter : css_filter
| ':' word
| ':' vendor_property
| ':' css_filter
| ':' ':' word
| ':' ':' vendor_property
"""
p[0] = list(p)[1:]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_expression_aux(self, p):
'''expression : expression '+' expression
| expression '-' expression
| expression '*' expression
| expression '/' expression
'''
p[0] = Expression(p)
def p_expression_p_neg(self, p):
""" expression : '-' t_popen expression t_pclose
"""
p[0] = [p[1], p[3]]
def p_expression_p(self, p):
""" expression : t_popen expression t_pclose
"""
p[0] = p[2]
def p_expression(self, p):
""" expression : factor
"""
p[0] = p[1]
def p_factor(self, p):
"""factor : color
| number
| variable
| css_dom
| fcall
"""
p[0] = p[1]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
#
def p_fcall(self, p):
""" fcall : css_ident t_popen argument_list t_pclose
| css_property t_popen argument_list t_pclose
| css_vendor_property t_popen argument_list t_pclose
""" fcall : word t_popen argument_list t_pclose
| property t_popen argument_list t_pclose
| vendor_property t_popen argument_list t_pclose
| less_open_format argument_list t_pclose
"""
p[0] = Call(p)
p[0] = Call(list(p)[1:])
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_argument_list_aux_1(self, p):
""" argument_list : argument_list ',' argument
"""
p[1].extend([p[2], p[3]])
p[0] = p[1]
def p_argument_list_aux(self, p):
""" argument_list : argument_list argument
""" argument_list : argument_list argument
| argument_list ',' argument
"""
p[1].extend([p[2]])
p[1].extend(list(p)[2:])
p[0] = p[1]
def p_argument_list(self, p):
@@ -575,67 +448,155 @@ class LessParser(object):
""" argument : expression
| css_string
| istring
| css_ident
| css_id
| word
| id
| css_uri
| '='
| fcall
"""
p[0] = p[1]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_expression_aux(self, p):
""" expression : expression operator expression
"""
p[0] = Expression(list(p)[1:])
def p_expression_p_neg(self, p):
""" expression : '-' t_popen expression t_pclose
"""
p[0] = [p[1], p[3]]
def p_expression_p(self, p):
""" expression : t_popen expression t_pclose
"""
p[0] = p[2]
def p_expression(self, p):
""" expression : factor
"""
p[0] = p[1]
def p_factor(self, p):
""" factor : color
| number
| variable
| css_dom
"""
p[0] = p[1]
def p_operator(self, p):
""" operator : operator t_ws
| '+'
| '-'
| '*'
| '/'
"""
p[0] = tuple(list(p)[1:])
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_interpolated_str(self, p):
""" istring : less_string
""" istring : less_string
"""
p[0] = String(p)
def p_variable_neg(self, p):
""" variable : '-' variable
""" variable : '-' variable
"""
p[0] = '-' + p[2]
def p_variable_strange(self, p):
""" variable : t_popen variable t_pclose
""" variable : t_popen variable t_pclose
"""
p[0] = p[2]
def p_variable(self, p):
""" variable : less_variable
""" variable : less_variable
| less_variable t_ws
"""
p[0] = p[1]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_color(self, p):
""" color : css_color
""" color : css_color
"""
p[0] = LessColor().format(p[1])
def p_number(self, p):
""" number : css_number
| css_number_unit
"""
p[0] = p[1]
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#
def p_number(self, p):
""" number : css_number
| css_number t_ws
"""
p[0] = tuple(list(p)[1:])
def p_dom(self, p):
""" dom : css_dom
| css_dom t_ws
"""
p[0] = tuple(list(p)[1:])
def p_word(self, p):
""" word : css_ident
| css_ident t_ws
"""
p[0] = tuple(list(p)[1:])
def p_class(self, p):
""" class : css_class
| css_class t_ws
"""
p[0] = tuple(list(p)[1:])
def p_id(self, p):
""" id : css_id
| css_id t_ws
"""
p[0] = tuple(list(p)[1:])
def p_property(self, p):
""" property : css_property
| css_property t_ws
"""
p[0] = tuple(list(p)[1:])
def p_vendor_property(self, p):
""" vendor_property : css_vendor_property
| css_vendor_property t_ws
"""
p[0] = tuple(list(p)[1:])
def p_combinator(self, p):
""" combinator : '&' t_ws
| '&'
"""
p[0] = tuple(list(p)[1:])
def p_child_selector(self, p):
""" child_selector : '>' t_ws
| '>'
"""
p[0] = tuple(list(p)[1:])
def p_scope_open(self, p):
""" brace_open : '{'
""" brace_open : '{'
"""
self.scope.push()
p[0] = p[1]
def p_scope_close(self, p):
""" brace_close : '}'
""" brace_close : '}'
"""
self.scope.pop()
p[0] = p[1]
def p_empty(self, p):
'empty :'
pass
#
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#

View File

@@ -129,26 +129,25 @@ def is_variable(v):
if type(v) is str:
return (v.startswith('@') or v.startswith('-@'))
return False
def print_recursive(ll, lvl=0):
""" Scopemap printer
@param list: parser result
@param int: depth
"""
if not ll: return
pad = ''.join(['. '] * lvl)
if type(ll) is list:
ll = flatten(ll)
for l in ll:
t = type(l)
if t == str:
print(pad + l)
else:
print_recursive(l, lvl+1)
pad = ''.join(['.'] * lvl)
t = type(ll)
if t is list:
for l in ll: print_recursive(l, lvl+1)
elif hasattr(ll, '_p'):
print(pad + str(type(ll)))
print_recursive(ll._p, lvl+1)
print(pad, type(ll))
print(pad, '[')
print_recursive(list(flatten(ll._p)), lvl+1)
print(pad, ']')
elif t is str:
print("%s '%s'" % (pad, ll))
else:
print(pad + ll)
print("%s %s" % (pad, ll))

View File

@@ -2,6 +2,7 @@ __all__ = [
'Block',
'Call',
'Expression',
'Identifier',
'Mixin',
'Property',
'Statement',
@@ -11,6 +12,7 @@ __all__ = [
from .block import Block
from .call import Call
from .expression import Expression
from .identifier import Identifier
from .mixin import Mixin
from .property import Property
from .statement import Statement

View File

@@ -1,87 +1,7 @@
"""
Block node.
Copyright (c)
See LICENSE for details.
<jtm@robot.is>
"""
from collections import OrderedDict
import lesscpy.lessc.utility as utility
from .process import Process
class Block(Process):
format = "%(identifier)s%(ws)s{%(nl)s%(proplist)s}%(endblock)s"
from .node import Node
from lesscpy.lessc import utility
class Block(Node):
def parse(self, scope):
""" Parse Node
@param list: current scope
"""
self._blocktype = None
self.scope = scope
# self._proplist()
self._pname()
self._proplist()
if self._name.startswith('@media'):
self._blocktype = 'inner'
self.parsed['identifier'] = self._ident.strip()
return self
def merge(self, block):
"""
"""
assert(type(block) is Block)
self.parsed['proplist'].extend(block.parsed['proplist'])
def _pname(self):
""" Parse block name and identifier
"""
name = ["%s " % t
if t in '>+*'
else t
for t in utility.flatten(self._p[1])]
self._name = ''.join(name)
self._ident = self._fullname(name)
self._cident = self._ident.replace(' ', '')
def _fullname(self, name):
"""
"""
parent = list(utility.flatten([s['__current__']
for s in self.scope
if s['__current__']]))
if parent:
parent.reverse()
if parent[-1].startswith('@media'):
parent.pop()
names = [p.strip()
for p in self._name.split(',')]
self._parts = names
for p in parent:
parts = p.split(',')
names = [n.replace('&', p)
if '&' in n
else
"%s %s" % (p.strip(), n)
for n in names
for p in parts]
return ', '.join(names) if len(names) < 6 else ',\n'.join(names)
def _proplist(self):
""" Reduce property list to remove redundant styles.
Multiple porperties of the same type overwrite,
so we can safely take only the last.
"""
store = OrderedDict()
self.parsed['inner'] = []
for p in utility.flatten(self._p[2]):
if not p: continue
if not p.parsed:
if type(p) is type(self):
self.scope.current = self._ident
p.parse(self.scope)
if type(p) is type(self):
self.parsed['inner'].append(p)
elif 'property' in p.parsed:
store[p.parsed['property']] = p
self.parsed['proplist'] = list(store.values())
pass

View File

@@ -1,101 +1,5 @@
"""
Call Node.
Copyright (c)
See LICENSE for details.
<jtm@robot.is>
"""
import re
from urllib.parse import quote as urlquote
from .process import Process
from lesscpy.lessc.color import LessColor
from .expression import Expression
import lesscpy.lessc.utility as utility
class Call(Process):
def parse(self, scope):
""" Parse Node
@param list: current scope
"""
self.scope = scope
call = list(utility.flatten(self._p[1:]))
name = call[0]
if name == '%(':
name = 'sformat'
elif name == '~':
name = 'e'
color = LessColor()
call = self.process_tokens(call[1:])
args = [t for t in call
if type(t) is not str or t not in '(),']
if hasattr(self, name):
try:
return getattr(self, name)(*args)
except ValueError:
pass
if hasattr(color, name):
try:
return getattr(color, name)(*args)
except ValueError:
pass
call = ' '.join([str(t) for t in call[1:-1]]).replace(' = ', '=')
return ["%s(%s)" % (name, call)]
def e(self, string):
""" Less Escape.
@param string: value
@return string
"""
return utility.destring(string.strip('~'))
def sformat(self, *args):
""" String format
@param list: values
@return string
"""
format = args[0]
items = []
m = re.findall('(%[asdA])', format)
i = 1
for n in m:
v = {
'%d' : int,
'%A' : urlquote,
'%s' : utility.destring,
}.get(n, str)(args[i])
items.append(v)
i += 1
format = format.replace('%A', '%s')
return format % tuple(items)
def increment(self, v):
""" Increment function
@param Mixed: value
@return: incremented value
"""
n, u = utility.analyze_number(v)
return utility.with_unit(n+1, u)
def decrement(self, v):
""" Decrement function
@param Mixed: value
@return: incremented value
"""
n, u = utility.analyze_number(v)
return utility.with_unit(n-1, u)
def add(self, *args):
""" Add integers
@param list: values
@return: int
"""
return sum([int(v) for v in args])
def round(self, v):
""" Round number
@param Mixed: value
@return: rounded value
"""
n, u = utility.analyze_number(v)
return utility.with_unit(round(float(n)), u)
from .node import Node
class Call(Node):
pass

View File

@@ -1,100 +1,5 @@
"""
Expression Node.
Copyright (c)
See LICENSE for details.
<jtm@robot.is>
"""
import lesscpy.lessc.utility as utility
from .process import Process
from lesscpy.lessc import color
class Expression(Process):
def parse(self, scope):
""" Parse Node
@param list: current scope
"""
self.scope = scope
expr = [self._p[1], self._p[2], self._p[3]]
while True:
done = True
expr = [self.neg(t) for t in expr]
if any(t for t in expr if hasattr(t, 'parse')):
expr = [t.parse(scope) if hasattr(t, 'parse')
else t
for t in expr]
done = False
if any(t for t in expr if utility.is_variable(t)):
expr = self.replace_vars(expr)
done = False
expr = list(utility.flatten(expr))
if done: break
p = self.process(expr)
return p
def neg(self, t):
"""
"""
if t and type(t) is list and t[0] == '-':
v = t[1]
if len(t) > 1 and hasattr(t[1], 'parse'):
v = t[1].parse(self.scope)
if type(v) is str:
return '-' + v
return -v
return t
def process(self, expression):
"""
"""
assert(len(expression) == 3)
A, O, B = expression
a, ua = utility.analyze_number(A, 'Illegal element in expression')
b, ub = utility.analyze_number(B, 'Illegal element in expression')
if(a is False or b is False):
return self.expression()
if ua == 'color' or ub == 'color':
return color.LessColor().process(expression)
out = self.operate(a, b, O)
if type(a) is int and type(b) is int:
out = int(out)
return self.units(out, ua, ub)
def units(self, v, ua, ub):
"""
"""
if v == 0: return v;
if ua and ub:
if ua == ub:
return str(v) + ua
else:
raise SyntaxError("Error in expression %s != %s" % (ua, ub))
elif ua:
return str(v) + ua
elif ub:
return str(v) + ub
return v
def operate(self, a, b, o):
"""
"""
# print("´%s´ ´%s´ ´%s´" % (a, b, o))
operation = {
'+': '__add__',
'-': '__sub__',
'*': '__mul__',
'/': '__truediv__'
}.get(o)
v = getattr(a, operation)(b)
if v is NotImplemented:
v = getattr(b, operation)(a)
return v
def expression(self):
"""
"""
return [self._p[1], self._p[2], self._p[3]]
from .node import Node
class Expression(Node):
pass

View File

@@ -0,0 +1,5 @@
"""
"""
from .node import Node
class Identifier(Node):
pass

View File

@@ -1,99 +1,5 @@
"""
Parametered Mixin Node.
Copyright (c)
See LICENSE for details.
<jtm@robot.is>
"""
from collections import deque
import lesscpy.lessc.utility as utility
from lesscpy.lessc.scope import Scope
import copy
from .process import Process
from .node import Node
class Mixin(Process):
""" Mixin Node.
"""
def parse(self, scope, stash=None):
""" Parse Node
@param list: current scope
"""
self.stash = stash
self._name = self._p[1][0].strip()
if len(self._p[1]) > 1:
if type(self._p[1][2]) is list:
self.argv = [[u[0], u[2]] if type(u) is list
else [u, None]
for u in self._p[1][2]
if u and u != ',']
else:
self.argv = self._p[1][2]
self.argc = len(self.argv)
else:
self.argv = []
self.argc = 0
self.nodes = self._p[2]
def call(self, args, scope=None):
""" Call mixin function.
@param list: Arguments passed to mixin
@return: Property list
"""
if self.argv == '@arguments':
return [self.replace_arguments(copy.copy(p), args).parse(self.scope)
for p in self.prop
if p]
self.scope = scope if scope else Scope(True)
self.scope[0]['__variables__'].update(self.stash)
nodes = [copy.deepcopy(p) for p in self.nodes if p]
nodes = utility.flatten([p.call(args, self.scope)
if type(p) is Mixin else p
for p in nodes])
self._process_args(args)
return [p.parse(self.scope) for p in nodes]
def _process_args(self, args):
""" Process arguments to mixin call.
Handle the @arguments variable
@param list: arguments
"""
variables = []
if args:
args = [a for a in self.process_tokens(args)
if a != ',']
else:
args = []
args = deque(args)
for v in self.argv:
if args:
u = args.popleft()
variables.append((v[0], u))
else:
variables.append(v)
for v in variables:
self._create_variable(v)
# Special @arguments
arguments = [v[1] for v in variables]
arguments.extend(args)
self._create_variable(('@arguments', [arguments]))
def _create_variable(self, l):
""" Create new variable in scope, from list or index
@param tuple: name/value pair
"""
assert(len(l) == 2)
var = Node()
var._name, var._value = l
self.scope.add_variable(var)
def replace_arguments(self, p, args):
""" Replace the special @arguments variable
@param Property object: Property object
@param list: Replacement list
@return: Property object
"""
assert(len(p._p) > 3)
p._p[3] = args
return p
class Mixin(Node):
pass

View File

@@ -1,18 +1,10 @@
"""
Parser node base class.
Copyright (c)
See LICENSE for details.
<jtm@robot.is>
"""
class Node(object):
def name(self):
""" @return: node name"""
return self._name
def value(self):
""" @return: node value"""
return self._value
def __init__(self, p):
self._p = p
def parse(self, scope):
raise NotImplementedError()
pass
# print(type(self), list(self._p))
# print()

View File

@@ -1,81 +0,0 @@
"""
Base process Node
Copyright (c)
See LICENSE for details.
<jtm@robot.is>
"""
import lesscpy.lessc.utility as utility
from .node import Node
class Process(Node):
def __init__(self, p):
self._p = list(p)
self.lines = [j for j in [p.lineno(i)
for i in range(len(self._p))]
if j]
self.scope = None
self.parsed = {}
def process_tokens(self, tokens):
"""
"""
while True:
done = True
if any(t for t in tokens if hasattr(t, 'parse')):
tokens = [t.parse(self.scope) if hasattr(t, 'parse')
else t
for t in tokens]
done = False
if any(t for t in tokens if utility.is_variable(t)):
tokens = self.replace_vars(tokens)
done = False
tokens = list(utility.flatten(tokens))
if done: break
return tokens
def replace_vars(self, tokens):
"""
Replace variables in tokenlist
"""
return [self.swap(t)
if utility.is_variable(t)
else t
for t in tokens]
def swap(self, var):
"""
Swap single variable
"""
if not self.scope:
raise SyntaxError("Unknown variable ´%s´" % var)
pad = ''
pre = ''
if var.endswith(' '):
var = var.strip()
pad = ' '
if var.startswith('-'):
var = ''.join(var[1:])
pre = '-'
r = var.startswith('@@')
t = ''.join(var[1:]) if r else var
variable = self.scope.variables(t)
if variable:
f = variable.value()
if r: return self.swap("%s@%s%s" % (pre, f[0].strip('"\''), pad))
return self.ftok(f, pre, pad)
raise SyntaxError("Unknown variable ´%s´" % var)
def ftok(self, t, pre, pad):
"""
"""
try:
r = ''.join(t)
except TypeError:
r = t[0] if type(t) is list else str(t)
if pad and type(r) is str:
r += pad
if pre and type(r) is str:
r = pre + r
return r

View File

@@ -1,40 +1,8 @@
"""
Property Node
Copyright (c)
See LICENSE for details.
<jtm@robot.is>
"""
import lesscpy.lessc.utility as utility
from .process import Process
class Property(Process):
format = "%(tab)s%(property)s:%(ws)s%(style)s;%(nl)s"
from .node import Node
class Property(Node):
def parse(self, scope):
""" Parse Node
@param list: current scope
"""
self.scope = scope
self.parsed = {}
tokens = list(utility.flatten([self._p[1], self._p[3]]))
self.parsed['property'] = tokens[0]
style = self.preprocess(tokens[1:])
style = self.process_tokens(style)
style = ' '.join([str(t).strip() for t in style
if t is not None]).replace(' , ', ', ')
self.parsed['style'] = style
return self
def preprocess(self, style):
""" Preprocess for annoying shorthand CSS declarations
@param list: style
@return: list
"""
if self.parsed['property'] == 'font':
style = [''.join(u.expression())
if hasattr(u, 'expression')
else u
for u in style]
return style
pass
# print(type(self), list(self._p))
# print()

View File

@@ -1,20 +1,5 @@
"""
Statement Node
Copyright (c)
See LICENSE for details.
<jtm@robot.is>
"""
from .process import Process
class Statement(Process):
format = "%(identifier)s %(value)s;%(nl)s"
def parse(self, scope):
""" Parse Node
@param list: current scope
"""
self._ident = self._p[1].strip()
self.parsed['identifier'] = self._ident
self.parsed['value'] = self._p[2]
from .node import Node
class Statement(Node):
pass

View File

@@ -1,27 +1,5 @@
"""
String Node
Copyright (c)
See LICENSE for details.
<jtm@robot.is>
"""
import re
from .process import Process
class String(Process):
def parse(self, scope):
""" Parse Node
@param list: current scope
@return: string
"""
self.scope = scope
return re.sub(r'@\{([^\}]+)\}', lambda m: self.format(m.group(1)), self._p[1])
def format(self, var):
""" Format variable for replacement
@param string: var
@return: string
"""
var = '@' + var
var = self.swap(var)
return var.strip("\"'")
from .node import Node
class String(Node):
pass

View File

@@ -1,18 +1,5 @@
"""
Variable Node
Copyright (c)
See LICENSE for details.
<jtm@robot.is>
"""
from .process import Process
class Variable(Process):
def name(self):
return self._p[1]
def value(self):
return self._p[3]
def parse(self, scope):
return None
from .node import Node
class Variable(Node):
pass

View File

@@ -1,13 +0,0 @@
.color_functions {
lighten: #ffcccc;
darken: #330000;
saturate: #203c31;
desaturate: #29332f;
greyscale: #4e0e27;
spin-p: #bf6b40;
spin-n: #bf4055;
hue: 100.0;
saturation: 12;
lightness: 95;
}

View File

@@ -1 +0,0 @@
.color_functions{lighten:#ffcccc;darken:#330000;saturate:#203c31;desaturate:#29332f;greyscale:#4e0e27;spin-p:#bf6b40;spin-n:#bf4055;hue:100.0;saturation:12;lightness:95;}

View File

@@ -1,48 +0,0 @@
#yelow #short {
color: #ffeeaa;
}
#yelow #long {
color: #ffeeaa;
}
#yelow #rgba {
color: rgba(255, 238, 170, 0.1);
}
#yelow #argb {
color: argb(rgba(255, 238, 170, 0.1));
}
#blue #short {
color: #0000ff;
}
#blue #long {
color: #0000ff;
}
#blue #rgba {
color: rgba(0, 0, 255, 0.1);
}
#blue #argb {
color: argb(rgba(0, 0, 255, 0.1));
}
#alpha #hsla {
color: hsla(11, 20%, 20%, 0.6);
}
#overflow .a {
color: #000000;
}
#overflow .b {
color: #ffffff;
}
#overflow .c {
color: #ffffff;
}
#overflow .d {
color: #00ff00;
}
#grey {
color: #c8c8c8;
}
#808080 {
color: #808080;
}
#00ff00 {
color: #00ff00;
}

View File

@@ -1,16 +0,0 @@
#yelow #short{color:#ffeeaa;}
#yelow #long{color:#ffeeaa;}
#yelow #rgba{color:rgba(255, 238, 170, 0.1);}
#yelow #argb{color:argb(rgba(255, 238, 170, 0.1));}
#blue #short{color:#0000ff;}
#blue #long{color:#0000ff;}
#blue #rgba{color:rgba(0, 0, 255, 0.1);}
#blue #argb{color:argb(rgba(0, 0, 255, 0.1));}
#alpha #hsla{color:hsla(11, 20%, 20%, 0.6);}
#overflow .a{color:#000000;}
#overflow .b{color:#ffffff;}
#overflow .c{color:#ffffff;}
#overflow .d{color:#00ff00;}
#grey{color:#c8c8c8;}
#808080{color:#808080;}
#00ff00{color:#00ff00;}

View File

@@ -1,17 +0,0 @@
#comments {
color: red;
background-color: orange;
font-size: 12px;
content: "content";
border: 1px solid black;
padding: 0;
margin: 2em;
}
.selector, .lots, .comments {
color: grey, orange;
-webkit-border-radius: 2px;
-moz-border-radius: 8px;
}
#last {
color: blue;
}

View File

@@ -1,3 +0,0 @@
#comments{color:red;background-color:orange;font-size:12px;content:"content";border:1px solid black;padding:0;margin:2em;}
.selector, .lots, .comments{color:grey, orange;-webkit-border-radius:2px;-moz-border-radius:8px;}
#last{color:blue;}

View File

@@ -1,46 +0,0 @@
.comma-delimited {
background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
-moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
}
@font-face {
font-family: Headline;
src: local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg");
}
.other {
-moz-transform: translate(0, 11em) rotate(-90deg);
}
p:not([class*="lead"]) {
color: black;
}
input[type="text"].class#id[attr=32]:not(1) {
color: white;
}
div#id.class[a=1][b=2].class:not(1) {
color: white;
}
ul.comma > li:not(:only-child)::after {
color: white;
}
ol.comma > li:nth-last-child(2)::after {
color: white;
}
li:nth-child(4n+1), li:nth-child(-5n), li:nth-child(-n+2) {
color: white;
}
a[href^="http://"] {
color: black;
}
a[href$="http://"] {
color: black;
}
form[data-disabled] {
color: black;
}
p::before {
color: black;
}
#issue322 {
-webkit-animation: anim2 7s infinite ease-in-out;
}

View File

@@ -1,14 +0,0 @@
.comma-delimited{background:url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);text-shadow:-1px -1px 1px red, 6px 5px 5px yellow;-moz-box-shadow:0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset;}
@font-face{font-family:Headline;src:local(Futura-Medium), url(fonts.svg#MyGeometricModern) format("svg");}
.other{-moz-transform:translate(0, 11em) rotate(-90deg);}
p:not([class*="lead"]){color:black;}
input[type="text"].class#id[attr=32]:not(1){color:white;}
div#id.class[a=1][b=2].class:not(1){color:white;}
ul.comma > li:not(:only-child)::after{color:white;}
ol.comma > li:nth-last-child(2)::after{color:white;}
li:nth-child(4n+1), li:nth-child(-5n), li:nth-child(-n+2){color:white;}
a[href^="http://"]{color:black;}
a[href$="http://"]{color:black;}
form[data-disabled]{color:black;}
p::before{color:black;}
#issue322{-webkit-animation:anim2 7s infinite ease-in-out;}

View File

@@ -1,16 +0,0 @@
.escape\|random\|char {
color: red;
}
.mixin\!tUp {
font-weight: bold;
}
.\34 04 {
background: red;
}
.\34 04 strong {
color: fuchsia;
font-weight: bold;
}
.trailingTest\+ {
color: red;
}

View File

@@ -1,5 +0,0 @@
.escape\|random\|char{color:red;}
.mixin\!tUp{font-weight:bold;}
.\34 04{background:red;}
.\34 04 strong{color:fuchsia;font-weight:bold;}
.trailingTest\+{color:red;}

View File

@@ -1,93 +0,0 @@
@charset "utf-8";
@CHARSET "utf-8";
div {
color: black;
}
div {
width: 99%;
}
* {
min-width: 45em;
}
* html .div {
min-width: 45em;
}
h1, h2 > a > p, h3 {
color: none;
}
div.class {
color: blue;
}
div#id {
color: green;
}
.class#id {
color: purple;
}
.one.two.three {
color: grey;
}
.one .two .three {
color: grey;
}
@media print {
font-size: 3em;
}
@media screen {
font-size: 10px;
}
@font-face {
font-family: 'Garamond Pro';
src: url("/fonts/garamond-pro.ttf");
}
a:hover, a:link {
color: #999999;
}
p, p:first-child {
text-transform: none;
}
q:lang(no) {
quotes: none;
}
p + h1 {
font-size: 2.2em;
}
#shorthands {
border: 1px solid #000000;
font: 12px/16px Arial;
margin: 1px 0;
padding: 0 auto;
background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
}
#shorthands {
font: 100%/16px Arial;
}
#more-shorthands {
margin: 0;
padding: 1px 0 2px 0;
font: normal small/20px 'Trebuchet MS', Verdana, sans-serif;
}
.misc {
-moz-border-radius: 2px;
display: -moz-inline-stack;
width: .1em;
background-color: #009998;
background-image: url(images/image.jpg);
background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
filter: alpha(opacity=100);
}
#important {
color: red !important;
width: 100% !important;
height: 20px !important;
}
#data-uri {
background: url(data:image/png;charset=utf-8;base64,
kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
}
#svg-data-uri {
background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
}

View File

@@ -1,28 +0,0 @@
@charset "utf-8";@CHARSET "utf-8";div{color:black;}
div{width:99%;}
*{min-width:45em;}
* html .div{min-width:45em;}
h1, h2 > a > p, h3{color:none;}
div.class{color:blue;}
div#id{color:green;}
.class#id{color:purple;}
.one.two.three{color:grey;}
.one .two .three{color:grey;}
@media print{font-size:3em;}
@media screen{font-size:10px;}
@font-face{font-family:'Garamond Pro';src:url("/fonts/garamond-pro.ttf");}
a:hover, a:link{color:#999999;}
p, p:first-child{text-transform:none;}
q:lang(no){quotes:none;}
p + h1{font-size:2.2em;}
#shorthands{border:1px solid #000000;font:12px/16px Arial;margin:1px 0;padding:0 auto;background:url("http://www.lesscss.org/spec.html") no-repeat 0 4px;}
#shorthands{font:100%/16px Arial;}
#more-shorthands{margin:0;padding:1px 0 2px 0;font:normal small/20px 'Trebuchet MS', Verdana, sans-serif;}
.misc{-moz-border-radius:2px;display:-moz-inline-stack;width:.1em;background-color:#009998;background-image:url(images/image.jpg);background:-webkit-gradient(linear, left top, left bottom, from(red), to(blue));filter:alpha(opacity=100);}
#important{color:red !important;width:100% !important;height:20px !important;}
#data-uri{background:url(data:image/png;charset=utf-8;base64,
kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);background-image:url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);}
#svg-data-uri{background:transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');}
.uri_test{background-image:url(fonts.svg#MyGeometricModern);behavior:url(border-radius.htc);}

View File

@@ -1,18 +0,0 @@
#functions {
width: 16;
height: undefined("self");
border-width: 5;
variable: 11;
decrement: 9;
}
#built-in {
escaped: -Some::weird(#thing, y);
escaped1: -Some::weird(#thing, z);
format: "rgb(32, 128, 64)";
format-string: "hello world";
format-multiple: "hello earth 2";
format-url-encode: 'red is %23ff0000';
eformat: rgb(32, 128, 64);
rounded: 10;
roundedpx: 3px;
}

View File

@@ -1,2 +0,0 @@
#functions{width:16;height:undefined("self");border-width:5;variable:11;decrement:9;}
#built-in{escaped:-Some::weird(#thing, y);escaped1:-Some::weird(#thing, z);format:"rgb(32, 128, 64)";format-string:"hello world";format-multiple:"hello earth 2";format-url-encode:'red is %23ff0000';eformat:rgb(32, 128, 64);rounded:10;roundedpx:3px;}

View File

@@ -1,12 +0,0 @@
.nav {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="#000000", GradientType=0);
}
.nav {
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0);
}
.nav {
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="#000000", GradientType=0);
}
body {
*zoom: 1px;
}

View File

@@ -1,4 +0,0 @@
.nav{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="#000000", GradientType=0);}
.nav{filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);}
.nav{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="#000000", GradientType=0);}
body{*zoom:1px;}

View File

@@ -1,7 +0,0 @@
@import 'some.css.file.css';
@import 'some/other.css.file.CSS';
.import {
color: red;
width: 6px;
height: 9px;
}

View File

@@ -1 +0,0 @@
@import 'some.css.file.css';@import 'some/other.css.file.CSS';.import{color:red;width:6px;height:9px;}

View File

@@ -1,3 +0,0 @@
.tiny-scope {
color: #998899;
}

View File

@@ -1,9 +0,0 @@
.class {
width: 99px;
}
.overwrite {
width: 99px;
}
.nested .class {
width: 5px;
}

View File

@@ -1,22 +0,0 @@
.class .inner {
height: 100;
}
.class .inner .innest {
width: 10;
border-width: 20;
}
.class2 .inner {
height: 300;
}
.class2 .inner .innest {
width: 30;
border-width: 60;
}
.class3 .inner {
height: 600;
}
.class3 .inner .innest {
width: 60;
border-width: 120;
}

View File

@@ -1,49 +0,0 @@
.zero {
zero: 0;
one: 1;
two: 2;
three: 3;
}
.one {
zero: 0;
one: 1;
one-req: 1;
two: 2;
three: 3;
}
.two {
zero: 0;
one: 1;
two: 2;
three: 3;
}
.three {
zero: 0;
one: 1;
two: 2;
three-req: 3;
three: 3;
}
.left {
left: 1;
}
.right {
right: 1;
}
.border-right {
color: black;
border-right: 4px;
}
.border-left {
color: black;
border-left: 4px;
}
.only-right {
right: 33;
}
.only-left {
left: 33;
}
.left-right {
both: 330;
}

View File

@@ -1,21 +0,0 @@
@media print {
.class {
color: blue;
}
.class .sub {
width: 42;
}
.top, header > h1 {
color: #444444;
}
}
@media screen {
body {
max-width: 480;
}
}
@media all and (orientation:portrait) {
aside {
float: none;
}
}

View File

@@ -1,5 +0,0 @@
@media print{.class{color:blue;}
.class .sub{width:42;}
.top, header > h1{color:#444444;}}
@media screen{body{max-width:480;}}
@media all and (orientation:portrait){aside{float:none;}}

View File

@@ -1,56 +0,0 @@
#hidden {
color: transparent;
}
.two-args {
color: blue;
width: 10px;
height: 99%;
border: 2px dotted black;
}
.one-arg {
width: 15px;
height: 49%;
}
.no-parens {
width: 5px;
height: 49%;
}
.no-args {
width: 5px;
height: 49%;
}
.var-args {
width: 45;
height: 17%;
}
.multi-mix {
width: 10px;
height: 29%;
margin: 4;
padding: 5;
}
body {
padding: 30px;
color: #f00;
}
.scope-mix {
width: 8;
}
#same-var-name {
radius: 5px;
}
#var-inside {
width: 10px;
}
.arguments {
border: 1px solid black;
}
.arguments2 {
border: 0px;
}
.div-a {
color: #ffffff;
}
.div-ax {
color: 10px;
}

View File

@@ -1,15 +0,0 @@
#hidden{color:transparent;}
.two-args{color:blue;width:10px;height:99%;border:2px dotted black;}
.one-arg{width:15px;height:49%;}
.no-parens{width:5px;height:49%;}
.no-args{width:5px;height:49%;}
.var-args{width:45;height:17%;}
.multi-mix{width:10px;height:29%;margin:4;padding:5;}
body{padding:30px;color:#f00;}
.scope-mix{width:8;}
#same-var-name{radius:5px;}
#var-inside{width:10px;}
.arguments{border:1px solid black;}
.arguments2{border:0px;}
.div-a{color:#ffffff;}
.div-ax{color:10px;}

View File

@@ -1,30 +0,0 @@
.content {
width: 600px;
}
.content .column {
margin: 600px;
}
.content .column.blue {
color: blue;
}
.content .column.blue .deep {
padding: 600px;
}
.content-em {
width: 200px;
}
.content-em .column {
margin: 200px;
}
.content-em .column.blue {
color: blue;
}
.content-em .column.blue .deep {
padding: 200px;
}
.div :-moz-placeholder {
color: #ffffff;
}
.div::-webkit-input-placeholder {
color: #ffffff;
}

View File

@@ -1,10 +0,0 @@
.content{width:600px;}
.content .column{margin:600px;}
.content .column.blue{color:blue;}
.content .column.blue .deep{padding:600px;}
.content-em{width:200px;}
.content-em .column{margin:200px;}
.content-em .column.blue{color:blue;}
.content-em .column.blue .deep{padding:200px;}
.div :-moz-placeholder{color:#ffffff;}
.div::-webkit-input-placeholder{color:#ffffff;}

View File

@@ -1,25 +0,0 @@
.ext {
color: red;
}
.ext {
color: blue;
}
.ext {
color: red;
}
.ext {
color: black;
}
.ext {
color: red;
}
.ext {
color: green;
}
p {
width: 1px;
color: green;
}
a {
color: green;
}

View File

@@ -1,8 +0,0 @@
.ext{color:red;}
.ext{color:blue;}
.ext{color:red;}
.ext{color:black;}
.ext{color:red;}
.ext{color:green;}
p{width:1px;color:green;}
a{color:green;}

View File

@@ -1,74 +0,0 @@
.mixin {
border: 1px solid black;
}
.mixout {
border-color: orange;
}
.borders {
border-style: dashed;
}
#namespace .borders {
border-style: dotted;
}
#namespace .biohazard {
content: "death";
}
#namespace .biohazard .man {
color: transparent;
}
#theme > .mixin {
background-color: grey;
}
#container {
color: black;
border: 1px solid black;
border-color: orange;
background-color: grey;
}
#header .milk {
color: white;
border: 1px solid black;
background-color: grey;
}
#header #cookie {
border-style: dashed;
}
#header #cookie .chips {
border-style: dotted;
}
#header #cookie .chips .calories {
color: black;
border: 1px solid black;
border-color: orange;
background-color: grey;
}
.secure-zone {
color: transparent;
}
.direct {
border-style: dotted;
}
.bo, .bar {
width: 100%;
}
.bo {
border: 1px;
}
.bo {
color: red;
}
.ar.bo.ca {
color: black;
}
.jo.ki {
background: none;
}
.extended {
width: 100%;
border: 1px;
color: red;
background: none;
}
.foo .bar {
width: 100%;
}

View File

@@ -1,21 +0,0 @@
.mixin{border:1px solid black;}
.mixout{border-color:orange;}
.borders{border-style:dashed;}
#namespace .borders{border-style:dotted;}
#namespace .biohazard{content:"death";}
#namespace .biohazard .man{color:transparent;}
#theme > .mixin{background-color:grey;}
#container{color:black;border:1px solid black;border-color:orange;background-color:grey;}
#header .milk{color:white;border:1px solid black;background-color:grey;}
#header #cookie{border-style:dashed;}
#header #cookie .chips{border-style:dotted;}
#header #cookie .chips .calories{color:black;border:1px solid black;border-color:orange;background-color:grey;}
.secure-zone{color:transparent;}
.direct{border-style:dotted;}
.bo, .bar{width:100%;}
.bo{border:1px;}
.bo{color:red;}
.ar.bo.ca{color:black;}
.jo.ki{background:none;}
.extended{width:100%;border:1px;color:red;background:none;}
.foo .bar{width:100%;}

View File

@@ -1,42 +0,0 @@
#operations {
color: #111111;
height: 9px;
width: 3em;
text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
substraction: 0;
division: 1;
}
#operations .spacing {
height: 9px;
width: 3em;
}
.with-variables {
height: 16em;
width: 24em;
size: 1cm;
}
.negative {
height: 0;
width: 4px;
}
.shorthands {
padding: -1px 2px 0 -4px;
}
.colors {
color: #112233;
border-color: #334455;
background-color: #000000;
}
.colors .other {
color: #222222;
border-color: #222222;
}
.negations {
variable: -4px;
variable1: 0;
variable2: 0;
variable3: 8px;
variable4: 0;
paren: -4px;
paren2: 16px;
}

View File

@@ -1,8 +0,0 @@
#operations{color:#111111;height:9px;width:3em;text-shadow:-1px -1px 1px red, 6px 5px 5px yellow;substraction:0;division:1;}
#operations .spacing{height:9px;width:3em;}
.with-variables{height:16em;width:24em;size:1cm;}
.negative{height:0;width:4px;}
.shorthands{padding:-1px 2px 0 -4px;}
.colors{color:#112233;border-color:#334455;background-color:#000000;}
.colors .other{color:#222222;border-color:#222222;}
.negations{variable:-4px;variable1:0;variable2:0;variable3:8px;variable4:0;paren:-4px;paren2:16px;}

View File

@@ -1,20 +0,0 @@
.parens {
border: 2px solid black;
margin: 1px 3px 16 3;
width: 36;
padding: 2px 36px;
}
.more-parens {
padding: 8 4 4 4px;
width: 96;
height: 113;
margin: 12;
}
.nested-parens {
width: 71;
height: 6;
}
.mixed-units {
margin: 2px 4em 1 5pc;
padding: 6px 1em 2px 2;
}

View File

@@ -1,4 +0,0 @@
.parens{border:2px solid black;margin:1px 3px 16 3;width:36;padding:2px 36px;}
.more-parens{padding:8 4 4 4px;width:96;height:113;margin:12;}
.nested-parens{width:71;height:6;}
.mixed-units{margin:2px 4em 1 5pc;padding:6px 1em 2px 2;}

View File

@@ -1,29 +0,0 @@
#first > .one {
font-size: 2em;
}
#first > .one > #second .two > #deux {
width: 50%;
}
#first > .one > #second .two > #deux #third {
height: 100%;
}
#first > .one > #second .two > #deux #third:focus {
color: black;
}
#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth {
color: purple;
}
#first > .one > #second .two > #deux #fourth, #first > .one > #second .two > #deux #five, #first > .one > #second .two > #deux #six {
color: #110000;
}
#first > .one > #second .two > #deux #fourth .seven,
#first > .one > #second .two > #deux #five .seven,
#first > .one > #second .two > #deux #six .seven,
#first > .one > #second .two > #deux #fourth .eight > #nine,
#first > .one > #second .two > #deux #five .eight > #nine,
#first > .one > #second .two > #deux #six .eight > #nine {
border: 1px solid black;
}
#first > .one > #second .two > #deux #fourth #ten, #first > .one > #second .two > #deux #five #ten, #first > .one > #second .two > #deux #six #ten {
color: red;
}

View File

@@ -1,13 +0,0 @@
#first > .one{font-size:2em;}
#first > .one > #second .two > #deux{width:50%;}
#first > .one > #second .two > #deux #third{height:100%;}
#first > .one > #second .two > #deux #third:focus{color:black;}
#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth{color:purple;}
#first > .one > #second .two > #deux #fourth, #first > .one > #second .two > #deux #five, #first > .one > #second .two > #deux #six{color:#110000;}
#first > .one > #second .two > #deux #fourth .seven,
#first > .one > #second .two > #deux #five .seven,
#first > .one > #second .two > #deux #six .seven,
#first > .one > #second .two > #deux #fourth .eight > #nine,
#first > .one > #second .two > #deux #five .eight > #nine,
#first > .one > #second .two > #deux #six .eight > #nine{border:1px solid black;}
#first > .one > #second .two > #deux #fourth #ten, #first > .one > #second .two > #deux #five #ten, #first > .one > #second .two > #deux #six #ten{color:red;}

View File

@@ -1,12 +0,0 @@
.scope1 {
color: blue;
border-color: black;
}
.scope1 .scope2 {
color: blue;
}
.scope1 .scope2 .scope3 {
color: red;
border-color: black;
background-color: white;
}

View File

@@ -1,3 +0,0 @@
.scope1{color:blue;border-color:black;}
.scope1 .scope2{color:blue;}
.scope1 .scope2 .scope3{color:red;border-color:black;background-color:white;}

View File

@@ -1,53 +0,0 @@
h1 a:hover,
h2 a:hover,
h3 a:hover,
h1 p:hover,
h2 p:hover,
h3 p:hover {
color: red;
}
#all {
color: blue;
}
#the {
color: blue;
}
#same {
color: blue;
}
ul,
li,
div,
q,
blockquote,
textarea {
margin: 0;
}
td {
margin: 0;
padding: 0;
}
td, input {
line-height: 1em;
}
a {
color: red;
}
a:hover {
color: blue;
}
div a {
color: green;
}
p a span {
color: yellow;
}
.foo .bar .qux, .foo .baz .qux {
display: block;
}
.foo .qux .bar, .foo .qux .baz {
display: inline;
}
.foo .qux .bar .biz, .foo .qux .baz .biz {
display: none;
}

View File

@@ -1,24 +0,0 @@
h1 a:hover,
h2 a:hover,
h3 a:hover,
h1 p:hover,
h2 p:hover,
h3 p:hover{color:red;}
#all{color:blue;}
#the{color:blue;}
#same{color:blue;}
ul,
li,
div,
q,
blockquote,
textarea{margin:0;}
td{margin:0;padding:0;}
td, input{line-height:1em;}
a{color:red;}
a:hover{color:blue;}
div a{color:green;}
p a span{color:yellow;}
.foo .bar .qux, .foo .baz .qux{display:block;}
.foo .qux .bar, .foo .qux .baz{display:inline;}
.foo .qux .bar .biz, .foo .qux .baz .biz{display:none;}

View File

@@ -1,32 +0,0 @@
#strings {
background-image: url("http://son-of-a-banana.com");
quotes: "~" "~";
content: "#*%:&^,)!.(~*})";
empty: "";
brackets: "{" "}";
}
#comments {
content: "/* hello */ // not-so-secret";
}
#single-quote {
quotes: "'" "'";
content: '""#!&""';
empty: '';
semi-colon: ';';
}
#escaped {
filter: DX.Transform.MS.BS.filter(opacity=50);
}
#one-line {
image: url(http://tooks.com);
}
#interpolation {
url: "http://lesscss.org/dev/image.jpg";
url2: "http://lesscss.org/image-256.jpg";
url3: "http://lesscss.org#445566";
url4: "http://lesscss.org/hello";
url5: "http://lesscss.org/54.4px";
}
.mix-mul-class {
color: orange;
}

View File

@@ -1,7 +0,0 @@
#strings{background-image:url("http://son-of-a-banana.com");quotes:"~" "~";content:"#*%:&^,)!.(~*})";empty:"";brackets:"{" "}";}
#comments{content:"/* hello */ // not-so-secret";}
#single-quote{quotes:"'" "'";content:'""#!&""';empty:'';semi-colon:';';}
#escaped{filter:DX.Transform.MS.BS.filter(opacity=50);}
#one-line{image:url(http://tooks.com);}
#interpolation{url:"http://lesscss.org/dev/image.jpg";url2:"http://lesscss.org/image-256.jpg";url3:"http://lesscss.org#445566";url4:"http://lesscss.org/hello";url5:"http://lesscss.org/54.4px";}
.mix-mul-class{color:orange;}

View File

@@ -1,27 +0,0 @@
.variables {
width: 14cm;
}
.variables {
height: 24px;
color: #888888;
font-family: "Trebuchet MS",Verdana,sans-serif;
quotes: "~""~";
}
.redefinition {
three: 3;
}
.values {
font-family: 'Trebuchet', 'Trebuchet', 'Trebuchet';
color: #888888 !important;
url: url('Trebuchet');
multi: something 'A',B,C, 'Trebuchet';
}
.variable-names {
name: 'hello';
}
.alpha {
filter: alpha(opacity=42);
}
.lazy-eval {
width: 100%;
}

View File

@@ -1,7 +0,0 @@
.variables{width:14cm;}
.variables{height:24px;color:#888888;font-family:"Trebuchet MS",Verdana,sans-serif;quotes:"~""~";}
.redefinition{three:3;}
.values{font-family:'Trebuchet', 'Trebuchet', 'Trebuchet';color:#888888 !important;url:url('Trebuchet');multi:something 'A',B,C, 'Trebuchet';}
.variable-names{name:'hello';}
.alpha{filter:alpha(opacity=42);}
.lazy-eval{width:100%;}

View File

@@ -1,32 +0,0 @@
.whitespace {
color: white;
}
.whitespace {
color: white;
}
.whitespace {
color: white;
}
.whitespace {
color: white;
}
.whitespace {
color: white;
}
.white, .space, .mania {
color: white;
}
.no-semi-column {
color: white;
}
.no-semi-column {
color: white;
white-space: pre;
}
.no-semi-column {
border: 2px solid white;
}
.newlines {
background: the, great, wall;
border: 2px solid black;
}

View File

@@ -1,10 +0,0 @@
.whitespace{color:white;}
.whitespace{color:white;}
.whitespace{color:white;}
.whitespace{color:white;}
.whitespace{color:white;}
.white, .space, .mania{color:white;}
.no-semi-column{color:white;}
.no-semi-column{color:white;white-space:pre;}
.no-semi-column{border:2px solid white;}
.newlines{background:the, great, wall;border:2px solid black;}

View File

@@ -1,16 +0,0 @@
import sys, re
sys.path.append('..')
import lesscpy.lessc.parser
m = []
with open('../lessc/parser.py') as f:
for l in f.readlines():
r = re.findall('def[ \t]+(p_[a-z_0-9]+)([^\(]*)', l)
if r: m.append(r[0][0])
p = lesscpy.lessc.parser.LessParser
for u in m:
if u == 'p_error': continue
print(getattr(p, u).__doc__)

View File

@@ -1,12 +0,0 @@
.color_functions {
lighten: lighten(#ff0000, 40%);
darken: darken(#ff0000, 40%);
saturate: saturate(#29332f, 20%);
desaturate: desaturate(#203c31, 20%);
greyscale: greyscale(#203c31);
spin-p: spin(hsl(340, 50%, 50%), 40);
spin-n: spin(hsl(30, 50%, 50%), -40);
hue: hue(hsl(98, 12%, 95%));
saturation: saturation(hsl(98, 12%, 95%));
lightness: lightness(hsl(98, 12%, 95%));
}

View File

@@ -1,52 +0,0 @@
#yelow {
#short {
color: #fea;
}
#long {
color: #ffeeaa;
}
#rgba {
color: rgba(255, 238, 170, 0.1);
}
#argb {
color: argb(rgba(255, 238, 170, 0.1));
}
}
#blue {
#short {
color: #00f;
}
#long {
color: #0000ff;
}
#rgba {
color: rgba(0, 0, 255, 0.1);
}
#argb {
color: argb(rgba(0, 0, 255, 0.1));
}
}
#alpha #hsla {
color: hsla(11, 20%, 20%, 0.6);
}
#overflow {
.a { color: #111111 - #444444; } // #000000
.b { color: #eee + #fff; } // #ffffff
.c { color: #aaa * 3; } // #ffffff
.d { color: #00ee00 + #009900; } // #00ff00
}
#grey {
color: rgb(200, 200, 200);
}
#808080 {
color: hsl(50, 0%, 50%);
}
#00ff00 {
color: hsl(120, 100%, 50%);
}

View File

@@ -1,65 +0,0 @@
/******************\
* *
* Comment Header *
* *
\******************/
/*
Comment
*/
/*
* Comment Test
*
* - cloudhead (http://cloudhead.net)
*
*/
////////////////
@var: "content";
////////////////
/* Colors
* ------
* #EDF8FC (background blue)
* #166C89 (darkest blue)
*
* Text:
* #333 (standard text) // A comment within a comment!
* #1F9EC9 (standard link)
*
*/
/* @group Variables
------------------- */
#comments /* boo */ {
/**/ // An empty comment
color: red; /* A C-style comment */
background-color: orange; // A little comment
font-size: 12px;
/* lost comment */ content: @var;
border: 1px solid black;
// padding & margin //
padding: 0; // }{ '"
margin: 2em;
} //
/* commented out
#more-comments {
color: grey;
}
*/
.selector /* .with */, .lots, /* of */ .comments {
color: grey, /* blue */ orange;
-webkit-border-radius: 2px /* webkit only */;
-moz-border-radius: 2px * 4 /* moz only with operation */;
}
#last { color: blue }
//

View File

@@ -1,66 +0,0 @@
.comma-delimited {
background: url(bg.jpg) no-repeat, url(bg.png) repeat-x top left, url(bg);
text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
-moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset,
0pt 4px 6px rgba(255, 255, 255, 0.4) inset;
}
@font-face {
font-family: Headline;
src: local(Futura-Medium),
url(fonts.svg#MyGeometricModern) format("svg");
}
.other {
-moz-transform: translate(0, 11em) rotate(-90deg);
}
p:not([class*="lead"]) {
color: black;
}
input[type="text"].class#id[attr=32]:not(1) {
color: white;
}
div#id.class[a=1][b=2].class:not(1) {
color: white;
}
ul.comma > li:not(:only-child)::after {
color: white;
}
ol.comma > li:nth-last-child(2)::after {
color: white;
}
li:nth-child(4n+1),
li:nth-child(-5n),
li:nth-child(-n+2) {
color: white;
}
a[href^="http://"] {
color: black;
}
a[href$="http://"] {
color: black;
}
form[data-disabled] {
color: black;
}
p::before {
color: black;
}
#issue322 {
-webkit-animation: anim2 7s infinite ease-in-out;
}
/*
@-webkit-keyframes frames {
0% { border: 1px }
5.5% { border: 2px }
100% { border: 3px }
}
*/

View File

@@ -1,23 +0,0 @@
@ugly: fuchsia;
.escape\|random\|char {
color: red;
}
.mixin\!tUp {
font-weight: bold;
}
// class="404"
.\34 04 {
background: red;
strong {
color: @ugly;
.mixin\!tUp;
}
}
.trailingTest\+ {
color: red;
}

View File

@@ -1,123 +0,0 @@
@charset "utf-8";
@CHARSET "utf-8";
div { color: black; }
div { width: 99%; }
* {
min-width: 45em;
}
* html .div {
min-width: 45em;
}
h1, h2 > a > p, h3 {
color: none;
}
div.class {
color: blue;
}
div#id {
color: green;
}
.class#id {
color: purple;
}
.one.two.three {
color: grey;
}
.one .two .three {
color: grey;
}
@media print {
font-size: 3em;
}
@media screen {
font-size: 10px;
}
@font-face {
font-family: 'Garamond Pro';
src: url("/fonts/garamond-pro.ttf");
}
a:hover, a:link {
color: #999;
}
p, p:first-child {
text-transform: none;
}
q:lang(no) {
quotes: none;
}
p + h1 {
font-size: 2.2em;
}
#shorthands {
border: 1px solid #000;
font : 12px/16px Arial;
margin: 1px 0;
padding: 0 auto;
background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px;
}
#shorthands {
font: 100%/16px Arial;
}
#more-shorthands {
margin: 0;
padding: 1px 0 2px 0;
font: normal small/20px 'Trebuchet MS', Verdana, sans-serif;
}
.misc {
-moz-border-radius: 2px;
display: -moz-inline-stack;
width: .1em;
background-color: #009998;
background-image: url(images/image.jpg);
background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue));
margin: ;
filter: alpha(opacity=100);
}
#important {
color: red !important;
width: 100%!important;
height: 20px ! important;
}
#data-uri {
background: url(data:image/png;charset=utf-8;base64,
kiVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD/
k//+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4U
kg9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC);
background-image: url(data:image/x-png,f9difSSFIIGFIFJD1f982FSDKAA9==);
}
#svg-data-uri {
background: transparent url('data:image/svg+xml, <svg version="1.1"><g></g></svg>');
}
.uri_test {
background-image: url(images/image.jpg);
background-image: url(../some/path);
background-image: url(./../some/path);
background-image: url(./images/image.jpg);
background-image: url(http://some/path/img.jpeg);
background-image: url(https://some.server.com:9696/path/img.jpeg);
behavior:url(border-radius.htc);
background-image: url(fonts.svg#MyGeometricModern);
}

View File

View File

View File

@@ -1,22 +0,0 @@
#functions {
@var: 10;
width: increment(15);
height: undefined("self");
border-width: add(2, 3);
variable: increment(@var);
decrement: decrement(@var);
}
#built-in {
@r: 32;
escaped: e("-Some::weird(#thing, y)");
escaped1: ~"-Some::weird(#thing, z)";
format: %("rgb(%d, %d, %d)", @r, 128, 64);
format-string: %("hello %s", "world");
format-multiple: %("hello %s %d", "earth", 2);
format-url-encode: %('red is %A', #ff0000);
eformat: e(%("rgb(%d, %d, %d)", @r, 128, 64));
rounded: round(@r/3);
roundedpx: round(10px / 3);
}

View File

View File

@@ -1,21 +0,0 @@
@fat: 0;
@cloudhead: "#000000";
//
// IE Filters
//
.nav {
filter: ~'progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="@{cloudhead}", GradientType=@{fat})';
}
.nav {
filter: ~"progid:DXImageTransform.Microsoft.Alpha(opacity=@{fat})";
}
.nav {
filter: ~'progid:DXImageTransform.Microsoft.gradient(startColorstr="#333333", endColorstr="@{cloudhead}", GradientType=@{fat})';
}
//
// IE Hacks
//
body {
*zoom: 1px;
}

View File

@@ -1,10 +0,0 @@
@import './imports/import.less';
@import 'some.css.file.css';
@import './imports/import.less'; // redundant
@import './imports/import_f'; // No ext
@import 'some/other.css.file.CSS';
.import {
.mixin;
.mixf(6px);
height: @imported;
}

View File

View File

@@ -1 +0,0 @@
@import 'circular.less';

View File

@@ -1,5 +0,0 @@
@imported: 9px;
.mixin {
color: red;
}

View File

@@ -1,6 +0,0 @@
/*
*/
.mixf (@var: 7px) {
width: @var;
}

View File

@@ -1,8 +0,0 @@
@mix: none;
.mixin {
@mix: #989;
}
.tiny-scope {
color: @mix; // #989
.mixin;
}

View File

@@ -1,26 +0,0 @@
.scope {
@var: 99px;
.mixin () {
width: @var;
}
}
.class {
.scope > .mixin;
}
.overwrite {
@var: 0px;
.scope > .mixin;
}
.nested {
@var: 5px;
.mixin () {
width: @var;
}
.class {
@var: 10px;
.mixin;
}
}

View File

@@ -1,25 +0,0 @@
.mix-inner (@var) {
border-width: @var;
}
.mix (@a: 10) {
.inner {
height: @a * 10;
.innest {
width: @a;
.mix-inner(@a * 2);
}
}
}
.class {
.mix();
}
.class2 {
.mix(30);
}
.class3 {
.mix(60);
}

View File

@@ -1,96 +0,0 @@
.mixin () {
zero: 0;
}
.mixin (@a: 1px) {
one: 1;
}
.mixin (@a) {
one-req: 1;
}
.mixin (@a: 1px, @b: 2px) {
two: 2;
}
.mixin (@a, @b, @c) {
three-req: 3;
}
.mixin (@a: 1px, @b: 2px, @c: 3px) {
three: 3;
}
.zero {
.mixin();
}
.one {
.mixin(1);
}
.two {
.mixin(1, 2);
}
.three {
.mixin(1, 2, 3);
}
//
.mixout ('left') {
left: 1;
}
.mixout ('right') {
right: 1;
}
.left {
.mixout('left');
}
.right {
.mixout('right');
}
//
.border (@side, @width) {
color: black;
.border-side(@side, @width);
}
.border-side (left, @w) {
border-left: @w;
}
.border-side (right, @w) {
border-right: @w;
}
.border-right {
.border(right, 4px);
}
.border-left {
.border(left, 4px);
}
//
.border-radius (@r) {
both: @r * 10;
}
.border-radius (@r, left) {
left: @r;
}
.border-radius (@r, right) {
right: @r;
}
.only-right {
.border-radius(33, right);
}
.only-left {
.border-radius(33, left);
}
.left-right {
.border-radius(33);
}

View File

@@ -1,5 +0,0 @@
#foo {
+ .one {
font-size: 2em;
}
}

View File

@@ -1,25 +0,0 @@
// For now, variables can't be declared inside @media blocks.
@var: 42;
@media print {
.class {
color: blue;
.sub {
width: @var;
}
}
.top, header > h1 {
color: #222 * 2;
}
}
@media screen {
@base: 8;
body { max-width: @base * 60; }
}
@media all and (orientation:portrait) {
aside { float: none; }
}

View File

@@ -1,123 +0,0 @@
.mixin (@a: 1px, @b: 50%) {
width: @a * 5;
height: @b - 1%;
}
.mixina (@style, @width, @color: black) {
border: @width @style @color;
}
.mixiny
(@a: 0, @b: 0) {
margin: @a;
padding: @b;
}
.hidden() {
color: transparent; // asd
}
#hidden {
.hidden;
.hidden();
}
.two-args {
color: blue;
.mixin(2px, 100%);
.mixina(dotted, 2px);
}
.one-arg {
.mixin(3px);
}
.no-parens {
.mixin;
}
.no-args {
.mixin();
}
.var-args {
@var: 9;
.mixin(@var, @var * 2);
}
.multi-mix {
.mixin(2px, 30%);
.mixiny(4, 5);
}
.maxa(@arg1: 10, @arg2: #f00) {
padding: @arg1 * 2px;
color: @arg2;
}
body {
.maxa(15);
}
@glob: 5;
.global-mixin(@a:2) {
width: @glob + @a;
}
.scope-mix {
.global-mixin(3);
}
//
.same-var-name2(@radius) {
radius: @radius;
}
.same-var-name(@radius) {
.same-var-name2(@radius);
}
#same-var-name {
.same-var-name(5px);
}
//
.var-inside () {
@var: 10px;
width: @var;
}
#var-inside { .var-inside; }
// # mixins
/* #id-mixin () {
color: red;
} */
.id-class {
#id-mixin();
#id-mixin;
}
.mixin-arguments (@width: 0px) {
border: @arguments;
}
.arguments {
.mixin-arguments(1px, solid, black);
}
.arguments2 {
.mixin-arguments();
}
//
// Variable argument
//
@var: #aaa;
.var-arg(@color: @var) {
color: @color;
}
.div-a {
.var-arg(#fff);
}
.div-ax {
.var-arg();
}

View File

@@ -1,33 +0,0 @@
.nested-ruleset (@width: 200px) {
width: @width;
.column {
margin: @width;
&.blue {
color: blue;
.deep {
padding: @width;
}
}
}
}
.content {
.nested-ruleset(600px);
}
.content-em {
.nested-ruleset();
}
//
// filter mixins
//
.placeholder(@color: #000) {
:-moz-placeholder {
color: @color;
}
&::-webkit-input-placeholder {
color: @color;
}
}
.div {
.placeholder(#fff);
}

View File

@@ -1,29 +0,0 @@
.ext {
color: red;
}
.ext {
color: blue;
}
.ext {
color: red;
}
.ext {
color: black;
}
.ext {
color: red;
}
.ext {
color: green;
}
p {
width: 1px;
.ext;
}
a {
.ext;
.ext;
.ext;
.ext;
.ext;
}

View File

@@ -1,73 +0,0 @@
.mixin { border: 1px solid black; }
.mixout { border-color: orange; }
.borders { border-style: dashed; }
#namespace {
.borders {
border-style: dotted;
}
.biohazard {
content: "death";
.man {
color: transparent;
}
}
}
#theme {
> .mixin {
background-color: grey;
}
}
#container {
color: black;
.mixin;
.mixout;
#theme > .mixin;
}
#header {
.milk {
color: white;
.mixin;
#theme > .mixin;
}
#cookie {
.chips {
#namespace .borders;
.calories {
#container;
}
}
.borders;
}
}
.secure-zone { #namespace .biohazard .man; }
.direct {
#namespace > .borders;
}
.bo, .bar {
width: 100%;
}
.bo {
border: 1px;
}
.bo {
color: red;
}
.ar.bo.ca {
color: black;
}
.jo.ki {
background: none;
}
.extended {
.bo;
.jo.ki;
}
.foo .bar {
.bar;
}

View File

@@ -1,53 +0,0 @@
#operations {
color: #110000 + #000011 + #001100; // #111111
height: 10px / 2px + 6px - 1px * 2; // 9px
width: 2 * 4 - 5em; // 3em
text-shadow: -1px -1px 1px red, 6px 5px 5px yellow;
.spacing {
height: 10px / 2px+6px- 1px*2;
width: 2 * 4 - 5em;
}
substraction: 20 - 10 - 5 - 5; // 0
division: 20 / 5 / 4; // 1
}
@x: 4;
@y: 12em;
.with-variables {
height: @x + @y; // 16em
width: 12 + @y; // 24em
size: 5cm - @x; // 1cm
}
@z: -2;
.negative {
height: 2px + @z; // 0px
width: 2px - @z; // 4px
}
.shorthands {
padding: -1px 2px 0 -4px; //
}
.colors {
color: #123; // #112233
border-color: #234 + #111111; // #334455
background-color: #222222 - #fff; // #000000
.other {
color: 2 * #111; // #222222
border-color: #333333 / 3 + #111; // #222222
}
}
.negations {
@var: 4px;
variable: -@var; // 4
variable1: -@var + @var; // 0
variable2: @var + -@var; // 0
variable3: @var - -@var; // 8
variable4: -@var - -@var; // 0
paren: -(@var); // -4px
paren2: -(2 + 2) * -@var; // 16
}

View File

View File

@@ -1,26 +0,0 @@
.parens {
@var: 1px;
border: (@var * 2) solid black;
margin: (@var * 1) (@var + 2) (4 * 4) 3;
width: (6 * 6);
padding: 2px (6px * 6px);
}
.more-parens {
@var: (2 * 2);
padding: (2 * @var) 4 4 (@var * 1px);
width: (@var * @var) * 6;
height: (7 * 7) + (8 * 8);
margin: 4 * (5 + 5) / 2 - (@var * 2);
//margin: (6 * 6)px;
}
.nested-parens {
width: 2 * (4 * (2 + (1 + 6))) - 1;
height: ((2+3)*(2+3) / (9 - 4)) + 1;
}
.mixed-units {
margin: 2px 4em 1 5pc;
padding: (2px + 4px) 1em 2px 2;
}

View File

View File

View File

@@ -1,28 +0,0 @@
#first > .one {
> #second .two > #deux {
width: 50%;
#third {
&:focus {
color: black;
#fifth {
> #sixth {
.seventh #eighth {
color: purple;
}
}
}
}
height: 100%;
}
#fourth, #five, #six {
color: #110000;
.seven, .eight > #nine {
border: 1px solid black;
}
#ten {
color: red;
}
}
}
font-size: 2em;
}

View File

@@ -1,22 +0,0 @@
@x: blue;
@z: transparent;
.scope1 {
@y: orange;
@z: black;
color: @x; // blue
border-color: @z; // black
.hidden {
@x: #131313;
}
.scope2 {
@y: red;
color: @x; // blue
.scope3 {
@local: white;
color: @y; // red
border-color: @z; // black
background-color: @local; // white
}
}
}

View File

@@ -1,48 +0,0 @@
h1, h2, h3 {
a, p {
&:hover {
color: red;
}
}
}
#all { color: blue; }
#the { color: blue; }
#same { color: blue; }
ul, li, div, q, blockquote, textarea {
margin: 0;
}
td {
margin: 0;
padding: 0;
}
td, input {
line-height: 1em;
}
a {
color: red;
&:hover { color: blue; }
div & { color: green; }
p & span { color: yellow; }
}
.foo {
.bar, .baz {
& .qux {
display: block;
}
.qux & {
display: inline;
}
.qux & .biz {
display: none;
}
}
}

Some files were not shown because too many files have changed in this diff Show More