Repository: matthewwithanm/python-markdownify

Issue:
unnecessary /n newlines resulting in a lot of white area in the markdown
```markdown











On\_Search - Beckn


























































 










 













* Home
* Overview
* Specification Reference
* Build with Beckn
* Projects

 

















 



















* Home
* Overview
* Specification Reference
* Build with Beckn
* Projects

 


## Logistics Specification



* API Reference
	+ Beckn Application Platform
		- On\_Cancel
		- On\_Confirm
		- On\_Init
		- On\_Rating
		- On\_Search
		- On\_Select
		- On\_Status
		- On\_Support
		- On\_Track
		- On\_Update
	+ Beckn Gateway
		- On\_Search
		- Search
	+ Beckn Provider Platform
		- Cancel
		- Confirm
		- Init
		- Rating
		- Search
		- Select
		- Status
		- Support
		- Track
		- Update
* Schema Reference
	+ Ack
	+ AddOn
	+ Address
	+ Agent
	+ Billing
	+ Catalog
	+ Category
	+ Circle
	+ City
	+ Contact
	+ Context
	+ ContextForCancel
	+ ContextForConfirm
	+ ContextForInit
	+ ContextForOn\_cancel
	+ ContextForOn\_confirm
	+ ContextForOn\_init
	+ ContextForOn\_rating
	+ ContextForOn\_search
	+ ContextForOn\_select
	+ ContextForOn\_status
	+ ContextForOn\_support
	+ ContextForOn\_track
	+ ContextForOn\_update
	+ ContextForRating
	+ ContextForSearch
	+ ContextForSelect
	+ ContextForStatus
	+ ContextForSupport
	+ ContextForTrack
	+ ContextForUpdate
	+ Country
	+ DecimalValue
	+ Descriptor
	+ Dimensions
	+ Domain
	+ Duration
	+ Error
	+ Feedback
	+ Fulfillment
	+ Gps
	+ Image
	+ Intent
	+ Item
	+ ItemQuantity
	+ Location
	+ MessageForCancel
	+ MessageForConfirm
	+ MessageForInit
	+ MessageForOn\_cancel
	+ MessageForOn\_confirm
	+ MessageForOn\_init
	+ MessageForOn\_rating
	+ MessageForOn\_search
	+ MessageForOn\_select
	+ MessageForOn\_status
	+ MessageForOn\_support
	+ MessageForOn\_track
	+ MessageForOn\_update
	+ MessageForRating
	+ MessageForSearch
	+ MessageForSelect
	+ MessageForStatus
	+ MessageForSupport
	+ MessageForTrack
	+ MessageForUpdate
	+ Name
	+ Offer
	+ Option
	+ Order
	+ Organization
	+ Payment
	+ Person
	+ Policy
	+ Price
	+ Provider
	+ Quotation
	+ Scalar
	+ State
	+ Tags
	+ Time
	+ Tracking
	+ Vehicle








 






All Docs
Beckn Protocol Specification Reference
Core Specification
Developer Documentation
Infrastructure Layer Specification
Logistics Specification
Logistics Specification
Mobility Specification
Overview
Projects













1. Home
2. Docs
3. On\_Search







 Updated on October 5, 2021 


















 



















* Home
* Overview
* Specification Reference
* Build with Beckn
* Projects

 


## Logistics Specification



* API Reference
	+ Beckn Application Platform
		- On\_Cancel
		- On\_Confirm
		- On\_Init
		- On\_Rating
		- On\_Search
		- On\_Select
		- On\_Status
		- On\_Support
		- On\_Track
		- On\_Update
	+ Beckn Gateway
		- On\_Search
		- Search
	+ Beckn Provider Platform
		- Cancel
		- Confirm
		- Init
		- Rating
		- Search
		- Select
		- Status
		- Support
		- Track
		- Update
* Schema Reference
	+ Ack
	+ AddOn
	+ Address
	+ Agent
	+ Billing
	+ Catalog
	+ Category
	+ Circle
	+ City
	+ Contact
	+ Context
	+ ContextForCancel
	+ ContextForConfirm
	+ ContextForInit
	+ ContextForOn\_cancel
	+ ContextForOn\_confirm
	+ ContextForOn\_init
	+ ContextForOn\_rating
	+ ContextForOn\_search
	+ ContextForOn\_select
	+ ContextForOn\_status
	+ ContextForOn\_support
	+ ContextForOn\_track
	+ ContextForOn\_update
	+ ContextForRating
	+ ContextForSearch
	+ ContextForSelect
	+ ContextForStatus
	+ ContextForSupport
	+ ContextForTrack
	+ ContextForUpdate
	+ Country
	+ DecimalValue
	+ Descriptor
	+ Dimensions
	+ Domain
	+ Duration
	+ Error
	+ Feedback
	+ Fulfillment
	+ Gps
	+ Image
	+ Intent
	+ Item
	+ ItemQuantity
	+ Location
	+ MessageForCancel
	+ MessageForConfirm
	+ MessageForInit
	+ MessageForOn\_cancel
	+ MessageForOn\_confirm
	+ MessageForOn\_init
	+ MessageForOn\_rating
	+ MessageForOn\_search
	+ MessageForOn\_select
	+ MessageForOn\_status
	+ MessageForOn\_support
	+ MessageForOn\_track
	+ MessageForOn\_update
	+ MessageForRating
	+ MessageForSearch
	+ MessageForSelect
	+ MessageForStatus
	+ MessageForSupport
	+ MessageForTrack
	+ MessageForUpdate
	+ Name
	+ Offer
	+ Option
	+ Order
	+ Organization
	+ Payment
	+ Person
	+ Policy
	+ Price
	+ Provider
	+ Quotation
	+ Scalar
	+ State
	+ Tags
	+ Time
	+ Tracking
	+ Vehicle








 






All Docs
Beckn Protocol Specification Reference
Core Specification
Developer Documentation
Infrastructure Layer Specification
Logistics Specification
Logistics Specification
Mobility Specification
Overview
Projects














1. Home
2. Docs
3. On\_Search








A-
A
A+




























## Logistics Specification



* API Reference
	+ Beckn Application Platform
		- On\_Search
		- On\_Select
		- On\_Init
		- On\_Confirm
		- On\_Status
		- On\_Track
		- On\_Cancel
		- On\_Update
		- On\_Rating
		- On\_Support
	+ Beckn Gateway
		- Search
		- On\_Search
	+ Beckn Provider Platform
		- Search
		- Select
		- Init
		- Confirm
		- Status
		- Track
		- Cancel
		- Update
		- Rating
		- Support
* Schema Reference
	+ Ack
	+ AddOn
	+ Address
	+ Agent
	+ Billing
	+ Catalog
	+ Category
	+ Circle
	+ City
	+ Contact
	+ Context
	+ ContextForCancel
	+ ContextForConfirm
	+ ContextForInit
	+ ContextForOn\_cancel
	+ ContextForOn\_confirm
	+ ContextForOn\_init
	+ ContextForOn\_rating
	+ ContextForOn\_search
	+ ContextForOn\_select
	+ ContextForOn\_status
	+ ContextForOn\_support
	+ ContextForOn\_track
	+ ContextForOn\_update
	+ ContextForRating
	+ ContextForSearch
	+ ContextForSelect
	+ ContextForStatus
	+ ContextForSupport
	+ ContextForTrack
	+ ContextForUpdate
	+ DecimalValue
	+ Descriptor
	+ Dimensions
	+ Domain
	+ Duration
	+ Error
	+ Feedback
	+ Fulfillment
	+ Gps
	+ Image
	+ Intent
	+ Item
	+ ItemQuantity
	+ Location
	+ MessageForCancel
	+ MessageForConfirm
	+ MessageForInit
	+ MessageForOn\_confirm
	+ MessageForOn\_init
	+ MessageForOn\_rating
	+ MessageForOn\_search
	+ MessageForOn\_select
	+ MessageForOn\_status
	+ MessageForOn\_support
	+ MessageForOn\_track
	+ MessageForOn\_update
	+ MessageForRating
	+ MessageForSearch
	+ MessageForSelect
	+ MessageForStatus
	+ MessageForSupport
	+ MessageForTrack
	+ MessageForUpdate
	+ Name
	+ Offer
	+ Option
	+ Order
	+ Organization
	+ Payment
	+ Person
	+ Policy
	+ Price
	+ Provider
	+ Quotation
	+ Scalar
	+ State
	+ Tags
	+ Time
	+ Tracking
	+ Vehicle
	+ MessageForOn\_cancel
	+ Country










Home » Logistics Specification » API Reference » Beckn Application Platform » On\_Search

 
1. Home
2. Docs
3. 








A-
A
A+








# On\_Search

 

> Send catalog


## Overview



> The BPP will send the catalog of logistics options matching the search intent to the BAP.


## Request


### URL



> /on\_search


### Method



> *POST*


### Request Body Schema




| **Field** | **Type** |
| --- | --- |
| context\* | ContextForOn\_search |
| message.catalog | { Catalog } |
| error | Error |


### Request Body Example



```

