Repository: sphinx-gallery/sphinx-gallery

Issue:
Adding a ReST block immediately after the module docstring breaks the generated .rst file
## Bug

It appears that both module docstring and ReST blocks are stripped of blank lines at the beginning and end.

Thus the example from https://sphinx-gallery.github.io/syntax.html

~~~
"""
This is my example script
=========================

This example doesn't do much, it just makes a simple plot
"""

###############################################################################
# This is a section header
# ------------------------
~~~

would result in an .rst file with
~~~
This example doesn't do much, it just makes a simple plot
This is a section header
------------------------
~~~

resulting in incorrect rendering of the section due to a missing line before it. A similar effect happens if you have just plain text paragraphs: They will be joined.

This appears to be a common pitfall:
https://github.com/matplotlib/matplotlib/pull/13911
https://github.com/matplotlib/matplotlib/pull/13950

## Proposed fix

Probably the correct fix would be to always add a blank line after the module docstring text in the generated .rst file.



Comments:

Patch:
diff --git a/sphinx_gallery/gen_rst.py b/sphinx_gallery/gen_rst.py
index 4ce518d..4eebf85 100644
--- a/sphinx_gallery/gen_rst.py
+++ b/sphinx_gallery/gen_rst.py
@@ -714,7 +714,8 @@ def rst_blocks(script_blocks, output_blocks, file_conf, gallery_conf):
                     example_rst += "\n\n|\n\n"
                 example_rst += code_rst
         else:
-            example_rst += bcontent + '\n'
+            block_separator = '\n\n' if not bcontent.endswith('\n') else '\n'
+            example_rst += bcontent + block_separator
     return example_rst
 
 


Test patch:
diff --git a/sphinx_gallery/tests/test_gen_rst.py b/sphinx_gallery/tests/test_gen_rst.py
index c9d97e3..8ca992c 100644
--- a/sphinx_gallery/tests/test_gen_rst.py
+++ b/sphinx_gallery/tests/test_gen_rst.py
@@ -97,6 +97,41 @@ def test_direct_comment_after_docstring():
     assert result == expected_result
 
 
+def test_rst_block_after_docstring(gallery_conf, tmpdir):
+    """Assert there is a blank line between the docstring and rst blocks."""
+    filename = str(tmpdir.join('temp.py'))
+    with open(filename, 'w') as f:
+        f.write('\n'.join(['"Docstring"',
+                           '####################',
+                           '# Paragraph 1',
+                           '',
+                           '####################',
+                           '# Paragraph 2',
+                           '']))
+    file_conf, blocks = sg.split_code_and_text_blocks(filename)
+
+    assert file_conf == {}
+    assert blocks[0][0] == 'text'
+    assert blocks[1][0] == 'text'
+    assert blocks[2][0] == 'text'
+
+    script_vars = {'execute_script': ''}
+
+    output_blocks, time_elapsed = sg.execute_script(blocks,
+                                                    script_vars,
+                                                    gallery_conf)
+
+    example_rst = sg.rst_blocks(blocks, output_blocks, file_conf, gallery_conf)
+    assert example_rst == '\n'.join([
+        'Docstring',
+        '',
+        'Paragraph 1',
+        '',
+        'Paragraph 2',
+        '',
+        ''])
+
+
 def test_codestr2rst():
     """Test the correct translation of a code block into rst"""
     output = sg.codestr2rst('print("hello world")')