id_placeholder* id_state::add_id( std::string const& id, id_category category) { return add_id_to_section(id, category, current_file->document->current_section); }
id_placeholder const* document_state_impl::add_id( boost::string_ref id, id_category category) { return add_id_to_section(id, category, current_file->document->current_section); }
id_placeholder const* document_state_impl::create_new_section( boost::string_ref id, id_category category, source_mode_info const& source_mode) { boost::shared_ptr<section_info> parent = current_file->document->current_section; id_placeholder const* p = 0; id_placeholder const* placeholder_1_6 = 0; std::string id_1_1; if (parent && current_file->compatibility_version < 106u) { id_1_1 = parent->id_1_1; if (!id_1_1.empty() && !id.empty()) id_1_1 += "."; id_1_1.append(id.begin(), id.end()); } if (current_file->compatibility_version >= 106u) { p = placeholder_1_6 = add_id_to_section(id, category, parent); } else if (current_file->compatibility_version >= 103u) { placeholder_1_6 = get_id_placeholder(parent); std::string new_id; if (!placeholder_1_6) { new_id = current_file->doc_id_1_1; if (!id_1_1.empty()) new_id += '.'; } new_id += id_1_1; p = add_placeholder(new_id, category, placeholder_1_6); } else { placeholder_1_6 = get_id_placeholder(parent); std::string new_id; if (parent && !placeholder_1_6) new_id = current_file->doc_id_1_1 + '.'; new_id += detail::to_s(id); p = add_placeholder(new_id, category, placeholder_1_6); } current_file->document->current_section = boost::make_shared<section_info>(parent, current_file.get(), id, id_1_1, placeholder_1_6, source_mode); return p; }
id_placeholder* id_state::create_new_section( std::string const& id, id_category category) { boost::intrusive_ptr<section_info> parent = current_file->document->current_section; boost::intrusive_ptr<section_info> new_section = new section_info(parent, current_file->compatibility_version, id); id_placeholder* p; if (new_section->compatibility_version >= 106u) { p = add_id_to_section(id, category, parent); new_section->placeholder_1_6 = p; } else if (new_section->compatibility_version >= 103u) { if (parent) new_section->placeholder_1_6 = parent->placeholder_1_6; std::string new_id; if (!new_section->placeholder_1_6) { new_id = current_file->doc_id_1_1; if (!new_section->id_1_1.empty()) new_id += '.'; } new_id += new_section->id_1_1; p = add_placeholder(new_id, category, new_section->placeholder_1_6); } else { if (parent) new_section->placeholder_1_6 = parent->placeholder_1_6; std::string new_id; if (parent && !new_section->placeholder_1_6) new_id = current_file->doc_id_1_1 + '.'; new_id += id; p = add_placeholder(new_id, category, new_section->placeholder_1_6); } current_file->document->current_section = new_section; return p; }
id_placeholder* id_state::start_file( unsigned compatibility_version, bool document_root, std::string const& include_doc_id, std::string const& id, value const& title) { // Create new file boost::intrusive_ptr<file_info> parent = current_file; if (document_root) { current_file = new file_info(parent, new doc_info(), compatibility_version); } else { current_file = new file_info(parent, compatibility_version); } // Choose specified id to use. Prefer 'include_doc_id' (the id // specified in an 'include' element) unless backwards compatibility // is required. std::string initial_doc_id; if (document_root || compatibility_version >= 106u || (parent && parent->compatibility_version >= 106u)) { initial_doc_id = !include_doc_id.empty() ? include_doc_id : id; } else { initial_doc_id = !id.empty() ? id : include_doc_id; } // Set variables used for backwards compatible id generation. // They're a bit odd because of old bugs. if (document_root || compatibility_version < 106u) { // Note: this is done for older versions even if docinfo is // otherwise ignored. if (title.check()) current_file->document->last_title_1_1 = title.get_quickbook(); current_file->doc_id_1_1 = !initial_doc_id.empty() ? initial_doc_id : detail::make_identifier(current_file->document->last_title_1_1); } else if (parent) { current_file->doc_id_1_1 = parent->doc_id_1_1; } if (document_root) { if (!initial_doc_id.empty()) { return create_new_section(id, id_category::explicit_section_id); } else if (!title.empty()) { return create_new_section( detail::make_identifier(title.get_quickbook()), id_category::generated_doc); } else if (compatibility_version >= 106u) { return create_new_section("doc", id_category::numbered); } else { return create_new_section("", id_category::generated_doc); } } else { // If an id was set for the file, then switch the current section // with a new section with this id. This will be maintained in // 'end_section' if the current section ends, and then the original // section restored in 'end_file' if (compatibility_version >= 106u && !initial_doc_id.empty()) { switch_section(add_id_to_section(initial_doc_id, id_category::explicit_section_id, boost::intrusive_ptr<section_info>())); } return 0; } }
id_placeholder const* document_state_impl::start_file( unsigned compatibility_version, bool document_root, boost::string_ref include_doc_id, boost::string_ref id, value const& title) { boost::shared_ptr<file_info> parent = current_file; assert(parent || document_root); boost::shared_ptr<doc_info> document = document_root ? boost::make_shared<doc_info>() : parent->document; // Choose specified id to use. Prefer 'include_doc_id' (the id // specified in an 'include' element) unless backwards compatibility // is required. boost::string_ref initial_doc_id; if (document_root || compatibility_version >= 106u || parent->compatibility_version >= 106u) { initial_doc_id = !include_doc_id.empty() ? include_doc_id : id; } else { initial_doc_id = !id.empty() ? id : include_doc_id; } // Work out this file's doc_id for older versions of quickbook. // A bug meant that this need to be done per file, not per // document. std::string doc_id_1_1; if (document_root || compatibility_version < 106u) { if (title.check()) document->last_title_1_1 = detail::to_s(title.get_quickbook()); doc_id_1_1 = !initial_doc_id.empty() ? detail::to_s(initial_doc_id) : detail::make_identifier(document->last_title_1_1); } else if (parent) { doc_id_1_1 = parent->doc_id_1_1; } if (document_root) { // Create new file current_file = boost::make_shared<file_info>(parent, document, compatibility_version, doc_id_1_1); // Create a section for the new document. source_mode_info default_source_mode; if (!initial_doc_id.empty()) { return create_new_section(id, id_category::explicit_section_id, default_source_mode); } else if (!title.empty()) { return create_new_section( detail::make_identifier(title.get_quickbook()), id_category::generated_doc, default_source_mode); } else if (compatibility_version >= 106u) { return create_new_section("doc", id_category::numbered, default_source_mode); } else { return create_new_section("", id_category::generated_doc, default_source_mode); } } else { // If an id was set for the file, then the file overrides the // current section's id with this id. // // Don't do this for document_root as it will create a section // for the document. // // Don't do this for older versions, as they use a different // backwards compatible mechanism to handle file ids. id_placeholder const* override_id = 0; if (!initial_doc_id.empty() && compatibility_version >= 106u) { boost::shared_ptr<section_info> null_section; override_id = add_id_to_section(initial_doc_id, id_category::explicit_section_id, null_section); } // Create new file current_file = boost::make_shared<file_info>(parent, compatibility_version, doc_id_1_1, override_id); return 0; } }