📄 actions.cpp
字号:
} if (section_level == 0) { qualified_section_id.clear(); } else { std::string::size_type const n = qualified_section_id.find_last_of('.'); BOOST_ASSERT(std::string::npos != n); qualified_section_id.erase(n, std::string::npos); } } fs::path path_difference(fs::path const& outdir, fs::path const& path) { fs::path outtmp, temp; fs::path::iterator out = outdir.begin(), file = path.begin(); for(; out != outdir.end() && file != path.end(); ++out, ++file) { if(!fs::equivalent(outtmp /= *out, temp /= *file)) break; } std::divides<fs::path> concat; out = (out == outdir.begin()) ? outdir.end() : out; temp = std::accumulate(out, outdir.end(), fs::path(), boost::bind(concat, _1, "..")); return std::accumulate(file, path.end(), temp, concat); } fs::path calculate_relative_path( iterator first, iterator last, quickbook::actions& actions) { // Given a source file and the current filename, calculate the // path to the source file relative to the output directory. fs::path path(std::string(first, last)); if (!path.is_complete()) { fs::path infile = fs::complete(actions.filename).normalize(); path = (infile.branch_path() / path).normalize(); fs::path outdir = fs::complete(actions.outdir).normalize(); path = path_difference(outdir, path); } return path; } void xinclude_action::operator()(iterator first, iterator last) const { fs::path path = calculate_relative_path(first, last, actions); out << "\n<xi:include href=\""; detail::print_string(detail::escape_uri(path.string()), out.get()); out << "\" />\n"; } void cpp_code_snippet_grammar::pass_thru(iterator first, iterator last) const { code += *first; } namespace detail { int callout_id = 0; } void cpp_code_snippet_grammar::callout(iterator first, iterator last, char const* role) const { using detail::callout_id; code += "``'''"; code += std::string("<phrase role=\"") + role + "\">"; code += "<co id=\""; code += doc_id + boost::lexical_cast<std::string>(callout_id + callouts.size()) + "co\" "; code += "linkends=\""; code += doc_id + boost::lexical_cast<std::string>(callout_id + callouts.size()) + "\" />"; code += "</phrase>"; code += "'''``"; callouts.push_back(std::string(first, last)); } void cpp_code_snippet_grammar::inline_callout(iterator first, iterator last) const { callout(first, last, "callout_bug"); } void cpp_code_snippet_grammar::line_callout(iterator first, iterator last) const { callout(first, last, "line_callout_bug"); } void cpp_code_snippet_grammar::escaped_comment(iterator first, iterator last) const { if (!code.empty()) { detail::unindent(code); // remove all indents if (code.size() != 0) { snippet += "\n\n``\n" + code + "``\n\n"; code.clear(); } } std::string temp(first, last); detail::unindent(temp); // remove all indents if (temp.size() != 0) { snippet += "\n" + temp; // add a linebreak to allow block marskups } } void cpp_code_snippet_grammar::compile(iterator first, iterator last) const { using detail::callout_id; if (!code.empty()) { detail::unindent(code); // remove all indents if (code.size() != 0) { snippet += "\n\n```\n" + code + "```\n\n"; } if(callouts.size() > 0) { snippet += "'''<calloutlist>'''"; for (size_t i = 0; i < callouts.size(); ++i) { snippet += "'''<callout arearefs=\""; snippet += doc_id + boost::lexical_cast<std::string>(callout_id + i) + "co\" "; snippet += "id=\""; snippet += doc_id + boost::lexical_cast<std::string>(callout_id + i) + "\">"; snippet += "'''"; snippet += "'''<para>'''"; snippet += callouts[i]; snippet += "'''</para>'''"; snippet += "'''</callout>'''"; } snippet += "'''</calloutlist>'''"; } } std::vector<std::string> tinfo; tinfo.push_back(id); tinfo.push_back(snippet); storage.push_back(boost::make_tuple(tinfo, first.get_position())); callout_id += callouts.size(); callouts.clear(); code.clear(); snippet.clear(); id.clear(); } void load_snippets( std::string const& file , std::vector<template_symbol>& storage // snippets are stored in a // vector of template_symbols , std::string const& extension , std::string const& doc_id) { std::string code; int err = detail::load(file, code); if (err != 0) return; // return early on error typedef position_iterator<std::string::const_iterator> iterator_type; iterator_type first(code.begin(), code.end(), file); iterator_type last(code.end(), code.end()); cpp_code_snippet_grammar g(storage, doc_id); boost::spirit::parse(first, last, g); } namespace { fs::path include_search(fs::path const & current, std::string const & name) { fs::path path(name,fs::native); // If the path is relative, try and resolve it. if (!path.is_complete()) { // See if it can be found locally first. if (fs::exists(current / path)) { return current / path; } // Search in each of the include path locations. BOOST_FOREACH(std::string const & p, include_path) { fs::path full(p,fs::native); full /= path; if (fs::exists(full)) { return full; } } } return path; } } void import_action::operator()(iterator first, iterator last) const { fs::path path = include_search(actions.filename.branch_path(), std::string(first,last)); std::string ext = fs::extension(path); std::vector<template_symbol> storage; load_snippets(path.string(), storage, ext, actions.doc_id); BOOST_FOREACH(template_symbol const& ts, storage) { std::string tname = boost::get<0>(ts)[0]; if (actions.templates.find_top_scope(tname)) { boost::spirit::file_position const pos = boost::get<1>(ts); detail::outerr(pos.file, pos.line) << "Template Redefinition: " << tname << std::endl; } else { actions.templates.add(tname, ts); } } } void include_action::operator()(iterator first, iterator last) const { fs::path filein = include_search(actions.filename.branch_path(), std::string(first,last)); std::string doc_type, doc_id, doc_dirname, doc_last_revision; // swap the filenames std::swap(actions.filename, filein); // save the doc info strings actions.doc_type.swap(doc_type); actions.doc_id.swap(doc_id); actions.doc_dirname.swap(doc_dirname); actions.doc_last_revision.swap(doc_last_revision); // scope the macros string_symbols macro = actions.macro; // scope the templates //~ template_symbols templates = actions.templates; $$$ fixme $$$ // if an id is specified in this include (as in [include:id foo.qbk]) // then use it as the doc_id. if (!actions.include_doc_id.empty()) { actions.doc_id = actions.include_doc_id; actions.include_doc_id.clear(); } // update the __FILENAME__ macro *boost::spirit::find(actions.macro, "__FILENAME__") = actions.filename.native_file_string(); // parse the file quickbook::parse(actions.filename.native_file_string().c_str(), actions, true); // restore the values std::swap(actions.filename, filein); actions.doc_type.swap(doc_type); actions.doc_id.swap(doc_id); actions.doc_dirname.swap(doc_dirname); actions.doc_last_revision.swap(doc_last_revision); // restore the macros actions.macro = macro; // restore the templates //~ actions.templates = templates; $$$ fixme $$$ } void xml_author::operator()(std::pair<std::string, std::string> const& author) const { out << " <author>\n" << " <firstname>" << author.first << "</firstname>\n" << " <surname>" << author.second << "</surname>\n" << " </author>\n"; } void xml_copyright::operator()(std::pair<std::vector<std::string>, std::string> const& copyright) const { out << "\n" << " <copyright>\n"; for_each( copyright.first.begin() , copyright.first.end() , xml_year(out)); out << " <holder>" << copyright.second << "</holder>\n" << " </copyright>\n" << "\n" ; } void xml_year::operator()(std::string const &year) const { out << " <year>" << year << "</year>\n"; } void pre(collector& out, quickbook::actions& actions, bool ignore_docinfo) { // The doc_info in the file has been parsed. Here's what we'll do // *before* anything else. if (actions.doc_id.empty()) actions.doc_id = detail::make_identifier( actions.doc_title.begin(),actions.doc_title.end()); if (actions.doc_dirname.empty()) actions.doc_dirname = actions.doc_id; if (actions.doc_last_revision.empty()) { // default value for last-revision is now char strdate[64]; strftime( strdate, sizeof(strdate), (debug_mode ? "DEBUG MODE Date: %Y/%m/%d %H:%M:%S $" : "$" /* prevent CVS substitution */ "Date: %Y/%m/%d %H:%M:%S $"), current_gm_time ); actions.doc_last_revision = strdate; } // if we're ignoring the document info, we're done. if (ignore_docinfo) { return; } if (qbk_major_version == 0) { // hard code quickbook version to v1.1 qbk_major_version = 1; qbk_minor_version = 1; qbk_version_n = 101; detail::outwarn(actions.filename.native_file_string(),1) << "Warning: Quickbook version undefined. " "Version 1.1 is assumed" << std::endl; } else { qbk_version_n = (qbk_major_version * 100) + qbk_minor_version; } out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" << "<!DOCTYPE library PUBLIC \"-//Boost//DTD BoostBook XML V1.0//EN\"\n" << " \"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd\">\n" << '<' << actions.doc_type << "\n" << " id=\"" << actions.doc_id << "\"\n" << " name=\"" << actions.doc_title << "\"\n" << " dirname=\"" << actions.doc_dirname << "\"\n" << " last-revision=\"" << actions.doc_last_revision << "\" \n" << " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n" << " <" << actions.doc_type << "info>\n"; if(!actions.doc_authors.empty()) { out << " <authorgroup>\n"; for_each( actions.doc_authors.begin() , actions.doc_authors.end() , xml_author(out)); out << " </authorgroup>\n"; } if (!actions.doc_copyrights.empty()) { for_each( actions.doc_copyrights.begin() , actions.doc_copyrights.end() , xml_copyright(out)); } if (qbk_version_n < 103) { // version < 1.3 compatibility actions.doc_license = actions.doc_license_1_1; actions.doc_purpose = actions.doc_purpose_1_1; } if (!actions.doc_license.empty()) { out << " <legalnotice>\n" << " <para>\n" << " " << actions.doc_license << "\n" << " </para>\n" << " </legalnotice>\n" << "\n" ; } if (!actions.doc_purpose.empty()) { out << " <" << actions.doc_type << "purpose>\n" << " " << actions.doc_purpose << " </" << actions.doc_type << "purpose>\n" << "\n" ; } if (!actions.doc_category.empty()) { out << " <" << actions.doc_type << "category name=\"category:" << actions.doc_category << "\"></" << actions.doc_type << "category>\n" << "\n" ; } out << " </" << actions.doc_type << "info>\n" << "\n" ; if (!actions.doc_title.empty()) { out << " <title>" << actions.doc_title; if (!actions.doc_version.empty()) out << ' ' << actions.doc_version; out << "</title>\n\n\n"; } } void post(collector& out, quickbook::actions& actions, bool ignore_docinfo) { // if we're ignoring the document info, do nothing. if (ignore_docinfo) { return; } // We've finished generating our output. Here's what we'll do // *after* everything else. out << "\n</" << actions.doc_type << ">\n\n"; } void phrase_to_string_action::operator()(iterator first, iterator last) const { phrase.swap(out); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -