Merge pull request #686 from scop/rjsmin1012

Upgrade rjsmin to 1.0.12
This commit is contained in:
Mathieu Pillard
2015-11-03 13:36:06 +01:00

View File

@@ -1,5 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: ascii -*-
r""" r"""
===================== =====================
Javascript Minifier Javascript Minifier
@@ -11,7 +11,7 @@ The minifier is based on the semantics of `jsmin.c by Douglas Crockford`_\\.
:Copyright: :Copyright:
Copyright 2011 - 2014 Copyright 2011 - 2015
Andr\xe9 Malo or his licensors, as applicable Andr\xe9 Malo or his licensors, as applicable
:License: :License:
@@ -39,6 +39,7 @@ same results as the original ``jsmin.c``. It differs in the following ways:
- Newline characters are not allowed inside string and regex literals, except - Newline characters are not allowed inside string and regex literals, except
for line continuations in string literals (ECMA-5). for line continuations in string literals (ECMA-5).
- "return /regex/" is recognized correctly. - "return /regex/" is recognized correctly.
- Line terminators after regex literals are handled more sensibly
- "+ +" and "- -" sequences are not collapsed to '++' or '--' - "+ +" and "- -" sequences are not collapsed to '++' or '--'
- Newlines before ! operators are removed more sensibly - Newlines before ! operators are removed more sensibly
- Comments starting with an exclamation mark (``!``) can be kept optionally - Comments starting with an exclamation mark (``!``) can be kept optionally
@@ -61,12 +62,12 @@ Both python 2 and python 3 are supported.
http://www.crockford.com/javascript/jsmin.c http://www.crockford.com/javascript/jsmin.c
""" """
if __doc__: if __doc__:
# pylint: disable = W0622 # pylint: disable = redefined-builtin
__doc__ = __doc__.encode('ascii').decode('unicode_escape') __doc__ = __doc__.encode('ascii').decode('unicode_escape')
__author__ = r"Andr\xe9 Malo".encode('ascii').decode('unicode_escape') __author__ = r"Andr\xe9 Malo".encode('ascii').decode('unicode_escape')
__docformat__ = "restructuredtext en" __docformat__ = "restructuredtext en"
__license__ = "Apache License, Version 2.0" __license__ = "Apache License, Version 2.0"
__version__ = '1.0.10' __version__ = '1.0.12'
__all__ = ['jsmin'] __all__ = ['jsmin']
import re as _re import re as _re
@@ -87,11 +88,12 @@ def _make_jsmin(python_only=False):
:Return: Minifier :Return: Minifier
:Rtype: ``callable`` :Rtype: ``callable``
""" """
# pylint: disable = R0912, R0914, W0612 # pylint: disable = unused-variable
# pylint: disable = too-many-locals
if not python_only: if not python_only:
try: try:
import _rjsmin # pylint: disable = F0401 import _rjsmin
except ImportError: except ImportError:
pass pass
else: else:
@@ -99,7 +101,7 @@ def _make_jsmin(python_only=False):
try: try:
xrange xrange
except NameError: except NameError:
xrange = range # pylint: disable = W0622 xrange = range # pylint: disable = redefined-builtin
space_chars = r'[\000-\011\013\014\016-\040]' space_chars = r'[\000-\011\013\014\016-\040]'
@@ -119,7 +121,6 @@ def _make_jsmin(python_only=False):
nospecial, charclass, nospecial nospecial, charclass, nospecial
) )
space = r'(?:%s|%s)' % (space_chars, space_comment) space = r'(?:%s|%s)' % (space_chars, space_comment)
space_nobang = r'(?:%s|%s)' % (space_chars, space_comment_nobang)
newline = r'(?:%s?[\r\n])' % line_comment newline = r'(?:%s?[\r\n])' % line_comment
def fix_charclass(result): def fix_charclass(result):
@@ -146,10 +147,10 @@ def _make_jsmin(python_only=False):
if last is not None: if last is not None:
result.append((first, last)) result.append((first, last))
return ''.join(['%s%s%s' % ( return ''.join(['%s%s%s' % (
chr(first2), chr(first),
last2 > first2 + 1 and '-' or '', last > first + 1 and '-' or '',
last2 != first2 and chr(last2) or '' last != first and chr(last) or ''
) for first2, last2 in result]) ) for first, last in result]) # noqa
return _re.sub( return _re.sub(
r'([\000-\040\047])', # \047 for better portability r'([\000-\040\047])', # \047 for better portability
@@ -184,34 +185,40 @@ def _make_jsmin(python_only=False):
id_literal = id_literal_(r'[a-zA-Z0-9_$]') id_literal = id_literal_(r'[a-zA-Z0-9_$]')
id_literal_open = id_literal_(r'[a-zA-Z0-9_${\[(!+-]') id_literal_open = id_literal_(r'[a-zA-Z0-9_${\[(!+-]')
id_literal_close = id_literal_(r'[a-zA-Z0-9_$}\])"\047+-]') id_literal_close = id_literal_(r'[a-zA-Z0-9_$}\])"\047+-]')
post_regex_off = id_literal_(r'[^\000-\040}\])?:|,;.&=+-]')
dull = r'[^\047"/\000-\040]' dull = r'[^\047"/\000-\040]'
space_sub_simple = _re.compile(( space_sub_simple = _re.compile((
# noqa pylint: disable = C0330 # noqa pylint: disable = bad-continuation
r'(%(dull)s+)' r'(%(dull)s+)' # 0
r'|(%(strings)s%(dull)s*)' r'|(%(strings)s%(dull)s*)' # 1
r'|(?<=%(preregex1)s)' r'|(?<=%(preregex1)s)'
r'%(space)s*(?:%(newline)s%(space)s*)*' r'%(space)s*(?:%(newline)s%(space)s*)*'
r'(%(regex)s%(dull)s*)' r'(%(regex)s)' # 2
r'(%(space)s*(?:%(newline)s%(space)s*)+' # 3
r'(?=%(post_regex_off)s))?'
r'|(?<=%(preregex2)s)' r'|(?<=%(preregex2)s)'
r'%(space)s*(?:%(newline)s%(space)s)*' r'%(space)s*(?:(%(newline)s)%(space)s*)*' # 4
r'(%(regex)s%(dull)s*)' r'(%(regex)s)' # 5
r'(%(space)s*(?:%(newline)s%(space)s*)+' # 6
r'(?=%(post_regex_off)s))?'
r'|(?<=%(id_literal_close)s)' r'|(?<=%(id_literal_close)s)'
r'%(space)s*(?:(%(newline)s)%(space)s*)+' r'%(space)s*(?:(%(newline)s)%(space)s*)+' # 7
r'(?=%(id_literal_open)s)' r'(?=%(id_literal_open)s)'
r'|(?<=%(id_literal)s)(%(space)s)+(?=%(id_literal)s)' r'|(?<=%(id_literal)s)(%(space)s)+(?=%(id_literal)s)' # 8
r'|(?<=\+)(%(space)s)+(?=\+)' r'|(?<=\+)(%(space)s)+(?=\+)' # 9
r'|(?<=-)(%(space)s)+(?=-)' r'|(?<=-)(%(space)s)+(?=-)' # 10
r'|%(space)s+' r'|%(space)s+'
r'|(?:%(newline)s%(space)s*)+' r'|(?:%(newline)s%(space)s*)+'
) % locals()).sub ) % locals()).sub
# print space_sub_simple.__self__.pattern # print space_sub_simple.__self__.pattern
def space_subber_simple(match): def space_subber_simple(match):
""" Substitution callback """ """ Substitution callback """
# pylint: disable = R0911 # pylint: disable = too-many-return-statements
groups = match.groups() groups = match.groups()
if groups[0]: if groups[0]:
@@ -219,62 +226,89 @@ def _make_jsmin(python_only=False):
elif groups[1]: elif groups[1]:
return groups[1] return groups[1]
elif groups[2]: elif groups[2]:
if groups[3]:
return groups[2] + '\n'
return groups[2] return groups[2]
elif groups[3]: elif groups[5]:
return groups[3] return "%s%s%s" % (
elif groups[4]: groups[4] and '\n' or '',
groups[5],
groups[6] and '\n' or '',
)
elif groups[7]:
return '\n' return '\n'
elif groups[5] or groups[6] or groups[7]: elif groups[8] or groups[9] or groups[10]:
return ' ' return ' '
else: else:
return '' return ''
space_sub_banged = _re.compile(( space_sub_banged = _re.compile((
# noqa pylint: disable = C0330 # noqa pylint: disable = bad-continuation
r'(%(dull)s+)' r'(%(dull)s+)' # 0
r'|(%(strings)s%(dull)s*)' r'|(%(strings)s%(dull)s*)' # 1
r'|(%(bang_comment)s%(dull)s*)'
r'|(?<=%(preregex1)s)' r'|(?<=%(preregex1)s)'
r'%(space)s*(?:%(newline)s%(space)s*)*' r'(%(space)s*(?:%(newline)s%(space)s*)*)' # 2
r'(%(regex)s%(dull)s*)' r'(%(regex)s)' # 3
r'(%(space)s*(?:%(newline)s%(space)s*)+' # 4
r'(?=%(post_regex_off)s))?'
r'|(?<=%(preregex2)s)' r'|(?<=%(preregex2)s)'
r'%(space)s*(?:%(newline)s%(space)s)*' r'(%(space)s*(?:(%(newline)s)%(space)s*)*)' # 5, 6
r'(%(regex)s%(dull)s*)' r'(%(regex)s)' # 7
r'(%(space)s*(?:%(newline)s%(space)s*)+' # 8
r'(?=%(post_regex_off)s))?'
r'|(?<=%(id_literal_close)s)' r'|(?<=%(id_literal_close)s)'
r'%(space)s*(?:(%(newline)s)%(space)s*)+' r'(%(space)s*(?:%(newline)s%(space)s*)+)' # 9
r'(?=%(id_literal_open)s)' r'(?=%(id_literal_open)s)'
r'|(?<=%(id_literal)s)(%(space)s)+(?=%(id_literal)s)' r'|(?<=%(id_literal)s)(%(space)s+)(?=%(id_literal)s)' # 10
r'|(?<=\+)(%(space)s)+(?=\+)' r'|(?<=\+)(%(space)s+)(?=\+)' # 11
r'|(?<=-)(%(space)s)+(?=-)' r'|(?<=-)(%(space)s+)(?=-)' # 12
r'|%(space)s+' r'|(%(space)s+)' # 13
r'|(?:%(newline)s%(space)s*)+' r'|((?:%(newline)s%(space)s*)+)' # 14
) % dict(locals(), space=space_nobang)).sub ) % locals()).sub
# print space_sub_banged.__self__.pattern # print space_sub_banged.__self__.pattern
keep = _re.compile((
r'%(space_chars)s+|%(space_comment_nobang)s+|%(newline)s+'
r'|(%(bang_comment)s+)'
) % locals()).sub
keeper = lambda m: m.groups()[0] or ''
# print keep.__self__.pattern
def space_subber_banged(match): def space_subber_banged(match):
""" Substitution callback """ """ Substitution callback """
# pylint: disable = R0911 # pylint: disable = too-many-return-statements
groups = match.groups() groups = match.groups()
if groups[0]: if groups[0]:
return groups[0] return groups[0]
elif groups[1]: elif groups[1]:
return groups[1] return groups[1]
elif groups[2]:
return groups[2]
elif groups[3]: elif groups[3]:
return groups[3] return "%s%s%s%s" % (
elif groups[4]: keep(keeper, groups[2]),
return groups[4] groups[3],
elif groups[5]: keep(keeper, groups[4] or ''),
return '\n' groups[4] and '\n' or '',
elif groups[6] or groups[7] or groups[8]: )
return ' ' elif groups[7]:
return "%s%s%s%s%s" % (
keep(keeper, groups[5]),
groups[6] and '\n' or '',
groups[7],
keep(keeper, groups[8] or ''),
groups[8] and '\n' or '',
)
elif groups[9]:
return keep(keeper, groups[9]) + '\n'
elif groups[10] or groups[11] or groups[12]:
return keep(keeper, groups[10] or groups[11] or groups[12]) or ' '
else: else:
return '' return keep(keeper, groups[13] or groups[14])
def jsmin(script, keep_bang_comments=False): # pylint: disable = W0621 def jsmin(script, keep_bang_comments=False):
r""" r"""
Minify javascript based on `jsmin.c by Douglas Crockford`_\. Minify javascript based on `jsmin.c by Douglas Crockford`_\.
@@ -295,6 +329,8 @@ def _make_jsmin(python_only=False):
:Return: Minified script :Return: Minified script
:Rtype: ``str`` :Rtype: ``str``
""" """
# pylint: disable = redefined-outer-name
if keep_bang_comments: if keep_bang_comments:
return space_sub_banged( return space_sub_banged(
space_subber_banged, '\n%s\n' % script space_subber_banged, '\n%s\n' % script
@@ -343,24 +379,30 @@ def jsmin_for_posers(script, keep_bang_comments=False):
r'][^*]*\*+)*/))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\0' r'][^*]*\*+)*/))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\0'
r'14\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)*((?:/(?![\r' r'14\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)*((?:/(?![\r'
r'\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r' r'\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r'
r'\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/)[^\047"/\000-\040]*)|(?<' r'\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/))((?:[\000-\011\013\014'
r'=[\000-#%-,./:-@\[-^`{-~-]return)(?:[\000-\011\013\014\016-\04' r'\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:(?:(?://[^\r'
r'0]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:(?:(?://[^\r\n]*)?[' r'\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:'
r'\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^' r'[^/*][^*]*\*+)*/))*)+(?=[^\000-\040&)+,.:;=?\]|}-]))?|(?<=[\00'
r'*]*\*+)*/)))*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:' r'0-#%-,./:-@\[-^`{-~-]return)(?:[\000-\011\013\014\016-\040]|(?'
r'\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/)[' r':/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:((?:(?://[^\r\n]*)?[\r\n]'
r'^\047"/\000-\040]*)|(?<=[^\000-!#%&(*,./:-@\[\\^`{|~])(?:[\000' r'))(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*'
r'-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?' r'\*+)*/))*)*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\['
r':((?:(?://[^\r\n]*)?[\r\n]))(?:[\000-\011\013\014\016-\040]|(?' r'[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/))(('
r':/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040"#%-\047)*,.' r'?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)'
r'/:-@\\-^`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-\011\0' r'*/))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\04'
r'13\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=[^\00' r'0]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040&)+,.:;'
r'0-#%-,./:-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]' r'=?\]|}-]))?|(?<=[^\000-!#%&(*,./:-@\[\\^`{|~])(?:[\000-\011\01'
r'|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-' r'3\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:((?:(?:'
r'\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?' r'//[^\r\n]*)?[\r\n]))(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]'
r'=-)|(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]' r'*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040"#%-\047)*,./:-@\\-^'
r'*\*+)*/))+|(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\0' r'`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-\011\013\014\0'
r'16-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+' r'16-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=[^\000-#%-,./'
r':-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]|(?:/\*['
r'^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-\011\013'
r'\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=-)|(?:['
r'\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)'
r')+|(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]'
r'|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+'
) )
def subber(match): def subber(match):
@@ -369,59 +411,85 @@ def jsmin_for_posers(script, keep_bang_comments=False):
return ( return (
groups[0] or groups[0] or
groups[1] or groups[1] or
(groups[3] and (groups[2] + '\n')) or
groups[2] or groups[2] or
groups[3] or (groups[5] and "%s%s%s" % (
(groups[4] and '\n') or groups[4] and '\n' or '',
(groups[5] and ' ') or groups[5],
(groups[6] and ' ') or groups[6] and '\n' or '',
(groups[7] and ' ') or )) or
(groups[7] and '\n') or
(groups[8] and ' ') or
(groups[9] and ' ') or
(groups[10] and ' ') or
'' ''
) )
else: else:
rex = ( rex = (
r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]' r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]'
r'|\r?\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]' r'|\r?\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]'
r'|\r?\n|\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|((?:/\*![^*]*\*' r'|\r?\n|\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|(?<=[(,=:\[!&|?'
r'+(?:[^/*][^*]*\*+)*/)[^\047"/\000-\040]*)|(?<=[(,=:\[!&|?{};\r' r'{};\r\n])((?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/'
r'\n])(?:[\000-\011\013\014\016-\040]|(?:/\*(?!!)[^*]*\*+(?:[^/*' r'*][^*]*\*+)*/))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013'
r'][^*]*\*+)*/))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\0' r'\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)*)((?:/(?!'
r'14\016-\040]|(?:/\*(?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/))*)*((?:/(' r'[\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^'
r'?![\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:' r'\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/))((?:[\000-\011\013\01'
r'\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/)[^\047"/\000-\040]' r'4\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:(?:(?://[^'
r'*)|(?<=[\000-#%-,./:-@\[-^`{-~-]return)(?:[\000-\011\013\014\0' r'\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+('
r'16-\040]|(?:/\*(?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:(?:(?://[' r'?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040&)+,.:;=?\]|}-]))?|(?<=['
r'^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*(?!!)[^*' r'\000-#%-,./:-@\[-^`{-~-]return)((?:[\000-\011\013\014\016-\040'
r']*\*+(?:[^/*][^*]*\*+)*/)))*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:(' r']|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:((?:(?://[^\r\n]*)?['
r'?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/' r'\r\n]))(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*]['
r'\\\[\r\n]*)*/)[^\047"/\000-\040]*)|(?<=[^\000-!#%&(*,./:-@\[\\' r'^*]*\*+)*/))*)*)((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|'
r'^`{|~])(?:[\000-\011\013\014\016-\040]|(?:/\*(?!!)[^*]*\*+(?:[' r'(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*'
r'^/*][^*]*\*+)*/))*(?:((?:(?://[^\r\n]*)?[\r\n]))(?:[\000-\011' r'/))((?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]'
r'\013\014\016-\040]|(?:/\*(?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+' r'*\*+)*/))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\01'
r'(?=[^\000-\040"#%-\047)*,./:-@\\-^`|-~])|(?<=[^\000-#%-,./:-@' r'6-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040&)'
r'\[-^`{-~-])((?:[\000-\011\013\014\016-\040]|(?:/\*(?!!)[^*]*\*' r'+,.:;=?\]|}-]))?|(?<=[^\000-!#%&(*,./:-@\[\\^`{|~])((?:[\000-'
r'+(?:[^/*][^*]*\*+)*/)))+(?=[^\000-#%-,./:-@\[-^`{-~-])|(?<=\+)' r'\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:'
r'((?:[\000-\011\013\014\016-\040]|(?:/\*(?!!)[^*]*\*+(?:[^/*][^' r'(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/'
r'*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-\011\013\014\016-\040]|(?:' r'\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+)(?=[^\000-\040"#%-\047)*,./'
r'/\*(?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=-)|(?:[\000-\011\013' r':-@\\-^`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-\011\01'
r'\014\016-\040]|(?:/\*(?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/))+|(?:(?' r'3\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))+)(?=[^\000'
r':(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*(' r'-#%-,./:-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]|'
r'?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+' r'(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))+)(?=\+)|(?<=-)((?:[\000-\0'
r'11\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))+)(?=-'
r')|((?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*'
r'\*+)*/))+)|((?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014'
r'\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+)'
) )
keep = _re.compile((
r'[\000-\011\013\014\016-\040]+|(?:/\*(?!!)[^*]*\*+(?:[^/*][^*]*'
r'\*+)*/)+|(?:(?://[^\r\n]*)?[\r\n])+|((?:/\*![^*]*\*+(?:[^/*][^'
r'*]*\*+)*/)+)'
) % locals()).sub
keeper = lambda m: m.groups()[0] or ''
def subber(match): def subber(match):
""" Substitution callback """ """ Substitution callback """
groups = match.groups() groups = match.groups()
return ( return (
groups[0] or groups[0] or
groups[1] or groups[1] or
groups[2] or (groups[3] and "%s%s%s%s" % (
groups[3] or keep(keeper, groups[2]),
groups[4] or groups[3],
(groups[5] and '\n') or keep(keeper, groups[4] or ''),
(groups[6] and ' ') or groups[4] and '\n' or '',
(groups[7] and ' ') or )) or
(groups[8] and ' ') or (groups[7] and "%s%s%s%s%s" % (
'' keep(keeper, groups[5]),
groups[6] and '\n' or '',
groups[7],
keep(keeper, groups[8] or ''),
groups[8] and '\n' or '',
)) or
(groups[9] and keep(keeper, groups[9] + '\n')) or
(groups[10] and keep(keeper, groups[10]) or ' ') or
(groups[11] and keep(keeper, groups[11]) or ' ') or
(groups[12] and keep(keeper, groups[12]) or ' ') or
keep(keeper, groups[13] or groups[14])
) )
return _re.sub(rex, subber, '\n%s\n' % script).strip() return _re.sub(rex, subber, '\n%s\n' % script).strip()
@@ -431,16 +499,16 @@ if __name__ == '__main__':
def main(): def main():
""" Main """ """ Main """
import sys as _sys import sys as _sys
keep_bang_comments = (
'-b' in _sys.argv[1:] argv = _sys.argv[1:]
or '-bp' in _sys.argv[1:] keep_bang_comments = '-b' in argv or '-bp' in argv or '-pb' in argv
or '-pb' in _sys.argv[1:] if '-p' in argv or '-bp' in argv or '-pb' in argv:
) xjsmin = _make_jsmin(python_only=True)
if '-p' in _sys.argv[1:] or '-bp' in _sys.argv[1:] \ else:
or '-pb' in _sys.argv[1:]: xjsmin = jsmin
global jsmin # pylint: disable = W0603
jsmin = _make_jsmin(python_only=True) _sys.stdout.write(xjsmin(
_sys.stdout.write(jsmin(
_sys.stdin.read(), keep_bang_comments=keep_bang_comments _sys.stdin.read(), keep_bang_comments=keep_bang_comments
)) ))
main() main()