corrade-nucleus-nucleons

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 1  →  ?path2? @ 2
/script-kiddie/002_script_kiddie/script-kiddie/bower_components/js-beautify/python/cssbeautifier/__init__.py
@@ -0,0 +1,539 @@
from __future__ import print_function
import sys
import re
import copy
from cssbeautifier.__version__ import __version__
 
#
# The MIT License (MIT)
 
# Copyright (c) 2007-2017 Einar Lielmanis, Liam Newman, and contributors.
 
# Permission is hereby granted, free of charge, to any person
# obtaining a copy of this software and associated documentation files
# (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge,
# publish, distribute, sublicense, and/or sell copies of the Software,
# and to permit persons to whom the Software is furnished to do so,
# subject to the following conditions:
 
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
 
 
class BeautifierOptions:
def __init__(self):
self.indent_size = 4
self.indent_char = ' '
self.indent_with_tabs = False
self.preserve_newlines = False
self.selector_separator_newline = True
self.end_with_newline = False
self.newline_between_rules = True
self.space_around_combinator = False
self.eol = 'auto'
 
self.css = None
self.js = None
self.html = None
 
# deprecated
self.space_around_selector_separator = False
 
def mergeOpts(self, targetType):
finalOpts = copy.copy(self)
 
local = getattr(finalOpts, targetType)
if (local):
delattr(finalOpts, targetType)
for key in local:
setattr(finalOpts, key, local[key])
 
return finalOpts
 
 
def __repr__(self):
return \
"""indent_size = %d
indent_char = [%s]
indent_with_tabs = [%s]
preserve_newlines = [%s]
separate_selectors_newline = [%s]
end_with_newline = [%s]
newline_between_rules = [%s]
space_around_combinator = [%s]
""" % (self.indent_size, self.indent_char, self.indent_with_tabs, self.preserve_newlines,
self.selector_separator_newline, self.end_with_newline, self.newline_between_rules,
self.space_around_combinator)
 
 
def default_options():
return BeautifierOptions()
 
 
def beautify(string, opts=default_options()):
b = Beautifier(string, opts)
return b.beautify()
 
 
def beautify_file(file_name, opts=default_options()):
if file_name == '-': # stdin
stream = sys.stdin
else:
stream = open(file_name)
content = ''.join(stream.readlines())
b = Beautifier(content, opts)
return b.beautify()
 
 
def usage(stream=sys.stdout):
 
print("cssbeautifier.py@" + __version__ + """
 
CSS beautifier (http://jsbeautifier.org/)
 
""", file=stream)
if stream == sys.stderr:
return 1
else:
return 0
 
WHITE_RE = re.compile("^\s+$")
WORD_RE = re.compile("[\w$\-_]")
 
 
class Printer:
 
def __init__(self, beautifier, indent_char, indent_size, default_indent=""):
self.beautifier = beautifier
self.newlines_from_last_ws_eat = 0
self.indentSize = indent_size
self.singleIndent = (indent_size) * indent_char
self.indentLevel = 0
self.nestedLevel = 0
 
self.baseIndentString = default_indent
self.output = []
 
def __lastCharWhitespace(self):
return len(self.output) > 0 and WHITE_RE.search(self.output[-1]) is not None
 
def indent(self):
self.indentLevel += 1
self.baseIndentString += self.singleIndent
 
def outdent(self):
if self.indentLevel:
self.indentLevel -= 1
self.baseIndentString = self.baseIndentString[:-(len(self.singleIndent))]
 
def push(self, string):
self.output.append(string)
 
def openBracket(self):
self.singleSpace()
self.output.append("{")
if self.beautifier.eatWhitespace(True) == 0:
self.newLine()
 
def closeBracket(self,newLine):
if newLine:
self.newLine()
self.output.append("}")
self.beautifier.eatWhitespace(True)
if self.beautifier.newlines_from_last_ws_eat == 0:
self.newLine()
 
def semicolon(self):
self.output.append(";")
 
def comment(self, comment):
self.output.append(comment)
 
def newLine(self, keepWhitespace=False):
if len(self.output) > 0 :
if not keepWhitespace and self.output[-1] != '\n':
self.trim()
elif self.output[-1] == self.baseIndentString:
self.output.pop()
 
self.output.append("\n")
 
if len(self.baseIndentString) > 0:
self.output.append(self.baseIndentString)
 
def trim(self):
while self.__lastCharWhitespace():
self.output.pop()
 
def singleSpace(self):
if len(self.output) > 0 and not self.__lastCharWhitespace():
self.output.append(" ")
 
def preserveSingleSpace(self,isAfterSpace):
if isAfterSpace:
self.singleSpace()
 
def result(self):
if self.baseIndentString:
return self.baseIndentString + "".join(self.output);
else:
return "".join(self.output)
 
 
class Beautifier:
 
def __init__(self, source_text, opts=default_options()):
# This is not pretty, but given how we did the version import
# it is the only way to do this without having setup.py fail on a missing six dependency.
self.six = __import__("six")
 
