diff options
Diffstat (limited to 'Source/cmRST.cxx')
-rw-r--r-- | Source/cmRST.cxx | 382 |
1 files changed, 157 insertions, 225 deletions
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index ad545aa..10d1cda 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -17,36 +17,36 @@ #include <cmsys/FStream.hxx> #include <ctype.h> -cmRST::cmRST(std::ostream& os, std::string const& docroot): - OS(os), - DocRoot(docroot), - IncludeDepth(0), - OutputLinePending(false), - LastLineEndedInColonColon(false), - Markup(MarkupNone), - Directive(DirectiveNone), - CMakeDirective("^.. (cmake:)?(" - "command|variable" - ")::[ \t]+([^ \t\n]+)$"), - CMakeModuleDirective("^.. cmake-module::[ \t]+([^ \t\n]+)$"), - ParsedLiteralDirective("^.. parsed-literal::[ \t]*(.*)$"), - CodeBlockDirective("^.. code-block::[ \t]*(.*)$"), - ReplaceDirective("^.. (\\|[^|]+\\|) replace::[ \t]*(.*)$"), - IncludeDirective("^.. include::[ \t]+([^ \t\n]+)$"), - TocTreeDirective("^.. toctree::[ \t]*(.*)$"), - ProductionListDirective("^.. productionlist::[ \t]*(.*)$"), - NoteDirective("^.. note::[ \t]*(.*)$"), - ModuleRST("^#\\[(=*)\\[\\.rst:$"), - CMakeRole("(:cmake)?:(" - "command|generator|variable|module|policy|" - "prop_cache|prop_dir|prop_gbl|prop_inst|prop_sf|" - "prop_test|prop_tgt|" - "manual" - "):`(<*([^`<]|[^` \t]<)*)([ \t]+<[^`]*>)?`"), - Substitution("(^|[^A-Za-z0-9_])" - "((\\|[^| \t\r\n]([^|\r\n]*[^| \t\r\n])?\\|)(__|_|))" - "([^A-Za-z0-9_]|$)"), - TocTreeLink("^.*[ \t]+<([^>]+)>$") +cmRST::cmRST(std::ostream& os, std::string const& docroot) + : OS(os) + , DocRoot(docroot) + , IncludeDepth(0) + , OutputLinePending(false) + , LastLineEndedInColonColon(false) + , Markup(MarkupNone) + , Directive(DirectiveNone) + , CMakeDirective("^.. (cmake:)?(" + "command|variable" + ")::[ \t]+([^ \t\n]+)$") + , CMakeModuleDirective("^.. cmake-module::[ \t]+([^ \t\n]+)$") + , ParsedLiteralDirective("^.. parsed-literal::[ \t]*(.*)$") + , CodeBlockDirective("^.. code-block::[ \t]*(.*)$") + , ReplaceDirective("^.. (\\|[^|]+\\|) replace::[ \t]*(.*)$") + , IncludeDirective("^.. include::[ \t]+([^ \t\n]+)$") + , TocTreeDirective("^.. toctree::[ \t]*(.*)$") + , ProductionListDirective("^.. productionlist::[ \t]*(.*)$") + , NoteDirective("^.. note::[ \t]*(.*)$") + , ModuleRST("^#\\[(=*)\\[\\.rst:$") + , CMakeRole("(:cmake)?:(" + "command|generator|variable|module|policy|" + "prop_cache|prop_dir|prop_gbl|prop_inst|prop_sf|" + "prop_test|prop_tgt|" + "manual" + "):`(<*([^`<]|[^` \t]<)*)([ \t]+<[^`]*>)?`") + , Substitution("(^|[^A-Za-z0-9_])" + "((\\|[^| \t\r\n]([^|\r\n]*[^| \t\r\n])?\\|)(__|_|))" + "([^A-Za-z0-9_]|$)") + , TocTreeLink("^.*[ \t]+<([^>]+)>$") { this->Replace["|release|"] = cmVersion::GetCMakeVersion(); } @@ -54,30 +54,25 @@ cmRST::cmRST(std::ostream& os, std::string const& docroot): bool cmRST::ProcessFile(std::string const& fname, bool isModule) { cmsys::ifstream fin(fname.c_str()); - if(fin) - { + if (fin) { this->DocDir = cmSystemTools::GetFilenamePath(fname); - if(isModule) - { + if (isModule) { this->ProcessModule(fin); - } - else - { + } else { this->ProcessRST(fin); - } + } this->OutputLinePending = true; return true; - } + } return false; } void cmRST::ProcessRST(std::istream& is) { std::string line; - while(cmSystemTools::GetLineFromStream(is, line)) - { + while (cmSystemTools::GetLineFromStream(is, line)) { this->ProcessLine(line); - } + } this->Reset(); } @@ -85,80 +80,71 @@ void cmRST::ProcessModule(std::istream& is) { std::string line; std::string rst; - while(cmSystemTools::GetLineFromStream(is, line)) - { - if(!rst.empty() && rst != "#") - { + while (cmSystemTools::GetLineFromStream(is, line)) { + if (!rst.empty() && rst != "#") { // Bracket mode: check for end bracket std::string::size_type pos = line.find(rst); - if(pos == line.npos) - { + if (pos == line.npos) { this->ProcessLine(line); - } - else - { - if(line[0] != '#') - { + } else { + if (line[0] != '#') { this->ProcessLine(line.substr(0, pos)); - } + } rst = ""; this->Reset(); this->OutputLinePending = true; - } } - else - { + } else { // Line mode: check for .rst start (bracket or line) - if(rst == "#") - { - if(line == "#") - { + if (rst == "#") { + if (line == "#") { this->ProcessLine(""); continue; - } - else if(line.substr(0, 2) == "# ") - { + } else if (line.substr(0, 2) == "# ") { this->ProcessLine(line.substr(2, line.npos)); continue; - } - else - { + } else { rst = ""; this->Reset(); this->OutputLinePending = true; - } } - if(line == "#.rst:") - { + } + if (line == "#.rst:") { rst = "#"; - } - else if(this->ModuleRST.find(line)) - { + } else if (this->ModuleRST.find(line)) { rst = "]" + this->ModuleRST.match(1) + "]"; - } } } - if(rst == "#") - { + } + if (rst == "#") { this->Reset(); - } + } } void cmRST::Reset() { - if(!this->MarkupLines.empty()) - { + if (!this->MarkupLines.empty()) { this->UnindentLines(this->MarkupLines); - } - switch(this->Directive) - { - 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; - } + } + switch (this->Directive) { + 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; + } this->Markup = MarkupNone; this->Directive = DirectiveNone; this->MarkupLines.clear(); @@ -170,105 +156,82 @@ void cmRST::ProcessLine(std::string const& line) this->LastLineEndedInColonColon = false; // A line starting in .. is an explicit markup start. - if(line == ".." || (line.size() >= 3 && line[0] == '.' && - line[1] == '.' && isspace(line[2]))) - { + if (line == ".." || (line.size() >= 3 && line[0] == '.' && line[1] == '.' && + isspace(line[2]))) { this->Reset(); - this->Markup = (line.find_first_not_of(" \t", 2) == line.npos ? - MarkupEmpty : MarkupNormal); - if(this->CMakeDirective.find(line)) - { + this->Markup = + (line.find_first_not_of(" \t", 2) == line.npos ? MarkupEmpty + : MarkupNormal); + if (this->CMakeDirective.find(line)) { // Output cmake domain directives and their content normally. this->NormalLine(line); - } - else if(this->CMakeModuleDirective.find(line)) - { + } else if (this->CMakeModuleDirective.find(line)) { // Process cmake-module directive: scan .cmake file comments. std::string file = this->CMakeModuleDirective.match(1); - if(file.empty() || !this->ProcessInclude(file, IncludeModule)) - { + if (file.empty() || !this->ProcessInclude(file, IncludeModule)) { this->NormalLine(line); - } } - else if(this->ParsedLiteralDirective.find(line)) - { + } else if (this->ParsedLiteralDirective.find(line)) { // Record the literal lines to output after whole block. this->Directive = DirectiveParsedLiteral; this->MarkupLines.push_back(this->ParsedLiteralDirective.match(1)); - } - else if(this->CodeBlockDirective.find(line)) - { + } else if (this->CodeBlockDirective.find(line)) { // Record the literal lines to output after whole block. // Ignore the language spec and record the opening line as blank. this->Directive = DirectiveCodeBlock; this->MarkupLines.push_back(""); - } - else if(this->ReplaceDirective.find(line)) - { + } else if (this->ReplaceDirective.find(line)) { // Record the replace directive content. this->Directive = DirectiveReplace; this->ReplaceName = this->ReplaceDirective.match(1); this->MarkupLines.push_back(this->ReplaceDirective.match(2)); - } - else if(this->IncludeDirective.find(line)) - { + } else if (this->IncludeDirective.find(line)) { // Process the include directive or output the directive and its // content normally if it fails. std::string file = this->IncludeDirective.match(1); - if(file.empty() || !this->ProcessInclude(file, IncludeNormal)) - { + if (file.empty() || !this->ProcessInclude(file, IncludeNormal)) { this->NormalLine(line); - } } - else if(this->TocTreeDirective.find(line)) - { + } else if (this->TocTreeDirective.find(line)) { // Record the toctree entries to process after whole block. this->Directive = DirectiveTocTree; this->MarkupLines.push_back(this->TocTreeDirective.match(1)); - } - else if(this->ProductionListDirective.find(line)) - { + } else if (this->ProductionListDirective.find(line)) { // Output productionlist directives and their content normally. this->NormalLine(line); - } - else if(this->NoteDirective.find(line)) - { + } else if (this->NoteDirective.find(line)) { // Output note directives and their content normally. this->NormalLine(line); - } } + } // An explicit markup start followed nothing but whitespace and a // blank line does not consume any indented text following. - else if(this->Markup == MarkupEmpty && line.empty()) - { + else if (this->Markup == MarkupEmpty && line.empty()) { this->NormalLine(line); - } + } // Indented lines following an explicit markup start are explicit markup. - else if(this->Markup && (line.empty() || isspace(line[0]))) - { + else if (this->Markup && (line.empty() || isspace(line[0]))) { this->Markup = MarkupNormal; // Record markup lines if the start line was recorded. - if(!this->MarkupLines.empty()) - { + if (!this->MarkupLines.empty()) { this->MarkupLines.push_back(line); - } } + } // A blank line following a paragraph ending in "::" starts a literal block. - else if(lastLineEndedInColonColon && line.empty()) - { + 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 - { + else { this->NormalLine(line); - this->LastLineEndedInColonColon = (line.size() >= 2 - && line[line.size()-2] == ':' && line[line.size()-1] == ':'); - } + this->LastLineEndedInColonColon = + (line.size() >= 2 && line[line.size() - 2] == ':' && + line[line.size() - 1] == ':'); + } } void cmRST::NormalLine(std::string const& line) @@ -279,109 +242,92 @@ void cmRST::NormalLine(std::string const& line) void cmRST::OutputLine(std::string const& line_in, bool inlineMarkup) { - if(this->OutputLinePending) - { + if (this->OutputLinePending) { this->OS << "\n"; this->OutputLinePending = false; - } - if(inlineMarkup) - { + } + if (inlineMarkup) { std::string line = this->ReplaceSubstitutions(line_in); std::string::size_type pos = 0; - while(this->CMakeRole.find(line.c_str()+pos)) - { + while (this->CMakeRole.find(line.c_str() + pos)) { 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) - { + 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 << line.substr(pos) << "\n"; } - else - { + this->OS << line.substr(pos) << "\n"; + } else { this->OS << line_in << "\n"; - } + } } std::string cmRST::ReplaceSubstitutions(std::string const& line) { std::string out; std::string::size_type pos = 0; - while(this->Substitution.find(line.c_str()+pos)) - { + while (this->Substitution.find(line.c_str() + pos)) { std::string::size_type start = this->Substitution.start(2); std::string::size_type end = this->Substitution.end(2); std::string substitute = this->Substitution.match(3); - std::map<std::string, std::string>::iterator - replace = this->Replace.find(substitute); - if(replace != this->Replace.end()) - { + std::map<std::string, std::string>::iterator replace = + this->Replace.find(substitute); + if (replace != this->Replace.end()) { std::pair<std::set<std::string>::iterator, bool> replaced = this->Replaced.insert(substitute); - if(replaced.second) - { + if (replaced.second) { substitute = this->ReplaceSubstitutions(replace->second); this->Replaced.erase(replaced.first); - } } + } out += line.substr(pos, start); out += substitute; pos += end; - } + } out += line.substr(pos); return out; } void cmRST::OutputMarkupLines(bool inlineMarkup) { - for(std::vector<std::string>::iterator i = this->MarkupLines.begin(); - i != this->MarkupLines.end(); ++i) - { + for (std::vector<std::string>::iterator i = this->MarkupLines.begin(); + i != this->MarkupLines.end(); ++i) { std::string line = *i; - if(!line.empty()) - { + if (!line.empty()) { line = " " + line; - } - this->OutputLine(line, inlineMarkup); } + this->OutputLine(line, inlineMarkup); + } this->OutputLinePending = true; } bool cmRST::ProcessInclude(std::string file, IncludeType type) { bool found = false; - if(this->IncludeDepth < 10) - { + if (this->IncludeDepth < 10) { cmRST r(this->OS, this->DocRoot); r.IncludeDepth = this->IncludeDepth + 1; r.OutputLinePending = this->OutputLinePending; - if(type != IncludeTocTree) - { + if (type != IncludeTocTree) { r.Replace = this->Replace; - } - if(file[0] == '/') - { + } + if (file[0] == '/') { file = this->DocRoot + file; - } - else - { + } else { file = this->DocDir + "/" + file; - } + } found = r.ProcessFile(file, type == IncludeModule); - if(type != IncludeTocTree) - { + if (type != IncludeTocTree) { this->Replace = r.Replace; - } - this->OutputLinePending = r.OutputLinePending; } + this->OutputLinePending = r.OutputLinePending; + } return found; } @@ -411,23 +357,18 @@ void cmRST::ProcessDirectiveReplace() void cmRST::ProcessDirectiveTocTree() { // Process documents referenced by toctree directive. - for(std::vector<std::string>::iterator i = this->MarkupLines.begin(); - i != this->MarkupLines.end(); ++i) - { + for (std::vector<std::string>::iterator i = this->MarkupLines.begin(); + i != this->MarkupLines.end(); ++i) { std::string const& line = *i; - if (!line.empty() && line[0] != ':') - { - if (this->TocTreeLink.find(line)) - { + if (!line.empty() && line[0] != ':') { + if (this->TocTreeLink.find(line)) { std::string const& link = this->TocTreeLink.match(1); this->ProcessInclude(link + ".rst", IncludeTocTree); - } - else - { + } else { this->ProcessInclude(line + ".rst", IncludeTocTree); - } } } + } } void cmRST::UnindentLines(std::vector<std::string>& lines) @@ -436,57 +377,48 @@ void cmRST::UnindentLines(std::vector<std::string>& lines) std::string indentText; std::string::size_type indentEnd = 0; bool first = true; - for(size_t i = 1; i < lines.size(); ++i) - { + for (size_t i = 1; i < lines.size(); ++i) { std::string const& line = lines[i]; // Do not consider empty lines. - if(line.empty()) - { + if (line.empty()) { continue; - } + } // Record indentation on first non-empty line. - if(first) - { + if (first) { first = false; indentEnd = line.find_first_not_of(" \t"); indentText = line.substr(0, indentEnd); continue; - } + } // Truncate indentation to match that on this line. indentEnd = std::min(indentEnd, line.size()); - for(std::string::size_type j = 0; j != indentEnd; ++j) - { - if(line[j] != indentText[j]) - { + for (std::string::size_type j = 0; j != indentEnd; ++j) { + if (line[j] != indentText[j]) { indentEnd = j; break; - } } } + } // Update second and later lines. - for(size_t i = 1; i < lines.size(); ++i) - { + for (size_t i = 1; i < lines.size(); ++i) { std::string& line = lines[i]; - if(!line.empty()) - { + if (!line.empty()) { line = line.substr(indentEnd); - } } + } std::vector<std::string>::const_iterator it = lines.begin(); size_t leadingEmpty = std::distance(it, cmFindNot(lines, std::string())); std::vector<std::string>::const_reverse_iterator rit = lines.rbegin(); - size_t trailingEmpty = std::distance(rit, - cmFindNot(cmReverseRange(lines), std::string())); + size_t trailingEmpty = + std::distance(rit, cmFindNot(cmReverseRange(lines), std::string())); - std::vector<std::string>::iterator contentEnd - = cmRotate(lines.begin(), - lines.begin() + leadingEmpty, - lines.end() - trailingEmpty); + std::vector<std::string>::iterator contentEnd = cmRotate( + lines.begin(), lines.begin() + leadingEmpty, lines.end() - trailingEmpty); lines.erase(contentEnd, lines.end()); } |