Discussion:

Patch:
diff --git a/markdownify/__init__.py b/markdownify/__init__.py
index cd66a39..a37f870 100644
--- a/markdownify/__init__.py
+++ b/markdownify/__init__.py
@@ -7,7 +7,8 @@ import six
 convert_heading_re = re.compile(r'convert_h(\d+)')
 line_beginning_re = re.compile(r'^', re.MULTILINE)
 whitespace_re = re.compile(r'[\t ]+')
-all_whitespace_re = re.compile(r'[\s]+')
+all_whitespace_re = re.compile(r'[\t \r\n]+')
+newline_whitespace_re = re.compile(r'[\t \r\n]*[\r\n][\t \r\n]*')
 html_heading_re = re.compile(r'h[1-6]')
 
 
@@ -148,7 +149,13 @@ class MarkdownConverter(object):
             elif isinstance(el, NavigableString):
                 text += self.process_text(el)
             else:
-                text += self.process_tag(el, convert_children_as_inline)
+                text_strip = text.rstrip('\n')
+                newlines_left = len(text) - len(text_strip)
+                next_text = self.process_tag(el, convert_children_as_inline)
+                next_text_strip = next_text.lstrip('\n')
+                newlines_right = len(next_text) - len(next_text_strip)
+                newlines = '\n' * max(newlines_left, newlines_right)
+                text = text_strip + newlines + next_text_strip
 
         if not children_only:
             convert_fn = getattr(self, 'convert_%s' % node.name, None)
