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.
This commit is contained in:
Brad King 2013-10-22 19:49:45 -04:00
parent 8bb2ee96cc
commit 2945814de2
6 changed files with 102 additions and 27 deletions

View File

@ -253,6 +253,21 @@ Add to the top of ``Modules/<module-name>.cmake`` a #-comment of the form:
# #
# <reStructuredText documentation of module> # <reStructuredText documentation of module>
or a bracket-comment of the form:
.. code-block:: cmake
#[[.rst:
<module-name>
-------------
<reStructuredText documentation of module>
#]]
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. Additional such ``.rst:`` comments may appear anywhere in the module file.
All such comments must start with ``#`` in the first column. All such comments must start with ``#`` in the first column.
@ -276,12 +291,13 @@ For example, a ``Modules/Findxxx.cmake`` module may contain:
<code> <code>
#.rst: #[========================================[.rst:
# .. command:: xxx_do_something .. command:: xxx_do_something
#
# This command does something for Xxx:: This command does something for Xxx::
#
# xxx_do_something(some arguments) xxx_do_something(some arguments)
#]========================================]
macro(xxx_do_something) macro(xxx_do_something)
<code> <code>
endmacro() endmacro()

View File

@ -34,6 +34,7 @@ cmRST::cmRST(std::ostream& os, std::string const& docroot):
ReplaceDirective("^.. (\\|[^|]+\\|) replace::[ \t]*(.*)$"), ReplaceDirective("^.. (\\|[^|]+\\|) replace::[ \t]*(.*)$"),
IncludeDirective("^.. include::[ \t]+([^ \t\n]+)$"), IncludeDirective("^.. include::[ \t]+([^ \t\n]+)$"),
TocTreeDirective("^.. toctree::[ \t]*(.*)$"), TocTreeDirective("^.. toctree::[ \t]*(.*)$"),
ModuleRST("^#\\[(=*)\\[\\.rst:$"),
CMakeRole("(:cmake)?:(" CMakeRole("(:cmake)?:("
"command|generator|variable|module|policy|" "command|generator|variable|module|policy|"
"prop_cache|prop_dir|prop_gbl|prop_sf|prop_test|prop_tgt|" "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; std::string rst;
while(cmSystemTools::GetLineFromStream(is, line)) 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(""); this->ProcessLine(line);
continue;
}
else if(line.substr(0, 2) == "# ")
{
this->ProcessLine(line.substr(2, line.npos));
continue;
} }
else else
{ {
if(line[0] != '#')
{
this->ProcessLine(line.substr(0, pos));
}
rst = ""; rst = "";
this->Reset(); this->Reset();
this->OutputLinePending = true; 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 == "#") if(rst == "#")

View File

@ -84,6 +84,7 @@ private:
cmsys::RegularExpression ReplaceDirective; cmsys::RegularExpression ReplaceDirective;
cmsys::RegularExpression IncludeDirective; cmsys::RegularExpression IncludeDirective;
cmsys::RegularExpression TocTreeDirective; cmsys::RegularExpression TocTreeDirective;
cmsys::RegularExpression ModuleRST;
cmsys::RegularExpression CMakeRole; cmsys::RegularExpression CMakeRole;
cmsys::RegularExpression Substitution; cmsys::RegularExpression Substitution;

View File

@ -27,6 +27,12 @@ CMake Module Content
More CMake Module Content More CMake Module Content
Bracket Comment Content
[
Bracket Comment Content
]
.. cmake:command:: some_cmd .. cmake:command:: some_cmd
Command some_cmd description. Command some_cmd description.

View File

@ -2,3 +2,10 @@
# CMake Module Content # CMake Module Content
#.rst: #.rst:
# More CMake Module Content # More CMake Module Content
#[[.rst:
Bracket Comment Content
# not part of content]] # not part of content
#[=[.rst:
[
Bracket Comment Content
]]=] # not part of content

View File

@ -31,7 +31,6 @@ class CMakeModule(Directive):
def __init__(self, *args, **keys): def __init__(self, *args, **keys):
self.re_start = re.compile(r'^#\[(?P<eq>=*)\[\.rst:$') self.re_start = re.compile(r'^#\[(?P<eq>=*)\[\.rst:$')
self.re_end = re.compile(r'^#?\](?P<eq>=*)\]$')
Directive.__init__(self, *args, **keys) Directive.__init__(self, *args, **keys)
def run(self): def run(self):
@ -61,18 +60,36 @@ class CMakeModule(Directive):
rst = None rst = None
lines = [] lines = []
for line in raw_lines: for line in raw_lines:
if line == '#.rst:': if rst is not None and rst != '#':
rst = '#' # Bracket mode: check for end bracket
line = '' pos = line.find(rst)
elif rst == '#': if pos >= 0:
if line == '#' or line[:2] == '# ': if line[0] == '#':
line = line[2:] line = ''
else: else:
line = line[0:pos]
rst = None rst = None
line = ''
else: 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) 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) self.state_machine.insert_input(lines, path)
return [] return []