diff options
author | Brad King <brad.king@kitware.com> | 2018-05-03 18:48:58 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2018-05-07 14:10:37 (GMT) |
commit | 7d918b3cee64961a1ed5e9c5a28f29cf0e48c130 (patch) | |
tree | 47dcff99686a84d3a87af3e6d4ad8230c93e528f /Source/cmRST.cxx | |
parent | 5e5ef61ed3b5808dfe1a71623ec12c451d7fe385 (diff) | |
download | CMake-7d918b3cee64961a1ed5e9c5a28f29cf0e48c130.zip CMake-7d918b3cee64961a1ed5e9c5a28f29cf0e48c130.tar.gz CMake-7d918b3cee64961a1ed5e9c5a28f29cf0e48c130.tar.bz2 |
cmRST: Parse inline links and inline literals
Render links as the link text only. Render literals as themselves.
This is closer to what the Sphinx text generator does.
Diffstat (limited to 'Source/cmRST.cxx')
-rw-r--r-- | Source/cmRST.cxx | 68 |
1 files changed, 57 insertions, 11 deletions
diff --git a/Source/cmRST.cxx b/Source/cmRST.cxx index edcbc22..d9e5bcb 100644 --- a/Source/cmRST.cxx +++ b/Source/cmRST.cxx @@ -39,6 +39,8 @@ cmRST::cmRST(std::ostream& os, std::string const& docroot) "prop_test|prop_tgt|" "manual" "):`(<*([^`<]|[^` \t]<)*)([ \t]+<[^`]*>)?`") + , InlineLink("`(<*([^`<]|[^` \t]<)*)([ \t]+<[^`]*>)?`_") + , InlineLiteral("``([^`]*)``") , Substitution("(^|[^A-Za-z0-9_])" "((\\|[^| \t\r\n]([^|\r\n]*[^| \t\r\n])?\\|)(__|_|))" "([^A-Za-z0-9_]|$)") @@ -245,18 +247,62 @@ void cmRST::OutputLine(std::string const& line_in, bool inlineMarkup) if (inlineMarkup) { std::string line = this->ReplaceSubstitutions(line_in); std::string::size_type pos = 0; - 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("()") == std::string::npos) { - text += "()"; + for (;;) { + std::string::size_type* first = nullptr; + std::string::size_type role_start = std::string::npos; + std::string::size_type link_start = std::string::npos; + std::string::size_type lit_start = std::string::npos; + if (this->CMakeRole.find(line.c_str() + pos)) { + role_start = this->CMakeRole.start(); + first = &role_start; + } + if (this->InlineLiteral.find(line.c_str() + pos)) { + lit_start = this->InlineLiteral.start(); + if (!first || lit_start < *first) { + first = &lit_start; + } + } + if (this->InlineLink.find(line.c_str() + pos)) { + link_start = this->InlineLink.start(); + if (!first || link_start < *first) { + first = &link_start; + } + } + if (first == &role_start) { + this->OS << line.substr(pos, role_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("()") == std::string::npos) { + text += "()"; + } + this->OS << "``" << text << "``"; + pos += this->CMakeRole.end(); + } else if (first == &lit_start) { + this->OS << line.substr(pos, lit_start); + std::string text = this->InlineLiteral.match(1); + pos += this->InlineLiteral.end(); + this->OS << "``" << text << "``"; + } else if (first == &link_start) { + this->OS << line.substr(pos, link_start); + std::string text = this->InlineLink.match(1); + bool escaped = false; + for (char c : text) { + if (escaped) { + escaped = false; + this->OS << c; + } else if (c == '\\') { + escaped = true; + } else { + this->OS << c; + } + } + pos += this->InlineLink.end(); + } else { + break; } - this->OS << "``" << text << "``"; - pos += this->CMakeRole.end(); } this->OS << line.substr(pos) << "\n"; } else { |