├── requirements.txt ├── htmlmin ├── tests │ ├── __init__.py │ ├── test_escape.py │ └── tests.py ├── __init__.py ├── decorator.py ├── middleware.py ├── python3html │ ├── __init__.py │ ├── LICENSE │ └── parser.py ├── command.py ├── escape.py ├── main.py └── parser.py ├── MANIFEST.in ├── .gitignore ├── docs ├── tutorial.rst ├── reference.rst ├── index.rst ├── make.bat ├── Makefile ├── quickstart.rst └── conf.py ├── tox.ini ├── .travis.yml ├── README.rst ├── CHANGELOG ├── setup.py └── LICENSE /requirements.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /htmlmin/tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst 2 | include LICENSE 3 | prune htmlmin/tests 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | *~ 3 | build 4 | _build 5 | *.egg-info 6 | dist 7 | .tox 8 | -------------------------------------------------------------------------------- /docs/tutorial.rst: -------------------------------------------------------------------------------- 1 | Tutorial & Examples 2 | =================== 3 | 4 | Coming soon... 5 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist=py27, py33, py34 3 | 4 | [testenv] 5 | commands=python setup.py test 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - "2.7" 4 | - "3.5" 5 | install: "pip install -r requirements.txt" 6 | script: "python setup.py test" 7 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | A configurable HTML Minifier with safety features. 2 | 3 | .. image:: https://travis-ci.org/mankyd/htmlmin.png?branch=master 4 | :target: http://travis-ci.org/mankyd/htmlmin 5 | 6 | Documentation: https://htmlmin.readthedocs.io/en/latest/ 7 | -------------------------------------------------------------------------------- /docs/reference.rst: -------------------------------------------------------------------------------- 1 | API Reference 2 | ============= 3 | 4 | Main Functions 5 | -------------- 6 | .. autofunction:: htmlmin.minify 7 | 8 | .. autoclass:: htmlmin.Minifier 9 | :members: 10 | :member-order: bysource 11 | 12 | WSGI Middlware 13 | -------------- 14 | .. autoclass:: htmlmin.middleware.HTMLMinMiddleware 15 | 16 | Decorator 17 | --------- 18 | .. autofunction:: htmlmin.decorator.htmlmin 19 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | 0.1.12 2 | ====== 3 | * Fix bug that can occur when minifying two pages in a row when the 4 | first page has a dangling tag. 5 | 6 | 0.1.11 7 | ====== 8 | * Fix XSS 9 | * Add support for a 'pre' attribute prefix 10 | * Remove redundat 'lang' tags 11 | (thanks mina86) 12 | * Fixed IndexError when data is empty 13 | (thanks mercuree) 14 | 15 | 0.1.10 16 | ====== 17 | * Fix bug in Python 3.5 where char refs were being improperly escaped 18 | (thanks tenzer) 19 | 20 | 0.1.9 21 | ===== 22 | * Fix bug introduced in 0.1.7 involving spaces in attribute values 23 | 24 | 25 | 0.1.8 26 | ===== 27 | * Fix bug introduced in 0.1.7 involving repeated ampersands. 28 | 29 | 0.1.7 30 | ===== 31 | * Improved attribute escaping. Greatly improves compression. 32 | 33 | 0.1.6 34 | ===== 35 | * Always quote attributes that end in "/". (Thanks nvie) 36 | * Use StringIO to speed up string building. (Thanks nvie) 37 | * Typo fixes in documentation. (Thanks aabrahamowicz and Namibnat) 38 | * Keep Microsoft's conditional comments. (Thanks mreinhardt) 39 | * Properly handle empty comments. (Thanks Epsirom) 40 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from setuptools import setup, find_packages 3 | 4 | from htmlmin import __version__ 5 | 6 | here = os.path.dirname(__file__) 7 | 8 | README = open(os.path.join(here, 'README.rst')).read() 9 | LICENSE = open(os.path.join(here, 'LICENSE')).read() 10 | 11 | setup( 12 | name='htmlmin', 13 | version=__version__, 14 | license='BSD', 15 | description='An HTML Minifier', 16 | long_description=README, 17 | url='https://htmlmin.readthedocs.io/en/latest/', 18 | download_url='https://github.com/mankyd/htmlmin', 19 | author='Dave Mankoff', 20 | author_email='mankyd@gmail.com', 21 | packages=find_packages(), 22 | include_package_data=True, 23 | zip_safe=True, 24 | test_suite='htmlmin.tests.tests.suite', 25 | install_requires=[], 26 | tests_require=[], 27 | classifiers=[ 28 | "Development Status :: 4 - Beta", 29 | "Intended Audience :: Developers", 30 | "License :: OSI Approved :: BSD License", 31 | "Operating System :: OS Independent", 32 | "Programming Language :: Python", 33 | "Programming Language :: Python :: 2.7", 34 | "Programming Language :: Python :: 3.2", 35 | "Topic :: Text Processing :: Markup :: HTML", 36 | ], 37 | entry_points={ 38 | 'console_scripts': [ 39 | 'htmlmin = htmlmin.command:main', 40 | ], 41 | }, 42 | ) 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Dave Mankoff 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of Dave Mankoff nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL DAVE MANKOFF BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /htmlmin/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (c) 2013, Dave Mankoff 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of Dave Mankoff nor the 13 | names of its contributors may be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL DAVE MANKOFF BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | """ 27 | 28 | from .main import minify, Minifier 29 | 30 | __version__ = '0.1.12' 31 | -------------------------------------------------------------------------------- /htmlmin/decorator.py: -------------------------------------------------------------------------------- 1 | """ 2 | Copyright (c) 2013, Dave Mankoff 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above copyright 10 | notice, this list of conditions and the following disclaimer in the 11 | documentation and/or other materials provided with the distribution. 12 | * Neither the name of Dave Mankoff nor the 13 | names of its contributors may be used to endorse or promote products 14 | derived from this software without specific prior written permission. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL DAVE MANKOFF BE LIABLE FOR ANY 20 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | """ 27 | 28 | from .main import Minifier 29 | 30 | def htmlmin(*args, **kwargs): 31 | """Minifies HTML that is returned by a function. 32 | 33 | A simple decorator that minifies the HTML output of any function that it 34 | decorates. It supports all the same options that :class:`htmlmin.minify` has. 35 | With no options, it uses ``minify``'s default settings:: 36 | 37 | @htmlmin 38 | def foobar(): 39 | return ' minify me! ' 40 | 41 | or:: 42 | 43 | @htmlmin(remove_comments=True) 44 | def foobar(): 45 | return ' minify me! ' 46 | """ 47 | def _decorator(fn): 48 | minify = Minifier(**kwargs).minify 49 | def wrapper(*a, **kw): 50 | return minify(fn(*a, **kw)) 51 | return wrapper 52 | 53 | if len(args) == 1: 54 | if callable(args[0]) and not kwargs: 55 | return _decorator(args[0]) 56 | else: 57 | raise RuntimeError( 58 | 'htmlmin decorator does accept positional arguments') 59 | elif len(args) > 1: 60 | raise RuntimeError( 61 | 'htmlmin decorator does accept positional arguments') 62 | else: 63 | return _decorator 64 | 65 | -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. htmlmin documentation master file, created by 2 | sphinx-quickstart on Thu Feb 14 22:56:34 2013. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | htmlmin 7 | =================================== 8 | An HTML Minifier with Seatbelts 9 | 10 | .. toctree:: 11 | 12 | quickstart 13 | tutorial 14 | reference 15 | 16 | 17 | htmlmin is an HTML minifier that just works. It comes with safe defaults and 18 | an easily configurable set options. It can turn this:: 19 | 20 | 21 |
22 |How are you doing?
26 | 27 | 28 | 29 | Into this:: 30 | 31 |How are you doing?
32 | 33 | When we say that htmlmin has 'seatbelts', what we mean is that it comes with 34 | features that you can use to safely minify beyond the defaults, but you have to 35 | put them in yourself. For instance, by default, htmlmin will never minimize the 36 | content between ````, ``