@@ -162,7 +169,11 @@ class MarkdownConverter(object):
 
         # normalize whitespace if we're not inside a preformatted element
         if not el.find_parent('pre'):
-            text = whitespace_re.sub(' ', text)
+            if self.options['wrap']:
+                text = all_whitespace_re.sub(' ', text)
+            else:
+                text = newline_whitespace_re.sub('\n', text)
+                text = whitespace_re.sub(' ', text)
 
         # escape special characters if we're not inside a preformatted or code element
         if not el.find_parent(['pre', 'code', 'kbd', 'samp']):
@@ -221,7 +232,7 @@ class MarkdownConverter(object):
 
     def underline(self, text, pad_char):
         text = (text or '').rstrip()
-        return '%s\n%s\n\n' % (text, pad_char * len(text)) if text else ''
+        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):
         prefix, suffix, text = chomp(text)
@@ -280,10 +291,11 @@ class MarkdownConverter(object):
         if style == UNDERLINED and n <= 2:
             line = '=' if n == 1 else '-'
             return self.underline(text, line)
+        text = all_whitespace_re.sub(' ', text)
         hashes = '#' * n
         if style == ATX_CLOSED:
-            return '%s %s %s\n\n' % (hashes, text, hashes)
-        return '%s %s\n\n' % (hashes, text)
+            return '\n%s %s %s\n\n' % (hashes, text, hashes)
+        return '\n%s %s\n\n' % (hashes, text)
 
     def convert_hr(self, el, text, convert_as_inline):
         return '\n\n---\n\n'
@@ -318,7 +330,7 @@ class MarkdownConverter(object):
         if nested:
             # remove trailing newline if nested
             return '\n' + self.indent(text, 1).rstrip()
-        return text + ('\n' if before_paragraph else '')
+        return '\n\n' + text + ('\n' if before_paragraph else '')
 
     convert_ul = convert_list
     convert_ol = convert_list
@@ -345,11 +357,22 @@ class MarkdownConverter(object):
         if convert_as_inline:
             return text
         if self.options['wrap']:
-            text = fill(text,
-                        width=self.options['wrap_width'],
-                        break_long_words=False,
-                        break_on_hyphens=False)
-        return '%s\n\n' % text if text else ''
+            # 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)
+        return '\n\n%s\n\n' % text if text else ''
 
     def convert_pre(self, el, text, convert_as_inline):
         if not text:


