mirror of
https://github.com/boostorg/quickbook.git
synced 2026-01-19 04:22:16 +00:00
Try to be smarter about adding links to section titles
When adding links, don't add them around other links. If there's anything outside of existing links, they'll still get linked. Although, maybe it would be better to only add link tags when the title doesn't contain any links. This might be over-complicated and confusing.
This commit is contained in:
@@ -1754,10 +1754,7 @@ namespace quickbook
|
||||
|
||||
if (self_linked_headers && state.document.compatibility_version() >= 103)
|
||||
{
|
||||
state.out << "<link linkend=\"" << full_id << "\">"
|
||||
<< content.get_encoded()
|
||||
<< "</link>"
|
||||
;
|
||||
state.out << quickbook::detail::linkify(content.get_encoded(), full_id);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
123
src/id_xml.cpp
123
src/id_xml.cpp
@@ -150,4 +150,127 @@ namespace quickbook
|
||||
|
||||
c.finish(source);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
std::string linkify(quickbook::string_view source, quickbook::string_view linkend)
|
||||
{
|
||||
typedef quickbook::string_view::const_iterator iterator;
|
||||
|
||||
std::string result;
|
||||
|
||||
iterator it = source.begin(), end = source.end();
|
||||
|
||||
int link_depth = 0;
|
||||
iterator start = it;
|
||||
read_some_of(it, end, " \t\n\r");
|
||||
result.append(start, it);
|
||||
start = it;
|
||||
// If the source is empty, we'll still create an empty link tag
|
||||
// to avoid gratuitous changes in generated output, need to track
|
||||
// that special case.
|
||||
bool empty = true;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
read_to_one_of(it, end, "<");
|
||||
if (it == end) break;
|
||||
iterator tag_start = it;
|
||||
++it;
|
||||
if (it == end) break;
|
||||
|
||||
if (read(it, end, "!--quickbook-escape-prefix-->"))
|
||||
{
|
||||
read_past(it, end, "<!--quickbook-escape-postfix-->");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(*it)
|
||||
{
|
||||
case '?':
|
||||
++it;
|
||||
read_past(it, end, "?>");
|
||||
break;
|
||||
|
||||
case '!':
|
||||
if (read(it, end, "!--")) {
|
||||
read_past(it, end, "-->");
|
||||
} else {
|
||||
read_past(it, end, ">");
|
||||
}
|
||||
break;
|
||||
|
||||
case '/':
|
||||
{
|
||||
++it;
|
||||
read_some_of(it, end, " \t\n\r");
|
||||
if (it == end) { break; }
|
||||
iterator tag_name_start = it;
|
||||
read_to_one_of(it, end, " \t\n\r>");
|
||||
quickbook::string_view tag_name(tag_name_start, it - tag_name_start);
|
||||
read_past(it, end, ">");
|
||||
|
||||
if (tag_name == "link") {
|
||||
if (link_depth > 0) { --link_depth; }
|
||||
if (link_depth == 0) {
|
||||
read_some_of(it, end, " \t\n\r");
|
||||
result.append(start, it);
|
||||
start = it;
|
||||
empty = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((*it >= 'a' && *it <= 'z') ||
|
||||
(*it >= 'A' && *it <= 'Z') ||
|
||||
*it == '_' || *it == ':')
|
||||
{
|
||||
iterator tag_name_start = it;
|
||||
read_to_one_of(it, end, " \t\n\r>");
|
||||
quickbook::string_view tag_name(tag_name_start, it - tag_name_start);
|
||||
|
||||
if (tag_name == "link") {
|
||||
if (link_depth == 0 && start != tag_start) {
|
||||
result += "<link linkend=\"";
|
||||
result .append(linkend.begin(), linkend.end());
|
||||
result += "\">";
|
||||
result.append(start, tag_start);
|
||||
result += "</link>";
|
||||
start = tag_start;
|
||||
empty = false;
|
||||
}
|
||||
++link_depth;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
read_to_one_of(it, end, "\"'\n\r>");
|
||||
if (it == end || *it == '>') break;
|
||||
if (*it == '"' || *it == '\'') {
|
||||
char delim = *it;
|
||||
++it;
|
||||
it = std::find(it, end, delim);
|
||||
if (it == end) break;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
read_past(it, end, ">");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (start != it || empty) {
|
||||
result += "<link linkend=\"";
|
||||
result.append(linkend.begin(), linkend.end());
|
||||
result += "\">";
|
||||
result.append(start, it);
|
||||
result += "</link>";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,9 @@ namespace quickbook { namespace detail {
|
||||
inline std::string to_s(quickbook::string_view x) {
|
||||
return std::string(x.begin(), x.end());
|
||||
}
|
||||
|
||||
// Defined in id_xml.cpp. Just because.
|
||||
std::string linkify(quickbook::string_view source, quickbook::string_view linkend);
|
||||
}}
|
||||
|
||||
#endif // BOOST_SPIRIT_QUICKBOOK_UTILS_HPP
|
||||
|
||||
@@ -23,4 +23,11 @@
|
||||
<section id="section_id_1_7.sect-abc">
|
||||
<title><link linkend="section_id_1_7.sect-abc">Section with template in id</link></title>
|
||||
</section>
|
||||
<section id="section_id_1_7.link_section_id_1_7_id_test1_lin">
|
||||
<title><link linkend="section_id_1_7.id_test1">Link in title</link></title>
|
||||
</section>
|
||||
<section id="section_id_1_7.link_section_id_1_7_id_test1_li0">
|
||||
<title><link linkend="section_id_1_7.id_test1">Link</link> <link linkend="section_id_1_7.link_section_id_1_7_id_test1_li0">in
|
||||
title</link></title>
|
||||
</section>
|
||||
</article>
|
||||
|
||||
@@ -16,3 +16,8 @@
|
||||
[template thing[] abc]
|
||||
[section:sect-[thing] Section with template in id]
|
||||
[endsect]
|
||||
|
||||
[section [link section_id_1_7.id_test1 Link in title]]
|
||||
[endsect]
|
||||
[section [link section_id_1_7.id_test1 Link] in title]
|
||||
[endsect]
|
||||
|
||||
@@ -22,6 +22,7 @@ run values_test.cpp ../../src/values.cpp ../../src/files.cpp ;
|
||||
run post_process_test.cpp ../../src/post_process.cpp ;
|
||||
run source_map_test.cpp ../../src/files.cpp ;
|
||||
run glob_test.cpp ../../src/glob.cpp ;
|
||||
run linkify_test.cpp ../../src/id_xml.cpp ;
|
||||
# TODO: Reinstate this test? Too painful to run at the moment.
|
||||
# run file_path_to_url_test.cpp ../../src/native_text.cpp ../../src/utils.cpp ;
|
||||
|
||||
|
||||
30
test/unit/linkify_test.cpp
Normal file
30
test/unit/linkify_test.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
/*=============================================================================
|
||||
Copyright (c) 2017 Daniel James
|
||||
|
||||
Use, modification and distribution is subject to the Boost Software
|
||||
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
|
||||
http://www.boost.org/LICENSE_1_0.txt)
|
||||
=============================================================================*/
|
||||
|
||||
#include "utils.hpp"
|
||||
#include <boost/detail/lightweight_test.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
void linkify_test() {
|
||||
using quickbook::detail::linkify;
|
||||
|
||||
BOOST_TEST(linkify("abc", "link") == "<link linkend=\"link\">abc</link>");
|
||||
BOOST_TEST(linkify("<link linkend=\"something\">abc</link>", "link") ==
|
||||
"<link linkend=\"something\">abc</link>");
|
||||
BOOST_TEST(linkify("abc <link linkend=\"something\">def</link>", "link") ==
|
||||
"<link linkend=\"link\">abc </link><link linkend=\"something\">def</link>");
|
||||
BOOST_TEST(linkify("<link linkend=\"something\">abc</link> def", "link") ==
|
||||
"<link linkend=\"something\">abc</link> <link linkend=\"link\">def</link>");
|
||||
}
|
||||
|
||||
int main() {
|
||||
linkify_test();
|
||||
return boost::report_errors();
|
||||
}
|
||||
Reference in New Issue
Block a user