# in javascript, these two differ
# in python they are the same, different methods are called on them
self.lineBreak = re.compile(self.six.u("\r\n|[\n\r\u2028\u2029]"))
self.allLineBreaks = self.lineBreak
 
if not source_text:
source_text = ''
 
opts = opts.mergeOpts('css')
 
# Continue to accept deprecated option
opts.space_around_combinator = opts.space_around_combinator or opts.space_around_selector_separator
 
self.opts = opts
self.indentSize = opts.indent_size
self.indentChar = opts.indent_char
self.pos = -1
self.ch = None
 
if self.opts.indent_with_tabs:
self.indentChar = "\t"
self.indentSize = 1
 
if self.opts.eol == 'auto':
self.opts.eol = '\n'
if self.lineBreak.search(source_text or ''):
self.opts.eol = self.lineBreak.search(source_text).group()
 
self.opts.eol = self.opts.eol.replace('\\r', '\r').replace('\\n', '\n')
 
# HACK: newline parsing inconsistent. This brute force normalizes the input newlines.
self.source_text = re.sub(self.allLineBreaks, '\n', source_text)
 
# https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule
# also in CONDITIONAL_GROUP_RULE below
self.NESTED_AT_RULE = [ \
"@page", \
"@font-face", \
"@keyframes", \
"@media", \
"@supports", \
"@document"]
self.CONDITIONAL_GROUP_RULE = [ \
"@media", \
"@supports", \
"@document"]
 
m = re.search("^[\t ]*", self.source_text)
baseIndentString = m.group(0)
self.printer = Printer(self, self.indentChar, self.indentSize, baseIndentString)
 
def next(self):
self.pos = self.pos + 1
if self.pos < len(self.source_text):
self.ch = self.source_text[self.pos]
else:
self.ch = ''
return self.ch
 
def peek(self,skipWhitespace=False):
start = self.pos
if skipWhitespace:
self.eatWhitespace()
result = ""
if self.pos + 1 < len(self.source_text):
result = self.source_text[self.pos + 1]
if skipWhitespace:
self.pos = start - 1
self.next()
 
return result
 
def eatString(self, endChars):
start = self.pos
while self.next():
if self.ch == "\\":
self.next()
elif self.ch in endChars:
break
elif self.ch == "\n":
break
return self.source_text[start:self.pos] + self.ch
 
def peekString(self, endChar):
start = self.pos
st = self.eatString(endChar)
self.pos = start - 1
self.next()
return st
 
def eatWhitespace(self, pn=False):
result = 0
while WHITE_RE.search(self.peek()) is not None:
self.next()
if self.ch == "\n" and pn and self.opts.preserve_newlines:
self.printer.newLine(True)
result += 1
self.newlines_from_last_ws_eat = result
return result
 
def skipWhitespace(self):
result = ''
if self.ch and WHITE_RE.search(self.ch):
result = self.ch
 
while WHITE_RE.search(self.next()) is not None:
result += self.ch
return result
 
def eatComment(self):
start = self.pos
singleLine = self.peek() == "/"
self.next()
while self.next():
if not singleLine and self.ch == "*" and self.peek() == "/":
self.next()
break
elif singleLine and self.ch == "\n":
return self.source_text[start:self.pos]
return self.source_text[start:self.pos] + self.ch
 
def lookBack(self, string):
past = self.source_text[self.pos - len(string):self.pos]
return past.lower() == string
 
# Nested pseudo-class if we are insideRule
# and the next special character found opens
# a new block
def foundNestedPseudoClass(self):
i = self.pos + 1
openParen = 0
while i < len(self.source_text):
ch = self.source_text[i]
if ch == "{":
return True
elif ch == "(":
# pseudoclasses can contain ()
openParen += 1
elif ch == ")":
if openParen == 0:
return False
openParen -= 1
elif ch == ";" or ch == "}":
return False
i += 1;
 
return False
 
def beautify(self):
printer = self.printer
insideRule = False
insidePropertyValue = False
enteringConditionalGroup = False
top_ch = ''
last_top_ch = ''
parenLevel = 0
 
while True:
whitespace = self.skipWhitespace()
isAfterSpace = whitespace != ''
isAfterNewline = '\n' in whitespace
last_top_ch = top_ch
top_ch = self.ch
 
if not self.ch:
break
elif self.ch == '/' and self.peek() == '*':
header = printer.indentLevel == 0
 
if not isAfterNewline or header:
printer.newLine()
 
 
comment = self.eatComment()
printer.comment(comment)
printer.newLine()
if header:
printer.newLine(True)
elif self.ch == '/' and self.peek() == '/':
if not isAfterNewline and last_top_ch != '{':
printer.trim()
 
printer.singleSpace()
printer.comment(self.eatComment())
printer.newLine()
elif self.ch == '@':
printer.preserveSingleSpace(isAfterSpace)
 
