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.
This commit is contained in:
Brad King
2018-05-03 14:48:58 -04:00
parent 5e5ef61ed3
commit 7d918b3cee
4 changed files with 67 additions and 11 deletions

View File

@@ -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 {

View File

@@ -85,6 +85,8 @@ private:
cmsys::RegularExpression NoteDirective;
cmsys::RegularExpression ModuleRST;
cmsys::RegularExpression CMakeRole;
cmsys::RegularExpression InlineLink;
cmsys::RegularExpression InlineLiteral;
cmsys::RegularExpression Substitution;
cmsys::RegularExpression TocTreeLink;

View File

@@ -19,6 +19,10 @@ Variable ``VARIABLE_<PLACEHOLDER>`` with trailing placeholder and target.
Environment variable ``SOME_ENV_VAR``.
Environment variable ``some env var`` with space and target.
Generator ``Some Generator`` with space.
Inline literal ``~!@#$%^&*( )_+-=\\[]{}'":;,<>.?/``.
Inline link Link Text.
Inline link Link Text <With \-escaped Brackets>.
Inline literal ``__`` followed by inline link Link Text.
First TOC entry.

View File

@@ -26,6 +26,10 @@ Variable :variable:`VARIABLE_<PLACEHOLDER> <target>` with trailing placeholder a
Environment variable :envvar:`SOME_ENV_VAR`.
Environment variable :envvar:`some env var <SOME_ENV_VAR>` with space and target.
Generator :generator:`Some Generator` with space.
Inline literal ``~!@#$%^&*( )_+-=\\[]{}'":;,<>.?/``.
Inline link `Link Text <ExternalDest>`_.
Inline link `Link Text \<With \\-escaped Brackets\> <ExternalDest>`_.
Inline literal ``__`` followed by inline link `Link Text <InternalDest_>`_.
.. |not replaced| replace:: not replaced through toctree
.. |not replaced in literal| replace:: replaced in parsed literal