Test patch:
diff --git a/tests/test_advanced.py b/tests/test_advanced.py
index 14bf3cd..a3a5fda 100644
--- a/tests/test_advanced.py
+++ b/tests/test_advanced.py
@@ -14,7 +14,7 @@ def test_chomp():
 
 def test_nested():
     text = md('<p>This is an <a href="http://example.com/">example link</a>.</p>')
-    assert text == 'This is an [example link](http://example.com/).\n\n'
+    assert text == '\n\nThis is an [example link](http://example.com/).\n\n'
 
 
 def test_ignore_comments():
diff --git a/tests/test_basic.py b/tests/test_basic.py
index bf25ee0..66f8b6c 100644
--- a/tests/test_basic.py
+++ b/tests/test_basic.py
@@ -11,3 +11,4 @@ def test_soup():
 
 def test_whitespace():
     assert md(' a  b \t\t c ') == ' a b c '
+    assert md(' a  b \n\n c ') == ' a b\nc '
diff --git a/tests/test_conversions.py b/tests/test_conversions.py
index a35b982..9c1edc3 100644
--- a/tests/test_conversions.py
+++ b/tests/test_conversions.py
@@ -1,4 +1,4 @@
-from markdownify import markdownify as md, ATX, ATX_CLOSED, BACKSLASH, UNDERSCORE
+from markdownify import markdownify as md, ATX, ATX_CLOSED, BACKSLASH, SPACES, UNDERSCORE
 
 
 def inline_tests(tag, markup):
@@ -112,36 +112,39 @@ def test_em():
 
 
 def test_header_with_space():
-    assert md('<h3>\n\nHello</h3>') == '### Hello\n\n'
-    assert md('<h4>\n\nHello</h4>') == '#### Hello\n\n'
-    assert md('<h5>\n\nHello</h5>') == '##### Hello\n\n'
-    assert md('<h5>\n\nHello\n\n</h5>') == '##### Hello\n\n'
-    assert md('<h5>\n\nHello   \n\n</h5>') == '##### Hello\n\n'
+    assert md('<h3>\n\nHello</h3>') == '\n### Hello\n\n'
+    assert md('<h3>Hello\n\n\nWorld</h3>') == '\n### Hello World\n\n'
+    assert md('<h4>\n\nHello</h4>') == '\n#### Hello\n\n'
+    assert md('<h5>\n\nHello</h5>') == '\n##### Hello\n\n'
+    assert md('<h5>\n\nHello\n\n</h5>') == '\n##### Hello\n\n'
+    assert md('<h5>\n\nHello   \n\n</h5>') == '\n##### Hello\n\n'
 
 
 def test_h1():
-    assert md('<h1>Hello</h1>') == 'Hello\n=====\n\n'
+    assert md('<h1>Hello</h1>') == '\n\nHello\n=====\n\n'
 
 
 def test_h2():
-    assert md('<h2>Hello</h2>') == 'Hello\n-----\n\n'
+    assert md('<h2>Hello</h2>') == '\n\nHello\n-----\n\n'
 
 
 def test_hn():
-    assert md('<h3>Hello</h3>') == '### Hello\n\n'
-    assert md('<h4>Hello</h4>') == '#### Hello\n\n'
-    assert md('<h5>Hello</h5>') == '##### Hello\n\n'
-    assert md('<h6>Hello</h6>') == '###### Hello\n\n'
+    assert md('<h3>Hello</h3>') == '\n### Hello\n\n'
+    assert md('<h4>Hello</h4>') == '\n#### Hello\n\n'
+    assert md('<h5>Hello</h5>') == '\n##### Hello\n\n'
+    assert md('<h6>Hello</h6>') == '\n###### Hello\n\n'
 
 
 def test_hn_chained():
