Просмотр исходного кода

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
Brad King 12 лет назад
Родитель
Сommit
ddef8a7cff
4 измененных файлов с 107 добавлено и 31 удалено
  1. 63 30
      Source/cmRST.cxx
  2. 5 1
      Source/cmRST.h
  3. 19 0
      Tests/CMakeLib/testRST.expect
  4. 20 0
      Tests/CMakeLib/testRST.rst

+ 63 - 30
Source/cmRST.cxx

@@ -22,6 +22,7 @@ cmRST::cmRST(std::ostream& os, std::string const& docroot):
   DocRoot(docroot),
   IncludeDepth(0),
   OutputLinePending(false),
+  LastLineEndedInColonColon(false),
   Markup(MarkupNone),
   Directive(DirectiveNone),
   CMakeDirective("^.. (cmake:)?("
@@ -125,6 +126,7 @@ void cmRST::Reset()
     {
     case DirectiveNone: break;
     case DirectiveParsedLiteral: this->ProcessDirectiveParsedLiteral(); break;
+    case DirectiveLiteralBlock: this->ProcessDirectiveLiteralBlock(); break;
     case DirectiveCodeBlock: this->ProcessDirectiveCodeBlock(); break;
     case DirectiveReplace: this->ProcessDirectiveReplace(); break;
     case DirectiveTocTree: this->ProcessDirectiveTocTree(); break;
@@ -137,6 +139,9 @@ void cmRST::Reset()
 //----------------------------------------------------------------------------
 void cmRST::ProcessLine(std::string const& line)
 {
+  bool lastLineEndedInColonColon = this->LastLineEndedInColonColon;
+  this->LastLineEndedInColonColon = false;
+
   // A line starting in .. is an explicit markup start.
   if(line == ".." || (line.size() >= 3 && line[0] == '.' &&
                       line[1] == '.' && isspace(line[2])))
@@ -211,10 +216,21 @@ void cmRST::ProcessLine(std::string const& 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.
   else
     {
     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)
 {
   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)
     {
     this->OS << "\n";
     this->OutputLinePending = false;
     }
-  std::string line = this->ReplaceSubstitutions(line_in);
-  std::string::size_type pos = 0;
-  while(this->CMakeRole.find(line.c_str()+pos))
+  if(inlineMarkup)
     {
-    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)
+    std::string line = this->ReplaceSubstitutions(line_in);
+    std::string::size_type pos = 0;
+    while(this->CMakeRole.find(line.c_str()+pos))
       {
-      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 << "``";
-    pos += this->CMakeRole.end();
+    this->OS << line.substr(pos) << "\n";
+    }
+  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;
 }
 
+//----------------------------------------------------------------------------
+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)
 {
@@ -317,25 +356,19 @@ bool cmRST::ProcessInclude(std::string file, IncludeType type)
 //----------------------------------------------------------------------------
 void cmRST::ProcessDirectiveParsedLiteral()
 {
-  // Output markup lines as literal text.
-  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);
-    }
-  this->OutputLinePending = true;
+  this->OutputMarkupLines(true);
+}
+
+//----------------------------------------------------------------------------
+void cmRST::ProcessDirectiveLiteralBlock()
+{
+  this->OutputMarkupLines(false);
 }
 
 //----------------------------------------------------------------------------
 void cmRST::ProcessDirectiveCodeBlock()
 {
-  // Treat markup lines the same as a parsed literal.
-  this->ProcessDirectiveParsedLiteral();
+  this->OutputMarkupLines(false);
 }
 
 //----------------------------------------------------------------------------

+ 5 - 1
Source/cmRST.h

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

+ 19 - 0
Tests/CMakeLib/testRST.expect

@@ -45,11 +45,30 @@ More CMake Module Content
 
   Parsed-literal included without directive.
  Common Indentation Removed
+ # replaced in parsed literal
 
  # Sample CMake code block
  if(condition)
    message(indented)
  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
 

+ 20 - 0
Tests/CMakeLib/testRST.rst

@@ -26,6 +26,7 @@ Variable :variable:`VARIABLE_<PLACEHOLDER> <target>` with trailing placeholder a
 Generator :generator:`Some Generator` with space.
 
 .. |not replaced| replace:: not replaced through toctree
+.. |not replaced in literal| replace:: replaced in parsed literal
 
 .. toctree::
    :maxdepth: 2
@@ -55,6 +56,7 @@ Generator :generator:`Some Generator` with space.
 
     Parsed-literal included without directive.
    Common Indentation Removed
+   # |not replaced in literal|
 
 .. code-block:: cmake
 
@@ -62,6 +64,24 @@ Generator :generator:`Some Generator` with space.
    if(condition)
      message(indented)
    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::
    |nested substitution|