#include #include #include "fwd.hpp" #include "boostbook.hpp" #include "phrase.hpp" #include "actions_class.hpp" namespace quickbook { struct output_action { output_action(quickbook::actions& actions) : actions(actions) {} quickbook::actions& actions; template void operator()(T const& x) const { output(actions, x); } }; template std::string encode(Iter first, Iter last) { std::string r; for(;first != last; ++first) { switch (*first) { case '<': r += "<"; break; case '>': r += ">"; break; case '&': r += "&"; break; case '"': r += """; break; default: r += *first; break; } } return r; } std::string encode(std::string const& x) { return encode(x.begin(), x.end()); } std::string encode(char const* x) { char const* end = x; while(*end) ++end; return encode(x, end); } std::string encode(char c) { return encode(&c, &c + 1); } namespace { struct boostbook_markup { char const* quickbook; char const* pre; char const* post; }; boostbook_markup markups[] = { { "", "", "" }, { "comment", "" }, { "paragraph", "\n", "\n" }, { "h1", "", "" }, { "h2", "", "" }, { "h3", "", "" }, { "h4", "", "" }, { "h5", "", "" }, { "h6", "", "" }, { "blurb", "\n", "\n" }, { "blockquote", "
", "
" }, { "preformatted", "", "" }, { "warning", "", "" }, { "caution", "", "" }, { "important", "", "" }, { "note", "", "" }, { "tip", "", "" }, { "list_item", "\n", "\n" }, { "bold", "", "" }, { "italic", "", "" }, { "underline", "", "" }, { "teletype", "", "" }, { "strikethrough", "", "" }, { "quote", "", "" }, { "url", "" }, { "link", "" }, { "funcref", "" }, { "classref", "" }, { "memberref", "" }, { "enumref", "" }, { "macroref", "" }, { "headerref", "" }, { "conceptref", "" }, { "globalref", "" }, { "footnote", "", "" }, { "escape", "", "" }, { "replaceable", "", "" }, { "varlistentry", "", "\n" }, { "varlistterm", "", "" }, { "varlistitem", "", "" }, { "header", "", "\n" }, { "row", "", "\n" }, { "cell", "", "" }, { "programlisting", "", "\n" }, { "code", "", "" }, { "hr", "", "" }, { "break", "", "" }, }; std::map markup_map; struct initialize { initialize() { BOOST_FOREACH(boostbook_markup m, markups) { markup_map[m.quickbook] = m; } } } initialize_instance; } void output(quickbook::actions& actions, std::string const& x) { actions.phrase << x; } void output(quickbook::actions& actions, char x) { actions.phrase << encode(x); } void output(quickbook::actions& actions, anchor const& x) { actions.phrase << "\n"; } void output(quickbook::actions& actions, link const& x) { boostbook_markup m = markup_map.at(x.type); actions.phrase << m.pre; actions.phrase << encode(x.destination); actions.phrase << "\">"; actions.phrase << x.content; actions.phrase << m.post; } void output(quickbook::actions& actions, formatted const& x) { boostbook_markup m = markup_map.at(x.type); actions.phrase << m.pre << x.content << m.post; } void output(quickbook::actions& actions, break_ const& x) { boostbook_markup m = markup_map.at("break"); actions.phrase << m.pre; } void output(quickbook::actions& actions, image2 const& x) { actions.phrase << ""; actions.phrase << "first == "alt") continue; actions.phrase << " " << attr_first->first << "=\"" << encode(attr_first->second) << "\""; } actions.phrase << ">"; image2::attribute_map::const_iterator it = x.attributes.find("alt"); if(it != x.attributes.end()) { // Also add a textobject -- use the basename of the image file. // This will mean we get "alt" attributes of the HTML img. actions.phrase << ""; actions.phrase << encode(it->second); actions.phrase << ""; } actions.phrase << ""; } void output(quickbook::actions& actions, hr) { actions.phrase << markup_map.at("hr").pre; } void output(quickbook::actions& actions, begin_section2 const& x) { actions.phrase << "\n
\n"; if(x.linkend.empty()) { actions.phrase << "" << x.content << "\n" ; } else { actions.phrase << "" << "<link linkend=\"" << x.linkend << "\">" << x.content << "</link>" << "\n" ; } } void output(quickbook::actions& actions, end_section2 const& x) { actions.phrase << "
"; } void output(quickbook::actions& actions, heading2 const& x) { actions.phrase << "" << ""; if(x.linkend.empty()) { actions.phrase << x.content; } else { actions.phrase << "" << x.content << ""; } actions.phrase << ""; } void output(quickbook::actions& actions, variablelist const& x) { actions.phrase << "\n"; actions.phrase << ""; actions.phrase << encode(x.title); actions.phrase << "\n"; boostbook_markup m = markup_map.at("varlistentry"); for(std::vector::const_iterator it = x.entries.begin(); it != x.entries.end(); ++it) { actions.phrase << m.pre; std::for_each(it->begin(), it->end(), output_action(actions)); actions.phrase << m.post; } actions.phrase << "\n"; } void output(quickbook::actions& actions, table2 const& x) { if (x.title) { actions.phrase << "\n"; actions.phrase << ""; actions.phrase << encode(*x.title); actions.phrase << ""; } else { actions.phrase << "\n"; } // This is a bit odd for backwards compatability: the old version just // used the last count that was calculated. actions.phrase << "\n"; boostbook_markup m = markup_map.at("row"); if (x.head) { actions.phrase << ""; actions.phrase << m.pre; std::for_each(x.head->begin(), x.head->end(), actions.process); actions.phrase << m.post; actions.phrase << "\n"; } actions.phrase << "\n"; for(std::vector::const_iterator it = x.rows.begin(); it != x.rows.end(); ++it) { actions.phrase << m.pre; std::for_each(it->begin(), it->end(), actions.process); actions.phrase << m.post; } actions.phrase << "\n" << "\n"; if (x.title) { actions.phrase << "
\n"; } else { actions.phrase << "\n"; } } void output(quickbook::actions& actions, xinclude2 const& x) { actions.phrase << "\n\n"; } void output(quickbook::actions& actions, list2 const& x) { actions.phrase << std::string(x.mark == '#' ? "\n" : "\n"); for(std::vector::const_iterator it = x.items.begin(), end = x.items.end(); it != end; ++it) { actions.phrase << "\n" << it->content; if(!it->sublist.items.empty()) output(actions, it->sublist); actions.phrase << std::string("\n"); } actions.phrase << std::string(x.mark == '#' ? "\n" : "\n"); } void output(quickbook::actions& actions, code_token const& x) { std::string type = x.type; if(type == "space") { actions.phrase << x.text; } else { actions.phrase << "" << encode(x.text) << ""; } } void output(quickbook::actions& actions, doc_info const& info) { // if we're ignoring the document info, we're done. if (info.ignore) return; actions.phrase << "\n" << ""; // Document tag actions.phrase << '<' << info.doc_type << " id=\"" << info.doc_id << "\"\n"; if(info.doc_type == "library") { actions.phrase << " name=\"" << info.doc_title << "\"\n"; } if(!info.doc_dirname.empty()) { actions.phrase << " dirname=\"" << info.doc_dirname << "\"\n"; } actions.phrase << "last-revision=\"" << info.doc_last_revision << "\"" << " xmlns:xi=\"http://www.w3.org/2001/XInclude\""; actions.phrase << ">"; // end document tag. // Title tag std::string title; if(!info.doc_title.empty()) { title = "" + info.doc_title; if (!info.doc_version.empty()) title += ' ' + info.doc_version; title += "\n"; } // For 'library', the title comes after the info block. if(info.doc_type != "library") actions.phrase << title; // Info tag actions.phrase << "<" << info.doc_type << "info>\n"; if(!info.doc_authors.empty()) { actions.phrase << "\n"; BOOST_FOREACH(doc_info::author const& author, info.doc_authors) { actions.phrase << "\n" << "" << author.first << "\n" << "" << author.second << "\n" << "\n"; } actions.phrase << "\n"; } BOOST_FOREACH(doc_info::copyright_entry const& copyright, info.doc_copyrights) { actions.phrase << "\n"; BOOST_FOREACH(std::string const& year, copyright.first) { actions.phrase << "" << year << "\n"; } actions.phrase << "" << copyright.second << "\n" << "\n" ; } if (!info.doc_license.empty()) { actions.phrase << "\n" << "\n" << info.doc_license << "\n" << "\n" << "\n" << "\n" ; } if (!info.doc_purpose.empty()) { actions.phrase << "<" << info.doc_type << "purpose>\n" << info.doc_purpose << "\n" << "\n" ; } if (!info.doc_category.empty()) { actions.phrase << "<" << info.doc_type << "category name=\"category:" << info.doc_category << "\">\n" << "\n" ; } actions.phrase << "\n" ; if(info.doc_type == "library") actions.phrase << title; } void output(quickbook::actions& actions, doc_info_post const& x) { // if we're ignoring the document info, do nothing. if (x.info.ignore) return; // We've finished generating our output. Here's what we'll do // *after* everything else. actions.phrase << ""; } }