We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Add support for cssminifier.com and javascript-minifier.com
They offer a nice service to minify CSS/JS and it's easy to use.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nikola/filters.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 
3 # Copyright © 2012-2015 Roberto Alsina and others.
4 
5 # Permission is hereby granted, free of charge, to any
6 # person obtaining a copy of this software and associated
7 # documentation files (the "Software"), to deal in the
8 # Software without restriction, including without limitation
9 # the rights to use, copy, modify, merge, publish,
10 # distribute, sublicense, and/or sell copies of the
11 # Software, and to permit persons to whom the Software is
12 # furnished to do so, subject to the following conditions:
13 #
14 # The above copyright notice and this permission notice
15 # shall be included in all copies or substantial portions of
16 # the Software.
17 #
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
21 # PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
22 # OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
24 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 
27 """Utility functions to help run filters on files."""
28 
29 from .utils import req_missing
30 from functools import wraps
31 import os
32 import io
33 import shutil
34 import subprocess
35 import tempfile
36 import shlex
37 
38 try:
39     import typogrify.filters as typo
40 except ImportError:
41     typo = None  # NOQA
42 
43 
44 def apply_to_binary_file(f):
45     """Apply a filter to a binary file.
46 
47     Take a function f that transforms a data argument, and returns
48     a function that takes a filename and applies f to the contents,
49     in place.  Reads files in binary mode.
50     """
51     @wraps(f)
52     def f_in_file(fname):
53         with open(fname, 'rb') as inf:
54             data = inf.read()
55         data = f(data)
56         with open(fname, 'wb+') as outf:
57             outf.write(data)
58 
59     return f_in_file
60 
61 
62 def apply_to_text_file(f):
63     """Apply a filter to a text file.
64 
65     Take a function f that transforms a data argument, and returns
66     a function that takes a filename and applies f to the contents,
67     in place.  Reads files in UTF-8.
68     """
69     @wraps(f)
70     def f_in_file(fname):
71         with io.open(fname, 'r', encoding='utf-8') as inf:
72             data = inf.read()
73         data = f(data)
74         with io.open(fname, 'w+', encoding='utf-8') as outf:
75             outf.write(data)
76 
77     return f_in_file
78 
79 
80 def list_replace(the_list, find, replacement):
81     """Replace all occurrences of ``find`` with ``replacement`` in ``the_list``."""
82     for i, v in enumerate(the_list):
83         if v == find:
84             the_list[i] = replacement
85 
86 
87 def runinplace(command, infile):
88     """Run a command in-place on a file.
89 
90     command is a string of the form: "commandname %1 %2" and
91     it will be execed with infile as %1 and a temporary file
92     as %2. Then, that temporary file will be moved over %1.
93 
94     Example usage:
95 
96     runinplace("yui-compressor %1 -o %2", "myfile.css")
97 
98     That will replace myfile.css with a minified version.
99 
100     You can also supply command as a list.
101     """
102     if not isinstance(command, list):
103         command = shlex.split(command)
104 
105     tmpdir = None
106 
107     if "%2" in command:
108         tmpdir = tempfile.mkdtemp(prefix="nikola")
109         tmpfname = os.path.join(tmpdir, os.path.basename(infile))
110 
111     try:
112         list_replace(command, "%1", infile)
113         if tmpdir:
114             list_replace(command, "%2", tmpfname)
115 
116         subprocess.check_call(command)
117 
118         if tmpdir:
119             shutil.move(tmpfname, infile)
120     finally:
121         if tmpdir:
122             shutil.rmtree(tmpdir)
123 
124 
125 def yui_compressor(infile):
126     """Run YUI Compressor on a file."""
127     yuicompressor = False
128     try:
129         subprocess.call('yui-compressor', stdout=open(os.devnull, 'w'), stderr=open(os.devnull, 'w'))
130         yuicompressor = 'yui-compressor'
131     except Exception:
132         pass
133     if not yuicompressor:
134         try:
135             subprocess.call('yuicompressor', stdout=open(os.devnull, 'w'), stderr=open(os.devnull, 'w'))
136             yuicompressor = 'yuicompressor'
137         except:
138             raise Exception("yui-compressor is not installed.")
139             return False
140 
141     return runinplace(r'{} --nomunge %1 -o %2'.format(yuicompressor), infile)
142 
143 
144 def closure_compiler(infile):
145     """Run closure-compiler on a file."""
146     return runinplace(r'closure-compiler --warning_level QUIET --js %1 --js_output_file %2', infile)
147 
148 
149 def optipng(infile):
150     """Run optipng on a file."""
151     return runinplace(r"optipng -preserve -o2 -quiet %1", infile)
152 
153 
154 def jpegoptim(infile):
155     """Run jpegoptim on a file."""
156     return runinplace(r"jpegoptim -p --strip-all -q %1", infile)
157 
158 
159 def html_tidy_withconfig(infile):
160     """Run HTML Tidy with tidy5.conf as config file."""
161     return _html_tidy_runner(infile, r"-quiet --show-info no --show-warnings no -utf8 -indent -config tidy5.conf -modify %1")
162 
163 
164 def html_tidy_nowrap(infile):
165     """Run HTML Tidy without line wrapping."""
166     return _html_tidy_runner(infile, r"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes no --sort-attributes alpha --wrap 0 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1")
167 
168 
169 def html_tidy_wrap(infile):
170     """Run HTML Tidy with line wrapping."""
171     return _html_tidy_runner(infile, r"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes no --sort-attributes alpha --wrap 80 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1")
172 
173 
174 def html_tidy_wrap_attr(infile):
175     """Run HTML tidy with line wrapping and attribute indentation."""
176     return _html_tidy_runner(infile, r"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes yes --sort-attributes alpha --wrap 80 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1")
177 
178 
179 def html_tidy_mini(infile):
180     """Run HTML tidy with minimal settings."""
181     return _html_tidy_runner(infile, r"-quiet --show-info no --show-warnings no -utf8 --indent-attributes no --sort-attributes alpha --wrap 0 --wrap-sections no --tidy-mark no --drop-empty-elements no -modify %1")
182 
183 
184 def _html_tidy_runner(infile, options):
185     """Run HTML Tidy."""
186     # Warnings (returncode 1) are not critical, and *everything* is a warning.
187     try:
188         status = runinplace(r"tidy5 " + options, infile)
189     except subprocess.CalledProcessError as err:
190         status = 0 if err.returncode == 1 else err.returncode
191     return status
192 
193 
194 @apply_to_text_file
195 def html5lib_minify(data):
196     """Minify with html5lib."""
197     import html5lib
198     import html5lib.serializer
199     data = html5lib.serializer.serialize(html5lib.parse(data, treebuilder='lxml'),
200                                          tree='lxml',
201                                          quote_attr_values=False,
202                                          omit_optional_tags=True,
203                                          minimize_boolean_attributes=True,
204                                          strip_whitespace=True,
205                                          alphabetical_attributes=True,
206                                          escape_lt_in_attrs=True)
207     return data
208 
209 
210 @apply_to_text_file
211 def html5lib_xmllike(data):
212     """Transform document to an XML-like form with html5lib."""
213     import html5lib
214     import html5lib.serializer
215     data = html5lib.serializer.serialize(html5lib.parse(data, treebuilder='lxml'),
216                                          tree='lxml',
217                                          quote_attr_values=True,
218                                          omit_optional_tags=False,
219                                          strip_whitespace=False,
220                                          alphabetical_attributes=True,
221                                          escape_lt_in_attrs=True)
222     return data
223 
224 
225 @apply_to_text_file
226 def minify_lines(data):
227     """Do nothing -- deprecated filter."""
228     return data
229 
230 
231 @apply_to_text_file
232 def typogrify(data):
233     """Prettify text with typogrify."""
234     if typo is None:
235         req_missing(['typogrify'], 'use the typogrify filter')
236 
237     data = typo.amp(data)
238     data = typo.widont(data)
239     data = typo.smartypants(data)
240     # Disabled because of typogrify bug where it breaks <title>
241     # data = typo.caps(data)
242     data = typo.initial_quotes(data)
243     return data
244 
245 
246 @apply_to_text_file
247 def typogrify_sans_widont(data):
248     """Prettify text with typogrify, skipping the widont filter."""
249     # typogrify with widont disabled because it caused broken headline
250     # wrapping, see issue #1465
251     if typo is None:
252         req_missing(['typogrify'], 'use the typogrify_sans_widont filter')
253 
254     data = typo.amp(data)
255     data = typo.smartypants(data)
256     # Disabled because of typogrify bug where it breaks <title>
257     # data = typo.caps(data)
258     data = typo.initial_quotes(data)
259     return data
260 
261 
262 @apply_to_text_file
263 def php_template_injection(data):
264     """Insert PHP code into Nikola templates."""
265     import re
266     template = re.search('<\!-- __NIKOLA_PHP_TEMPLATE_INJECTION source\:(.*) checksum\:(.*)__ -->', data)
267     if template:
268         source = template.group(1)
269         with io.open(source, "r", encoding="utf-8") as in_file:
270             phpdata = in_file.read()
271         _META_SEPARATOR = '(' + os.linesep * 2 + '|' + ('\n' * 2) + '|' + ("\r\n" * 2) + ')'
272         phpdata = re.split(_META_SEPARATOR, phpdata, maxsplit=1)[-1]
273         phpdata = re.sub(template.group(0), phpdata, data)
274         return phpdata
275     else:
276         return data
277
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/nikola/filters.py b/nikola/filters.py
--- a/nikola/filters.py
+++ b/nikola/filters.py
@@ -26,7 +26,6 @@
 
 """Utility functions to help run filters on files."""
 
