1 /*=============================================================================
2 Copyright (c) 2011-2013 Daniel James
4 Use, modification and distribution is subject to the Boost Software
5 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
9 #include <boost/range/algorithm/find.hpp>
10 #include <boost/range/algorithm/sort.hpp>
11 #include "document_state_impl.hpp"
12 #include "simple_parse.hpp"
19 char const* id_attributes_[] = {"id", "linkend", "linkends",
23 xml_processor::xml_processor()
25 static std::size_t const n_id_attributes =
26 sizeof(id_attributes_) / sizeof(char const*);
27 for (int i = 0; i != n_id_attributes; ++i) {
28 id_attributes.push_back(id_attributes_[i]);
31 boost::sort(id_attributes);
34 void xml_processor::parse(quickbook::string_view source, callback& c)
36 typedef string_iterator iterator;
40 iterator it = source.begin(), end = source.end();
43 read_past(it, end, "<");
46 if (read(it, end, "!--quickbook-escape-prefix-->")) {
47 read_past(it, end, "<!--quickbook-escape-postfix-->");
54 read_past(it, end, "?>");
58 if (read(it, end, "!--"))
59 read_past(it, end, "-->");
61 read_past(it, end, ">");
65 if ((*it >= 'a' && *it <= 'z') || (*it >= 'A' && *it <= 'Z') ||
66 *it == '_' || *it == ':') {
67 read_to_one_of(it, end, " \t\n\r>");
70 read_some_of(it, end, " \t\n\r");
71 iterator name_start = it;
72 read_to_one_of(it, end, "= \t\n\r>");
73 if (it == end || *it == '>') break;
74 quickbook::string_view name(
75 name_start, it - name_start);
78 read_some_of(it, end, "= \t\n\r");
79 if (it == end || (*it != '"' && *it != '\'')) break;
84 iterator value_start = it;
86 it = std::find(it, end, delim);
88 quickbook::string_view value(
89 value_start, it - value_start);
92 if (boost::find(id_attributes, name.to_s()) !=
93 id_attributes.end()) {
99 read_past(it, end, ">");
110 quickbook::string_view source, quickbook::string_view linkend)
112 typedef string_iterator iterator;
114 iterator it = source.begin(), end = source.end();
116 bool contains_link = false;
118 for (; !contains_link;) {
119 read_past(it, end, "<");
120 if (it == end) break;
125 read_past(it, end, "?>");
129 if (read(it, end, "!--")) {
130 read_past(it, end, "-->");
133 read_past(it, end, ">");
138 if ((*it >= 'a' && *it <= 'z') ||
139 (*it >= 'A' && *it <= 'Z') || *it == '_' ||
141 iterator tag_name_start = it;
142 read_to_one_of(it, end, " \t\n\r>");
143 quickbook::string_view tag_name(
144 tag_name_start, it - tag_name_start);
145 if (tag_name == "link") {
146 contains_link = true;
150 read_to_one_of(it, end, "\"'\n\r>");
151 if (it == end || *it == '>') break;
152 if (*it == '"' || *it == '\'') {
155 it = std::find(it, end, delim);
156 if (it == end) break;
162 read_past(it, end, ">");
169 if (!contains_link) {
170 result += "<link linkend=\"";
171 result.append(linkend.begin(), linkend.end());
173 result.append(source.begin(), source.end());
177 result.append(source.begin(), source.end());