Repository: AbhinavOmprakash/py-htminify

Issue:
code blocks don't render properly
![image](https://user-images.githubusercontent.com/55880260/119223206-ba587a00-bb15-11eb-96e9-7bb4ad89c524.png)


Discussion:

Patch:
diff --git a/README.rst b/README.rst
index e22cf54..b8994d7 100644
--- a/README.rst
+++ b/README.rst
@@ -7,7 +7,7 @@ ________
 
 * Using a web framework, like django, flask, and pyramid? We got you covered.
 * Or you're feeling adventurous and you're building your own wsgi app? We got you covered there too. This will work with any program that complies with the WSGI specification
-* Using an encoding that is not UTF-8? Just pass an argument, and we'll take it from there. 😉   
+* Using an encoding that is not UTF-8? Just pass an argument,and we'll take it from there. 😉   
 * Mixing Javascript and html? We'll try to minify that too, without judging you too much. (No promises though😜).
 * No external dependencies.
 
@@ -72,7 +72,7 @@ An example flask file would be like this.
 
 Note that we are wrapping the ``app.wsgi_app`` object and not the ``app`` object.
 
-**For any other WSGI app.**
+**For any other wsgi framework**
 
 
 A similar procedure can be followed to integrate the middleware with other wsgi-Python web frameworks.
diff --git a/htminify/htminify.py b/htminify/htminify.py
index b7d10c4..2cfda2a 100644
--- a/htminify/htminify.py
+++ b/htminify/htminify.py
@@ -1,38 +1,69 @@
 import re
+import uuid
 
 
-def minify(html: str) -> str:
-    """A function that strips extra white space in an HTML string"""
 
+def minify(html: str) -> str:
+    """A function that strips extra white space in an HTML string."""
+    # protect tags like code|pre|textarea that are sensitive to whitespace
+    # strip off whitespace
+    # reintroduce the protected groups
+    html = _protect_text(html)
+    
     for (expression, replacement) in patterns:
         html = re.sub(expression, replacement, html, flags=re.IGNORECASE)
+    
+    html = _reintroduce_protected_text(html)
+    
+    return html
+
+
+protected = {} # used to store the protected tags
+
 
+def _protect_text(html):
+    pre_text = re.findall(r"<pre>[\s\S]*?</pre>", html, re.IGNORECASE)
+    code_text = re.findall(r"<code>[\s\S]*?</code>", html, re.IGNORECASE)
+    text_area = re.findall(r"<textarea>[\s\S]*?</textarea>", html, re.IGNORECASE)
+
+    for text_matches in [pre_text, code_text, text_area]:
+        for match in text_matches:
+            html = _substitute_with_hex_value(match, html)
+
+    return html
+
+def _substitute_with_hex_value(text_match, html):
+    hex_id = uuid.uuid4().hex
+    html = re.sub(re.escape(text_match), hex_id, html)
+    protected[hex_id]=text_match
+    return html
+     
+def _reintroduce_protected_text(html):
+    for hex_id, protected_str in protected.items():
+        html = re.sub(re.escape(hex_id), protected_str, html) 
     return html
 
 
 def _replace_space_inside_tag(match):
     # for replacing extra space characters In matched text
-    return re.sub(r"(\s\s+)", " ", match.group(0))
-
+    return re.sub(r"\s\s+", " ", match.group(0))
 
 patterns = [
     # Space characters refer to all characters denoted by r"\s"
     # for e.g tab, space, new line
     (
-        r"(?<=<)[\s\S]*?(?=>)",  #  For matching all text inside an HTML tag
+        r"(?<=<)[\s\S]*?(?=>)",  #For matching all text inside an HTML tag < this text will be matched >
         _replace_space_inside_tag,
     ),
-    (  # this will prevent matching code inside <code|pre> tags nested inside <p> tags
-        r"<\b(?!(code|pre|textarea)\b)\w+>[\s\S]*?<",  #  For matching text between tags
-        _replace_space_inside_tag,  # like <p> asdfawdf</p> but not Inside<code> </code>
+    (  
+        r"(?<=>)[\s\S]*?(?=<)",  #  For matching text between tags
+        _replace_space_inside_tag,  # like <p> asdfawdf</p> 
     ),
     (
-        r"</\w+>[\s\S]*?<",  #  For matching text between tags
-        _replace_space_inside_tag,  # like <p> asdfawdf<p> but not Inside<code> </code>
+        r"/>[\s\S]*?<", # for matching text in between <img/> text <tag>
+        _replace_space_inside_tag
     ),
     (r"(?<=>)\s*(?=<)", ""),  # For matching space characters between HTML tags
     (r"<!--*(.*?)--*>", ""),  # for matching comments
-    # The below two patterns are sensitive to ordering and must be at the end.
-    (r"\s(?=<)",""), #For stripping Whitespace at the end of tags for e.g <p>word </p> -> <p>word</p>
-    (r"(?<=>)\s",""),#For stripping Whitespace at the Beginning of tags for e.g <p> word</p> -> <p>word</p>
-]
+    (r"^[\s]*(?=<)", ""), #stripping whitespace at the beginning of the file
+]
\ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index 9cc0e20..1608c87 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,13 +1,16 @@
 [tool.poetry]
 name = "htminify"
-version = "0.1.0"
+version = "0.1.2"
 description = "A lightweight html minifier for all Python web frameworks and WSGI apps."
 authors = ["Abhinav Omprakash"]
-licence="BSD-3"
+license="BSD-3-Clause"
 readme="README.rst"
 homepage="https://github.com/AbhinavOmprakash/py-htminify"
 repository="https://github.com/AbhinavOmprakash/py-htminify"
 keywords=["html", "django","flask","wsgi", "middleware"]
+include=[
+    "LICENSE",
+]
 
 [tool.poetry.dependencies]
 python = "^3.6"


Test patch:
diff --git a/tests/test_htminify.py b/tests/test_htminify.py
index bd1d65e..cf0befc 100644
--- a/tests/test_htminify.py
+++ b/tests/test_htminify.py
@@ -67,7 +67,7 @@ def test_newlines_between_html_tags_with_text_is_stripped():
     html = """<p>Some random text
     
     
-    Some more random text </p>"""
+    Some more random text</p>"""
     minified_html = """<p>Some random text Some more random text</p>"""
     assert minified_html == minify(html)
 
@@ -77,24 +77,17 @@ def test_nested_code_blocks_are_protected():
         
         print("Ha ha I am safe from the minifier") </code>
     
-    Some more random text </p>"""
-    minified_html = """<p>Some random text<code>def protected():
+    Some more random text</p>"""
+    minified_html = """<p>Some random text <code>def protected():
         
-        print("Ha ha I am safe from the minifier")</code>Some more random text</p>"""
+        print("Ha ha I am safe from the minifier") </code> Some more random text</p>"""
     assert minified_html == minify(html)
 
 def test_regex_is_not_case_sensitive():
     html = """<P>Some random text
-    <CODE>def protected():
-        
-        print("Ha ha I am safe from the minifier")
-        print("blah blah") </CODE>
     
     Some more random text </P>"""
-    minified_html = """<P>Some random text<CODE>def protected():
-        
-        print("Ha ha I am safe from the minifier")
-        print("blah blah")</CODE>Some more random text</P>"""
+    minified_html = """<P>Some random text Some more random text </P>"""
     assert minified_html == minify(html)
 
 
@@ -105,6 +98,6 @@ def test_javascript_inside_script_tags_is_minified():
     
     
             </script>"""
-    minified_html = """<script>function myFunction(p1, p2) { return p1 * p2; }</script>"""
+    minified_html = """<script>function myFunction(p1, p2) { return p1 * p2; } </script>"""
 
     assert minified_html == minify(html)
\ No newline at end of file