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