コード例 #1
0
ファイル: doc_info_actions.cpp プロジェクト: AlexMioMio/boost
     BOOST_FOREACH(value_consumer copyright, copyrights)
     {
         while(copyright.check())
         {
             tmp << "\n" << "    <copyright>\n";
 
             while(copyright.check(doc_info_tags::copyright_year))
             {
                 value year_start_value = copyright.consume();
                 int year_start = year_start_value.get_int();
                 int year_end =
                     copyright.check(doc_info_tags::copyright_year_end) ?
                     copyright.consume().get_int() :
                     year_start;
 
                 if (year_end < year_start) {
                     ++state.error_count;
 
                     detail::outerr(state.current_file, copyright.begin()->get_position())
                         << "Invalid year range: "
                         << year_start
                         << "-"
                         << year_end
                         << "."
                         << std::endl;
                 }
 
                 for(; year_start <= year_end; ++year_start)
                     tmp << "      <year>" << year_start << "</year>\n";
             }
         
             tmp << "      <holder>"
                 << doc_info_output(copyright.consume(doc_info_tags::copyright_name), 106)
                 << "</holder>\n"
                 << "    </copyright>\n"
                 << "\n"
             ;
         }
     }
コード例 #2
0
ファイル: doc_info_actions.cpp プロジェクト: AlexMioMio/boost
    std::string pre(quickbook::state& state, parse_iterator pos,
            value include_doc_id, bool nested_file)
    {
        // The doc_info in the file has been parsed. Here's what we'll do
        // *before* anything else.
        //
        // If there isn't a doc info block, then values will be empty, so most
        // of the following code won't actually do anything.

        value_consumer values = state.values.release();

        // Skip over invalid attributes

        while (values.check(value::default_tag)) values.consume();

        bool use_doc_info = false;
        std::string doc_type;
        value doc_title;

        if (values.check(doc_info_tags::type))
        {
            doc_type = detail::to_s(values.consume(doc_info_tags::type).get_quickbook());
            doc_title = values.consume(doc_info_tags::title);
            use_doc_info = !nested_file || qbk_version_n >= 106u;
        }
        else
        {
            if (!nested_file)
            {
                detail::outerr(state.current_file, pos.base())
                    << "No doc_info block."
                    << std::endl;

                ++state.error_count;

                // Create a fake document info block in order to continue.
                doc_type = "article";
                doc_title = qbk_value(state.current_file,
                    pos.base(), pos.base(),
                    doc_info_tags::type);
                use_doc_info = true;
            }
        }

        std::vector<std::string> duplicates;

        std::vector<value> escaped_attributes = consume_multiple_values(values, doc_info_tags::escaped_attribute);

        value qbk_version = consume_list(values, doc_attributes::qbk_version, &duplicates);
        value compatibility_mode = consume_list(values, doc_attributes::compatibility_mode, &duplicates);
        consume_multiple_values(values, doc_attributes::source_mode);

        value id = consume_value_in_list(values, doc_info_attributes::id, &duplicates);
        value dirname = consume_value_in_list(values, doc_info_attributes::dirname, &duplicates);
        value last_revision = consume_value_in_list(values, doc_info_attributes::last_revision, &duplicates);
        value purpose = consume_value_in_list(values, doc_info_attributes::purpose, &duplicates);
        std::vector<value> categories = consume_multiple_values(values, doc_info_attributes::category);
        value lang = consume_value_in_list(values, doc_info_attributes::lang, &duplicates);
        value version = consume_value_in_list(values, doc_info_attributes::version, &duplicates);
        std::vector<value> authors = consume_multiple_values(values, doc_info_attributes::authors);
        std::vector<value> copyrights = consume_multiple_values(values, doc_info_attributes::copyright);
        value license = consume_value_in_list(values, doc_info_attributes::license, &duplicates);
        std::vector<value> biblioids = consume_multiple_values(values, doc_info_attributes::biblioid);
        value xmlbase = consume_value_in_list(values, doc_info_attributes::xmlbase, &duplicates);

        values.finish();

        if(!duplicates.empty())
        {
            detail::outwarn(state.current_file->path)
                << (duplicates.size() > 1 ?
                    "Duplicate attributes" : "Duplicate attribute")
                << ":" << boost::algorithm::join(duplicates, ", ")
                << "\n"
                ;
        }

        std::string include_doc_id_, id_;

        if (!include_doc_id.empty())
            include_doc_id_ = detail::to_s(include_doc_id.get_quickbook());
        if (!id.empty())
            id_ = detail::to_s(id.get_quickbook());

        // Quickbook version

        unsigned new_version = get_version(state, use_doc_info, qbk_version);

        if (new_version != qbk_version_n)
        {
            if (new_version >= 107u)
            {
                detail::outwarn(state.current_file->path)
                    << "Quickbook " << (new_version / 100) << "." << (new_version % 100)
                    << " is still under development and is "
                    "likely to change in the future." << std::endl;
            }
        }

        if (new_version) {
            qbk_version_n = new_version;
        }
        else if (use_doc_info) {
            // hard code quickbook version to v1.1
            qbk_version_n = 101;
            detail::outwarn(state.current_file, pos.base())
                << "Quickbook version undefined. "
                "Version 1.1 is assumed" << std::endl;
        }

        state.current_file->version(qbk_version_n);

        // Compatibility Version

        unsigned compatibility_version =
            get_version(state, use_doc_info, compatibility_mode);

        if (!compatibility_version) {
            compatibility_version = use_doc_info ?
                qbk_version_n : state.document.compatibility_version();
        }

        // Start file, finish here if not generating document info.

        if (!use_doc_info)
        {
            state.document.start_file(compatibility_version, include_doc_id_, id_,
                    doc_title);
            return "";
        }

        std::string id_placeholder =
            state.document.start_file_with_docinfo(
                compatibility_version, include_doc_id_, id_, doc_title);

        // Make sure we really did have a document info block.

        assert(doc_title.check() && !doc_type.empty());

        // Set xmlbase

        std::string xmlbase_value;

        if (!xmlbase.empty())
        {
            xinclude_path x = calculate_xinclude_path(xmlbase, state);

            if (!fs::is_directory(x.path))
            {
                detail::outerr(xmlbase.get_file(), xmlbase.get_position())
                    << "xmlbase \""
                    << xmlbase.get_quickbook()
                    << "\" isn't a directory."
                    << std::endl;

                ++state.error_count;
            }
            else
            {
                xmlbase_value = x.uri;
                state.xinclude_base = x.path;
            }
        }

        // Warn about invalid fields

        if (doc_type != "library")
        {
            std::vector<std::string> invalid_attributes;

            if (!purpose.empty())
                invalid_attributes.push_back("purpose");

            if (!categories.empty())
                invalid_attributes.push_back("category");

            if (!dirname.empty())
                invalid_attributes.push_back("dirname");

            if(!invalid_attributes.empty())
            {
                detail::outwarn(state.current_file->path)
                    << (invalid_attributes.size() > 1 ?
                        "Invalid attributes" : "Invalid attribute")
                    << " for '" << doc_type << " document info': "
                    << boost::algorithm::join(invalid_attributes, ", ")
                    << "\n"
                    ;
            }
        }

        // Write out header

        if (!nested_file)
        {
            state.out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
                << "<!DOCTYPE "
                << doc_type
                << " PUBLIC \"-//Boost//DTD BoostBook XML V1.0//EN\"\n"
                << "     \"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd\">\n"
                ;
        }

        state.out << '<' << doc_type << "\n"
            << "    id=\""
            << id_placeholder
            << "\"\n";

        if(!lang.empty())
        {
            state.out << "    lang=\""
                << doc_info_output(lang, 106)
                << "\"\n";
        }

        if(doc_type == "library" && !doc_title.empty())
        {
            state.out << "    name=\"" << doc_info_output(doc_title, 106) << "\"\n";
        }

        // Set defaults for dirname + last_revision

        if (!dirname.empty() || doc_type == "library")
        {
            state.out << "    dirname=\"";
            if (!dirname.empty()) {
                state.out << doc_info_output(dirname, 106);
            }
            else if (!id_.empty()) {
                state.out << id_;
            }
            else if (!include_doc_id_.empty()) {
                state.out << include_doc_id_;
            }
            else if (!doc_title.empty()) {
                state.out << detail::make_identifier(doc_title.get_quickbook());
            }
            else {
                state.out << "library";
            }

            state.out << "\"\n";
        }

        state.out << "    last-revision=\"";
        if (!last_revision.empty())
        {
            state.out << doc_info_output(last_revision, 106);
        }
        else
        {
            // default value for last-revision is now

            char strdate[64];
            strftime(
                strdate, sizeof(strdate),
                (debug_mode ?
                    "DEBUG MODE Date: %Y/%m/%d %H:%M:%S $" :
                    "$" /* prevent CVS substitution */ "Date: %Y/%m/%d %H:%M:%S $"),
                current_gm_time
            );

            state.out << strdate;
        }

        state.out << "\" \n";

        if (!xmlbase.empty())
        {
            state.out << "    xml:base=\""
                << xmlbase_value
                << "\"\n";
        }

        state.out << "    xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n";

        std::ostringstream tmp;

        if(!authors.empty())
        {
            tmp << "    <authorgroup>\n";
            BOOST_FOREACH(value_consumer author_values, authors)
            {
                while (author_values.check()) {
                    value surname = author_values.consume(doc_info_tags::author_surname);
                    value first = author_values.consume(doc_info_tags::author_first);
    
                    tmp << "      <author>\n"
                        << "        <firstname>"
                        << doc_info_output(first, 106)
                        << "</firstname>\n"
                        << "        <surname>"
                        << doc_info_output(surname, 106)
                        << "</surname>\n"
                        << "      </author>\n";
                }
            }
            tmp << "    </authorgroup>\n";
        }
コード例 #3
0
    void pre(collector& out, quickbook::actions& actions, bool ignore_docinfo)
    {
        // The doc_info in the file has been parsed. Here's what we'll do
        // *before* anything else.

        value_consumer values = actions.values.release();

        // Skip over invalid attributes

        while (values.check(value::default_tag)) values.consume();
        
        value qbk_version = values.optional_consume(doc_info_tags::qbk_version);
        
        value doc_title;
        if (values.check())
        {
            actions.doc_type = values.consume(doc_info_tags::type).get_quickbook();
            doc_title = values.consume(doc_info_tags::title);
            actions.doc_title_qbk = doc_title.get_quickbook();
        }

        std::vector<std::string> duplicates;

        value id = consume_last_single(values, doc_info_attributes::id, &duplicates);
        value dirname = consume_last_single(values, doc_info_attributes::dirname, &duplicates);
        value last_revision = consume_last_single(values, doc_info_attributes::last_revision, &duplicates);
        value purpose = consume_last_single(values, doc_info_attributes::purpose, &duplicates);
        std::vector<value> categories = consume_multiple(values, doc_info_attributes::category);
        value lang = consume_last_single(values, doc_info_attributes::lang, &duplicates);
        value version = consume_last_single(values, doc_info_attributes::version, &duplicates);
        std::vector<value> authors = consume_multiple(values, doc_info_attributes::authors);
        std::vector<value> copyrights = consume_multiple(values, doc_info_attributes::copyright);
        value license = consume_last_single(values, doc_info_attributes::license, &duplicates);
        std::vector<value> biblioids = consume_multiple(values, doc_info_attributes::biblioid);
        
        // Skip over source-mode tags (already dealt with)

        while (values.check(doc_info_attributes::source_mode)) values.consume();

        values.finish();

        if(!duplicates.empty())
        {
            detail::outwarn(actions.filename,1)
                << (duplicates.size() > 1 ?
                    "Duplicate attributes" : "Duplicate attribute")
                << ":" << detail::utf8(boost::algorithm::join(duplicates, ", "))
                << "\n"
                ;
        }

        bool generated_id = false;

        if (!id.empty())
            actions.doc_id = id.get_quickbook();

        if (actions.doc_id.empty())
        {
            actions.doc_id = detail::make_identifier(actions.doc_title_qbk);
            generated_id = true;
        }

        if (dirname.empty() && actions.doc_type == "library") {
            if (!id.empty()) {
                dirname = id;
            }
            else {
                dirname = qbk_bbk_value(actions.doc_id, doc_info_attributes::dirname);
            }
        }

        if (last_revision.empty())
        {
            // default value for last-revision is now

            char strdate[64];
            strftime(
                strdate, sizeof(strdate),
                (debug_mode ?
                    "DEBUG MODE Date: %Y/%m/%d %H:%M:%S $" :
                    "$" /* prevent CVS substitution */ "Date: %Y/%m/%d %H:%M:%S $"),
                current_gm_time
            );
            last_revision = qbk_bbk_value(strdate, doc_info_attributes::last_revision);
        }

        // if we're ignoring the document info, we're done.
        if (ignore_docinfo)
        {
            return;
        }

        // Quickbook version

        int qbk_major_version, qbk_minor_version;

        if (qbk_version.empty())
        {
            // hard code quickbook version to v1.1
            qbk_major_version = 1;
            qbk_minor_version = 1;
            detail::outwarn(actions.filename,1)
                << "Warning: Quickbook version undefined. "
                "Version 1.1 is assumed" << std::endl;
        }
        else
        {
            value_consumer qbk_version_values(qbk_version);
            qbk_major_version = qbk_version_values.consume().get_int();
            qbk_minor_version = qbk_version_values.consume().get_int();
            qbk_version_values.finish();
        }
        
        qbk_version_n = ((unsigned) qbk_major_version * 100) +
            (unsigned) qbk_minor_version;

        if (qbk_version_n == 106)
        {
            detail::outwarn(actions.filename,1)
                << "Quickbook 1.6 is still under development and is "
                "likely to change in the future." << std::endl;
        }
        else if(qbk_version_n < 100 || qbk_version_n > 106)
        {
            detail::outerr(actions.filename,1)
                << "Unknown version of quickbook: quickbook "
                << qbk_major_version
                << "."
                << qbk_minor_version
                << std::endl;
            ++actions.error_count;
        }

        // Warn about invalid fields

        if (actions.doc_type != "library")
        {
            std::vector<std::string> invalid_attributes;

            if (!purpose.empty())
                invalid_attributes.push_back("purpose");

            if (!categories.empty())
                invalid_attributes.push_back("category");

            if (!dirname.empty())
                invalid_attributes.push_back("dirname");

            if(!invalid_attributes.empty())
            {
                detail::outwarn(actions.filename,1)
                    << (invalid_attributes.size() > 1 ?
                        "Invalid attributes" : "Invalid attribute")
                    << " for '" << detail::utf8(actions.doc_type) << " document info': "
                    << detail::utf8(boost::algorithm::join(invalid_attributes, ", "))
                    << "\n"
                    ;
            }
        }

        // Write out header

        out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
            << "<!DOCTYPE "
            << actions.doc_type
            << " PUBLIC \"-//Boost//DTD BoostBook XML V1.0//EN\"\n"
            << "     \"http://www.boost.org/tools/boostbook/dtd/boostbook.dtd\">\n"
            << '<' << actions.doc_type << "\n"
            << "    id=\""
            << actions.ids.add(actions.doc_id, generated_id ?
                id_generator::generated_doc : id_generator::explicit_id)
            << "\"\n";
        
        if(!lang.empty())
        {
            out << "    lang=\""
                << doc_info_output(lang, 106)
                << "\"\n";
        }

        if(actions.doc_type == "library")
        {
            out << "    name=\"" << doc_info_output(doc_title, 106) << "\"\n";
        }

        if(!dirname.empty())
        {
            out << "    dirname=\""
                << doc_info_output(dirname, 106)
                << "\"\n";
        }

        out << "    last-revision=\""
            << doc_info_output(last_revision, 106)
            << "\" \n"
            << "    xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n";

        std::ostringstream tmp;

        if(!authors.empty())
        {
            tmp << "    <authorgroup>\n";
            BOOST_FOREACH(value_consumer author_values, authors)
            {
                while (author_values.check()) {
                    value surname = author_values.consume(doc_info_tags::author_surname);
                    value first = author_values.consume(doc_info_tags::author_first);
    
                    tmp << "      <author>\n"
                        << "        <firstname>"
                        << doc_info_output(first, 106)
                        << "</firstname>\n"
                        << "        <surname>"
                        << doc_info_output(surname, 106)
                        << "</surname>\n"
                        << "      </author>\n";
                }
            }
            tmp << "    </authorgroup>\n";
        }