#include #include #include "encoder_impl.hpp" namespace quickbook { template std::string encode_impl(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 boostbook_encoder::encode(std::string const& x) const { return encode_impl(x.begin(), x.end()); } std::string boostbook_encoder::encode(char const* x) const { char const* end = x; while(*end) ++end; return encode_impl(x, end); } std::string boostbook_encoder::encode(char c) const { return encode_impl(&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 boostbook_encoder::operator()(quickbook::state& state, std::string const& x) const { state.phrase << x; } void boostbook_encoder::operator()(quickbook::state& state, char x) const { state.phrase << encode(x); } void boostbook_encoder::operator()(quickbook::state& state, anchor const& x) const { state.phrase << "\n"; } void boostbook_encoder::operator()(quickbook::state& state, link const& x) const { boostbook_markup m = markup_map.at(x.type); state.phrase << m.pre; state.phrase << encode(x.destination); state.phrase << "\">"; state.phrase << x.content; state.phrase << m.post; } void boostbook_encoder::operator()(quickbook::state& state, formatted const& x) const { boostbook_markup m = markup_map.at(x.type); state.phrase << m.pre << x.content << m.post; } void boostbook_encoder::operator()(quickbook::state& state, break_ const& x) const { boostbook_markup m = markup_map.at("break"); state.phrase << m.pre; } void boostbook_encoder::operator()(quickbook::state& state, image2 const& x) const { state.phrase << ""; state.phrase << "first == "alt") continue; state.phrase << " " << attr_first->first << "=\"" << encode(attr_first->second) << "\""; } state.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. state.phrase << ""; state.phrase << encode(it->second); state.phrase << ""; } state.phrase << ""; } void boostbook_encoder::operator()(quickbook::state& state, hr) const { state.phrase << markup_map.at("hr").pre; } void boostbook_encoder::operator()(quickbook::state& state, begin_section2 const& x) const { state.phrase << "\n
\n"; if(x.linkend.empty()) { state.phrase << "" << x.content << "\n" ; } else { state.phrase << "" << "<link linkend=\"" << x.linkend << "\">" << x.content << "</link>" << "\n" ; } } void boostbook_encoder::operator()(quickbook::state& state, end_section2 const& x) const { state.phrase << "
"; } void boostbook_encoder::operator()(quickbook::state& state, heading2 const& x) const { state.phrase << "" << ""; if(x.linkend.empty()) { state.phrase << x.content; } else { state.phrase << "" << x.content << ""; } state.phrase << ""; } void boostbook_encoder::operator()(quickbook::state& state, variablelist const& x) const { state.phrase << "\n"; state.phrase << ""; state.phrase << encode(x.title); state.phrase << "\n"; boostbook_markup m = markup_map.at("varlistentry"); for(std::vector::const_iterator it = x.entries.begin(); it != x.entries.end(); ++it) { state.phrase << m.pre; std::for_each(it->begin(), it->end(), encode_action(state, *this)); state.phrase << m.post; } state.phrase << "\n"; } void boostbook_encoder::operator()(quickbook::state& state, table2 const& x) const { if (x.title) { state.phrase << "\n"; state.phrase << ""; state.phrase << encode(*x.title); state.phrase << ""; } else { state.phrase << "\n"; } // This is a bit odd for backwards compatability: the old version just // used the last count that was calculated. state.phrase << "\n"; boostbook_markup m = markup_map.at("row"); if (x.head) { state.phrase << ""; state.phrase << m.pre; std::for_each(x.head->begin(), x.head->end(), encode_action(state, *this)); state.phrase << m.post; state.phrase << "\n"; } state.phrase << "\n"; for(std::vector::const_iterator it = x.rows.begin(); it != x.rows.end(); ++it) { state.phrase << m.pre; std::for_each(it->begin(), it->end(), encode_action(state, *this)); state.phrase << m.post; } state.phrase << "\n" << "\n"; if (x.title) { state.phrase << "
\n"; } else { state.phrase << "\n"; } } void boostbook_encoder::operator()(quickbook::state& state, xinclude2 const& x) const { state.phrase << "\n\n"; } void boostbook_encoder::operator()(quickbook::state& state, list2 const& x) const { state.phrase << std::string(x.mark == '#' ? "\n" : "\n"); for(std::vector::const_iterator it = x.items.begin(), end = x.items.end(); it != end; ++it) { state.phrase << "\n" << it->content; if(!it->sublist.items.empty()) (*this)(state, it->sublist); state.phrase << std::string("\n"); } state.phrase << std::string(x.mark == '#' ? "\n" : "\n"); } void boostbook_encoder::operator()(quickbook::state& state, code_token const& x) const { std::string type = x.type; if(type == "space") { state.phrase << x.text; } else { state.phrase << "" << encode(x.text) << ""; } } void boostbook_encoder::operator()(quickbook::state& state, doc_info const& info) const { // if we're ignoring the document info, we're done. if (info.ignore) return; state.phrase << "\n" << ""; // Document tag state.phrase << '<' << info.doc_type << " id=\"" << info.doc_id << "\"\n"; if(info.doc_type == "library") { state.phrase << " name=\"" << info.doc_title << "\"\n"; } if(!info.doc_dirname.empty()) { state.phrase << " dirname=\"" << info.doc_dirname << "\"\n"; } state.phrase << "last-revision=\"" << info.doc_last_revision << "\"" << " xmlns:xi=\"http://www.w3.org/2001/XInclude\""; state.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") state.phrase << title; // Info tag state.phrase << "<" << info.doc_type << "info>\n"; if(!info.doc_authors.empty()) { state.phrase << "\n"; BOOST_FOREACH(doc_info::author const& author, info.doc_authors) { state.phrase << "\n" << "" << author.first << "\n" << "" << author.second << "\n" << "\n"; } state.phrase << "\n"; } BOOST_FOREACH(doc_info::copyright_entry const& copyright, info.doc_copyrights) { state.phrase << "\n"; BOOST_FOREACH(std::string const& year, copyright.first) { state.phrase << "" << year << "\n"; } state.phrase << "" << copyright.second << "\n" << "\n" ; } if (!info.doc_license.empty()) { state.phrase << "\n" << "\n" << info.doc_license << "\n" << "\n" << "\n" << "\n" ; } if (!info.doc_purpose.empty()) { state.phrase << "<" << info.doc_type << "purpose>\n" << info.doc_purpose << "\n" << "\n" ; } if (!info.doc_category.empty()) { state.phrase << "<" << info.doc_type << "category name=\"category:" << info.doc_category << "\">\n" << "\n" ; } state.phrase << "\n" ; if(info.doc_type == "library") state.phrase << title; } void boostbook_encoder::operator()(quickbook::state& state, doc_info_post const& x) const { // 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. state.phrase << ""; } }