Merge topic 'rst-literal-blocks'

2d0287d cmRST: Process literal blocks after paragraphs ending in '::'
7b9ae40 cmRST: Do not process inline markup in code-block literals
This commit is contained in:
Brad King 2013-10-22 09:08:38 -04:00 committed by CMake Topic Stage
commit ddef8a7cff
4 changed files with 107 additions and 31 deletions

View File

@ -22,6 +22,7 @@ cmRST::cmRST(std::ostream& os, std::string const& docroot):
DocRoot(docroot), DocRoot(docroot),
IncludeDepth(0), IncludeDepth(0),
OutputLinePending(false), OutputLinePending(false),
LastLineEndedInColonColon(false),
Markup(MarkupNone), Markup(MarkupNone),
Directive(DirectiveNone), Directive(DirectiveNone),
CMakeDirective("^.. (cmake:)?(" CMakeDirective("^.. (cmake:)?("
@ -125,6 +126,7 @@ void cmRST::Reset()
{ {
case DirectiveNone: break; case DirectiveNone: break;
case DirectiveParsedLiteral: this->ProcessDirectiveParsedLiteral(); break; case DirectiveParsedLiteral: this->ProcessDirectiveParsedLiteral(); break;
case DirectiveLiteralBlock: this->ProcessDirectiveLiteralBlock(); break;
case DirectiveCodeBlock: this->ProcessDirectiveCodeBlock(); break; case DirectiveCodeBlock: this->ProcessDirectiveCodeBlock(); break;
case DirectiveReplace: this->ProcessDirectiveReplace(); break; case DirectiveReplace: this->ProcessDirectiveReplace(); break;
case DirectiveTocTree: this->ProcessDirectiveTocTree(); break; case DirectiveTocTree: this->ProcessDirectiveTocTree(); break;
@ -137,6 +139,9 @@ void cmRST::Reset()
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmRST::ProcessLine(std::string const& line) void cmRST::ProcessLine(std::string const& line)
{ {
bool lastLineEndedInColonColon = this->LastLineEndedInColonColon;
this->LastLineEndedInColonColon = false;
// A line starting in .. is an explicit markup start. // A line starting in .. is an explicit markup start.
if(line == ".." || (line.size() >= 3 && line[0] == '.' && if(line == ".." || (line.size() >= 3 && line[0] == '.' &&
line[1] == '.' && isspace(line[2]))) line[1] == '.' && isspace(line[2])))
@ -211,10 +216,21 @@ void cmRST::ProcessLine(std::string const& line)
this->MarkupLines.push_back(line); this->MarkupLines.push_back(line);
} }
} }
// A blank line following a paragraph ending in "::" starts a literal block.
else if(lastLineEndedInColonColon && line.empty())
{
// Record the literal lines to output after whole block.
this->Markup = MarkupNormal;
this->Directive = DirectiveLiteralBlock;
this->MarkupLines.push_back("");
this->OutputLine("", false);
}
// Print non-markup lines. // Print non-markup lines.
else else
{ {
this->NormalLine(line); this->NormalLine(line);
this->LastLineEndedInColonColon = (line.size() >= 2
&& line[line.size()-2] == ':' && line[line.size()-1] == ':');
} }
} }
@ -222,35 +238,42 @@ void cmRST::ProcessLine(std::string const& line)
void cmRST::NormalLine(std::string const& line) void cmRST::NormalLine(std::string const& line)
{ {
this->Reset(); this->Reset();
this->OutputLine(line); this->OutputLine(line, true);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmRST::OutputLine(std::string const& line_in) void cmRST::OutputLine(std::string const& line_in, bool inlineMarkup)
{ {
if(this->OutputLinePending) if(this->OutputLinePending)
{ {
this->OS << "\n"; this->OS << "\n";
this->OutputLinePending = false; this->OutputLinePending = false;
} }
std::string line = this->ReplaceSubstitutions(line_in); if(inlineMarkup)
std::string::size_type pos = 0;
while(this->CMakeRole.find(line.c_str()+pos))
{ {
this->OS << line.substr(pos, this->CMakeRole.start()); std::string line = this->ReplaceSubstitutions(line_in);
std::string text = this->CMakeRole.match(3); std::string::size_type pos = 0;
// If a command reference has no explicit target and while(this->CMakeRole.find(line.c_str()+pos))
// no explicit "(...)" then add "()" to the text.
if(this->CMakeRole.match(2) == "command" &&
this->CMakeRole.match(5).empty() &&
text.find_first_of("()") == text.npos)
{ {
text += "()"; this->OS << line.substr(pos, this->CMakeRole.start());
std::string text = this->CMakeRole.match(3);
// If a command reference has no explicit target and
// no explicit "(...)" then add "()" to the text.
if(this->CMakeRole.match(2) == "command" &&
this->CMakeRole.match(5).empty() &&
text.find_first_of("()") == text.npos)
{
text += "()";
}
this->OS << "``" << text << "``";
pos += this->CMakeRole.end();
} }
this->OS << "``" << text << "``"; this->OS << line.substr(pos) << "\n";
pos += this->CMakeRole.end(); }
else
{
this->OS << line_in << "\n";
} }
this->OS << line.substr(pos) << "\n";
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@ -283,6 +306,22 @@ std::string cmRST::ReplaceSubstitutions(std::string const& line)
return out; return out;
} }
//----------------------------------------------------------------------------
void cmRST::OutputMarkupLines(bool inlineMarkup)
{
for(std::vector<std::string>::iterator i = this->MarkupLines.begin();
i != this->MarkupLines.end(); ++i)
{
std::string line = *i;
if(!line.empty())
{
line = " " + line;
}
this->OutputLine(line, inlineMarkup);
}
this->OutputLinePending = true;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool cmRST::ProcessInclude(std::string file, IncludeType type) bool cmRST::ProcessInclude(std::string file, IncludeType type)
{ {
@ -317,25 +356,19 @@ bool cmRST::ProcessInclude(std::string file, IncludeType type)
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmRST::ProcessDirectiveParsedLiteral() void cmRST::ProcessDirectiveParsedLiteral()
{ {
// Output markup lines as literal text. this->OutputMarkupLines(true);
for(std::vector<std::string>::iterator i = this->MarkupLines.begin(); }
i != this->MarkupLines.end(); ++i)
{ //----------------------------------------------------------------------------
std::string line = *i; void cmRST::ProcessDirectiveLiteralBlock()
if(!line.empty()) {
{ this->OutputMarkupLines(false);
line = " " + line;
}
this->OutputLine(line);
}
this->OutputLinePending = true;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmRST::ProcessDirectiveCodeBlock() void cmRST::ProcessDirectiveCodeBlock()
{ {
// Treat markup lines the same as a parsed literal. this->OutputMarkupLines(false);
this->ProcessDirectiveParsedLiteral();
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------

View File

@ -38,6 +38,7 @@ private:
{ {
DirectiveNone, DirectiveNone,
DirectiveParsedLiteral, DirectiveParsedLiteral,
DirectiveLiteralBlock,
DirectiveCodeBlock, DirectiveCodeBlock,
DirectiveReplace, DirectiveReplace,
DirectiveTocTree DirectiveTocTree
@ -48,10 +49,12 @@ private:
void Reset(); void Reset();
void ProcessLine(std::string const& line); void ProcessLine(std::string const& line);
void NormalLine(std::string const& line); void NormalLine(std::string const& line);
void OutputLine(std::string const& line); void OutputLine(std::string const& line, bool inlineMarkup);
std::string ReplaceSubstitutions(std::string const& line); std::string ReplaceSubstitutions(std::string const& line);
void OutputMarkupLines(bool inlineMarkup);
bool ProcessInclude(std::string file, IncludeType type); bool ProcessInclude(std::string file, IncludeType type);
void ProcessDirectiveParsedLiteral(); void ProcessDirectiveParsedLiteral();
void ProcessDirectiveLiteralBlock();
void ProcessDirectiveCodeBlock(); void ProcessDirectiveCodeBlock();
void ProcessDirectiveReplace(); void ProcessDirectiveReplace();
void ProcessDirectiveTocTree(); void ProcessDirectiveTocTree();
@ -61,6 +64,7 @@ private:
std::string DocRoot; std::string DocRoot;
int IncludeDepth; int IncludeDepth;
bool OutputLinePending; bool OutputLinePending;
bool LastLineEndedInColonColon;
MarkupType Markup; MarkupType Markup;
DirectiveType Directive; DirectiveType Directive;
cmsys::RegularExpression CMakeDirective; cmsys::RegularExpression CMakeDirective;

View File

@ -45,11 +45,30 @@ More CMake Module Content
Parsed-literal included without directive. Parsed-literal included without directive.
Common Indentation Removed Common Indentation Removed
# replaced in parsed literal
# Sample CMake code block # Sample CMake code block
if(condition) if(condition)
message(indented) message(indented)
endif() endif()
# |not replaced in literal|
A literal block starts after a line consisting of two colons
::
Literal block.
Common Indentation Removed
# |not replaced in literal|
or after a paragraph ending in two colons::
Literal block.
Common Indentation Removed
# |not replaced in literal|
but not after a line ending in two colons::
in the middle of a paragraph.
substituted text with multiple lines becomes one line substituted text with multiple lines becomes one line

View File

@ -26,6 +26,7 @@ Variable :variable:`VARIABLE_<PLACEHOLDER> <target>` with trailing placeholder a
Generator :generator:`Some Generator` with space. Generator :generator:`Some Generator` with space.
.. |not replaced| replace:: not replaced through toctree .. |not replaced| replace:: not replaced through toctree
.. |not replaced in literal| replace:: replaced in parsed literal
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
@ -55,6 +56,7 @@ Generator :generator:`Some Generator` with space.
Parsed-literal included without directive. Parsed-literal included without directive.
Common Indentation Removed Common Indentation Removed
# |not replaced in literal|
.. code-block:: cmake .. code-block:: cmake
@ -62,6 +64,24 @@ Generator :generator:`Some Generator` with space.
if(condition) if(condition)
message(indented) message(indented)
endif() endif()
# |not replaced in literal|
A literal block starts after a line consisting of two colons
::
Literal block.
Common Indentation Removed
# |not replaced in literal|
or after a paragraph ending in two colons::
Literal block.
Common Indentation Removed
# |not replaced in literal|
but not after a line ending in two colons::
in the middle of a paragraph.
.. |substitution| replace:: .. |substitution| replace::
|nested substitution| |nested substitution|