From c9579c430a11064fc328b4c90b362de9383cdd2c Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Tue, 23 Apr 2024 16:52:21 +0200 Subject: [PATCH 1/4] =?UTF-8?q?=F0=9F=93=9A=20Update=20live=20preview=20(#?= =?UTF-8?q?921)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/live-preview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/live-preview.md b/docs/live-preview.md index 82dee8df..b6da3806 100644 --- a/docs/live-preview.md +++ b/docs/live-preview.md @@ -3,7 +3,7 @@ py-config: splashscreen: autoclose: true packages: - - myst-docutils==2.0 + - myst-docutils==3.0 - docutils==0.20 - pygments --- From 446febadcaec172144e31927e935ee34bfdca4e2 Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Sun, 28 Apr 2024 21:38:48 +0200 Subject: [PATCH 2/4] =?UTF-8?q?=F0=9F=90=9B=20FIX=20empty=20value=20for=20?= =?UTF-8?q?final=20directive=20option=20(#924)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- myst_parser/parsers/directives.py | 3 +- myst_parser/parsers/options.py | 4 +- .../fixtures/directive_parsing.txt | 44 +++++++++++++++++++ .../fixtures/option_parsing.yaml | 19 ++++++++ tests/test_renderers/test_parse_directives.py | 6 ++- 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/myst_parser/parsers/directives.py b/myst_parser/parsers/directives.py index 5a2a7f46..d6a000c1 100644 --- a/myst_parser/parsers/directives.py +++ b/myst_parser/parsers/directives.py @@ -49,8 +49,7 @@ from myst_parser.warnings_ import MystWarnings -from .options import TokenizeError -from .options import to_items as options_to_items +from .options import TokenizeError, options_to_items @dataclass diff --git a/myst_parser/parsers/options.py b/myst_parser/parsers/options.py index cf4d3532..366d4559 100644 --- a/myst_parser/parsers/options.py +++ b/myst_parser/parsers/options.py @@ -168,7 +168,7 @@ class State: has_comments: bool = False -def to_items( +def options_to_items( text: str, line_offset: int = 0, column_offset: int = 0 ) -> tuple[list[tuple[str, str]], State]: """Parse a directive option block into (key, value) tuples. @@ -211,6 +211,8 @@ def _to_tokens( raise TokenizeError("expected key before value", token.start) yield key_token, token key_token = None + if key_token is not None: + yield key_token, None except TokenizeError as exc: if line_offset or column_offset: raise exc.clone(line_offset, column_offset) from exc diff --git a/tests/test_renderers/fixtures/directive_parsing.txt b/tests/test_renderers/fixtures/directive_parsing.txt index 663d09e0..3b8cc86a 100644 --- a/tests/test_renderers/fixtures/directive_parsing.txt +++ b/tests/test_renderers/fixtures/directive_parsing.txt @@ -257,3 +257,47 @@ error: missing argument . error: 1 argument(s) required, 0 supplied . + +option_flags_std +. +```{code-block} +:linenos: +:lineno-start: 2 +:force: + +body +``` +. +arguments: [] +body: +- body +content_offset: 4 +options: + force: null + lineno-start: 2 + linenos: null +warnings: [] +. + +option_flags_delimited +. +```{code-block} +--- +linenos: +lineno-start: 2 +force: +--- + +body +``` +. +arguments: [] +body: +- body +content_offset: 6 +options: + force: null + lineno-start: 2 + linenos: null +warnings: [] +. diff --git a/tests/test_renderers/fixtures/option_parsing.yaml b/tests/test_renderers/fixtures/option_parsing.yaml index 14fe0a5c..772aa7f9 100644 --- a/tests/test_renderers/fixtures/option_parsing.yaml +++ b/tests/test_renderers/fixtures/option_parsing.yaml @@ -182,3 +182,22 @@ folded values: ], "comments": false } + +empty_final_value: + content: |- + key1: val1 + key2: + expected: |- + { + "dict": [ + [ + "key1", + "val1" + ], + [ + "key2", + "" + ] + ], + "comments": false + } diff --git a/tests/test_renderers/test_parse_directives.py b/tests/test_renderers/test_parse_directives.py index e6b2c2b4..3813cc97 100644 --- a/tests/test_renderers/test_parse_directives.py +++ b/tests/test_renderers/test_parse_directives.py @@ -6,10 +6,10 @@ from docutils.parsers.rst.directives.admonitions import Admonition, Note from docutils.parsers.rst.directives.body import Rubric from markdown_it import MarkdownIt +from sphinx.directives.code import CodeBlock from myst_parser.parsers.directives import MarkupError, parse_directive_text -from myst_parser.parsers.options import TokenizeError -from myst_parser.parsers.options import to_items as options_to_items +from myst_parser.parsers.options import TokenizeError, options_to_items FIXTURE_PATH = Path(__file__).parent.joinpath("fixtures") @@ -50,6 +50,8 @@ def test_parsing(file_params): klass = Note elif name == "{admonition}": klass = Admonition + elif name == "{code-block}": + klass = CodeBlock else: raise AssertionError(f"Unknown directive: {name}") try: From 790a926df37861657cc083248c4d5580ebd4ebfc Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Sun, 28 Apr 2024 21:58:44 +0200 Subject: [PATCH 3/4] =?UTF-8?q?=F0=9F=90=9B=20FIX:=20allow=20indented=20op?= =?UTF-8?q?tion=20block=20(#925)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- myst_parser/parsers/directives.py | 24 +++++++++---------- .../fixtures/directive_parsing.txt | 18 ++++++++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/myst_parser/parsers/directives.py b/myst_parser/parsers/directives.py index d6a000c1..22ff5a64 100644 --- a/myst_parser/parsers/directives.py +++ b/myst_parser/parsers/directives.py @@ -175,34 +175,34 @@ def _parse_directive_options( :returns: (content, options, validation_errors) """ - yaml_block: None | str = None + options_block: None | str = None if content.startswith("---"): line = None if line is None else line + 1 content = "\n".join(content.splitlines()[1:]) match = re.search(r"^-{3,}", content, re.MULTILINE) if match: - yaml_block = content[: match.start()] + options_block = content[: match.start()] content = content[match.end() + 1 :] # TODO advance line number else: - yaml_block = content + options_block = content content = "" - yaml_block = dedent(yaml_block) - elif content.startswith(":"): + options_block = dedent(options_block) + elif content.lstrip().startswith(":"): content_lines = content.splitlines() yaml_lines = [] while content_lines: - if not content_lines[0].startswith(":"): + if not content_lines[0].lstrip().startswith(":"): break - yaml_lines.append(content_lines.pop(0)[1:]) - yaml_block = "\n".join(yaml_lines) + yaml_lines.append(content_lines.pop(0).lstrip()[1:]) + options_block = "\n".join(yaml_lines) content = "\n".join(content_lines) - has_options_block = yaml_block is not None + has_options_block = options_block is not None if as_yaml: yaml_errors: list[ParseWarnings] = [] try: - yaml_options = yaml.safe_load(yaml_block or "") or {} + yaml_options = yaml.safe_load(options_block or "") or {} except (yaml.parser.ParserError, yaml.scanner.ScannerError): yaml_options = {} yaml_errors.append( @@ -226,9 +226,9 @@ def _parse_directive_options( validation_errors: list[ParseWarnings] = [] options: dict[str, str] = {} - if yaml_block is not None: + if options_block is not None: try: - _options, state = options_to_items(yaml_block) + _options, state = options_to_items(options_block) options = dict(_options) except TokenizeError as err: return _DirectiveOptions( diff --git a/tests/test_renderers/fixtures/directive_parsing.txt b/tests/test_renderers/fixtures/directive_parsing.txt index 3b8cc86a..d1480940 100644 --- a/tests/test_renderers/fixtures/directive_parsing.txt +++ b/tests/test_renderers/fixtures/directive_parsing.txt @@ -258,6 +258,24 @@ error: missing argument error: 1 argument(s) required, 0 supplied . +indented_options +. +```{note} + :class: name + +body +``` +. +arguments: [] +body: +- body +content_offset: 2 +options: + class: + - name +warnings: [] +. + option_flags_std . ```{code-block} From 3d84ff87badc795d44451c79d7e78b8eef6c04bf Mon Sep 17 00:00:00 2001 From: Chris Sewell Date: Sun, 28 Apr 2024 22:19:50 +0200 Subject: [PATCH 4/4] =?UTF-8?q?=F0=9F=9A=80=20Release=20v3.0.1=20(#926)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 9 +++++++++ myst_parser/__init__.py | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2eb1b337..9bfb28b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog +## 3.0.1 - 2024-04-28 + +### 🐛 Bug Fixes + +- Account for the final directive option having an empty value, by in +- Re-allow indented directive option blocks, by in + +**Full Changelog**: [v3.0.1...v3.0.0](https://github.com/executablebooks/MyST-Parser/compare/v3.0.1...v3.0.0) + ## 3.0.0 - 2024-04-23 ### Upgraded dependencies diff --git a/myst_parser/__init__.py b/myst_parser/__init__.py index aaaf31f4..020188e2 100644 --- a/myst_parser/__init__.py +++ b/myst_parser/__init__.py @@ -3,7 +3,7 @@ and [Sphinx](https://github.com/sphinx-doc/sphinx). """ -__version__ = "3.0.0" +__version__ = "3.0.1" def setup(app):