Skip to content

Commit 9ab33ab

Browse files
committed
DOP-2611: Improve handling of null characters in docutils output
1 parent 21310ef commit 9ab33ab

File tree

3 files changed

+55
-11
lines changed

3 files changed

+55
-11
lines changed

snooty/rstparser.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
import docutils.parsers.rst.states
3232
import docutils.statemachine
3333
import docutils.utils
34-
from docutils.nodes import unescape
3534
from typing_extensions import Protocol
3635

3736
from . import n, specparser, util
@@ -89,12 +88,22 @@ def split(self, text: str) -> List[str]:
8988
docutils.nodes.dupname = lambda node, name: None
9089

9190

91+
def unescape_backslashes(text: str) -> str:
92+
"""docutils replaces backslashes with null characters. Deal with this in
93+
a fairly inane way that matches how backslashes seem to be used in our
94+
corpus."""
95+
return text.replace("\x00<", "<").replace("\x00>", ">").replace("\x00", "\\")
96+
97+
9298
def parse_explicit_title(text: str) -> Tuple[str, Optional[str]]:
9399
match = PAT_EXPLICIT_TITLE.match(text)
100+
94101
if match:
95-
return unescape(match["target"]), unescape(match["label"])
102+
return unescape_backslashes(match["target"]), unescape_backslashes(
103+
match["label"]
104+
)
96105

97-
return (unescape(text), None)
106+
return (unescape_backslashes(text), None)
98107

99108

100109
def strip_parameters(target: str) -> str:

snooty/test_postprocess.py

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -302,10 +302,10 @@ def test_guides() -> None:
302302
:description: The description exists! No errors
303303
304304
.. guide:: /path/to/guide2.txt
305-
305+
306306
.. chapter:: No Guides
307307
:description: No guides
308-
308+
309309
.. guide:: /path/to/guide3.txt
310310
311311
.. chapter::
@@ -357,12 +357,12 @@ def test_guides() -> None:
357357
"source/index.txt"
358358
): """
359359
.. chapters::
360-
360+
361361
.. chapter:: Test
362362
:description: This is a chapter
363363
364364
.. guide:: /path/to/guide1.txt
365-
365+
366366
.. chapter:: Test
367367
:description: This is a chapter
368368
@@ -386,7 +386,7 @@ def test_guides() -> None:
386386
:description: This is a chapter
387387
388388
.. guide:: /path/to/guide1.txt
389-
389+
390390
.. chapter:: Test: The Sequel
391391
:description: This is another chapter
392392
@@ -2207,3 +2207,41 @@ def test_block_substitutions_in_lists() -> None:
22072207
</directive>
22082208
</root>""",
22092209
)
2210+
2211+
2212+
def test_targets_with_backslashes() -> None:
2213+
with make_test(
2214+
{
2215+
Path(
2216+
"source/index.txt"
2217+
): r"""
2218+
:phpmethod:`MongoDB\Database::listCollections()`
2219+
:phpmethod:`foobar <MongoDB\Database::listCollections()>`
2220+
2221+
.. phpmethod:: MongoDB\Database::listCollections()
2222+
"""
2223+
}
2224+
) as result:
2225+
assert not result.diagnostics[FileId("index.txt")]
2226+
check_ast_testing_string(
2227+
result.pages[FileId("index.txt")].ast,
2228+
r"""
2229+
<root fileid="index.txt">
2230+
<paragraph>
2231+
<ref_role domain="mongodb" name="phpmethod" target="phpmethod.MongoDB\Database::listCollections()" fileid="['index', 'mongodb-phpmethod-phpmethod.MongoDB-Database--listCollections--']">
2232+
<literal><text>MongoDB\Database::listCollections()</text></literal>
2233+
</ref_role>
2234+
<text> </text>
2235+
<ref_role domain="mongodb" name="phpmethod" target="phpmethod.MongoDB\Database::listCollections()" fileid="['index', 'mongodb-phpmethod-phpmethod.MongoDB-Database--listCollections--']">
2236+
<literal><text>foobar</text></literal>
2237+
</ref_role>
2238+
</paragraph>
2239+
<target domain="mongodb" name="phpmethod" html_id="mongodb-phpmethod-phpmethod.MongoDB-Database--listCollections--">
2240+
<directive_argument><literal><text>MongoDB\Database::listCollections()</text></literal></directive_argument>
2241+
<target_identifier ids="['phpmethod.MongoDB\\Database::listCollections()']">
2242+
<text>MongoDB\Database::listCollections()</text>
2243+
</target_identifier>
2244+
</target>
2245+
</root>
2246+
""",
2247+
)

stubs/docutils/nodes.pyi

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@ from typing import Any, Optional, List, Iterable, Union
44
from typing_extensions import Protocol
55

66

7-
def unescape(text: str) -> str: ...
8-
9-
107
def make_id(input_value: str) -> str: ...
118

129

0 commit comments

Comments
 (0)