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 "document_state_impl.hpp"
11 #include <boost/range/algorithm.hpp>
17 char const* id_attributes_[] =
26 xml_processor::xml_processor()
28 static int const n_id_attributes = sizeof(id_attributes_)/sizeof(char const*);
29 for (int i = 0; i != n_id_attributes; ++i)
31 id_attributes.push_back(id_attributes_[i]);
34 boost::sort(id_attributes);
37 template <typename Iterator>
38 bool read(Iterator& it, Iterator end, char const* text)
40 for(Iterator it2 = it;; ++it2, ++text) {
46 if (it2 == end || *it2 != *text)
51 template <typename Iterator>
52 void read_past(Iterator& it, Iterator end, char const* text)
54 while (it != end && !read(it, end, text)) ++it;
57 bool find_char(char const* text, char c)
60 if (c == *text) return true;
64 template <typename Iterator>
65 void read_some_of(Iterator& it, Iterator end, char const* text)
67 while(it != end && find_char(text, *it)) ++it;
70 template <typename Iterator>
71 void read_to_one_of(Iterator& it, Iterator end, char const* text)
73 while(it != end && !find_char(text, *it)) ++it;
76 void xml_processor::parse(boost::string_ref source, callback& c)
78 typedef boost::string_ref::const_iterator iterator;
82 iterator it = source.begin(), end = source.end();
86 read_past(it, end, "<");
89 if (read(it, end, "!--quickbook-escape-prefix-->"))
91 read_past(it, end, "<!--quickbook-escape-postfix-->");
99 read_past(it, end, "?>");
103 if (read(it, end, "!--"))
104 read_past(it, end, "-->");
106 read_past(it, end, ">");
110 if ((*it >= 'a' && *it <= 'z') ||
111 (*it >= 'A' && *it <= 'Z') ||
112 *it == '_' || *it == ':')
114 read_to_one_of(it, end, " \t\n\r>");
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;
121 boost::string_ref name(name_start, it - name_start);
124 read_some_of(it, end, "= \t\n\r");
125 if (it == end || (*it != '"' && *it != '\'')) break;
130 iterator value_start = it;
132 it = std::find(it, end, delim);
133 if (it == end) break;
134 boost::string_ref value(value_start, it - value_start);
137 if (boost::find(id_attributes, detail::to_s(name))
138 != id_attributes.end())
146 read_past(it, end, ">");