]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/quickbook/src/id_xml.cpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / tools / quickbook / src / id_xml.cpp
1 /*=============================================================================
2 Copyright (c) 2011-2013 Daniel James
3
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 =============================================================================*/
8
9 #include <boost/range/algorithm.hpp>
10 #include "document_state_impl.hpp"
11 #include "utils.hpp"
12
13 namespace quickbook
14 {
15 namespace
16 {
17 char const* id_attributes_[] = {"id", "linkend", "linkends",
18 "arearefs"};
19 }
20
21 xml_processor::xml_processor()
22 {
23 static std::size_t const n_id_attributes =
24 sizeof(id_attributes_) / sizeof(char const*);
25 for (int i = 0; i != n_id_attributes; ++i) {
26 id_attributes.push_back(id_attributes_[i]);
27 }
28
29 boost::sort(id_attributes);
30 }
31
32 template <typename Iterator>
33 bool read(Iterator& it, Iterator end, char const* text)
34 {
35 for (Iterator it2 = it;; ++it2, ++text) {
36 if (!*text) {
37 it = it2;
38 return true;
39 }
40
41 if (it2 == end || *it2 != *text) return false;
42 }
43 }
44
45 template <typename Iterator>
46 void read_past(Iterator& it, Iterator end, char const* text)
47 {
48 while (it != end && !read(it, end, text))
49 ++it;
50 }
51
52 bool find_char(char const* text, char c)
53 {
54 for (; *text; ++text)
55 if (c == *text) return true;
56 return false;
57 }
58
59 template <typename Iterator>
60 void read_some_of(Iterator& it, Iterator end, char const* text)
61 {
62 while (it != end && find_char(text, *it))
63 ++it;
64 }
65
66 template <typename Iterator>
67 void read_to_one_of(Iterator& it, Iterator end, char const* text)
68 {
69 while (it != end && !find_char(text, *it))
70 ++it;
71 }
72
73 void xml_processor::parse(quickbook::string_view source, callback& c)
74 {
75 typedef string_iterator iterator;
76
77 c.start(source);
78
79 iterator it = source.begin(), end = source.end();
80
81 for (;;) {
82 read_past(it, end, "<");
83 if (it == end) break;
84
85 if (read(it, end, "!--quickbook-escape-prefix-->")) {
86 read_past(it, end, "<!--quickbook-escape-postfix-->");
87 continue;
88 }
89
90 switch (*it) {
91 case '?':
92 ++it;
93 read_past(it, end, "?>");
94 break;
95
96 case '!':
97 if (read(it, end, "!--"))
98 read_past(it, end, "-->");
99 else
100 read_past(it, end, ">");
101 break;
102
103 default:
104 if ((*it >= 'a' && *it <= 'z') || (*it >= 'A' && *it <= 'Z') ||
105 *it == '_' || *it == ':') {
106 read_to_one_of(it, end, " \t\n\r>");
107
108 for (;;) {
109 read_some_of(it, end, " \t\n\r");
110 iterator name_start = it;
111 read_to_one_of(it, end, "= \t\n\r>");
112 if (it == end || *it == '>') break;
113 quickbook::string_view name(
114 name_start, it - name_start);
115 ++it;
116
117 read_some_of(it, end, "= \t\n\r");
118 if (it == end || (*it != '"' && *it != '\'')) break;
119
120 char delim = *it;
121 ++it;
122
123 iterator value_start = it;
124
125 it = std::find(it, end, delim);
126 if (it == end) break;
127 quickbook::string_view value(
128 value_start, it - value_start);
129 ++it;
130
131 if (boost::find(id_attributes, name.to_s()) !=
132 id_attributes.end()) {
133 c.id_value(value);
134 }
135 }
136 }
137 else {
138 read_past(it, end, ">");
139 }
140 }
141 }
142
143 c.finish(source);
144 }
145
146 namespace detail
147 {
148 std::string linkify(
149 quickbook::string_view source, quickbook::string_view linkend)
150 {
151 typedef string_iterator iterator;
152
153 iterator it = source.begin(), end = source.end();
154
155 bool contains_link = false;
156
157 for (; !contains_link;) {
158 read_past(it, end, "<");
159 if (it == end) break;
160
161 switch (*it) {
162 case '?':
163 ++it;
164 read_past(it, end, "?>");
165 break;
166
167 case '!':
168 if (read(it, end, "!--")) {
169 read_past(it, end, "-->");
170 }
171 else {
172 read_past(it, end, ">");
173 }
174 break;
175
176 default:
177 if ((*it >= 'a' && *it <= 'z') ||
178 (*it >= 'A' && *it <= 'Z') || *it == '_' ||
179 *it == ':') {
180 iterator tag_name_start = it;
181 read_to_one_of(it, end, " \t\n\r>");
182 quickbook::string_view tag_name(
183 tag_name_start, it - tag_name_start);
184 if (tag_name == "link") {
185 contains_link = true;
186 }
187
188 for (;;) {
189 read_to_one_of(it, end, "\"'\n\r>");
190 if (it == end || *it == '>') break;
191 if (*it == '"' || *it == '\'') {
192 char delim = *it;
193 ++it;
194 it = std::find(it, end, delim);
195 if (it == end) break;
196 ++it;
197 }
198 }
199 }
200 else {
201 read_past(it, end, ">");
202 }
203 }
204 }
205
206 std::string result;
207
208 if (!contains_link) {
209 result += "<link linkend=\"";
210 result.append(linkend.begin(), linkend.end());
211 result += "\">";
212 result.append(source.begin(), source.end());
213 result += "</link>";
214 }
215 else {
216 result.append(source.begin(), source.end());
217 }
218
219 return result;
220 }
221 }
222 }