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 "document_state.hpp" 13 #include "phrase_tags.hpp" 14 #include "utils.hpp" 15 #include <boost/utility/string_ref.hpp> 16 #include <boost/shared_ptr.hpp> 17 #include <deque> 18 #include <string> 19 #include <vector> 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 unsigned index; // The index in document_state_impl::placeholders. 34 // Use for the dollar identifiers in 35 // intermediate xml. 36 std::string unresolved_id; 37 // The id that would be generated 38 // without any duplicate handling. 39 // Used for generating old style header anchors. 40 std::string id; // The node id. 41 id_placeholder const* parent; 42 // Placeholder of the parent id. 43 id_category category; 44 unsigned 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(unsigned index, boost::string_ref id, 50 id_category category, id_placeholder const* parent_); 51 52 std::string to_string() const; 53 }; 54 55 // 56 // document_state_impl 57 // 58 // Contains all the data tracked by document_state. 59 // 60 61 struct file_info; 62 struct doc_info; 63 struct section_info; 64 65 struct document_state_impl 66 { 67 boost::shared_ptr<file_info> current_file; 68 std::deque<id_placeholder> placeholders; 69 70 // Placeholder methods 71 72 id_placeholder const* add_placeholder(boost::string_ref, id_category, 73 id_placeholder const* parent = 0); 74 75 id_placeholder const* get_placeholder(boost::string_ref) const; 76 77 id_placeholder const* get_id_placeholder( 78 boost::shared_ptr<section_info> const& section) const; 79 80 // Events 81 82 id_placeholder const* start_file( 83 unsigned compatibility_version, 84 bool document_root, 85 boost::string_ref include_doc_id, 86 boost::string_ref id, 87 value const& title); 88 89 void end_file(); 90 91 id_placeholder const* add_id( 92 boost::string_ref id, 93 id_category category); 94 id_placeholder const* old_style_id( 95 boost::string_ref id, 96 id_category category); 97 id_placeholder const* begin_section( 98 boost::string_ref id, 99 id_category category, 100 source_mode_info const&); 101 void end_section(); 102 103 private: 104 id_placeholder const* add_id_to_section( 105 boost::string_ref id, 106 id_category category, 107 boost::shared_ptr<section_info> const& section); 108 id_placeholder const* create_new_section( 109 boost::string_ref id, 110 id_category category, 111 source_mode_info const&); 112 }; 113 114 std::string replace_ids(document_state_impl const& state, boost::string_ref xml, 115 std::vector<std::string> const* = 0); 116 std::vector<std::string> generate_ids(document_state_impl const&, boost::string_ref); 117 118 std::string normalize_id(boost::string_ref src_id); 119 std::string normalize_id(boost::string_ref src_id, std::size_t); 120 121 // 122 // Xml subset parser used for finding id values. 123 // 124 // I originally tried to integrate this into the post processor 125 // but that proved tricky. Alternatively it could use a proper 126 // xml parser, but I want this to be able to survive badly 127 // marked up escapes. 128 // 129 130 struct xml_processor 131 { 132 xml_processor(); 133 134 std::vector<std::string> id_attributes; 135 136 struct callback { startquickbook::xml_processor::callback137 virtual void start(boost::string_ref) {} id_valuequickbook::xml_processor::callback138 virtual void id_value(boost::string_ref) {} finishquickbook::xml_processor::callback139 virtual void finish(boost::string_ref) {} ~callbackquickbook::xml_processor::callback140 virtual ~callback() {} 141 }; 142 143 void parse(boost::string_ref, callback&); 144 }; 145 } 146 147 #endif 148