From ea7d7f9ee8c584738619bb78e6e4b288e530c5f3 Mon Sep 17 00:00:00 2001 From: leakec Date: Thu, 9 Jul 2026 15:46:46 -0600 Subject: [PATCH 1/3] Fixed newline not showing up after Args. Assisted by GPT:5.5. --- pybind11_mkdoc/mkdoc_lib.py | 6 ++++- tests/doxygen_parsing_test.py | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/pybind11_mkdoc/mkdoc_lib.py b/pybind11_mkdoc/mkdoc_lib.py index 8bdf228..e3b54d7 100755 --- a/pybind11_mkdoc/mkdoc_lib.py +++ b/pybind11_mkdoc/mkdoc_lib.py @@ -222,6 +222,10 @@ def _append_continuation(target, text): return if target[0] == "body": target[1].append(text) + elif target[0] == "brief": + if target[1] and target[1][-1].rstrip().endswith((".", "!", "?")): + target[1].append("") + target[1].append(text) elif target[0] == "section": target[1][-1][1].append(text) elif target[0] == "list": @@ -277,7 +281,7 @@ def _consume_doxygen_sections(s): if rest: body_lines.append(rest) pending_brief_separator = True - active = None + active = ("brief", body_lines) else: active = None continue diff --git a/tests/doxygen_parsing_test.py b/tests/doxygen_parsing_test.py index ebcb68a..bc5fffc 100644 --- a/tests/doxygen_parsing_test.py +++ b/tests/doxygen_parsing_test.py @@ -109,6 +109,50 @@ def test_single_line_function_docstrings_do_not_get_extra_blank_lines(): assert format_function_docstring(comment) == "Summary line." +def test_google_sections_are_separated_when_brief_touches_param(): + comment = process_comment("""/** + * @brief Summary line. + * @param value Value description. + * @return Result description. + */""") + + expected = """\ +Summary line. + +Args: + value: Value description. + +Returns: + Result description.""" + + assert comment == expected + + +def test_brief_continuation_stays_in_summary_before_google_sections(): + comment = process_comment("""/** + * @brief Create a chained f2f between this frame and the target frame. This frame will be + * the o-frame and the target frame will become the p-frame. + * @param frame The target frame. This will be the p-frame in the chained frame to frame. + * @return The ChainedFrameToFrame connecting this frame (o-frame) + * and the target frame (p-frame). + */""") + + expected = """\ +Create a chained f2f between this frame and the target frame. This +frame will be the o-frame and the target frame will become the +p-frame. + +Args: + frame: The target frame. This will be the p-frame in the chained + frame to frame. + +Returns: + The ChainedFrameToFrame connecting this frame (o-frame) and the + target frame (p-frame).""" + + assert comment == expected + + def test_multiline_parameter_descriptions_with_mixed_indentation(): comment = """/** * @brief Handles several inputs. From 83891b67b73c3ac1aad7c7aaa4a5f3f4c4705ac9 Mon Sep 17 00:00:00 2001 From: leakec Date: Thu, 9 Jul 2026 16:32:53 -0600 Subject: [PATCH 2/3] Fixed case where :: used in class name. Regex updated so we need to have whitespace or newline afterwards to be considered a section label. Assisted by GPT:5.5. --- pybind11_mkdoc/mkdoc_lib.py | 2 +- tests/doxygen_parsing_test.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/pybind11_mkdoc/mkdoc_lib.py b/pybind11_mkdoc/mkdoc_lib.py index e3b54d7..4b4ab34 100755 --- a/pybind11_mkdoc/mkdoc_lib.py +++ b/pybind11_mkdoc/mkdoc_lib.py @@ -120,7 +120,7 @@ def sanitize_name(name): section_command_re = re.compile(r"\s*[\\@](\w+)(?:\[([^\]]+)\])?(?:\s+(.*))?$") code_segment_re = re.compile(r"(```)") -prefix_re = re.compile(r"(\s*)((?:[*\-•]\s)|(?:\(?\d+[\.)]\s)|(?:[\w:]+(?:\s+\[[^\]]+\])?:)\s*)") +prefix_re = re.compile(r"(\s*)((?:[*\-•]\s)|(?:\(?\d+[\.)]\s)|(?:[\w:]+(?:\s+\[[^\]]+\])?:(?:\s+|$)))") param_arg_re = re.compile(r"([\w:]+)\s*(.*)") raises_arg_re = re.compile(r"([\w:]+)\s*(.*)") diff --git a/tests/doxygen_parsing_test.py b/tests/doxygen_parsing_test.py index bc5fffc..986d579 100644 --- a/tests/doxygen_parsing_test.py +++ b/tests/doxygen_parsing_test.py @@ -153,6 +153,34 @@ def test_brief_continuation_stays_in_summary_before_google_sections(): assert comment == expected +def test_cpp_scope_operator_does_not_create_false_google_prefix(): + comment = process_comment("""/** + * @brief Return the transform rates for the oframe to pframe relative velocity + * + * This method converts the spatial velocity of the pframe with respect to + * the oframe, into the minimal coordinate rates 6-vector for + * the relative transform. The minimal coordinates are the + * Karana::Math::RotationVector representation of the attitude part, and the + * relative position of the linear part. + * + * @return The coordinate rates as a 6-vector + */""") + + expected = """\ +Return the transform rates for the oframe to pframe relative velocity + +This method converts the spatial velocity of the pframe with respect +to the oframe, into the minimal coordinate rates 6-vector for the +relative transform. The minimal coordinates are the +Karana::Math::RotationVector representation of the attitude part, and +the relative position of the linear part. + +Returns: + The coordinate rates as a 6-vector""" + + assert comment == expected + + def test_multiline_parameter_descriptions_with_mixed_indentation(): comment = """/** * @brief Handles several inputs. From bba62ef01ae3717e9f567a1c8e99fb4e67a91909 Mon Sep 17 00:00:00 2001 From: leake Date: Thu, 9 Jul 2026 17:02:29 -0600 Subject: [PATCH 3/3] Formatted. --- tests/cmake_test.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/cmake_test.py b/tests/cmake_test.py index 5d1d616..f33f3df 100644 --- a/tests/cmake_test.py +++ b/tests/cmake_test.py @@ -1,6 +1,6 @@ import os -import sys import subprocess +import sys from pathlib import Path DIR = Path(__file__).resolve().parent @@ -9,7 +9,9 @@ def test_pybind11_mkdoc_cmake(tmp_path: Path) -> None: # Run pybind11-mkdoc and put the output in a temp file build_dir = tmp_path / "build" - subprocess.run(["cmake", "-B", build_dir, "-S", DIR / "cmake_docs", f"-DPython_EXECUTABLE={sys.executable}"], check=True) + subprocess.run( + ["cmake", "-B", build_dir, "-S", DIR / "cmake_docs", f"-DPython_EXECUTABLE={sys.executable}"], check=True + ) subprocess.run(["cmake", "--build", build_dir], check=True) # Ensure the header file matches @@ -27,7 +29,11 @@ def test_pybind11_mkdoc_cmake_extra_args(tmp_path: Path) -> None: env = os.environ.copy() env["PYBIND11_TEST_EXTRA_ARGS"] = "-DMY_EXTRA_DEFINE=1" - subprocess.run(["cmake", "-B", build_dir, "-S", DIR / "cmake_docs", f"-DPython_EXECUTABLE={sys.executable}"], check=True, env=env) + subprocess.run( + ["cmake", "-B", build_dir, "-S", DIR / "cmake_docs", f"-DPython_EXECUTABLE={sys.executable}"], + check=True, + env=env, + ) subprocess.run(["cmake", "--build", build_dir], check=True, env=env) # Ensure the header file matches