From 2945814de29923b8f063fa179f282fbbae630a36 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 22 Oct 2013 19:49:45 -0400 Subject: [PATCH] cmRST: Teach cmake-module directive to scan bracket comments When scanning CMake module files for .rst comments, recognize bracket comments starting in ".rst:" too. For example: #[[.rst: Include the bracket comment content terminated by the closing bracket. Exclude the line containing the bracket if it starts in "#". Teach the CMakeLib.testRST test to cover multiple bracket lengths and ending brackets on lines with and without "#". Update the cmake-developer.7 manual to document the bracket-comment syntax for .rst documentation. --- Help/manual/cmake-developer.7.rst | 28 +++++++++++++---- Source/cmRST.cxx | 50 ++++++++++++++++++++++++------- Source/cmRST.h | 1 + Tests/CMakeLib/testRST.expect | 6 ++++ Tests/CMakeLib/testRSTmod.cmake | 7 +++++ Utilities/Sphinx/cmake.py | 37 ++++++++++++++++------- 6 files changed, 102 insertions(+), 27 deletions(-) diff --git a/Help/manual/cmake-developer.7.rst b/Help/manual/cmake-developer.7.rst index f6b8150b7..198a240a2 100644 --- a/Help/manual/cmake-developer.7.rst +++ b/Help/manual/cmake-developer.7.rst @@ -253,6 +253,21 @@ Add to the top of ``Modules/.cmake`` a #-comment of the form: # # +or a bracket-comment of the form: + +.. code-block:: cmake + + #[[.rst: + + ------------- + + + #]] + +Any number of ``=`` may be used in the opening and closing brackets +as long as they match. Content on the line containing the closing +bracket is excluded if and only if the line starts in ``#``. + Additional such ``.rst:`` comments may appear anywhere in the module file. All such comments must start with ``#`` in the first column. @@ -276,12 +291,13 @@ For example, a ``Modules/Findxxx.cmake`` module may contain: - #.rst: - # .. command:: xxx_do_something - # - # This command does something for Xxx:: - # - # xxx_do_something(some arguments) + #[========================================[.rst: + .. command:: xxx_do_something + + This command does something for Xxx:: + + xxx_do_something(some arguments) + #]========================================] macro(xxx_do_something) endmacro() diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index d2eeb0ce7..6d4e2810c 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -34,6 +34,7 @@ cmRST::cmRST(std::ostream& os, std::string const& docroot): ReplaceDirective("^.. (\\|[^|]+\\|) replace::[ \t]*(.*)$"), IncludeDirective("^.. include::[ \t]+([^ \t\n]+)$"), TocTreeDirective("^.. toctree::[ \t]*(.*)$"), + ModuleRST("^#\\[(=*)\\[\\.rst:$"), CMakeRole("(:cmake)?:(" "command|generator|variable|module|policy|" "prop_cache|prop_dir|prop_gbl|prop_sf|prop_test|prop_tgt|" @@ -85,28 +86,55 @@ void cmRST::ProcessModule(std::istream& is) std::string rst; while(cmSystemTools::GetLineFromStream(is, line)) { - if(rst == "#") + if(!rst.empty() && rst != "#") { - if(line == "#") + // Bracket mode: check for end bracket + std::string::size_type pos = line.find(rst); + if(pos == line.npos) { - this->ProcessLine(""); - continue; - } - else if(line.substr(0, 2) == "# ") - { - this->ProcessLine(line.substr(2, line.npos)); - continue; + this->ProcessLine(line); } else { + if(line[0] != '#') + { + this->ProcessLine(line.substr(0, pos)); + } rst = ""; this->Reset(); this->OutputLinePending = true; } } - if(line == "#.rst:") + else { - rst = "#"; + // Line mode: check for .rst start (bracket or line) + if(rst == "#") + { + if(line == "#") + { + this->ProcessLine(""); + continue; + } + else if(line.substr(0, 2) == "# ") + { + this->ProcessLine(line.substr(2, line.npos)); + continue; + } + else + { + rst = ""; + this->Reset(); + this->OutputLinePending = true; + } + } + if(line == "#.rst:") + { + rst = "#"; + } + else if(this->ModuleRST.find(line)) + { + rst = "]" + this->ModuleRST.match(1) + "]"; + } } } if(rst == "#") diff --git a/Source/cmRST.h b/Source/cmRST.h index 1a3cd994c..fa987cdce 100644 --- a/Source/cmRST.h +++ b/Source/cmRST.h @@ -84,6 +84,7 @@ private: cmsys::RegularExpression ReplaceDirective; cmsys::RegularExpression IncludeDirective; cmsys::RegularExpression TocTreeDirective; + cmsys::RegularExpression ModuleRST; cmsys::RegularExpression CMakeRole; cmsys::RegularExpression Substitution; diff --git a/Tests/CMakeLib/testRST.expect b/Tests/CMakeLib/testRST.expect index 9bd0ca474..744cb8829 100644 --- a/Tests/CMakeLib/testRST.expect +++ b/Tests/CMakeLib/testRST.expect @@ -27,6 +27,12 @@ CMake Module Content More CMake Module Content +Bracket Comment Content + +[ +Bracket Comment Content +] + .. cmake:command:: some_cmd Command some_cmd description. diff --git a/Tests/CMakeLib/testRSTmod.cmake b/Tests/CMakeLib/testRSTmod.cmake index dfa793dd9..8b807a605 100644 --- a/Tests/CMakeLib/testRSTmod.cmake +++ b/Tests/CMakeLib/testRSTmod.cmake @@ -2,3 +2,10 @@ # CMake Module Content #.rst: # More CMake Module Content +#[[.rst: +Bracket Comment Content +# not part of content]] # not part of content +#[=[.rst: +[ +Bracket Comment Content +]]=] # not part of content diff --git a/Utilities/Sphinx/cmake.py b/Utilities/Sphinx/cmake.py index 75f62dff5..146e1f64d 100644 --- a/Utilities/Sphinx/cmake.py +++ b/Utilities/Sphinx/cmake.py @@ -31,7 +31,6 @@ class CMakeModule(Directive): def __init__(self, *args, **keys): self.re_start = re.compile(r'^#\[(?P=*)\[\.rst:$') - self.re_end = re.compile(r'^#?\](?P=*)\]$') Directive.__init__(self, *args, **keys) def run(self): @@ -61,18 +60,36 @@ class CMakeModule(Directive): rst = None lines = [] for line in raw_lines: - if line == '#.rst:': - rst = '#' - line = '' - elif rst == '#': - if line == '#' or line[:2] == '# ': - line = line[2:] - else: + if rst is not None and rst != '#': + # Bracket mode: check for end bracket + pos = line.find(rst) + if pos >= 0: + if line[0] == '#': + line = '' + else: + line = line[0:pos] rst = None - line = '' else: - line = '' + # Line mode: check for .rst start (bracket or line) + m = self.re_start.match(line) + if m: + rst = ']%s]' % m.group('eq') + line = '' + elif line == '#.rst:': + rst = '#' + line = '' + elif rst == '#': + if line == '#' or line[:2] == '# ': + line = line[2:] + else: + rst = None + line = '' + elif rst is None: + line = '' lines.append(line) + if rst is not None and rst != '#': + raise self.warning('"%s" found unclosed bracket "#[%s[.rst:" in %s' % + (self.name, rst[1:-1], path)) self.state_machine.insert_input(lines, path) return []