-    assert md('<h1>First</h1>\n<h2>Second</h2>\n<h3>Third</h3>', heading_style=ATX) == '# First\n\n\n## Second\n\n\n### Third\n\n'
-    assert md('X<h1>First</h1>', heading_style=ATX) == 'X# First\n\n'
+    assert md('<h1>First</h1>\n<h2>Second</h2>\n<h3>Third</h3>', heading_style=ATX) == '\n# First\n\n\n## Second\n\n\n### Third\n\n'
+    assert md('X<h1>First</h1>', heading_style=ATX) == 'X\n# First\n\n'
+    assert md('X<h1>First</h1>', heading_style=ATX_CLOSED) == 'X\n# First #\n\n'
+    assert md('X<h1>First</h1>') == 'X\n\nFirst\n=====\n\n'
 
 
 def test_hn_nested_tag_heading_style():
-    assert md('<h1>A <p>P</p> C </h1>', heading_style=ATX_CLOSED) == '# A P C #\n\n'
-    assert md('<h1>A <p>P</p> C </h1>', heading_style=ATX) == '# A P C\n\n'
+    assert md('<h1>A <p>P</p> C </h1>', heading_style=ATX_CLOSED) == '\n# A P C #\n\n'
+    assert md('<h1>A <p>P</p> C </h1>', heading_style=ATX) == '\n# A P C\n\n'
 
 
 def test_hn_nested_simple_tag():
@@ -157,12 +160,12 @@ def test_hn_nested_simple_tag():
     ]
 
     for tag, markdown in tag_to_markdown:
-        assert md('<h3>A <' + tag + '>' + tag + '</' + tag + '> B</h3>') == '### A ' + markdown + ' B\n\n'
+        assert md('<h3>A <' + tag + '>' + tag + '</' + tag + '> B</h3>') == '\n### A ' + markdown + ' B\n\n'
 
-    assert md('<h3>A <br>B</h3>', heading_style=ATX) == '### A B\n\n'
+    assert md('<h3>A <br>B</h3>', heading_style=ATX) == '\n### A B\n\n'
 
     # Nested lists not supported
-    # assert md('<h3>A <ul><li>li1</i><li>l2</li></ul></h3>', heading_style=ATX) == '### A li1 li2 B\n\n'
+    # assert md('<h3>A <ul><li>li1</i><li>l2</li></ul></h3>', heading_style=ATX) == '\n### A li1 li2 B\n\n'
 
 
 def test_hn_nested_img():
@@ -172,18 +175,18 @@ def test_hn_nested_img():
         ("alt='Alt Text' title='Optional title'", "Alt Text", " \"Optional title\""),
     ]
     for image_attributes, markdown, title in image_attributes_to_markdown:
-        assert md('<h3>A <img src="/path/to/img.jpg" ' + image_attributes + '/> B</h3>') == '### A ' + markdown + ' B\n\n'
-        assert md('<h3>A <img src="/path/to/img.jpg" ' + image_attributes + '/> B</h3>', keep_inline_images_in=['h3']) == '### A ![' + markdown + '](/path/to/img.jpg' + title + ') B\n\n'
+        assert md('<h3>A <img src="/path/to/img.jpg" ' + image_attributes + '/> B</h3>') == '\n### A' + (' ' + markdown + ' ' if markdown else ' ') + 'B\n\n'
+        assert md('<h3>A <img src="/path/to/img.jpg" ' + image_attributes + '/> B</h3>', keep_inline_images_in=['h3']) == '\n### A ![' + markdown + '](/path/to/img.jpg' + title + ') B\n\n'
 
 
 def test_hn_atx_headings():
-    assert md('<h1>Hello</h1>', heading_style=ATX) == '# Hello\n\n'
-    assert md('<h2>Hello</h2>', heading_style=ATX) == '## Hello\n\n'
+    assert md('<h1>Hello</h1>', heading_style=ATX) == '\n# Hello\n\n'
+    assert md('<h2>Hello</h2>', heading_style=ATX) == '\n## Hello\n\n'
 
 
 def test_hn_atx_closed_headings():
-    assert md('<h1>Hello</h1>', heading_style=ATX_CLOSED) == '# Hello #\n\n'
-    assert md('<h2>Hello</h2>', heading_style=ATX_CLOSED) == '## Hello ##\n\n'
+    assert md('<h1>Hello</h1>', heading_style=ATX_CLOSED) == '\n# Hello #\n\n'
+    assert md('<h2>Hello</h2>', heading_style=ATX_CLOSED) == '\n## Hello ##\n\n'
 
 
 def test_head():
