handsdown
handsdown copied to clipboard
Doctest blocks are not closed
I have a module that works on multiline string input, like as read from a file.
In the Example section of my docstring, I show a contrived "multiline" string using the \n
character, e.g. "a\nb"
.
Handsdown does not escape the \n
character and it further causes it not to terminate the code block, which cascades formatting issues down the page.
To Reproduce
- Create a file containing
def test(s: str):
"""A pointless function that replaces \n with | in strings.
Example:
>>> s = 'this\nthat\nother'
>>> test(s)
this|that|other
"""
pass
- Run
handsdown
on it - Get the following markdown generated:
```python
def test(s: str):
```
A pointless function that replaces
with | in strings.
Example:
```python
>>> s = 'this
```
that
other'
```python
>>> test(s)
this|that|other
Notice the final code block is also not closed.
Expected behavior
The \n
character in the docstring should be escaped and displayed verbatim in the markdown.
I did notice that if I manually escape the character, i.e., use s = 'this\\nthat\\nother'
it does show \n
in the markdown, but this is not an acceptable workaround, because this leaves the actual docstring example incorrect. And, it still does appear to cause some formatting issues either way.
Desktop (please complete the following information): MacOS
$ handsdown --version
1.1.0
This is not a bug in handsdown
. The reason you get this output is that Python docstrings are just regular strings. So, in order to get a valid output, you should either:
- escape
\n
as\\n
. this is probably not what you want - use
r
string
def test(s: str):
r"""A pointless function that replaces \n with | in strings.
Example:
>>> s = 'this\nthat\nother'
>>> test(s)
this|that|other
"""
pass
Please let me know if this solution works for you.
Good point, yes using a raw string as the comment would work for me!
However, I am still able to reproduce the parsing issue with the raw string. From my original comment, regarding manually escaping the newlines:
And, it still does appear to cause some formatting issues either way.
I'll try and provide you an example I can share even using raw strings.
Given the following test setup:
$ tree helper/
helper/
├── __init__.py
└── helper.py
0 directories, 2 files
$ cat helper/__init__.py
from . import helper
# helper.py
def helper1(s: str):
r"""A pointless function that replaces \n with | in strings.
Example:
>>> s = 'this\nthat\nother'
>>> helper1(s)
this|that|other
"""
return s.replace("\n", "|")
def helper2(s: str):
r"""Another pointless function that replaces \n with - in strings.
Example:
>>> s = 'this\nthat\nother'
>>> helper2(s)
this-that-other
"""
return s.replace("\n", "-")
I run
$ handsdown helper
INFO Creating folder /private/tmp/docs
$ tree docs
docs
├── MODULES.md
├── README.md
└── helper
├── helper.md
└── index.md
1 directory, 4 files
helper.md
contains the following:
# Helper
> Auto-generated documentation for [helper.helper](../../helper/helper.py) module.
- [Tmp](../README.md#tmp-index) / [Modules](../MODULES.md#tmp-modules) / [Helper](index.md#helper) / Helper
- [helper1](#helper1)
- [helper2](#helper2)
## helper1
[[find in source code]](../../helper/helper.py#L3)
```python
def helper1(s: str):
```
A pointless function that replaces \n with | in strings.
#### Examples
```python
>>> s = 'this\nthat\nother'
>>> helper1(s)
this|that|other
## helper2
[[find in source code]](../../helper/helper.py#L15)
```python
def helper2(s: str):
```
Another pointless function that replaces \n with - in strings.
#### Examples
```python
>>> s = 'this\nthat\nother'
>>> helper2(s)
this-that-other
This may be completely unrelated to \n
, it may be just that handsdown
does not close the ``` of the Example code block if it's the last section of the docstring?
I see. Doctest blocks are not closed correctly. Thank you for the report!
The fix will be included in the upcoming 2.0.0
release.
Finally! It took one month, but Handsdown 2.0 is ready to be used. Tons of new features and Material Design included!
Looks great, thanks!