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

📄 actions.cpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 CPP
📖 第 1 页 / 共 3 页
字号:
        phrase << "<imageobject><imagedata ";        phrase << attr_text;        phrase << " fileref=\"";        while (first != last)            detail::print_char(*first++, phrase.get());        phrase << "\"></imagedata></imageobject>";        // Also add a textobject -- use the basename of the image file.        // This will mean we get "alt" attributes of the HTML img.        phrase << "<textobject><phrase>";        detail::print_string(fs::basename(img_path), phrase.get());        phrase << "</phrase></textobject>";        phrase << "</inlinemediaobject>";    }    void macro_identifier_action::operator()(iterator first, iterator last) const    {        actions.macro_id.assign(first, last);        actions.phrase.push(); // save the phrase    }    void macro_definition_action::operator()(iterator first, iterator last) const    {        actions.macro.add(            actions.macro_id.begin()          , actions.macro_id.end()          , actions.phrase.str());        actions.phrase.pop(); // restore the phrase    }    void template_body_action::operator()(iterator first, iterator last) const    {        BOOST_ASSERT(actions.template_info.size());        if (actions.templates.find_top_scope(actions.template_info[0]))        {            boost::spirit::file_position const pos = first.get_position();            detail::outerr(pos.file,pos.line)                << "Template Redefinition: " << actions.template_info[0] << std::endl;        }        actions.template_info.push_back(std::string(first, last));        actions.templates.add(            actions.template_info[0]          , boost::make_tuple(actions.template_info, first.get_position()));        actions.template_info.clear();    }    namespace    {        bool break_arguments(            std::vector<std::string>& template_info          , std::vector<std::string> const& template_          , boost::spirit::file_position const& pos        )        {            if (template_.size()-1 != template_info.size())            {                while (template_.size()-1 != template_info.size())                {                    // Try to break the last argument at the first space found                    // and push it into the back of template_info. Do this                    // recursively until we have all the expected number of                    // arguments, or if there are no more spaces left.                    std::string& str = template_info.back();                    std::string::size_type l_pos = str.find_first_of(" \t\r\n");                    if (l_pos == std::string::npos)                        break;                    std::string first(str.begin(), str.begin()+l_pos);                    std::string::size_type r_pos = str.find_first_not_of(" \t\r\n", l_pos);                    std::string second(str.begin()+r_pos, str.end());                    str = first;                    template_info.push_back(second);                }                if (template_.size()-1 != template_info.size())                {                    detail::outerr(pos.file, pos.line)                        << "Invalid number of arguments passed. Expecting: "                        << template_.size()-2                        << " argument(s), got: "                        << template_info.size()-1                        << " argument(s) instead."                        << std::endl;                    return false;                }            }            return true;        }        std::pair<bool, std::vector<std::string>::const_iterator>        get_arguments(            std::vector<std::string>& template_info          , std::vector<std::string> const& template_          , boost::spirit::file_position const& pos          , quickbook::actions& actions        )        {            std::vector<std::string>::const_iterator arg = template_info.begin()+1;            std::vector<std::string>::const_iterator tpl = template_.begin()+1;            // Store each of the argument passed in as local templates:            while (arg != template_info.end())            {                std::vector<std::string> tinfo;                tinfo.push_back(*tpl);                tinfo.push_back(*arg);                template_symbol template_(tinfo, pos);                if (template_symbol* p = actions.templates.find_top_scope(*tpl))                {                    detail::outerr(pos.file,pos.line)                        << "Duplicate Symbol Found" << std::endl;                    return std::make_pair(false, tpl);                }                else                {                    actions.templates.add(*tpl, template_);                }                ++arg; ++tpl;            }            return std::make_pair(true, tpl);        }        bool parse_template(            std::string& body          , std::string& result          , boost::spirit::file_position const& template_pos          , quickbook::actions& actions        )        {            simple_phrase_grammar<quickbook::actions> phrase_p(actions);            block_grammar<quickbook::actions, true> block_p(actions);            // How do we know if we are to parse the template as a block or            // a phrase? We apply a simple heuristic: if the body starts with            // a newline, then we regard it as a block, otherwise, we parse            // it as a phrase.            std::string::const_iterator iter = body.begin();            while (iter != body.end() && ((*iter == ' ') || (*iter == '\t')))                ++iter; // skip spaces and tabs            bool is_block = (iter != body.end()) && ((*iter == '\r') || (*iter == '\n'));            bool r = false;            if (actions.template_escape)            {                //  escape the body of the template                //  we just copy out the literal body                result = body;                r = true;            }            else if (!is_block)            {                //  do a phrase level parse                iterator first(body.begin(), body.end(), actions.filename.native_file_string().c_str());                first.set_position(template_pos);                iterator last(body.end(), body.end());                r = boost::spirit::parse(first, last, phrase_p).full;                actions.phrase.swap(result);            }            else            {                //  do a block level parse                //  ensure that we have enough trailing newlines to eliminate                //  the need to check for end of file in the grammar.                body.push_back('\n');                body.push_back('\n');                while (iter != body.end() && ((*iter == '\r') || (*iter == '\n')))                    ++iter; // skip initial newlines                iterator first(iter, body.end(), actions.filename.native_file_string().c_str());                first.set_position(template_pos);                iterator last(body.end(), body.end());                r = boost::spirit::parse(first, last, block_p).full;                actions.out.swap(result);            }            return r;        }    }    void do_template_action::operator()(iterator first, iterator) const    {        boost::spirit::file_position const pos = first.get_position();        ++actions.template_depth;        if (actions.template_depth > actions.max_template_depth)        {            detail::outerr(pos.file,pos.line)                << "Infinite loop detected" << std::endl;            --actions.template_depth;            return;        }        std::string result;        actions.push(); // scope the actions' states        {            template_symbol const* symbol =                actions.templates.find(actions.template_info[0]);            BOOST_ASSERT(symbol);            std::vector<std::string> template_ = boost::get<0>(*symbol);            boost::spirit::file_position template_pos = boost::get<1>(*symbol);            std::vector<std::string> template_info;            std::swap(template_info, actions.template_info);            ///////////////////////////////////            // Break the arguments            if (!break_arguments(template_info, template_, pos))            {                actions.pop(); // restore the actions' states                --actions.template_depth;                return;            }            ///////////////////////////////////            // Prepare the arguments as local templates            bool get_arg_result;            std::vector<std::string>::const_iterator tpl;            boost::tie(get_arg_result, tpl) =                get_arguments(template_info, template_, pos, actions);            if (!get_arg_result)            {                actions.pop(); // restore the actions' states                --actions.template_depth;                return;            }            ///////////////////////////////////            // parse the template body:            std::string body;            body.assign(tpl->begin(), tpl->end());            body.reserve(body.size()+2); // reserve 2 more            if (!parse_template(body, result, template_pos, actions))            {                boost::spirit::file_position const pos = first.get_position();                detail::outerr(pos.file,pos.line)                    << "Expanding template:" << template_info[0] << std::endl                    << "------------------begin------------------" << std::endl                    << body                    << "------------------end--------------------" << std::endl                    << std::endl;                actions.pop(); // restore the actions' states                --actions.template_depth;                return;            }        }        actions.pop(); // restore the actions' states        actions.phrase << result; // print it!!!        --actions.template_depth;    }    void link_action::operator()(iterator first, iterator last) const    {        iterator save = first;        phrase << tag;        while (first != last)            detail::print_char(*first++, phrase.get());        phrase << "\">";        // Yes, it is safe to dereference last here. When we        // reach here, *last is certainly valid. We test if        // *last == ']'. In which case, the url is the text.        // Example: [@http://spirit.sourceforge.net/]        if (*last == ']')        {            first = save;            while (first != last)                detail::print_char(*first++, phrase.get());        }    }    void variablelist_action::operator()(iterator, iterator) const    {        actions.out << "<variablelist>\n";        actions.out << "<title>";        std::string::iterator first = actions.table_title.begin();        std::string::iterator last = actions.table_title.end();        while (first != last)            detail::print_char(*first++, actions.out.get());        actions.out << "</title>\n";        std::string str;        actions.phrase.swap(str);        actions.out << str;        actions.out << "</variablelist>\n";        actions.table_span = 0;        actions.table_header.clear();        actions.table_title.clear();    }    void start_varlistitem_action::operator()(char) const    {        phrase << start_varlistitem_;        phrase.push();    }    void end_varlistitem_action::operator()(char) const    {        std::string str;        temp_para.swap(str);        phrase.pop();        phrase << str << end_varlistitem_;    }    void table_action::operator()(iterator, iterator) const    {        std::string::iterator first = actions.table_title.begin();        std::string::iterator last = actions.table_title.end();        bool has_title = first != last;        if (has_title)        {            actions.out << "<table frame=\"all\">\n";            actions.out << "<title>";            while (first != last)                detail::print_char(*first++, actions.out.get());            actions.out << "</title>";        }        else        {            actions.out << "<informaltable frame=\"all\">\n";        }        actions.out << "<tgroup cols=\"" << actions.table_span << "\">\n";        if (!actions.table_header.empty())        {            actions.out << "<thead>" << actions.table_header << "</thead>\n";        }        actions.out << "<tbody>\n";        std::string str;        actions.phrase.swap(str);        actions.out << str;        actions.out << "</tbody>\n"                     << "</tgroup>\n";        if (has_title)        {            actions.out << "</table>\n";        }        else        {            actions.out << "</informaltable>\n";        }        actions.table_span = 0;        actions.table_header.clear();        actions.table_title.clear();    }    void start_row_action::operator()(char) const    {        // the first row is the header        if (header.empty() && !phrase.str().empty())        {            phrase.swap(header);        }        phrase << start_row_;        span = 0;    }    void start_row_action::operator()(iterator f, iterator) const    {        (*this)(*f);    }    void start_col_action::operator()(char) const    {        phrase << start_cell_;        phrase.push();        ++span;    }    void end_col_action::operator()(char) const    {        std::string str;        temp_para.swap(str);        phrase.pop();        phrase << str << end_cell_;    }    void begin_section_action::operator()(iterator first, iterator last) const    {        if (section_id.empty())            section_id = detail::make_identifier(first, last);        if (section_level != 0)            qualified_section_id += '.';        else            BOOST_ASSERT(qualified_section_id.empty());        qualified_section_id += section_id;        ++section_level;        if (qbk_version_n < 103) // version 1.2 and below        {            out << "\n<section id=\""                << library_id << "." << section_id << "\">\n";        }        else // version 1.3 and above        {            out << "\n<section id=\"" << library_id                << "." << qualified_section_id << "\">\n";        }        std::string str;        phrase.swap(str);        if (qbk_version_n < 103) // version 1.2 and below        {            out << "<title>" << str << "</title>\n";        }        else // version 1.3 and above        {            out << "<title>"                << "<link linkend=\"" << library_id                    << "." << qualified_section_id << "\">"                << str                << "</link>"                << "</title>\n"                ;        }    }    void end_section_action::operator()(iterator first, iterator last) const    {        out << "</section>";        --section_level;        if (section_level < 0)        {            boost::spirit::file_position const pos = first.get_position();            detail::outerr(pos.file,pos.line)                << "Mismatched [endsect] near column " << pos.column << ".\n";            // $$$ TODO: somehow fail parse else BOOST_ASSERT(std::string::npos != n)            // $$$ below will assert.

⌨️ 快捷键说明

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