@@ -193,7 +196,7 @@ def test_head():
 def test_hr():
     assert md('Hello<hr>World') == 'Hello\n\n---\n\nWorld'
     assert md('Hello<hr />World') == 'Hello\n\n---\n\nWorld'
-    assert md('<p>Hello</p>\n<hr>\n<p>World</p>') == 'Hello\n\n\n\n\n---\n\n\nWorld\n\n'
+    assert md('<p>Hello</p>\n<hr>\n<p>World</p>') == '\n\nHello\n\n\n---\n\n\nWorld\n\n'
 
 
 def test_i():
@@ -210,12 +213,23 @@ def test_kbd():
 
 
 def test_p():
-    assert md('<p>hello</p>') == 'hello\n\n'
-    assert md('<p>123456789 123456789</p>') == '123456789 123456789\n\n'
-    assert md('<p>123456789 123456789</p>', wrap=True, wrap_width=10) == '123456789\n123456789\n\n'
-    assert md('<p><a href="https://example.com">Some long link</a></p>', wrap=True, wrap_width=10) == '[Some long\nlink](https://example.com)\n\n'
-    assert md('<p>12345<br />67890</p>', wrap=True, wrap_width=10, newline_style=BACKSLASH) == '12345\\\n67890\n\n'
-    assert md('<p>12345678901<br />12345</p>', wrap=True, wrap_width=10, newline_style=BACKSLASH) == '12345678901\\\n12345\n\n'
+    assert md('<p>hello</p>') == '\n\nhello\n\n'
+    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 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'
+    assert md('<p>12345<br />67890</p>', wrap=True, wrap_width=50, newline_style=BACKSLASH) == '\n\n12345\\\n67890\n\n'
+    assert md('<p>12345<br />67890</p>', wrap=True, wrap_width=10, newline_style=SPACES) == '\n\n12345  \n67890\n\n'
+    assert md('<p>12345<br />67890</p>', wrap=True, wrap_width=50, newline_style=SPACES) == '\n\n12345  \n67890\n\n'
+    assert md('<p>12345678901<br />12345</p>', wrap=True, wrap_width=10, newline_style=BACKSLASH) == '\n\n12345678901\\\n12345\n\n'
+    assert md('<p>12345678901<br />12345</p>', wrap=True, wrap_width=50, newline_style=BACKSLASH) == '\n\n12345678901\\\n12345\n\n'
+    assert md('<p>12345678901<br />12345</p>', wrap=True, wrap_width=10, newline_style=SPACES) == '\n\n12345678901  \n12345\n\n'
+    assert md('<p>12345678901<br />12345</p>', wrap=True, wrap_width=50, newline_style=SPACES) == '\n\n12345678901  \n12345\n\n'
+    assert md('<p>1234 5678 9012<br />67890</p>', wrap=True, wrap_width=10, newline_style=BACKSLASH) == '\n\n1234 5678\n9012\\\n67890\n\n'
+    assert md('<p>1234 5678 9012<br />67890</p>', wrap=True, wrap_width=10, newline_style=SPACES) == '\n\n1234 5678\n9012  \n67890\n\n'
+    assert md('First<p>Second</p><p>Third</p>Fourth') == 'First\n\nSecond\n\nThird\n\nFourth'
 
 
 def test_pre():
