Skip to content

Commit

Permalink
Avoid duplicate anchors (#159)
Browse files Browse the repository at this point in the history
Fixes #158

Signed-off-by: Dave Thaler <[email protected]>
  • Loading branch information
dthaler authored Feb 29, 2024
1 parent e8f151d commit 9ced488
Show file tree
Hide file tree
Showing 3 changed files with 197 additions and 28 deletions.
53 changes: 44 additions & 9 deletions lib/rst2rfcxml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,33 @@ _replace_all(string line, string from, string to)
return line;
}

string
rst2rfcxml::define_anchor(string value)
{
string anchor;
if (_anchors.find(value) == _anchors.end()) {
// Create a new anchor.
anchor = _anchor(value);
} else {
// This is a duplicate anchor definition so create a new one and
// map all future lookups to this latest one.
anchor = _anchors[value] + "-";
}
_anchors[value] = anchor;
return anchor;
}

string
rst2rfcxml::lookup_anchor(string value)
{
if (_anchors.find(value) != _anchors.end()) {
return _anchors[value];
}

// Undefined anchor.
return _anchor(value);
}

string
rst2rfcxml::replace_term_links(string line)
{
Expand All @@ -325,7 +352,7 @@ rst2rfcxml::replace_term_links(string line)
term = middle.substr(label_end + 4, term_end - label_end - 4);
}

line = fmt::format("{}<xref target=\"term-{}\">{}</xref>{}", before, _anchor(term), label, after);
line = fmt::format("{}<xref target=\"{}\">{}</xref>{}", before, lookup_anchor("term-" + term), label, after);
}
return line;
}
Expand Down Expand Up @@ -425,7 +452,7 @@ rst2rfcxml::replace_reference_links(string line)
}
}

line = fmt::format("{}<xref target=\"{}\">{}</xref>{}", before, _anchor(middle), middle, after);
line = fmt::format("{}<xref target=\"{}\">{}</xref>{}", before, lookup_anchor(middle), middle, after);
}
return line;
}
Expand Down Expand Up @@ -802,11 +829,14 @@ rst2rfcxml::handle_section_title(int level, string marker, string current, strin
push_context(output_stream, xml_context::MIDDLE);
}
string title = handle_escapes_and_links(current);
push_context(
output_stream,
xml_context::SECTION,
current_indentation,
fmt::format("anchor=\"{}\" title=\"{}\"", _anchor(title), title));
string anchor = define_anchor(title);
string attributes;
if (anchor.empty()) {
attributes = fmt::format("title=\"{}\"", title);
} else {
attributes = fmt::format("anchor=\"{}\" title=\"{}\"", anchor, title);
}
push_context(output_stream, xml_context::SECTION, current_indentation, attributes);
return true;
}
if (current.starts_with(marker) && current.find_first_not_of(marker, 0) == string::npos &&
Expand Down Expand Up @@ -972,8 +1002,13 @@ rst2rfcxml::process_line(string current, string next, ostream& output_stream)
if (!in_context(xml_context::DEFINITION_LIST)) {
push_context(output_stream, xml_context::DEFINITION_LIST, current_indentation);
}
string attributes = fmt::format("anchor=\"term-{}\"", _anchor(_trim(current)));
push_context(output_stream, xml_context::DEFINITION_TERM, current_indentation, attributes);
string anchor = define_anchor("term-" + _trim(current));
if (anchor.empty()) {
push_context(output_stream, xml_context::DEFINITION_TERM, current_indentation);
} else {
string attributes = fmt::format("anchor=\"{}\"", anchor);
push_context(output_stream, xml_context::DEFINITION_TERM, current_indentation, attributes);
}
}

// Handle artwork.
Expand Down
5 changes: 5 additions & 0 deletions lib/rst2rfcxml.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ class rst2rfcxml
std::string
replace_term_links(std::string line);
std::string
define_anchor(std::string term);
std::string
lookup_anchor(std::string term);
std::string
handle_escapes_and_links(std::string line);
void
output_table_row(std::ostream& output_stream);
Expand All @@ -140,6 +144,7 @@ class rst2rfcxml
std::string _ipr;
std::string _category;
std::vector<size_t> _column_indices;
std::map<std::string, std::string> _anchors;
std::map<std::string, author> _authors;
std::string _submission_type;
std::string _abbreviated_title;
Expand Down
167 changes: 148 additions & 19 deletions test/basic_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,25 @@