-from .utils import req_missing
 from functools import wraps
 import os
 import io
@@ -39,6 +38,9 @@
     import typogrify.filters as typo
 except ImportError:
     typo = None  # NOQA
+import requests
+
+from .utils import req_missing, LOGGER
 
 
 def apply_to_binary_file(f):
@@ -274,3 +276,29 @@
         return phpdata
     else:
         return data
+
+
+@apply_to_text_file
+def cssminify(data):
+    """Minify CSS using http://cssminifier.com/."""
+    try:
+        url = 'http://cssminifier.com/raw'
+        _data = {'input': data}
+        response = requests.post(url, data=_data)
+        return response.text
+    except Exception as exc:
+        LOGGER.error("can't use cssminifier.com: {}", exc)
+        return data
+
+
+@apply_to_text_file
+def jsminify(data):
+    """Minify JS using http://javascript-minifier.com/."""
+    try:
+        url = 'http://javascript-minifier.com/raw'
+        _data = {'input': data}
+        response = requests.post(url, data=_data)
+        return response.text
+    except Exception as exc:
+        LOGGER.error("can't use javascript-minifier.com: {}", exc)
+        return data

{"golden_diff": "diff --git a/nikola/filters.py b/nikola/filters.py\n--- a/nikola/filters.py\n+++ b/nikola/filters.py\n@@ -26,7 +26,6 @@\n \n \"\"\"Utility functions to help run filters on files.\"\"\"\n \n-from .utils import req_missing\n from functools import wraps\n import os\n import io\n@@ -39,6 +38,9 @@\n     import typogrify.filters as typo\n except ImportError:\n     typo = None  # NOQA\n+import requests\n+\n+from .utils import req_missing, LOGGER\n \n \n def apply_to_binary_file(f):\n@@ -274,3 +276,29 @@\n         return phpdata\n     else:\n         return data\n+\n+\n+@apply_to_text_file\n+def cssminify(data):\n+    \"\"\"Minify CSS using http://cssminifier.com/.\"\"\"\n+    try:\n+        url = 'http://cssminifier.com/raw'\n+        _data = {'input': data}\n+        response = requests.post(url, data=_data)\n+        return response.text\n+    except Exception as exc:\n+        LOGGER.error(\"can't use cssminifier.com: {}\", exc)\n+        return data\n+\n+\n+@apply_to_text_file\n+def jsminify(data):\n+    \"\"\"Minify JS using http://javascript-minifier.com/.\"\"\"\n+    try:\n+        url = 'http://javascript-minifier.com/raw'\n+        _data = {'input': data}\n+        response = requests.post(url, data=_data)\n+        return response.text\n+    except Exception as exc:\n+        LOGGER.error(\"can't use javascript-minifier.com: {}\", exc)\n+        return data\n", "issue": "Add support for cssminifier.com and javascript-minifier.com\nThey offer a nice service to minify CSS/JS and it's easy to use.\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Copyright \u00a9 2012-2015 Roberto Alsina and others.\n\n# Permission is hereby granted, free of charge, to any\n# person obtaining a copy of this software and associated\n# documentation files (the \"Software\"), to deal in the\n# Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the\n# Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice\n# shall be included in all copies or substantial portions of\n# the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY\n# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS\n# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\"\"\"Utility functions to help run filters on files.\"\"\"\n\nfrom .utils import req_missing\nfrom functools import wraps\nimport os\nimport io\nimport shutil\nimport subprocess\nimport tempfile\nimport shlex\n\ntry:\n    import typogrify.filters as typo\nexcept ImportError:\n    typo = None  # NOQA\n\n\ndef apply_to_binary_file(f):\n    \"\"\"Apply a filter to a binary file.\n\n    Take a function f that transforms a data argument, and returns\n    a function that takes a filename and applies f to the contents,\n    in place.  Reads files in binary mode.\n    \"\"\"\n    @wraps(f)\n    def f_in_file(fname):\n        with open(fname, 'rb') as inf:\n            data = inf.read()\n        data = f(data)\n        with open(fname, 'wb+') as outf:\n            outf.write(data)\n\n    return f_in_file\n\n\ndef apply_to_text_file(f):\n    \"\"\"Apply a filter to a text file.\n\n    Take a function f that transforms a data argument, and returns\n    a function that takes a filename and applies f to the contents,\n    in place.  Reads files in UTF-8.\n    \"\"\"\n    @wraps(f)\n    def f_in_file(fname):\n        with io.open(fname, 'r', encoding='utf-8') as inf:\n            data = inf.read()\n        data = f(data)\n        with io.open(fname, 'w+', encoding='utf-8') as outf:\n            outf.write(data)\n\n    return f_in_file\n\n\ndef list_replace(the_list, find, replacement):\n    \"\"\"Replace all occurrences of ``find`` with ``replacement`` in ``the_list``.\"\"\"\n    for i, v in enumerate(the_list):\n        if v == find:\n            the_list[i] = replacement\n\n\ndef runinplace(command, infile):\n    \"\"\"Run a command in-place on a file.\n\n    command is a string of the form: \"commandname %1 %2\" and\n    it will be execed with infile as %1 and a temporary file\n    as %2. Then, that temporary file will be moved over %1.\n\n    Example usage:\n\n    runinplace(\"yui-compressor %1 -o %2\", \"myfile.css\")\n\n    That will replace myfile.css with a minified version.\n\n    You can also supply command as a list.\n    \"\"\"\n    if not isinstance(command, list):\n        command = shlex.split(command)\n\n    tmpdir = None\n\n    if \"%2\" in command:\n        tmpdir = tempfile.mkdtemp(prefix=\"nikola\")\n        tmpfname = os.path.join(tmpdir, os.path.basename(infile))\n\n    try:\n        list_replace(command, \"%1\", infile)\n        if tmpdir:\n            list_replace(command, \"%2\", tmpfname)\n\n        subprocess.check_call(command)\n\n        if tmpdir:\n            shutil.move(tmpfname, infile)\n    finally:\n        if tmpdir:\n            shutil.rmtree(tmpdir)\n\n\ndef yui_compressor(infile):\n    \"\"\"Run YUI Compressor on a file.\"\"\"\n    yuicompressor = False\n    try:\n        subprocess.call('yui-compressor', stdout=open(os.devnull, 'w'), stderr=open(os.devnull, 'w'))\n        yuicompressor = 'yui-compressor'\n    except Exception:\n        pass\n    if not yuicompressor:\n        try:\n            subprocess.call('yuicompressor', stdout=open(os.devnull, 'w'), stderr=open(os.devnull, 'w'))\n            yuicompressor = 'yuicompressor'\n        except:\n            raise Exception(\"yui-compressor is not installed.\")\n            return False\n\n    return runinplace(r'{} --nomunge %1 -o %2'.format(yuicompressor), infile)\n\n\ndef closure_compiler(infile):\n    \"\"\"Run closure-compiler on a file.\"\"\"\n    return runinplace(r'closure-compiler --warning_level QUIET --js %1 --js_output_file %2', infile)\n\n\ndef optipng(infile):\n    \"\"\"Run optipng on a file.\"\"\"\n    return runinplace(r\"optipng -preserve -o2 -quiet %1\", infile)\n\n\ndef jpegoptim(infile):\n    \"\"\"Run jpegoptim on a file.\"\"\"\n    return runinplace(r\"jpegoptim -p --strip-all -q %1\", infile)\n\n\ndef html_tidy_withconfig(infile):\n    \"\"\"Run HTML Tidy with tidy5.conf as config file.\"\"\"\n    return _html_tidy_runner(infile, r\"-quiet --show-info no --show-warnings no -utf8 -indent -config tidy5.conf -modify %1\")\n\n\ndef html_tidy_nowrap(infile):\n    \"\"\"Run HTML Tidy without line wrapping.\"\"\"\n    return _html_tidy_runner(infile, r\"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes no --sort-attributes alpha --wrap 0 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1\")\n\n\ndef html_tidy_wrap(infile):\n    \"\"\"Run HTML Tidy with line wrapping.\"\"\"\n    return _html_tidy_runner(infile, r\"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes no --sort-attributes alpha --wrap 80 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1\")\n\n\ndef html_tidy_wrap_attr(infile):\n    \"\"\"Run HTML tidy with line wrapping and attribute indentation.\"\"\"\n    return _html_tidy_runner(infile, r\"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes yes --sort-attributes alpha --wrap 80 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1\")\n\n\ndef html_tidy_mini(infile):\n    \"\"\"Run HTML tidy with minimal settings.\"\"\"\n    return _html_tidy_runner(infile, r\"-quiet --show-info no --show-warnings no -utf8 --indent-attributes no --sort-attributes alpha --wrap 0 --wrap-sections no --tidy-mark no --drop-empty-elements no -modify %1\")\n\n\ndef _html_tidy_runner(infile, options):\n    \"\"\"Run HTML Tidy.\"\"\"\n    # Warnings (returncode 1) are not critical, and *everything* is a warning.\n    try:\n        status = runinplace(r\"tidy5 \" + options, infile)\n    except subprocess.CalledProcessError as err:\n        status = 0 if err.returncode == 1 else err.returncode\n    return status\n\n\n@apply_to_text_file\ndef html5lib_minify(data):\n    \"\"\"Minify with html5lib.\"\"\"\n    import html5lib\n    import html5lib.serializer\n    data = html5lib.serializer.serialize(html5lib.parse(data, treebuilder='lxml'),\n                                         tree='lxml',\n                                         quote_attr_values=False,\n                                         omit_optional_tags=True,\n                                         minimize_boolean_attributes=True,\n                                         strip_whitespace=True,\n                                         alphabetical_attributes=True,\n                                         escape_lt_in_attrs=True)\n    return data\n\n\n@apply_to_text_file\ndef html5lib_xmllike(data):\n    \"\"\"Transform document to an XML-like form with html5lib.\"\"\"\n    import html5lib\n    import html5lib.serializer\n    data = html5lib.serializer.serialize(html5lib.parse(data, treebuilder='lxml'),\n                                         tree='lxml',\n                                         quote_attr_values=True,\n                                         omit_optional_tags=False,\n                                         strip_whitespace=False,\n                                         alphabetical_attributes=True,\n                                         escape_lt_in_attrs=True)\n    return data\n\n\n@apply_to_text_file\ndef minify_lines(data):\n    \"\"\"Do nothing -- deprecated filter.\"\"\"\n    return data\n\n\n@apply_to_text_file\ndef typogrify(data):\n    \"\"\"Prettify text with typogrify.\"\"\"\n    if typo is None:\n        req_missing(['typogrify'], 'use the typogrify filter')\n\n    data = typo.amp(data)\n    data = typo.widont(data)\n    data = typo.smartypants(data)\n    # Disabled because of typogrify bug where it breaks <title>\n    # data = typo.caps(data)\n    data = typo.initial_quotes(data)\n    return data\n\n\n@apply_to_text_file\ndef typogrify_sans_widont(data):\n    \"\"\"Prettify text with typogrify, skipping the widont filter.\"\"\"\n    # typogrify with widont disabled because it caused broken headline\n    # wrapping, see issue #1465\n    if typo is None:\n        req_missing(['typogrify'], 'use the typogrify_sans_widont filter')\n\n    data = typo.amp(data)\n    data = typo.smartypants(data)\n    # Disabled because of typogrify bug where it breaks <title>\n    # data = typo.caps(data)\n    data = typo.initial_quotes(data)\n    return data\n\n\n@apply_to_text_file\ndef php_template_injection(data):\n    \"\"\"Insert PHP code into Nikola templates.\"\"\"\n    import re\n    template = re.search('<\\!-- __NIKOLA_PHP_TEMPLATE_INJECTION source\\:(.*) checksum\\:(.*)__ -->', data)\n    if template:\n        source = template.group(1)\n        with io.open(source, \"r\", encoding=\"utf-8\") as in_file:\n            phpdata = in_file.read()\n        _META_SEPARATOR = '(' + os.linesep * 2 + '|' + ('\\n' * 2) + '|' + (\"\\r\\n\" * 2) + ')'\n        phpdata = re.split(_META_SEPARATOR, phpdata, maxsplit=1)[-1]\n        phpdata = re.sub(template.group(0), phpdata, data)\n        return phpdata\n    else:\n        return data\n", "path": "nikola/filters.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n\n# Copyright \u00a9 2012-2015 Roberto Alsina and others.\n\n# Permission is hereby granted, free of charge, to any\n# person obtaining a copy of this software and associated\n# documentation files (the \"Software\"), to deal in the\n# Software without restriction, including without limitation\n# the rights to use, copy, modify, merge, publish,\n# distribute, sublicense, and/or sell copies of the\n# Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice\n# shall be included in all copies or substantial portions of\n# the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY\n# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE\n# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR\n# PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS\n# OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR\n# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\"\"\"Utility functions to help run filters on files.\"\"\"\n\nfrom functools import wraps\nimport os\nimport io\nimport shutil\nimport subprocess\nimport tempfile\nimport shlex\n\ntry:\n    import typogrify.filters as typo\nexcept ImportError:\n    typo = None  # NOQA\nimport requests\n\nfrom .utils import req_missing, LOGGER\n\n\ndef apply_to_binary_file(f):\n    \"\"\"Apply a filter to a binary file.\n\n    Take a function f that transforms a data argument, and returns\n    a function that takes a filename and applies f to the contents,\n    in place.  Reads files in binary mode.\n    \"\"\"\n    @wraps(f)\n    def f_in_file(fname):\n        with open(fname, 'rb') as inf:\n            data = inf.read()\n        data = f(data)\n        with open(fname, 'wb+') as outf:\n            outf.write(data)\n\n    return f_in_file\n\n\ndef apply_to_text_file(f):\n    \"\"\"Apply a filter to a text file.\n\n    Take a function f that transforms a data argument, and returns\n    a function that takes a filename and applies f to the contents,\n    in place.  Reads files in UTF-8.\n    \"\"\"\n    @wraps(f)\n    def f_in_file(fname):\n        with io.open(fname, 'r', encoding='utf-8') as inf:\n            data = inf.read()\n        data = f(data)\n        with io.open(fname, 'w+', encoding='utf-8') as outf:\n            outf.write(data)\n\n    return f_in_file\n\n\ndef list_replace(the_list, find, replacement):\n    \"\"\"Replace all occurrences of ``find`` with ``replacement`` in ``the_list``.\"\"\"\n    for i, v in enumerate(the_list):\n        if v == find:\n            the_list[i] = replacement\n\n\ndef runinplace(command, infile):\n    \"\"\"Run a command in-place on a file.\n\n    command is a string of the form: \"commandname %1 %2\" and\n    it will be execed with infile as %1 and a temporary file\n    as %2. Then, that temporary file will be moved over %1.\n\n    Example usage:\n\n    runinplace(\"yui-compressor %1 -o %2\", \"myfile.css\")\n\n    That will replace myfile.css with a minified version.\n\n    You can also supply command as a list.\n    \"\"\"\n    if not isinstance(command, list):\n        command = shlex.split(command)\n\n    tmpdir = None\n\n    if \"%2\" in command:\n        tmpdir = tempfile.mkdtemp(prefix=\"nikola\")\n        tmpfname = os.path.join(tmpdir, os.path.basename(infile))\n\n    try:\n        list_replace(command, \"%1\", infile)\n        if tmpdir:\n            list_replace(command, \"%2\", tmpfname)\n\n        subprocess.check_call(command)\n\n        if tmpdir:\n            shutil.move(tmpfname, infile)\n    finally:\n        if tmpdir:\n            shutil.rmtree(tmpdir)\n\n\ndef yui_compressor(infile):\n    \"\"\"Run YUI Compressor on a file.\"\"\"\n    yuicompressor = False\n    try:\n        subprocess.call('yui-compressor', stdout=open(os.devnull, 'w'), stderr=open(os.devnull, 'w'))\n        yuicompressor = 'yui-compressor'\n    except Exception:\n        pass\n    if not yuicompressor:\n        try:\n            subprocess.call('yuicompressor', stdout=open(os.devnull, 'w'), stderr=open(os.devnull, 'w'))\n            yuicompressor = 'yuicompressor'\n        except:\n            raise Exception(\"yui-compressor is not installed.\")\n            return False\n\n    return runinplace(r'{} --nomunge %1 -o %2'.format(yuicompressor), infile)\n\n\ndef closure_compiler(infile):\n    \"\"\"Run closure-compiler on a file.\"\"\"\n    return runinplace(r'closure-compiler --warning_level QUIET --js %1 --js_output_file %2', infile)\n\n\ndef optipng(infile):\n    \"\"\"Run optipng on a file.\"\"\"\n    return runinplace(r\"optipng -preserve -o2 -quiet %1\", infile)\n\n\ndef jpegoptim(infile):\n    \"\"\"Run jpegoptim on a file.\"\"\"\n    return runinplace(r\"jpegoptim -p --strip-all -q %1\", infile)\n\n\ndef html_tidy_withconfig(infile):\n    \"\"\"Run HTML Tidy with tidy5.conf as config file.\"\"\"\n    return _html_tidy_runner(infile, r\"-quiet --show-info no --show-warnings no -utf8 -indent -config tidy5.conf -modify %1\")\n\n\ndef html_tidy_nowrap(infile):\n    \"\"\"Run HTML Tidy without line wrapping.\"\"\"\n    return _html_tidy_runner(infile, r\"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes no --sort-attributes alpha --wrap 0 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1\")\n\n\ndef html_tidy_wrap(infile):\n    \"\"\"Run HTML Tidy with line wrapping.\"\"\"\n    return _html_tidy_runner(infile, r\"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes no --sort-attributes alpha --wrap 80 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1\")\n\n\ndef html_tidy_wrap_attr(infile):\n    \"\"\"Run HTML tidy with line wrapping and attribute indentation.\"\"\"\n    return _html_tidy_runner(infile, r\"-quiet --show-info no --show-warnings no -utf8 -indent --indent-attributes yes --sort-attributes alpha --wrap 80 --wrap-sections no --drop-empty-elements no --tidy-mark no -modify %1\")\n\n\ndef html_tidy_mini(infile):\n    \"\"\"Run HTML tidy with minimal settings.\"\"\"\n    return _html_tidy_runner(infile, r\"-quiet --show-info no --show-warnings no -utf8 --indent-attributes no --sort-attributes alpha --wrap 0 --wrap-sections no --tidy-mark no --drop-empty-elements no -modify %1\")\n\n\ndef _html_tidy_runner(infile, options):\n    \"\"\"Run HTML Tidy.\"\"\"\n    # Warnings (returncode 1) are not critical, and *everything* is a warning.\n    try:\n        status = runinplace(r\"tidy5 \" + options, infile)\n    except subprocess.CalledProcessError as err:\n        status = 0 if err.returncode == 1 else err.returncode\n    return status\n\n\n@apply_to_text_file\ndef html5lib_minify(data):\n    \"\"\"Minify with html5lib.\"\"\"\n    import html5lib\n    import html5lib.serializer\n    data = html5lib.serializer.serialize(html5lib.parse(data, treebuilder='lxml'),\n                                         tree='lxml',\n                                         quote_attr_values=False,\n                                         omit_optional_tags=True,\n                                         minimize_boolean_attributes=True,\n                                         strip_whitespace=True,\n                                         alphabetical_attributes=True,\n                                         escape_lt_in_attrs=True)\n    return data\n\n\n@apply_to_text_file\ndef html5lib_xmllike(data):\n    \"\"\"Transform document to an XML-like form with html5lib.\"\"\"\n    import html5lib\n    import html5lib.serializer\n    data = html5lib.serializer.serialize(html5lib.parse(data, treebuilder='lxml'),\n                                         tree='lxml',\n                                         quote_attr_values=True,\n                                         omit_optional_tags=False,\n                                         strip_whitespace=False,\n                                         alphabetical_attributes=True,\n                                         escape_lt_in_attrs=True)\n    return data\n\n\n@apply_to_text_file\ndef minify_lines(data):\n    \"\"\"Do nothing -- deprecated filter.\"\"\"\n    return data\n\n\n@apply_to_text_file\ndef typogrify(data):\n    \"\"\"Prettify text with typogrify.\"\"\"\n    if typo is None:\n        req_missing(['typogrify'], 'use the typogrify filter')\n\n    data = typo.amp(data)\n    data = typo.widont(data)\n    data = typo.smartypants(data)\n    # Disabled because of typogrify bug where it breaks <title>\n    # data = typo.caps(data)\n    data = typo.initial_quotes(data)\n    return data\n\n\n@apply_to_text_file\ndef typogrify_sans_widont(data):\n    \"\"\"Prettify text with typogrify, skipping the widont filter.\"\"\"\n    # typogrify with widont disabled because it caused broken headline\n    # wrapping, see issue #1465\n    if typo is None:\n        req_missing(['typogrify'], 'use the typogrify_sans_widont filter')\n\n    data = typo.amp(data)\n    data = typo.smartypants(data)\n    # Disabled because of typogrify bug where it breaks <title>\n    # data = typo.caps(data)\n    data = typo.initial_quotes(data)\n    return data\n\n\n@apply_to_text_file\ndef php_template_injection(data):\n    \"\"\"Insert PHP code into Nikola templates.\"\"\"\n    import re\n    template = re.search('<\\!-- __NIKOLA_PHP_TEMPLATE_INJECTION source\\:(.*) checksum\\:(.*)__ -->', data)\n    if template:\n        source = template.group(1)\n        with io.open(source, \"r\", encoding=\"utf-8\") as in_file:\n            phpdata = in_file.read()\n        _META_SEPARATOR = '(' + os.linesep * 2 + '|' + ('\\n' * 2) + '|' + (\"\\r\\n\" * 2) + ')'\n        phpdata = re.split(_META_SEPARATOR, phpdata, maxsplit=1)[-1]\n        phpdata = re.sub(template.group(0), phpdata, data)\n        return phpdata\n    else:\n        return data\n\n\n@apply_to_text_file\ndef cssminify(data):\n    \"\"\"Minify CSS using http://cssminifier.com/.\"\"\"\n    try:\n        url = 'http://cssminifier.com/raw'\n        _data = {'input': data}\n        response = requests.post(url, data=_data)\n        return response.text\n    except Exception as exc:\n        LOGGER.error(\"can't use cssminifier.com: {}\", exc)\n        return data\n\n\n@apply_to_text_file\ndef jsminify(data):\n    \"\"\"Minify JS using http://javascript-minifier.com/.\"\"\"\n    try:\n        url = 'http://javascript-minifier.com/raw'\n        _data = {'input': data}\n        response = requests.post(url, data=_data)\n        return response.text\n    except Exception as exc:\n        LOGGER.error(\"can't use javascript-minifier.com: {}\", exc)\n        return data\n", "path": "nikola/filters.py"}]}