• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2 Copyright (c) 2017 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 #if !defined(BOOST_QUICKBOOK_XML_PARSE_HPP)
10 #define BOOST_QUICKBOOK_XML_PARSE_HPP
11 
12 #include <list>
13 #include <string>
14 #include "string_view.hpp"
15 #include "tree.hpp"
16 
17 namespace quickbook
18 {
19     namespace detail
20     {
21         struct xml_element;
22         typedef tree<xml_element> xml_tree;
23         typedef tree_builder<xml_element> xml_tree_builder;
24         struct xml_parse_error;
25 
26         struct xml_element : tree_node<xml_element>
27         {
28             enum element_type
29             {
30                 element_node,
31                 element_text,
32                 element_html
33             } type_;
34             std::string name_;
35 
36           private:
37             std::list<std::pair<std::string, std::string> > attributes_;
38 
39           public:
40             std::string contents_;
41 
xml_elementquickbook::detail::xml_element42             explicit xml_element(element_type n) : type_(n) {}
43 
xml_elementquickbook::detail::xml_element44             explicit xml_element(element_type n, quickbook::string_view name)
45                 : type_(n), name_(name.begin(), name.end())
46             {
47             }
48 
text_nodequickbook::detail::xml_element49             static xml_element* text_node(quickbook::string_view x)
50             {
51                 xml_element* n = new xml_element(element_text);
52                 n->contents_.assign(x.begin(), x.end());
53                 return n;
54             }
55 
html_nodequickbook::detail::xml_element56             static xml_element* html_node(quickbook::string_view x)
57             {
58                 xml_element* n = new xml_element(element_html);
59                 n->contents_.assign(x.begin(), x.end());
60                 return n;
61             }
62 
nodequickbook::detail::xml_element63             static xml_element* node(quickbook::string_view x)
64             {
65                 return new xml_element(element_node, x);
66             }
67 
has_attributequickbook::detail::xml_element68             bool has_attribute(quickbook::string_view name)
69             {
70                 for (auto it = attributes_.begin(), end = attributes_.end();
71                      it != end; ++it) {
72                     if (name == it->first) {
73                         return true;
74                     }
75                 }
76                 return false;
77             }
78 
get_attributequickbook::detail::xml_element79             string_view get_attribute(quickbook::string_view name)
80             {
81                 for (auto it = attributes_.begin(), end = attributes_.end();
82                      it != end; ++it) {
83                     if (name == it->first) {
84                         return it->second;
85                     }
86                 }
87                 return string_view();
88             }
89 
set_attributequickbook::detail::xml_element90             string_view set_attribute(
91                 quickbook::string_view name, quickbook::string_view value)
92             {
93                 for (auto it = attributes_.begin(), end = attributes_.end();
94                      it != end; ++it) {
95                     if (name == it->first) {
96                         it->second.assign(value.begin(), value.end());
97                         return it->second;
98                     }
99                 }
100 
101                 attributes_.push_back(
102                     std::make_pair(name.to_s(), value.to_s()));
103                 return attributes_.back().second;
104             }
105 
get_childquickbook::detail::xml_element106             xml_element* get_child(quickbook::string_view name)
107             {
108                 for (auto it = children(); it; it = it->next()) {
109                     if (it->type_ == element_node && it->name_ == name) {
110                         return it;
111                     }
112                 }
113 
114                 return 0;
115             }
116         };
117 
118         struct xml_parse_error
119         {
120             char const* message;
121             string_iterator pos;
122 
xml_parse_errorquickbook::detail::xml_parse_error123             xml_parse_error(char const* m, string_iterator p)
124                 : message(m), pos(p)
125             {
126             }
127         };
128 
129         void write_xml_tree(xml_element*);
130         xml_tree xml_parse(quickbook::string_view);
131     }
132 }
133 
134 #endif
135