diff --git a/changelogs/fragments/15-code-blocks.yml b/changelogs/fragments/15-code-blocks.yml new file mode 100644 index 0000000..50be1b4 --- /dev/null +++ b/changelogs/fragments/15-code-blocks.yml @@ -0,0 +1,3 @@ +minor_changes: + - "Allow to find all literal blocks without language + (https://github.com/ansible-community/antsibull-docutils/pull/15)." diff --git a/src/antsibull_docutils/rst_code_finder.py b/src/antsibull_docutils/rst_code_finder.py index 056b0d0..faf51cf 100644 --- a/src/antsibull_docutils/rst_code_finder.py +++ b/src/antsibull_docutils/rst_code_finder.py @@ -191,7 +191,9 @@ def __init__( callback: t.Callable[ [str, int, int, bool, bool, str, nodes.literal_block], None ], - warn_unknown_block: t.Callable[[int | str, int, nodes.literal_block], None], + warn_unknown_block: t.Callable[ + [int | str, int, nodes.literal_block, bool], None + ], ): super().__init__(document) self.__content_lines = content.splitlines() @@ -216,7 +218,9 @@ def visit_literal_block(self, node: nodes.literal_block) -> None: """ if "antsibull-code-block" not in node.attributes: # This could be a `::` block, or something else (unknown) - self.__warn_unknown_block(node.line or "unknown", 0, node) + self.__warn_unknown_block( + node.line or "unknown", 0, node, bool(node.attributes["classes"]) + ) raise nodes.SkipNode language = node.attributes["antsibull-code-language"] @@ -316,6 +320,9 @@ def find_code_blocks_in_document( document: nodes.document, content: str, warn_unknown_block: t.Callable[[int | str, int, str], None] | None = None, + warn_unknown_block_w_unknown_info: ( + t.Callable[[int | str, int, str, bool], None] | None + ) = None, ) -> t.Generator[CodeBlockInfo]: """ Given a parsed RST document, finds all code blocks. @@ -323,6 +330,12 @@ def find_code_blocks_in_document( All code blocks must be parsed with special directives (see ``get_code_block_directives()``) that have appropriate metadata registered with ``mark_antsibull_code_block()``. + + You can provide callbacks: + * ``warn_unknown_block()`` will be called for every literal block + that's of unknown origin. + * ``warn_unknown_block_w_unknown_info()`` will be called for every + literal block that's of known or unknown origin. """ # If someone can figure out how to yield from a sub-function, we can avoid # using this ugly list @@ -357,9 +370,14 @@ def warn_unknown_block_cb( line: int | str, col: int, node: nodes.literal_block, + unknown_directive: bool, ) -> None: - if warn_unknown_block: + if warn_unknown_block and unknown_directive: warn_unknown_block(line, col, node.rawsource) + if warn_unknown_block_w_unknown_info: + warn_unknown_block_w_unknown_info( + line, col, node.rawsource, unknown_directive + ) # Process the document try: @@ -371,13 +389,16 @@ def warn_unknown_block_cb( yield from results -def find_code_blocks( +def find_code_blocks( # pylint: disable=too-many-arguments content: str, *, path: str | os.PathLike[str] | None = None, root_prefix: str | os.PathLike[str] | None = None, extra_directives: Mapping[str, t.Type[Directive]] | None = None, warn_unknown_block: t.Callable[[int | str, int, str], None] | None = None, + warn_unknown_block_w_unknown_info: ( + t.Callable[[int | str, int, str, bool], None] | None + ) = None, ) -> t.Generator[CodeBlockInfo]: """ Given a RST document, finds all code blocks. @@ -385,6 +406,12 @@ def find_code_blocks( To add support for own types of code blocks, you can pass these as ``extra_directives``. Use ``mark_antsibull_code_block()`` to mark them to be found by ``find_code_blocks()``. + + You can provide callbacks: + * ``warn_unknown_block()`` will be called for every literal block + that's of unknown origin. + * ``warn_unknown_block_w_unknown_info()`` will be called for every + literal block that's of known or unknown origin. """ directives = get_code_block_directives(extra_directives=extra_directives) @@ -400,6 +427,7 @@ def find_code_blocks( document=doc, content=content, warn_unknown_block=warn_unknown_block, + warn_unknown_block_w_unknown_info=warn_unknown_block_w_unknown_info, ) diff --git a/tests/test_rst_code_finder.py b/tests/test_rst_code_finder.py index b82174b..9b0cc69 100644 --- a/tests/test_rst_code_finder.py +++ b/tests/test_rst_code_finder.py @@ -284,17 +284,37 @@ def test_find_code_blocks_ext(): foobar Some invalid `markup + +.. highlight:: python + +:: + + def foo(): + pass + +.. literalinclude:: nox.py + +| a +| b + c """ found_warnings = [] + found_warnings_2 = [] def add_warning(line: int | str, col: int, message: str) -> None: found_warnings.append((line, col, message)) + def add_warning_2( + line: int | str, col: int, message: str, unknown_origin: bool + ) -> None: + found_warnings_2.append((line, col, message, unknown_origin)) + found_code_block_infos = list( find_code_blocks( source, extra_directives={"foo": CodeBlockTest}, warn_unknown_block=add_warning, + warn_unknown_block_w_unknown_info=add_warning_2, ) ) assert found_code_block_infos == [ @@ -317,9 +337,11 @@ def add_warning(line: int | str, col: int, message: str) -> None: attributes={}, ), ] - assert found_warnings == [ - (6, 0, "bar"), - (12, 0, "bazbam"), + assert found_warnings == [] + assert found_warnings_2 == [ + (6, 0, "bar", False), + (12, 0, "bazbam", False), + (24, 0, "def foo():\n pass", False), ]