# deal with less propery mixins @{...}
if self.peek(True) == '{':
printer.push(self.eatString('}'));
else:
printer.push(self.ch)
# strip trailing space, if present, for hash property check
variableOrRule = self.peekString(": ,;{}()[]/='\"")
 
if variableOrRule[-1] in ": ":
# wwe have a variable or pseudo-class, add it and insert one space before continuing
self.next()
variableOrRule = self.eatString(": ")
if variableOrRule[-1].isspace():
variableOrRule = variableOrRule[:-1]
printer.push(variableOrRule)
printer.singleSpace();
 
if variableOrRule[-1].isspace():
variableOrRule = variableOrRule[:-1]
 
# might be a nesting at-rule
if variableOrRule in self.NESTED_AT_RULE:
printer.nestedLevel += 1
if variableOrRule in self.CONDITIONAL_GROUP_RULE:
enteringConditionalGroup = True
elif self.ch == '#' and self.peek() == '{':
printer.preserveSingleSpace(isAfterSpace)
printer.push(self.eatString('}'));
elif self.ch == '{':
if self.peek(True) == '}':
self.eatWhitespace()
self.next()
printer.singleSpace()
printer.push("{")
printer.closeBracket(False)
if self.newlines_from_last_ws_eat < 2 and self.opts.newline_between_rules and printer.indentLevel == 0:
printer.newLine(True)
else:
printer.indent()
printer.openBracket()
# when entering conditional groups, only rulesets are allowed
if enteringConditionalGroup:
enteringConditionalGroup = False
insideRule = printer.indentLevel > printer.nestedLevel
else:
# otherwise, declarations are also allowed
insideRule = printer.indentLevel >= printer.nestedLevel
elif self.ch == '}':
printer.outdent()
printer.closeBracket(True)
insideRule = False
insidePropertyValue = False
if printer.nestedLevel:
printer.nestedLevel -= 1
if self.newlines_from_last_ws_eat < 2 and self.opts.newline_between_rules and printer.indentLevel == 0:
printer.newLine(True)
elif self.ch == ":":
self.eatWhitespace()
if (insideRule or enteringConditionalGroup) and \
not (self.lookBack('&') or self.foundNestedPseudoClass()) and \
not self.lookBack('('):
# 'property: value' delimiter
# which could be in a conditional group query
printer.push(":")
if not insidePropertyValue:
insidePropertyValue = True
printer.singleSpace()
else:
# sass/less parent reference don't use a space
# sass nested pseudo-class don't use a space
 
# preserve space before pseudoclasses/pseudoelements, as it means "in any child"
if (self.lookBack(' ')) and (printer.output[-1] != ' '):
printer.push(" ")
if self.peek() == ":":
# pseudo-element
self.next()
printer.push("::")
else:
# pseudo-element
printer.push(":")
elif self.ch == '"' or self.ch == '\'':
printer.preserveSingleSpace(isAfterSpace)
printer.push(self.eatString(self.ch))
elif self.ch == ';':
insidePropertyValue = False
printer.semicolon()
if self.eatWhitespace(True) == 0:
printer.newLine()
elif self.ch == '(':
# may be a url
if self.lookBack("url"):
printer.push(self.ch)
self.eatWhitespace()
if self.next():
if self.ch is not ')' and self.ch is not '"' \
and self.ch is not '\'':
printer.push(self.eatString(')'))
else:
self.pos = self.pos - 1
else:
parenLevel += 1
printer.preserveSingleSpace(isAfterSpace)
printer.push(self.ch)
self.eatWhitespace()
elif self.ch == ')':
printer.push(self.ch)
parenLevel -= 1
elif self.ch == ',':
printer.push(self.ch)
if self.eatWhitespace(True) == 0 and not insidePropertyValue and self.opts.selector_separator_newline and parenLevel < 1:
printer.newLine()
else:
printer.singleSpace()
elif (self.ch == '>' or self.ch == '+' or self.ch == '~') and \
not insidePropertyValue and parenLevel < 1:
# handle combinator spacing
if self.opts.space_around_combinator:
printer.singleSpace()
printer.push(self.ch)
printer.singleSpace()
else:
printer.push(self.ch)
self.eatWhitespace()
# squash extra whitespace
if self.ch and WHITE_RE.search(self.ch):
self.ch = ''
elif self.ch == ']':
printer.push(self.ch)
elif self.ch == '[':
printer.preserveSingleSpace(isAfterSpace)
printer.push(self.ch)
elif self.ch == '=':
# no whitespace before or after
self.eatWhitespace()
printer.push('=')
if WHITE_RE.search(self.ch):
self.ch = ''
else:
printer.preserveSingleSpace(isAfterSpace)
printer.push(self.ch)
 
sweet_code = re.sub('[\r\n\t ]+$', '', printer.result())
 
# establish end_with_newline
if self.opts.end_with_newline:
sweet_code += '\n'
 
if not self.opts.eol == '\n':
sweet_code = sweet_code.replace('\n', self.opts.eol)
 
return sweet_code