Skip to content

Commit c17d855

Browse files
authored
🐛 FIX: parse_directive_text when body followed by options (#580)
1 parent cc44a35 commit c17d855

File tree

7 files changed

+168
-34
lines changed

7 files changed

+168
-34
lines changed

myst_parser/parsers/directives.py

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,8 @@ def parse_directive_text(
7878
body_lines = content.splitlines()
7979
content_offset = 0
8080

81-
if not (
82-
directive_class.required_arguments
83-
or directive_class.optional_arguments
84-
or options
85-
):
86-
# If there are no possible arguments and no option block,
87-
# then the body starts on the argument line
81+
if not (directive_class.required_arguments or directive_class.optional_arguments):
82+
# If there are no possible arguments, then the body starts on the argument line
8883
if first_line:
8984
body_lines.insert(0, first_line)
9085
arguments = []

test.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.. note:: hallo
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
note: content in first line only
2+
.
3+
```{note} a
4+
```
5+
.
6+
arguments: []
7+
body:
8+
- a
9+
content_offset: 0
10+
options: {}
11+
.
12+
13+
note: content in body only
14+
.
15+
```{note}
16+
a
17+
```
18+
.
19+
arguments: []
20+
body:
21+
- a
22+
content_offset: 0
23+
options: {}
24+
.
25+
26+
note: content after option
27+
.
28+
```{note}
29+
:class: name
30+
a
31+
```
32+
.
33+
arguments: []
34+
body:
35+
- a
36+
content_offset: 1
37+
options:
38+
class:
39+
- name
40+
.
41+
42+
note: content after option with new line
43+
.
44+
```{note}
45+
:class: name
46+
47+
a
48+
```
49+
.
50+
arguments: []
51+
body:
52+
- a
53+
content_offset: 2
54+
options:
55+
class:
56+
- name
57+
.
58+
59+
note: content after yaml option
60+
.
61+
```{note}
62+
---
63+
class: name
64+
---
65+
a
66+
```
67+
.
68+
arguments: []
69+
body:
70+
- a
71+
content_offset: 3
72+
options:
73+
class:
74+
- name
75+
.
76+
77+
note: content in first line and body
78+
.
79+
```{note} first line
80+
:class: tip
81+
82+
body line
83+
```
84+
.
85+
arguments: []
86+
body:
87+
- first line
88+
- ''
89+
- body line
90+
content_offset: 1
91+
options:
92+
class:
93+
- tip
94+
.
95+
96+
admonition: no options, no new line
97+
.
98+
```{admonition} first line
99+
body line
100+
```
101+
.
102+
arguments:
103+
- first line
104+
body:
105+
- body line
106+
content_offset: 0
107+
options: {}
108+
.
109+
110+
admonition: no options, new line
111+
.
112+
```{admonition} first line
113+
114+
body line
115+
```
116+
.
117+
arguments:
118+
- first line
119+
body:
120+
- body line
121+
content_offset: 1
122+
options: {}
123+
.
124+
125+
admonition: with options
126+
.
127+
```{admonition} first line
128+
:class: tip
129+
130+
body line
131+
```
132+
.
133+
arguments:
134+
- first line
135+
body:
136+
- body line
137+
content_offset: 2
138+
options:
139+
class:
140+
- tip
141+
.

tests/test_renderers/test_parse_directives.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,41 @@
1-
# TODO add more tests
1+
from pathlib import Path
2+
23
import pytest
3-
from docutils.parsers.rst.directives.admonitions import Note
4+
import yaml
5+
from docutils.parsers.rst.directives.admonitions import Admonition, Note
46
from docutils.parsers.rst.directives.body import Rubric
7+
from markdown_it import MarkdownIt
58

69
from myst_parser.parsers.directives import DirectiveParsingError, parse_directive_text
710

11+
FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures")
812

9-
@pytest.mark.parametrize(
10-
"klass,arguments,content",
11-
[(Note, "", "a"), (Note, "a", ""), (Note, "", ":class: name\n\na")],
12-
)
13-
def test_parsing(klass, arguments, content, data_regression):
13+
14+
@pytest.mark.param_file(FIXTURE_PATH / "directive_parsing.txt")
15+
def test_parsing(file_params):
16+
"""Test parsing of directive text."""
17+
tokens = MarkdownIt("commonmark").parse(file_params.content)
18+
assert len(tokens) == 1 and tokens[0].type == "fence"
19+
name, *first_line = tokens[0].info.split(maxsplit=1)
20+
if name == "{note}":
21+
klass = Note
22+
elif name == "{admonition}":
23+
klass = Admonition
24+
else:
25+
raise AssertionError(f"Unknown directive: {name}")
1426
arguments, options, body_lines, content_offset = parse_directive_text(
15-
klass, arguments, content
27+
klass, first_line[0] if first_line else "", tokens[0].content
1628
)
17-
data_regression.check(
29+
outcome = yaml.safe_dump(
1830
{
1931
"arguments": arguments,
2032
"options": options,
2133
"body": body_lines,
2234
"content_offset": content_offset,
23-
}
35+
},
36+
sort_keys=True,
2437
)
38+
file_params.assert_expected(outcome, rstrip_lines=True)
2539

2640

2741
@pytest.mark.parametrize(

tests/test_renderers/test_parse_directives/test_parsing_Note___class__name_n_na_.yml

Lines changed: 0 additions & 7 deletions
This file was deleted.

tests/test_renderers/test_parse_directives/test_parsing_Note__a_.yml

Lines changed: 0 additions & 5 deletions
This file was deleted.

tests/test_renderers/test_parse_directives/test_parsing_Note_a__.yml

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)