From 4a5a86ba91e08769f98af271be739744d682faea Mon Sep 17 00:00:00 2001 From: John McFarland Date: Sun, 4 Aug 2019 18:09:24 -0500 Subject: [PATCH] Special handling for python doctest code blocks A doctest code block begins with ">>>" and is not indented. Identify these in doxygen comments and treat them accordingly. Also add check to padCodeAndVerbatimBlocks for these because Sphinx requires an empty line before. Add test case to doxygen_code_blocks.i. --- Examples/test-suite/doxygen_code_blocks.i | 6 ++++ .../python/doxygen_code_blocks_runme.py | 7 +++- Source/Doxygen/pydoc.cxx | 35 ++++++++++++------- 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/Examples/test-suite/doxygen_code_blocks.i b/Examples/test-suite/doxygen_code_blocks.i index 220ae13a3..900e8f9bb 100644 --- a/Examples/test-suite/doxygen_code_blocks.i +++ b/Examples/test-suite/doxygen_code_blocks.i @@ -46,6 +46,12 @@ * \code{.py} * print('hello world') * \endcode + * + * A python doctest example: + * \code{.py} + * >>> 1 + 1 + * 2 + * \endcode */ int function() { diff --git a/Examples/test-suite/python/doxygen_code_blocks_runme.py b/Examples/test-suite/python/doxygen_code_blocks_runme.py index a421c8267..46a0a3d84 100644 --- a/Examples/test-suite/python/doxygen_code_blocks_runme.py +++ b/Examples/test-suite/python/doxygen_code_blocks_runme.py @@ -50,4 +50,9 @@ A code block for python: .. code-block:: python - print('hello world')""") + print('hello world') + +A python doctest example: + +>>> 1 + 1 +2""") diff --git a/Source/Doxygen/pydoc.cxx b/Source/Doxygen/pydoc.cxx index 649d3a03d..5216553dc 100644 --- a/Source/Doxygen/pydoc.cxx +++ b/Source/Doxygen/pydoc.cxx @@ -174,7 +174,8 @@ static string padCodeAndVerbatimBlocks(const string &docString) { } else { if (lastLineWasNonBlank && (line.compare(pos, 13, ".. code-block") == 0 || - line.compare(pos, 7, ".. math") == 0)) { + line.compare(pos, 7, ".. math") == 0 || + line.compare(pos, 3, ">>>") == 0)) { // Must separate code or math blocks from the previous line result += '\n'; } @@ -563,9 +564,6 @@ void PyDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComme trimWhitespace(translatedComment); - // Use the current indent for the code-block line itself. - translatedComment += indent.getFirstLineIndent(); - // Check for an option given to the code command (e.g. code{.py}), // and try to set the code-block language accordingly. string option = getCommandOption(tag.typeOfEntity, '{', '}'); @@ -589,14 +587,6 @@ void PyDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComme // limb and assume that the examples in the C or C++ sources use // C++. codeLanguage = "c++"; - - translatedComment += ".. code-block:: " + codeLanguage + "\n\n"; - - // Specify the level of extra indentation that will be used for - // subsequent lines within the code block. Note that the correct - // "starting indentation" is already present in the input, so we - // only need to add the desired code block indentation. - string codeIndent = m_indent; std::string code; handleTagVerbatim(tag, code, arg); @@ -605,6 +595,27 @@ void PyDocConverter::handleCode(DoxygenEntity &tag, std::string &translatedComme // command: eraseLeadingNewLine(code); + // Check for python doctest blocks, and treat them specially: + bool isDocTestBlock = false; + size_t startPos; + // ">>>" would normally appear at the beginning, but doxygen comment + // style may have space in front, so skip leading whitespace + if ((startPos=code.find_first_not_of(" \t")) != string::npos && code.substr(startPos,3) == ">>>") + isDocTestBlock = true; + + string codeIndent; + if (! isDocTestBlock) { + // Use the current indent for the code-block line itself. + translatedComment += indent.getFirstLineIndent(); + translatedComment += ".. code-block:: " + codeLanguage + "\n\n"; + + // Specify the level of extra indentation that will be used for + // subsequent lines within the code block. Note that the correct + // "starting indentation" is already present in the input, so we + // only need to add the desired code block indentation. + codeIndent = m_indent; + } + translatedComment += codeIndent; for (size_t n = 0; n < code.length(); n++) { if (code[n] == '\n') {