⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 actions.cpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*=============================================================================    Copyright (c) 2002 2004 2006 Joel de Guzman    Copyright (c) 2004 Eric Niebler    Copyright (c) 2005 Thomas Guest    http://spirit.sourceforge.net/    Use, modification and distribution is subject to the Boost Software    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at    http://www.boost.org/LICENSE_1_0.txt)=============================================================================*/#include <numeric>#include <functional>#include <boost/bind.hpp>#include <boost/filesystem/convenience.hpp>#include <boost/filesystem/fstream.hpp>#include <boost/lexical_cast.hpp>#include "./actions.hpp"#include "./utils.hpp"#include "./markups.hpp"#include "./actions_class.hpp"#include "../block.hpp"#include "../phrase.hpp"#include "../code_snippet.hpp"namespace quickbook{    // Handles line-breaks (DEPRECATED!!!)    void break_action::operator()(iterator first, iterator) const    {        boost::spirit::file_position const pos = first.get_position();        detail::outwarn(pos.file,pos.line) << "in column:" << pos.column << ", "            << "[br] and \\n are deprecated" << ".\n";        phrase << break_mark;    }    void error_action::operator()(iterator first, iterator /*last*/) const    {        boost::spirit::file_position const pos = first.get_position();        detail::outerr(pos.file,pos.line)            << "Syntax Error near column " << pos.column << ".\n";    }    void phrase_action::operator()(iterator first, iterator last) const    {        std::string str;        phrase.swap(str);        out << pre << str << post;    }    void header_action::operator()(iterator first, iterator last) const    {        std::string str;        phrase.swap(str);        if (qbk_version_n < 103) // version 1.2 and below        {            out << "<anchor id=\""                << section_id << '.'                << detail::make_identifier(str.begin(), str.end())                << "\" />"                << pre << str << post                ;        }        else // version 1.3 and above        {            std::string anchor =                library_id + '.' + qualified_section_id + '.' +                detail::make_identifier(str.begin(), str.end());            out << "<anchor id=\"" << anchor << "\"/>"                << pre                << "<link linkend=\"" << anchor << "\">"                << str                << "</link>"                << post                ;        }    }    void generic_header_action::operator()(iterator first, iterator last) const    {        int level_ = section_level + 2;     // section_level is zero-based. We need to use a                                            // 0ne-based heading which is one greater                                            // than the current. Thus: section_level + 2.        if (level_ > 6)                     // The max is h6, clip it if it goes            level_ = 6;                     // further than that        std::string str;        phrase.swap(str);        std::string anchor =            library_id + '.' + qualified_section_id + '.' +            detail::make_identifier(str.begin(), str.end());        out            << "<anchor id=\"" << anchor << "\"/>"            << "<bridgehead renderas=\"sect" << level_ << "\">"            << "<link linkend=\"" << anchor << "\">"            << str            << "</link>"            << "</bridgehead>"            ;    }    void simple_phrase_action::operator()(iterator first, iterator last) const    {        out << pre;        std::string str(first, last);        if (std::string const* ptr = find(macro, str.c_str()))        {            out << *ptr;        }        else        {            while (first != last)                detail::print_char(*first++, out.get());        }        out << post;    }    void cond_phrase_action_pre::operator()(iterator first, iterator last) const    {        std::string str(first, last);        conditions.push_back(find(macro, str.c_str()));        out.push(); // save the stream    }    void cond_phrase_action_post::operator()(iterator first, iterator last) const    {        bool symbol_found = conditions.back();        conditions.pop_back();        if (first == last || !symbol_found)        {            out.pop(); // restore the stream        }        else        {            std::string save;            out.swap(save);            out.pop(); // restore the stream            out << save; // print the body        }    }    void list_action::operator()(iterator first, iterator last) const    {        BOOST_ASSERT(!list_marks.empty()); // there must be at least one item in the stack        out << list_buffer.str();        list_buffer.clear();        while (!list_marks.empty())        {            char mark = list_marks.top().first;            list_marks.pop();            out << std::string((mark == '#') ? "\n</orderedlist>" : "\n</itemizedlist>");            if (list_marks.size() >= 1)                out << std::string("\n</listitem>");        }        list_indent = -1; // reset    }    void list_format_action::operator()(iterator first, iterator last) const    {        int new_indent = 0;        while (first != last && (*first == ' ' || *first == '\t'))        {            char mark = *first++;            if (mark == ' ')            {                ++new_indent;            }            else // must be a tab            {                BOOST_ASSERT(mark == '\t');                // hardcoded tab to 4 for now                new_indent = ((new_indent + 4) / 4) * 4;            }        }        char mark = *first;        BOOST_ASSERT(mark == '#' || mark == '*'); // expecting a mark        if (list_indent == -1) // the very start        {            BOOST_ASSERT(new_indent == 0);        }        if (new_indent > list_indent)        {            list_indent = new_indent;            list_marks.push(mark_type(mark, list_indent));            if (list_marks.size() > 1)            {                // Make this new list a child of the previous list.                // The previous listelem has already ended so we erase                // </listitem> to accomodate this sub-list. We'll close                // the listelem later.                std::string str;                out.swap(str);                std::string::size_type pos = str.rfind("\n</listitem>");                BOOST_ASSERT(pos <= str.size());                str.erase(str.begin()+pos, str.end());                out << str;            }            out << std::string((mark == '#') ? "<orderedlist>\n" : "<itemizedlist>\n");        }        else if (new_indent < list_indent)        {            BOOST_ASSERT(!list_marks.empty());            list_indent = new_indent;            while (!list_marks.empty() && (list_indent < list_marks.top().second))            {                char mark = list_marks.top().first;                list_marks.pop();                out << std::string((mark == '#') ? "\n</orderedlist>" : "\n</itemizedlist>");                if (list_marks.size() >= 1)                    out << std::string("\n</listitem>");            }        }        if (mark != list_marks.top().first) // new_indent == list_indent        {            boost::spirit::file_position const pos = first.get_position();            detail::outerr(pos.file,pos.line)                << "Illegal change of list style near column " << pos.column << ".\n";            detail::outwarn(pos.file,pos.line)                << "Ignoring change of list style" << std::endl;        }    }    void span::operator()(iterator first, iterator last) const    {        out << "<phrase role=\"" << name << "\">";        while (first != last)            detail::print_char(*first++, out.get());        out << "</phrase>";    }    void unexpected_char::operator()(char) const    {        out << '#'; // print out an unexpected character    }    void anchor_action::operator()(iterator first, iterator last) const    {        out << "<anchor id=\"";        while (first != last)            detail::print_char(*first++, out.get());        out << "\" />\n";    }    void do_macro_action::operator()(std::string const& str) const    {        if (str == quickbook_get_date)        {            char strdate[64];            strftime(strdate, sizeof(strdate), "%Y-%b-%d", current_time);            phrase << strdate;        }        else if (str == quickbook_get_time)        {            char strdate[64];            strftime(strdate, sizeof(strdate), "%I:%M:%S %p", current_time);            phrase << strdate;        }        else        {            phrase << str;        }    }    void space::operator()(char ch) const    {        detail::print_space(ch, out.get());    }    void space::operator()(iterator first, iterator last) const    {        while (first != last)            detail::print_space(*first++, out.get());    }    void pre_escape_back::operator()(iterator first, iterator last) const    {        escape_actions.phrase.push(); // save the stream    }    void post_escape_back::operator()(iterator first, iterator last) const    {        out << escape_actions.phrase.str();        escape_actions.phrase.pop(); // restore the stream    }    void code_action::operator()(iterator first, iterator last) const    {        std::string save;        phrase.swap(save);        // preprocess the code section to remove the initial indentation        std::string program(first, last);        detail::unindent(program);        if (program.size() == 0)            return; // Nothing left to do here. The program is empty.        iterator first_(program.begin(), program.end());        iterator last_(program.end(), program.end());        first_.set_position(first.get_position());        // print the code with syntax coloring        if (source_mode == "c++")        {            parse(first_, last_, cpp_p);        }        else if (source_mode == "python")        {            parse(first_, last_, python_p);        }        std::string str;        temp.swap(str);        phrase.swap(save);        //        // We must not place a \n after the <programlisting> tag        // otherwise PDF output starts code blocks with a blank line:        //        out << "<programlisting>";        out << str;        out << "</programlisting>\n";    }    void inline_code_action::operator()(iterator first, iterator last) const    {        std::string save;        out.swap(save);        // print the code with syntax coloring        if (source_mode == "c++")        {            parse(first, last, cpp_p);        }        else if (source_mode == "python")        {            parse(first, last, python_p);        }        std::string str;        temp.swap(str);        out.swap(save);        out << "<code>";        out << str;        out << "</code>";    }    void raw_char_action::operator()(char ch) const    {        phrase << ch;    }    void raw_char_action::operator()(iterator first, iterator /*last*/) const    {        phrase << *first;    }    void plain_char_action::operator()(char ch) const    {        detail::print_char(ch, phrase.get());    }    void plain_char_action::operator()(iterator first, iterator /*last*/) const    {        detail::print_char(*first, phrase.get());    }    void image_action::operator()(iterator first, iterator last) const    {        fs::path const img_path(std::string(first, last));        std::string attr_text;        if(fs::extension(img_path) == ".svg")        {           //           // SVG's need special handling:           //           // 1) We must set the "format" attribute, otherwise           //    HTML generation produces code that will not display           //    the image at all.           // 2) We need to set the "contentwidth" and "contentdepth"           //    attributes, otherwise the image will be displayed inside           //    a tiny box with scrollbars (Firefox), or else cropped to           //    fit in a tiny box (IE7).           //           attr_text = " format=\"SVG\"";           //           // Image paths are relative to the html subdirectory:           //           fs::path img;           if(img_path.root_path().empty())              img = "html" / img_path;  // relative path           else              img = img_path;   // absolute path           //           // Now load the SVG file:           //           std::string svg_text;           fs::ifstream fs(img);           char c;           while(fs.get(c) && fs.good())              svg_text.push_back(c);           //           // Extract the svg header from the file:           //           std::string::size_type a, b;           a = svg_text.find("<svg");           b = svg_text.find('>', a);           svg_text = (a == std::string::npos) ? "" : svg_text.substr(a, b - a);           //           // Now locate the "width" and "height" attributes           // and borrow their values:           //           a = svg_text.find("width");           a = svg_text.find('=', a);           a = svg_text.find('\"', a);           b = svg_text.find('\"', a + 1);           if(a != std::string::npos)           {              attr_text.append(" contentwidth=");              attr_text.append(svg_text.begin() + a, svg_text.begin() + b + 1);           }           a = svg_text.find("height");           a = svg_text.find('=', a);           a = svg_text.find('\"', a);           b = svg_text.find('\"', a + 1);           if(a != std::string::npos)           {              attr_text.append(" contentdepth=");              attr_text.append(svg_text.begin() + a, svg_text.begin() + b + 1);           }        }        phrase << "<inlinemediaobject>";

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -