From 961a63899073d8ca77f6c2ce5b5d62ce18182be2 Mon Sep 17 00:00:00 2001 From: Samson Umezulike Date: Tue, 26 Mar 2024 05:36:45 +0100 Subject: [PATCH] :sparkles: NEW: Emits sphinx include-read event (#887) Adds emission of Sphinx `include-read` events while processing include directives See: https://www.sphinx-doc.org/en/master/extdev/appapi.html#event-include-read Co-authored-by: Chris Sewell --- myst_parser/mocking.py | 16 +++++++ .../test_sphinx/sourcedirs/includes/index.md | 3 ++ tests/test_sphinx/test_sphinx_builds.py | 46 +++++++++++++++++++ .../test_sphinx_builds/test_includes.html | 13 ++++++ .../test_sphinx_builds/test_includes.xml | 6 +++ 5 files changed, 84 insertions(+) diff --git a/myst_parser/mocking.py b/myst_parser/mocking.py index fa49ecc6..f37d9ef3 100644 --- a/myst_parser/mocking.py +++ b/myst_parser/mocking.py @@ -381,6 +381,22 @@ def run(self) -> list[nodes.Element]: 4, f'Directive "{self.name}": error reading file: {path}\n{error}.' ) from error + if self.renderer.sphinx_env is not None: + # Emit the "include-read" event + # see: https://github.com/sphinx-doc/sphinx/commit/ff18318613db56d0000db47e5c8f0140556cef0c + arg = [file_content] + relative_path = Path( + os.path.relpath(path, start=self.renderer.sphinx_env.srcdir) + ) + parent_docname = Path(self.renderer.document["source"]).stem + self.renderer.sphinx_env.app.events.emit( + "include-read", + relative_path, + parent_docname, + arg, + ) + file_content = arg[0] + # get required section of text startline = self.options.get("start-line", None) endline = self.options.get("end-line", None) diff --git a/tests/test_sphinx/sourcedirs/includes/index.md b/tests/test_sphinx/sourcedirs/includes/index.md index dc904e37..9957b6d9 100644 --- a/tests/test_sphinx/sourcedirs/includes/index.md +++ b/tests/test_sphinx/sourcedirs/includes/index.md @@ -1,5 +1,8 @@ # Main Title +```{include} ../include_from_rst/include.md +``` + ```{include} include1.inc.md ``` diff --git a/tests/test_sphinx/test_sphinx_builds.py b/tests/test_sphinx/test_sphinx_builds.py index 62abc7af..fcc1e463 100644 --- a/tests/test_sphinx/test_sphinx_builds.py +++ b/tests/test_sphinx/test_sphinx_builds.py @@ -8,10 +8,14 @@ (e.g. converting `
` to `
`) """ +from __future__ import annotations + import os import re +from pathlib import Path import pytest +import sphinx from docutils import VersionInfo, __version_info__ SOURCE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "sourcedirs")) @@ -583,3 +587,45 @@ def test_texinfo(app, status, warning): assert "build succeeded" in status.getvalue() # Build succeeded warnings = warning.getvalue().strip() assert warnings == "" + + +@pytest.mark.skipif( + sphinx.version_info < (7, 2, 5), reason="include-read event added in sphinx 7.2.5" +) +@pytest.mark.sphinx( + buildername="html", + srcdir=os.path.join(SOURCE_DIR, "includes"), + freshenv=True, +) +def test_include_read_event(app, status, warning): + """Test that include-read event is emitted correctly.""" + + include_read_events = [] + + def handle_include_read( + app, relative_path: Path, parent_docname: str, content: list[str] + ) -> None: + include_read_events.append((relative_path, parent_docname, content)) + + app.connect("include-read", handle_include_read) + app.build() + assert "build succeeded" in status.getvalue() # Build succeeded + warnings = warning.getvalue().strip() + assert warnings == "" + expected = [ + ("../include_from_rst/include.md", "index"), + ("include1.inc.md", "index"), + (os.path.join("subfolder", "include2.inc.md"), "include1.inc"), + ("include_code.py", "index"), + ("include_code.py", "index"), + ("include_literal.txt", "index"), + ("include_literal.txt", "index"), + ] + expected_events = [] + for include_file_name, parent_docname in expected: + with open(os.path.join(SOURCE_DIR, "includes", include_file_name)) as file: + content = file.read() + expected_events.append((Path(include_file_name), parent_docname, [content])) + assert len(include_read_events) == len(expected_events), "Wrong number of events" + for evt in expected_events: + assert evt in include_read_events diff --git a/tests/test_sphinx/test_sphinx_builds/test_includes.html b/tests/test_sphinx/test_sphinx_builds/test_includes.html index 89a477d7..fde9438f 100644 --- a/tests/test_sphinx/test_sphinx_builds/test_includes.html +++ b/tests/test_sphinx/test_sphinx_builds/test_includes.html @@ -8,6 +8,19 @@

+
+
+

+ Markdown + + ¶ + +

+

+ + target + +

diff --git a/tests/test_sphinx/test_sphinx_builds/test_includes.xml b/tests/test_sphinx/test_sphinx_builds/test_includes.xml index 65a197bd..9af883de 100644 --- a/tests/test_sphinx/test_sphinx_builds/test_includes.xml +++ b/tests/test_sphinx/test_sphinx_builds/test_includes.xml @@ -2,6 +2,12 @@
Main Title + <section ids="markdown" names="markdown"> + <title> + Markdown + <paragraph> + <reference refuri="http://example.com/"> + target <target refid="inc-header"> <section ids="a-sub-heading-in-include inc-header" names="a\ sub-heading\ in\ include inc_header"> <title>