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 #if !defined(BOOST_QUICKBOOK_DOCUMENT_STATE_IMPL_HPP)
10 #define BOOST_QUICKBOOK_DOCUMENT_STATE_IMPL_HPP
11 
12 #include <deque>
13 #include <string>
14 #include <vector>
15 #include <boost/shared_ptr.hpp>
16 #include "document_state.hpp"
17 #include "phrase_tags.hpp"
18 #include "string_view.hpp"
19 #include "utils.hpp"
20 
21 namespace quickbook
22 {
23     //
24     // id_placeholder
25     //
26     // When generating the xml, quickbook can't allocate the identifiers until
27     // the end, so it stores in the intermedia xml a placeholder string,
28     // e.g. id="$1". This represents one of these placeholders.
29     //
30 
31     struct id_placeholder
32     {
33         std::size_t index; // The index in document_state_impl::placeholders.
34                            // Use for the dollar identifiers in
35                            // intermediate xml.
36         std::string id;    // The node id.
37         std::string unresolved_id;
38         // The id that would be generated
39         // without any duplicate handling.
40         // Used for generating old style header anchors.
41         id_placeholder const* parent;
42         // Placeholder of the parent id.
43         id_category category;
44         std::ptrdiff_t num_dots; // Number of dots in the id.
45                                  // Normally equal to the section level
46                                  // but not when an explicit id contains
47                                  // dots.
48 
49         id_placeholder(
50             std::size_t index,
51             quickbook::string_view id,
52             id_category category,
53             id_placeholder const* parent_);
54 
55         std::string to_string() const;
56     };
57 
58     //
59     // document_state_impl
60     //
61     // Contains all the data tracked by document_state.
62     //
63 
64     struct file_info;
65     struct doc_info;
66     struct section_info;
67 
68     struct document_state_impl
69     {
70         boost::shared_ptr<file_info> current_file;
71         std::deque<id_placeholder> placeholders;
72 
73         // Placeholder methods
74 
75         id_placeholder const* add_placeholder(
76             quickbook::string_view,
77             id_category,
78             id_placeholder const* parent = 0);
79 
80         id_placeholder const* get_placeholder(quickbook::string_view) const;
81 
82         id_placeholder const* get_id_placeholder(
83             boost::shared_ptr<section_info> const& section) const;
84 
85         // Events
86 
87         id_placeholder const* start_file(
88             unsigned compatibility_version,
89             bool document_root,
90             quickbook::string_view include_doc_id,
91             quickbook::string_view id,
92             value const& title);
93 
94         void end_file();
95 
96         id_placeholder const* add_id(
97             quickbook::string_view id, id_category category);
98         id_placeholder const* old_style_id(
99             quickbook::string_view id, id_category category);
100         id_placeholder const* begin_section(
101             value const& explicit_id,
102             quickbook::string_view id,
103             id_category category,
104             source_mode_info const&);
105         void end_section();
106 
107       private:
108         id_placeholder const* add_id_to_section(
109             quickbook::string_view id,
110             id_category category,
111             boost::shared_ptr<section_info> const& section);
112         id_placeholder const* create_new_section(
113             value const& explicit_id,
114             quickbook::string_view id,
115             id_category category,
116             source_mode_info const&);
117     };
118 
119     std::string replace_ids(
120         document_state_impl const& state,
121         quickbook::string_view xml,
122         std::vector<std::string> const* = 0);
123     std::vector<std::string> generate_ids(
124         document_state_impl const&, quickbook::string_view);
125 
126     std::string normalize_id(quickbook::string_view src_id);
127     std::string normalize_id(quickbook::string_view src_id, std::size_t);
128 
129     //
130     // Xml subset parser used for finding id values.
131     //
132     // I originally tried to integrate this into the post processor
133     // but that proved tricky. Alternatively it could use a proper
134     // xml parser, but I want this to be able to survive badly
135     // marked up escapes.
136     //
137 
138     struct xml_processor
139     {
140         xml_processor();
141 
142         std::vector<std::string> id_attributes;
143 
144         struct callback
145         {
startquickbook::xml_processor::callback146             virtual void start(quickbook::string_view) {}
id_valuequickbook::xml_processor::callback147             virtual void id_value(quickbook::string_view) {}
finishquickbook::xml_processor::callback148             virtual void finish(quickbook::string_view) {}
~callbackquickbook::xml_processor::callback149             virtual ~callback() {}
150         };
151 
152         void parse(quickbook::string_view, callback&);
153     };
154 }
155 
156 #endif
157