#include "fwd.hpp" #include "boostbook.hpp" #include "phrase.hpp" #include "actions_class.hpp" #include 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 << ">"; 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) << ""; } } }