using namespace std;

constexpr const char* BASIC_PREAMBLE = R"(<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt"?>
<!-- generated by https://github.com/dthaler/rst2rfcxml version 0.1 -->
<!DOCTYPE rfc [
]>
<?rfc rfcedstyle="yes"?>
<?rfc toc="yes"?>
<?rfc tocindent="yes"?>
<?rfc sortrefs="yes"?>
<?rfc symrefs="yes"?>
<?rfc strict="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc text-list-symbols="-o*+"?>
<?rfc docmapping="yes"?>
)";

void
test_rst2rfcxml(const char* input, const char* expected_output)
{
Expand Down Expand Up @@ -99,6 +118,40 @@ TEST_CASE("titles", "[basic]")
test_rst2rfcxml("Foo\n~~~\n", "<section anchor=\"foo\" title=\"Foo\">\n</section>\n");
}

TEST_CASE("duplicate titles", "[basic]")
{
test_rst2rfcxml(
R"(.. header::
foo
===
bar
foo
===
baz
)", (std::string(BASIC_PREAMBLE) + R"(
<rfc ipr="" docName="" category="" submissionType="">
<front>
</front>
<middle>
<section anchor="foo" title="foo">
<t>
bar
</t>
</section>
<section anchor="foo-" title="foo">
<t>
baz
</t>
</section>
</middle>
</rfc>
)").c_str());
}

TEST_CASE("line block", "[basic]")
{
test_rst2rfcxml(
Expand Down Expand Up @@ -315,6 +368,101 @@ baz :term:`foo-ish<foo>` baz
)");
}

TEST_CASE("definition list duplication", "[basic]")
{
test_rst2rfcxml(
R"(
foo
description
bar
description
baz :term:`foo-ish<foo>` baz
foo
description 2
bar
description 2
baz :term:`foo-ish<foo>` baz
foo
description 3
bar
description 3
baz :term:`foo-ish<foo>` baz
)",
R"(<dl>
<dt anchor="term-foo">
foo
</dt>
<dd>
<t>
description
</t>
</dd>
<dt anchor="term-bar">
bar
</dt>
<dd>
<t>
description
</t>
</dd>
</dl>
<t>
baz <xref target="term-foo">foo-ish</xref> baz
</t>
<dl>
<dt anchor="term-foo-">
foo
</dt>
<dd>
<t>
description 2
</t>
</dd>
<dt anchor="term-bar-">
bar
</dt>
<dd>
<t>
description 2
</t>
</dd>
</dl>
<t>
baz <xref target="term-foo-">foo-ish</xref> baz
</t>
<dl>
<dt anchor="term-foo--">
foo
</dt>
<dd>
<t>
description 3
</t>
</dd>
<dt anchor="term-bar--">
bar
</dt>
<dd>
<t>
description 3
</t>
</dd>
</dl>
<t>
baz <xref target="term-foo--">foo-ish</xref> baz
</t>
)");
}

TEST_CASE("definition list with glossary label", "[basic]")
{
test_rst2rfcxml(
Expand Down Expand Up @@ -775,25 +923,6 @@ Paragraph two.
)");
}

constexpr const char* BASIC_PREAMBLE = R"(<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt"?>
<!-- generated by https://github.com/dthaler/rst2rfcxml version 0.1 -->
<!DOCTYPE rfc [
]>
<?rfc rfcedstyle="yes"?>
<?rfc toc="yes"?>
<?rfc tocindent="yes"?>
<?rfc sortrefs="yes"?>
<?rfc symrefs="yes"?>
<?rfc strict="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc text-list-symbols="-o*+"?>
<?rfc docmapping="yes"?>
)";

TEST_CASE("empty header", "[basic]")
{
string expected_output = BASIC_PREAMBLE;
Expand Down

0 comments on commit 9ced488

Please sign in to comment.