summaryrefslogtreecommitdiffstats
path: root/Source/cmRST.cxx
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2018-05-03 18:48:58 (GMT)
committerBrad King <brad.king@kitware.com>2018-05-07 14:10:37 (GMT)
commit7d918b3cee64961a1ed5e9c5a28f29cf0e48c130 (patch)
tree47dcff99686a84d3a87af3e6d4ad8230c93e528f /Source/cmRST.cxx
parent5e5ef61ed3b5808dfe1a71623ec12c451d7fe385 (diff)
downloadCMake-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.cxx68
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 {