diff --git a/tests/test_lists.py b/tests/test_lists.py
index 35eee13..ecc1a65 100644
--- a/tests/test_lists.py
+++ b/tests/test_lists.py
@@ -41,19 +41,20 @@ nested_ols = """
 
 
 def test_ol():
-    assert md('<ol><li>a</li><li>b</li></ol>') == '1. a\n2. b\n'
-    assert md('<ol start="3"><li>a</li><li>b</li></ol>') == '3. a\n4. b\n'
-    assert md('<ol start="-1"><li>a</li><li>b</li></ol>') == '1. a\n2. b\n'
-    assert md('<ol start="foo"><li>a</li><li>b</li></ol>') == '1. a\n2. b\n'
-    assert md('<ol start="1.5"><li>a</li><li>b</li></ol>') == '1. a\n2. b\n'
+    assert md('<ol><li>a</li><li>b</li></ol>') == '\n\n1. a\n2. b\n'
+    assert md('<ol start="3"><li>a</li><li>b</li></ol>') == '\n\n3. a\n4. b\n'
+    assert md('foo<ol start="3"><li>a</li><li>b</li></ol>bar') == 'foo\n\n3. a\n4. b\n\nbar'
+    assert md('<ol start="-1"><li>a</li><li>b</li></ol>') == '\n\n1. a\n2. b\n'
+    assert md('<ol start="foo"><li>a</li><li>b</li></ol>') == '\n\n1. a\n2. b\n'
+    assert md('<ol start="1.5"><li>a</li><li>b</li></ol>') == '\n\n1. a\n2. b\n'
 
 
 def test_nested_ols():
-    assert md(nested_ols) == '\n1. 1\n\t1. a\n\t\t1. I\n\t\t2. II\n\t\t3. III\n\t2. b\n\t3. c\n2. 2\n3. 3\n'
+    assert md(nested_ols) == '\n\n1. 1\n\t1. a\n\t\t1. I\n\t\t2. II\n\t\t3. III\n\t2. b\n\t3. c\n2. 2\n3. 3\n'
 
 
 def test_ul():
-    assert md('<ul><li>a</li><li>b</li></ul>') == '* a\n* b\n'
+    assert md('<ul><li>a</li><li>b</li></ul>') == '\n\n* a\n* b\n'
     assert md("""<ul>
      <li>
              a
@@ -61,11 +62,12 @@ def test_ul():
      <li> b </li>
      <li>   c
      </li>
- </ul>""") == '* a\n* b\n* c\n'
+ </ul>""") == '\n\n* a\n* b\n* c\n'
 
 
 def test_inline_ul():
-    assert md('<p>foo</p><ul><li>a</li><li>b</li></ul><p>bar</p>') == 'foo\n\n* a\n* b\n\nbar\n\n'
+    assert md('<p>foo</p><ul><li>a</li><li>b</li></ul><p>bar</p>') == '\n\nfoo\n\n* a\n* b\n\nbar\n\n'
+    assert md('foo<ul><li>bar</li></ul>baz') == 'foo\n\n* bar\n\nbaz'
 
 
 def test_nested_uls():
@@ -73,12 +75,12 @@ def test_nested_uls():
     Nested ULs should alternate bullet characters.
 
     """
-    assert md(nested_uls) == '\n* 1\n\t+ a\n\t\t- I\n\t\t- II\n\t\t- III\n\t+ b\n\t+ c\n* 2\n* 3\n'
+    assert md(nested_uls) == '\n\n* 1\n\t+ a\n\t\t- I\n\t\t- II\n\t\t- III\n\t+ b\n\t+ c\n* 2\n* 3\n'
 
 
 def test_bullets():
-    assert md(nested_uls, bullets='-') == '\n- 1\n\t- a\n\t\t- I\n\t\t- II\n\t\t- III\n\t- b\n\t- c\n- 2\n- 3\n'
+    assert md(nested_uls, bullets='-') == '\n\n- 1\n\t- a\n\t\t- I\n\t\t- II\n\t\t- III\n\t- b\n\t- c\n- 2\n- 3\n'
 
 
 def test_li_text():
-    assert md('<ul><li>foo <a href="#">bar</a></li><li>foo bar  </li><li>foo <b>bar</b>   <i>space</i>.</ul>') == '* foo [bar](#)\n* foo bar\n* foo **bar** *space*.\n'
+    assert md('<ul><li>foo <a href="#">bar</a></li><li>foo bar  </li><li>foo <b>bar</b>   <i>space</i>.</ul>') == '\n\n* foo [bar](#)\n* foo bar\n* foo **bar** *space*.\n'
diff --git a/tests/test_tables.py b/tests/test_tables.py
index 594e5bf..fc6eee6 100644
--- a/tests/test_tables.py
+++ b/tests/test_tables.py
@@ -242,7 +242,7 @@ def test_table():
     assert md(table) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
     assert md(table_with_html_content) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| **Jill** | *Smith* | [50](#) |\n| Eve | Jackson | 94 |\n\n'
     assert md(table_with_paragraphs) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
-    assert md(table_with_linebreaks) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith  Jackson | 50 |\n| Eve | Jackson  Smith | 94 |\n\n'
+    assert md(table_with_linebreaks) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith Jackson | 50 |\n| Eve | Jackson Smith | 94 |\n\n'
     assert md(table_with_header_column) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
     assert md(table_head_body) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
     assert md(table_head_body_missing_head) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'