Repository: matthewwithanm/python-markdownify

Issue:
Support a wrap width value of `None` that explicitly indicates no width limit (unlimited line length)
Currently we use a large numerical `wrap_width` value to collapse newlines inside paragraphs:

```python
from markdownify import markdownify as md

html = "<p>" + "\n".join(["This is some text."] * 10) + "</p>"
print(md(html, wrap=True, wrap_width=1e8))
#                         ^^^^^^^^^^^^^^
```

However, when processing large amounts of content in batch processing (which we do), there is a runtime penalty for running all text through the wrapping code.

It would be great if `wrap_width` supported an explicit value of `None` to reflow text with no width limit:

```python
print(md(html, wrap=True, wrap_width=None))
#                         ^^^^^^^^^^^^^^^
```

Discussion:

Patch:
diff --git a/README.rst b/README.rst
index 98473c6..af87f51 100644
--- a/README.rst
+++ b/README.rst
@@ -143,6 +143,7 @@ wrap, wrap_width
   If ``wrap`` is set to ``True``, all text paragraphs are wrapped at
   ``wrap_width`` characters. Defaults to ``False`` and ``80``.
   Use with ``newline_style=BACKSLASH`` to keep line breaks in paragraphs.
+  A `wrap_width` value of `None` reflows lines to unlimited line length.
 
 Options may be specified as kwargs to the ``markdownify`` function, or as a
 nested ``Options`` class in ``MarkdownConverter`` subclasses.
diff --git a/markdownify/__init__.py b/markdownify/__init__.py
index 3272ce5..b70a0e5 100644
--- a/markdownify/__init__.py
+++ b/markdownify/__init__.py
@@ -264,6 +264,8 @@ class MarkdownConverter(object):
         return '\n\n%s\n%s\n\n' % (text, pad_char * len(text)) if text else ''
 
     def convert_a(self, el, text, convert_as_inline):
+        if el.find_parent(['pre', 'code', 'kbd', 'samp']):
+            return text
         prefix, suffix, text = chomp(text)
         if not text:
             return ''
@@ -398,18 +400,19 @@ class MarkdownConverter(object):
             # Preserve newlines (and preceding whitespace) resulting
             # from <br> tags.  Newlines in the input have already been
             # replaced by spaces.
-            lines = text.split('\n')
-            new_lines = []
-            for line in lines:
-                line = line.lstrip()
-                line_no_trailing = line.rstrip()
-                trailing = line[len(line_no_trailing):]
-                line = fill(line,
-                            width=self.options['wrap_width'],
-                            break_long_words=False,
-                            break_on_hyphens=False)
-                new_lines.append(line + trailing)
-            text = '\n'.join(new_lines)
+            if self.options['wrap_width'] is not None:
+                lines = text.split('\n')
+                new_lines = []
+                for line in lines:
+                    line = line.lstrip()
+                    line_no_trailing = line.rstrip()
+                    trailing = line[len(line_no_trailing):]
+                    line = fill(line,
+                                width=self.options['wrap_width'],
+                                break_long_words=False,
+                                break_on_hyphens=False)
+                    new_lines.append(line + trailing)
+                text = '\n'.join(new_lines)
         return '\n\n%s\n\n' % text if text else ''
 
     def convert_pre(self, el, text, convert_as_inline):
@@ -442,7 +445,7 @@ class MarkdownConverter(object):
         return '\n\n' + text + '\n'
 
     def convert_caption(self, el, text, convert_as_inline):
-        return text + '\n'
+        return text + '\n\n'
 
     def convert_figcaption(self, el, text, convert_as_inline):
         return '\n\n' + text + '\n\n'


Test patch:
diff --git a/tests/test_conversions.py b/tests/test_conversions.py
index 2283c29..01f8b91 100644
--- a/tests/test_conversions.py
+++ b/tests/test_conversions.py
@@ -39,6 +39,11 @@ def test_a_no_autolinks():
     assert md('<a href="https://google.com">https://google.com</a>', autolinks=False) == '[https://google.com](https://google.com)'
 
 
+def test_a_in_code():
+    assert md('<code><a href="https://google.com">Google</a></code>') == '`Google`'
+    assert md('<pre><a href="https://google.com">Google</a></pre>') == '\n```\nGoogle\n```\n'
+
+
 def test_b():
     assert md('<b>Hello</b>') == '**Hello**'
 
@@ -219,6 +224,7 @@ def test_p():
     assert md('<p>123456789 123456789</p>') == '\n\n123456789 123456789\n\n'
     assert md('<p>123456789\n\n\n123456789</p>') == '\n\n123456789\n123456789\n\n'
     assert md('<p>123456789\n\n\n123456789</p>', wrap=True, wrap_width=80) == '\n\n123456789 123456789\n\n'
+    assert md('<p>123456789\n\n\n123456789</p>', wrap=True, wrap_width=None) == '\n\n123456789 123456789\n\n'
     assert md('<p>123456789 123456789</p>', wrap=True, wrap_width=10) == '\n\n123456789\n123456789\n\n'
     assert md('<p><a href="https://example.com">Some long link</a></p>', wrap=True, wrap_width=10) == '\n\n[Some long\nlink](https://example.com)\n\n'
     assert md('<p>12345<br />67890</p>', wrap=True, wrap_width=10, newline_style=BACKSLASH) == '\n\n12345\\\n67890\n\n'
diff --git a/tests/test_tables.py b/tests/test_tables.py
index fc6eee6..dcf9ad7 100644
--- a/tests/test_tables.py
+++ b/tests/test_tables.py
@@ -249,6 +249,6 @@ def test_table():
     assert md(table_missing_text) == '\n\n|  | Lastname | Age |\n| --- | --- | --- |\n| Jill |  | 50 |\n| Eve | Jackson | 94 |\n\n'
     assert md(table_missing_head) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
     assert md(table_body) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
-    assert md(table_with_caption) == 'TEXT\n\nCaption\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n\n'
+    assert md(table_with_caption) == 'TEXT\n\nCaption\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n\n'
     assert md(table_with_colspan) == '\n\n| Name | | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
     assert md(table_with_undefined_colspan) == '\n\n| Name | Age |\n| --- | --- |\n| Jill | Smith |\n\n'