Merge pull request #639 from sdelements/develop

Upgrade to latest rJSmin
This commit is contained in:
Mathieu Pillard
2015-07-28 00:10:03 +02:00
2 changed files with 236 additions and 87 deletions

View File

@@ -5,6 +5,9 @@ from compressor.filters.jsmin.slimit import SlimItFilter # noqa
class rJSMinFilter(CallbackOutputFilter): class rJSMinFilter(CallbackOutputFilter):
callback = "compressor.filters.jsmin.rjsmin.jsmin" callback = "compressor.filters.jsmin.rjsmin.jsmin"
args = {
"b": True
}
# This is for backwards compatibility # This is for backwards compatibility
JSMinFilter = rJSMinFilter JSMinFilter = rJSMinFilter

View File

@@ -1,20 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#
# Copyright 2011 - 2013
# Andr\xe9 Malo or his licensors, as applicable
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
r""" r"""
===================== =====================
Javascript Minifier Javascript Minifier
@@ -22,7 +7,26 @@ r"""
rJSmin is a javascript minifier written in python. rJSmin is a javascript minifier written in python.
The minifier is based on the semantics of `jsmin.c by Douglas Crockford`_\. The minifier is based on the semantics of `jsmin.c by Douglas Crockford`_\\.
:Copyright:
Copyright 2011 - 2014
Andr\xe9 Malo or his licensors, as applicable
:License:
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
The module is a re-implementation aiming for speed, so it can be used at The module is a re-implementation aiming for speed, so it can be used at
runtime (rather than during a preprocessing step). Usually it produces the runtime (rather than during a preprocessing step). Usually it produces the
@@ -31,22 +35,23 @@ same results as the original ``jsmin.c``. It differs in the following ways:
- there is no error detection: unterminated string, regex and comment - there is no error detection: unterminated string, regex and comment
literals are treated as regular javascript code and minified as such. literals are treated as regular javascript code and minified as such.
- Control characters inside string and regex literals are left untouched; they - Control characters inside string and regex literals are left untouched; they
are not converted to spaces (nor to \n) are not converted to spaces (nor to \\n)
- 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.
- "+ +" 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
- rJSmin does not handle streams, but only complete strings. (However, the - rJSmin does not handle streams, but only complete strings. (However, the
module provides a "streamy" interface). module provides a "streamy" interface).
Since most parts of the logic are handled by the regex engine it's way Since most parts of the logic are handled by the regex engine it's way faster
faster than the original python port of ``jsmin.c`` by Baruch Even. The speed than the original python port of ``jsmin.c`` by Baruch Even. The speed factor
factor varies between about 6 and 55 depending on input and python version varies between about 6 and 55 depending on input and python version (it gets
(it gets faster the more compressed the input already is). Compared to the faster the more compressed the input already is). Compared to the
speed-refactored python port by Dave St.Germain the performance gain is less speed-refactored python port by Dave St.Germain the performance gain is less
dramatic but still between 1.2 and 7. See the docs/BENCHMARKS file for dramatic but still between 3 and 50 (for huge inputs). See the docs/BENCHMARKS
details. file for details.
rjsmin.c is a reimplementation of rjsmin.py in C and speeds it up even more. rjsmin.c is a reimplementation of rjsmin.py in C and speeds it up even more.
@@ -55,11 +60,13 @@ Both python 2 and python 3 are supported.
.. _jsmin.c by Douglas Crockford: .. _jsmin.c by Douglas Crockford:
http://www.crockford.com/javascript/jsmin.c http://www.crockford.com/javascript/jsmin.c
""" """
__author__ = "Andr\xe9 Malo" if __doc__:
__author__ = getattr(__author__, 'decode', lambda x: __author__)('latin-1') # pylint: disable = W0622
__doc__ = __doc__.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.7' __version__ = '1.0.10'
__all__ = ['jsmin'] __all__ = ['jsmin']
import re as _re import re as _re
@@ -81,9 +88,10 @@ def _make_jsmin(python_only=False):
:Rtype: ``callable`` :Rtype: ``callable``
""" """
# pylint: disable = R0912, R0914, W0612 # pylint: disable = R0912, R0914, W0612
if not python_only: if not python_only:
try: try:
import _rjsmin import _rjsmin # pylint: disable = F0401
except ImportError: except ImportError:
pass pass
else: else:
@@ -91,12 +99,15 @@ def _make_jsmin(python_only=False):
try: try:
xrange xrange
except NameError: except NameError:
xrange = range # pylint: disable = W0622 xrange = range # pylint: disable = W0622
space_chars = r'[\000-\011\013\014\016-\040]' space_chars = r'[\000-\011\013\014\016-\040]'
line_comment = r'(?://[^\r\n]*)' line_comment = r'(?://[^\r\n]*)'
space_comment = r'(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)' space_comment = r'(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)'
space_comment_nobang = r'(?:/\*(?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/)'
bang_comment = r'(?:/\*![^*]*\*+(?:[^/*][^*]*\*+)*/)'
string1 = \ string1 = \
r'(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^\047\\\r\n]*)*\047)' r'(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^\047\\\r\n]*)*\047)'
string2 = r'(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^"\\\r\n]*)*")' string2 = r'(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|\r)[^"\\\r\n]*)*")'
@@ -108,6 +119,7 @@ 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):
@@ -139,8 +151,10 @@ def _make_jsmin(python_only=False):
last2 != first2 and chr(last2) or '' last2 != first2 and chr(last2) or ''
) for first2, last2 in result]) ) for first2, last2 in result])
return _re.sub(r'([\000-\040\047])', # for better portability return _re.sub(
lambda m: '\\%03o' % ord(m.group(1)), (sequentize(result) r'([\000-\040\047])', # \047 for better portability
lambda m: '\\%03o' % ord(m.group(1)), (
sequentize(result)
.replace('\\', '\\\\') .replace('\\', '\\\\')
.replace('[', '\\[') .replace('[', '\\[')
.replace(']', '\\]') .replace(']', '\\]')
@@ -173,7 +187,9 @@ def _make_jsmin(python_only=False):
dull = r'[^\047"/\000-\040]' dull = r'[^\047"/\000-\040]'
space_sub = _re.compile(( space_sub_simple = _re.compile((
# noqa pylint: disable = C0330
r'(%(dull)s+)' r'(%(dull)s+)'
r'|(%(strings)s%(dull)s*)' r'|(%(strings)s%(dull)s*)'
r'|(?<=%(preregex1)s)' r'|(?<=%(preregex1)s)'
@@ -191,21 +207,74 @@ def _make_jsmin(python_only=False):
r'|%(space)s+' r'|%(space)s+'
r'|(?:%(newline)s%(space)s*)+' r'|(?:%(newline)s%(space)s*)+'
) % locals()).sub ) % locals()).sub
# print space_sub.__self__.pattern # print space_sub_simple.__self__.pattern
def space_subber(match): def space_subber_simple(match):
""" Substitution callback """ """ Substitution callback """
# pylint: disable = C0321, R0911 # pylint: disable = R0911
groups = match.groups()
if groups[0]: return groups[0]
elif groups[1]: return groups[1]
elif groups[2]: return groups[2]
elif groups[3]: return groups[3]
elif groups[4]: return '\n'
elif groups[5] or groups[6] or groups[7]: return ' '
else: return ''
def jsmin(script): # pylint: disable = W0621 groups = match.groups()
if groups[0]:
return groups[0]
elif groups[1]:
return groups[1]
elif groups[2]:
return groups[2]
elif groups[3]:
return groups[3]
elif groups[4]:
return '\n'
elif groups[5] or groups[6] or groups[7]:
return ' '
else:
return ''
space_sub_banged = _re.compile((
# noqa pylint: disable = C0330
r'(%(dull)s+)'
r'|(%(strings)s%(dull)s*)'
r'|(%(bang_comment)s%(dull)s*)'
r'|(?<=%(preregex1)s)'
r'%(space)s*(?:%(newline)s%(space)s*)*'
r'(%(regex)s%(dull)s*)'
r'|(?<=%(preregex2)s)'
r'%(space)s*(?:%(newline)s%(space)s)*'
r'(%(regex)s%(dull)s*)'
r'|(?<=%(id_literal_close)s)'
r'%(space)s*(?:(%(newline)s)%(space)s*)+'
r'(?=%(id_literal_open)s)'
r'|(?<=%(id_literal)s)(%(space)s)+(?=%(id_literal)s)'
r'|(?<=\+)(%(space)s)+(?=\+)'
r'|(?<=-)(%(space)s)+(?=-)'
r'|%(space)s+'
r'|(?:%(newline)s%(space)s*)+'
) % dict(locals(), space=space_nobang)).sub
# print space_sub_banged.__self__.pattern
def space_subber_banged(match):
""" Substitution callback """
# pylint: disable = R0911
groups = match.groups()
if groups[0]:
return groups[0]
elif groups[1]:
return groups[1]
elif groups[2]:
return groups[2]
elif groups[3]:
return groups[3]
elif groups[4]:
return groups[4]
elif groups[5]:
return '\n'
elif groups[6] or groups[7] or groups[8]:
return ' '
else:
return ''
def jsmin(script, keep_bang_comments=False): # pylint: disable = W0621
r""" r"""
Minify javascript based on `jsmin.c by Douglas Crockford`_\. Minify javascript based on `jsmin.c by Douglas Crockford`_\.
@@ -220,17 +289,27 @@ def _make_jsmin(python_only=False):
`script` : ``str`` `script` : ``str``
Script to minify Script to minify
`keep_bang_comments` : ``bool``
Keep comments starting with an exclamation mark? (``/*!...*/``)
:Return: Minified script :Return: Minified script
:Rtype: ``str`` :Rtype: ``str``
""" """
return space_sub(space_subber, '\n%s\n' % script).strip() if keep_bang_comments:
return space_sub_banged(
space_subber_banged, '\n%s\n' % script
).strip()
else:
return space_sub_simple(
space_subber_simple, '\n%s\n' % script
).strip()
return jsmin return jsmin
jsmin = _make_jsmin() jsmin = _make_jsmin()
def jsmin_for_posers(script): def jsmin_for_posers(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`_\.
@@ -242,59 +321,126 @@ def jsmin_for_posers(script):
http://www.crockford.com/javascript/jsmin.c http://www.crockford.com/javascript/jsmin.c
:Warning: This function is the digest of a _make_jsmin() call. It just :Warning: This function is the digest of a _make_jsmin() call. It just
utilizes the resulting regex. It's just for fun here and may utilizes the resulting regexes. It's here for fun and may
vanish any time. Use the `jsmin` function instead. vanish any time. Use the `jsmin` function instead.
:Parameters: :Parameters:
`script` : ``str`` `script` : ``str``
Script to minify Script to minify
`keep_bang_comments` : ``bool``
Keep comments starting with an exclamation mark? (``/*!...*/``)
:Return: Minified script :Return: Minified script
:Rtype: ``str`` :Rtype: ``str``
""" """
def subber(match): if not keep_bang_comments:
""" Substitution callback """ rex = (
groups = match.groups() r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]'
return ( r'|\r?\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]'
groups[0] or r'|\r?\n|\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|(?<=[(,=:\[!&|?'
groups[1] or r'{};\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*'
groups[2] or r'][^*]*\*+)*/))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\0'
groups[3] or r'14\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)*((?:/(?![\r'
(groups[4] and '\n') or r'\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r'
(groups[5] and ' ') or r'\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/)[^\047"/\000-\040]*)|(?<'
(groups[6] and ' ') or r'=[\000-#%-,./:-@\[-^`{-~-]return)(?:[\000-\011\013\014\016-\04'
(groups[7] and ' ') or r'0]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:(?:(?://[^\r\n]*)?['
'' r'\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^'
r'*]*\*+)*/)))*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:'
r'\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/)['
r'^\047"/\000-\040]*)|(?<=[^\000-!#%&(*,./:-@\[\\^`{|~])(?:[\000'
r'-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?'
r':((?:(?://[^\r\n]*)?[\r\n]))(?:[\000-\011\013\014\016-\040]|(?'
r':/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040"#%-\047)*,.'
r'/:-@\\-^`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-\011\0'
r'13\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=[^\00'
r'0-#%-,./:-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]'
r'|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-'
r'\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?'
r'=-)|(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]'
r'*\*+)*/))+|(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\0'
r'16-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+'
) )
return _re.sub( def subber(match):
r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]|\r?' """ Substitution callback """
r'\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]|\r?\n|' groups = match.groups()
r'\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|(?<=[(,=:\[!&|?{};\r\n])(?' return (
r':[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*' groups[0] or
r'(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*' groups[1] or
r'[^*]*\*+(?:[^/*][^*]*\*+)*/))*)*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:(' groups[2] or
r'?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[' groups[3] or
r'\r\n]*)*/)[^\047"/\000-\040]*)|(?<=[\000-#%-,./:-@\[-^`{-~-]return' (groups[4] and '\n') or
r')(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/' (groups[5] and ' ') or
r'))*(?:(?:(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:' (groups[6] and ' ') or
r'/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?' (groups[7] and ' ') or
r':(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/' ''
r'\\\[\r\n]*)*/)[^\047"/\000-\040]*)|(?<=[^\000-!#%&(*,./:-@\[\\^`{|' )
r'~])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)' else:
r'*/))*(?:((?:(?://[^\r\n]*)?[\r\n]))(?:[\000-\011\013\014\016-\040]' rex = (
r'|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+(?=[^\000-\040"#%-\047)*,./' r'([^\047"/\000-\040]+)|((?:(?:\047[^\047\\\r\n]*(?:\\(?:[^\r\n]'
r':-@\\-^`|-~])|(?<=[^\000-#%-,./:-@\[-^`{-~-])((?:[\000-\011\013\01' r'|\r?\n|\r)[^\047\\\r\n]*)*\047)|(?:"[^"\\\r\n]*(?:\\(?:[^\r\n]'
r'4\016-\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=[^\000-#%-,./:' r'|\r?\n|\r)[^"\\\r\n]*)*"))[^\047"/\000-\040]*)|((?:/\*![^*]*\*'
r'-@\[-^`{-~-])|(?<=\+)((?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*' r'+(?:[^/*][^*]*\*+)*/)[^\047"/\000-\040]*)|(?<=[(,=:\[!&|?{};\r'
r'\*+(?:[^/*][^*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-\011\013\014\016-' r'\n])(?:[\000-\011\013\014\016-\040]|(?:/\*(?!!)[^*]*\*+(?:[^/*'
r'\040]|(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=-)|(?:[\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])(?:[\000-\011\013\014\016-\040]|(?:/\*[^*]*\*+(?:[^' r'?![\r\n/*])[^/\\\[\r\n]*(?:(?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:'
r'/*][^*]*\*+)*/))*)+', subber, '\n%s\n' % script r'\\[^\r\n][^\\\]\r\n]*)*\]))[^/\\\[\r\n]*)*/)[^\047"/\000-\040]'
).strip() r'*)|(?<=[\000-#%-,./:-@\[-^`{-~-]return)(?:[\000-\011\013\014\0'
r'16-\040]|(?:/\*(?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/))*(?:(?:(?://['
r'^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*(?!!)[^*'
r']*\*+(?:[^/*][^*]*\*+)*/)))*((?:/(?![\r\n/*])[^/\\\[\r\n]*(?:('
r'?:\\[^\r\n]|(?:\[[^\\\]\r\n]*(?:\\[^\r\n][^\\\]\r\n]*)*\]))[^/'
r'\\\[\r\n]*)*/)[^\047"/\000-\040]*)|(?<=[^\000-!#%&(*,./:-@\[\\'
r'^`{|~])(?:[\000-\011\013\014\016-\040]|(?:/\*(?!!)[^*]*\*+(?:['
r'^/*][^*]*\*+)*/))*(?:((?:(?://[^\r\n]*)?[\r\n]))(?:[\000-\011'
r'\013\014\016-\040]|(?:/\*(?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+'
r'(?=[^\000-\040"#%-\047)*,./:-@\\-^`|-~])|(?<=[^\000-#%-,./:-@'
r'\[-^`{-~-])((?:[\000-\011\013\014\016-\040]|(?:/\*(?!!)[^*]*\*'
r'+(?:[^/*][^*]*\*+)*/)))+(?=[^\000-#%-,./:-@\[-^`{-~-])|(?<=\+)'
r'((?:[\000-\011\013\014\016-\040]|(?:/\*(?!!)[^*]*\*+(?:[^/*][^'
r'*]*\*+)*/)))+(?=\+)|(?<=-)((?:[\000-\011\013\014\016-\040]|(?:'
r'/\*(?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/)))+(?=-)|(?:[\000-\011\013'
r'\014\016-\040]|(?:/\*(?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/))+|(?:(?'
r':(?://[^\r\n]*)?[\r\n])(?:[\000-\011\013\014\016-\040]|(?:/\*('
r'?!!)[^*]*\*+(?:[^/*][^*]*\*+)*/))*)+'
)
def subber(match):
""" Substitution callback """
groups = match.groups()
return (
groups[0] or
groups[1] or
groups[2] or
groups[3] or
groups[4] or
(groups[5] and '\n') or
(groups[6] and ' ') or
(groups[7] and ' ') or
(groups[8] and ' ') or
''
)
return _re.sub(rex, subber, '\n%s\n' % script).strip()
if __name__ == '__main__': if __name__ == '__main__':
import sys as _sys def main():
_sys.stdout.write(jsmin(_sys.stdin.read())) """ Main """
import sys as _sys
keep_bang_comments = (
'-b' in _sys.argv[1:]
or '-bp' in _sys.argv[1:]
or '-pb' in _sys.argv[1:]
)
if '-p' in _sys.argv[1:] or '-bp' in _sys.argv[1:] \
or '-pb' in _sys.argv[1:]:
global jsmin # pylint: disable = W0603
jsmin = _make_jsmin(python_only=True)
_sys.stdout.write(jsmin(
_sys.stdin.read(), keep_bang_comments=keep_bang_comments
))
main()