css-parser-grammar: parse values into iterator_range via boost::spirit::x3::raw directive (no conversions) + cleanup

This commit is contained in:
Artem Pavlenko 2020-02-06 11:23:02 +00:00
parent 0d693b151d
commit 8d73767949
5 changed files with 12 additions and 39 deletions

View file

@ -25,8 +25,6 @@
#include <vector>
#include <unordered_map>
#include <mapnik/color.hpp>
#include <mapnik/util/variant.hpp>
#pragma GCC diagnostic push
#include <mapnik/warning_ignore.hpp>
#include <boost/spirit/home/x3.hpp>
@ -34,7 +32,7 @@
namespace mapnik
{
using property_value_type = mapnik::util::variant<double, mapnik::color, std::string>;
using property_value_type = boost::iterator_range<char const*>;
using css_key_value = std::pair<std::string, property_value_type>;
using definition_type = std::vector<css_key_value>;
using css_data = std::unordered_multimap<std::string, definition_type>;
@ -72,4 +70,4 @@ css_grammar::css_grammar_type const grammar();
css_grammar::css_skipper_type const skipper();
}
#endif // MAPNIK_CSS_COLOR_GRAMMAR_X3_HPP
#endif // MAPNIK_CSS_GRAMMAR_X3_HPP

View file

@ -25,8 +25,6 @@
#define MAPNIK_CSS_GRAMMAR_X3_DEF_HPP
#include <mapnik/css/css_grammar_x3.hpp>
#include <mapnik/css/css_unit_value.hpp>
#include <mapnik/css/css_color_grammar_x3.hpp>
#include <mapnik/json/unicode_string_grammar_x3.hpp>
#pragma GCC diagnostic push
@ -150,24 +148,18 @@ namespace x3 = boost::spirit::x3;
namespace css_grammar {
using x3::lit;
using x3::int_;
using x3::uint_parser;
using x3::hex;
using x3::symbols;
using x3::omit;
using x3::attr;
using x3::double_;
using x3::no_case;
using x3::no_skip;
using x3::lexeme;
using x3::alpha;
using x3::alnum;
using x3::char_;
using x3::raw;
using x3::standard::space;
// import unicode string rule
namespace { auto const& css_string = mapnik::json::grammar::unicode_string; }
namespace { auto const& css_color = mapnik::css_color_grammar::css_color; }
auto assign_def = [] (auto const& ctx)
{
@ -183,16 +175,11 @@ auto assign_key = [] (auto const& ctx)
};
auto assign_value = [] (auto const& ctx) {_val(ctx).second = std::move(_attr(ctx));};
auto apply_value = [](auto const& ctx) { _val(ctx) = _attr(ctx); };
auto apply_units = [](auto const& ctx) { _val(ctx) *= _attr(ctx);};
// units
const mapnik::css_unit_value unit_value;
// rules
x3::rule<class simple_selector_tag, std::string> const simple_selector {"Simple selector"};
x3::rule<class selector_tag, std::vector<std::string>> const selector {"Selector"};
x3::rule<class number_tag, double> const number{"number"};
x3::rule<class value_tag, property_value_type> const value {"value"};
x3::rule<class value_tag, property_value_type> const value {"Value"};
x3::rule<class key_value_tag, css_key_value> const key_value {"CSS Key/Value"};
x3::rule<class definition_tag, std::pair<std::vector<std::string>, definition_type>> const definition {"CSS Definition"};
@ -202,8 +189,7 @@ auto const simple_selector_def = lexeme[ident >> -((char_('.') | char_('#') | ch
| lexeme[char_('.') >> ident >> -(char_(':') >> ident)];
auto const selector_def = simple_selector % lit(',');
auto const number_def = lexeme[double_[apply_value] > -unit_value[apply_units]];
auto const value_def = number | css_color | lexeme[+~char_(";}")];
auto const value_def = raw[lexeme[+~char_(";}")]];
auto const key_value_def = lexeme[ident][assign_key] >> lit(':') >> value[assign_value] >> -lit(';');
auto const definition_def = selector >> lit('{') >> *key_value >> lit('}');
@ -219,7 +205,6 @@ BOOST_SPIRIT_DEFINE(
css_classes,
simple_selector,
selector,
number,
value,
key_value,
definition,

View file

@ -20,7 +20,6 @@
*
*****************************************************************************/
#include <mapnik/css/css_grammar_x3.hpp>
#include <mapnik/css/css_color_grammar_x3_def.hpp>
#if BOOST_VERSION < 107000
#include <mapnik/image_filter_types.hpp>
@ -29,13 +28,9 @@ namespace mapnik { namespace css_color_grammar {
namespace x3 = boost::spirit::x3;
using iterator_type = std::string::const_iterator;
using iterator_css_type = char const*;
using context_type = x3::phrase_parse_context<x3::ascii::space_type>::type;
using context_css_type = x3::phrase_parse_context<css_grammar::css_skipper_type>::type;
BOOST_SPIRIT_INSTANTIATE(css_color_grammar_type, iterator_type, context_type);
BOOST_SPIRIT_INSTANTIATE(css_color_grammar_type, iterator_css_type, context_css_type);
#if BOOST_VERSION < 107000
template bool parse_rule<iterator_type, context_type, mapnik::filter::color_to_alpha>

View file

@ -21,7 +21,6 @@
*****************************************************************************/
#include <mapnik/css/css_grammar_x3_def.hpp>
#include <mapnik/css/css_color_grammar_x3.hpp>
namespace mapnik { namespace css_grammar {

View file

@ -66,10 +66,9 @@ void print_css(mapnik::css_data & data)
std::cerr << std::get<0>(kv) << " {" << std::endl;
for (auto const& def : std::get<1>(kv))
{
std::cerr << " " << std::get<0>(def) << ":";
mapnik::util::apply_visitor([](auto const& val){
std::cerr << val << std::endl;
}, std::get<1>(def));
auto const& r = std::get<1>(def);
std::cerr << " " << std::get<0>(def) << ":"
<< std::string(r.begin(), r.end());
}
std::cerr << "}" << std::endl;
}
@ -464,12 +463,10 @@ void process_css(svg_parser & parser, rapidxml::xml_node<char> const* node)
std::ostringstream ss;
for (auto const& def : style)
{
std::ostringstream ss;
mapnik::util::apply_visitor([&](auto const& val) {
ss << val;
}, std::get<1>(def));
//std::cerr << "PARSE ATTR:" << std::get<0>(def) << ":" << ss.str() << std::endl;
parse_attr(parser, std::get<0>(def).c_str(), ss.str().c_str());
auto const& r = std::get<1>(def);
std::string val{r.begin(), r.end()};
//std::cerr << "PARSE ATTR:" << std::get<0>(def) << ":" << val << std::endl;
parse_attr(parser, std::get<0>(def).c_str(), val.c_str());
}
}
}
@ -565,7 +562,6 @@ void traverse_tree(svg_parser & parser, rapidxml::xml_node<char> const* node)
auto const skipper = mapnik::skipper();
char const* first = child->value();
char const* last = first + child->value_size();
std::vector<std::string> classes;
bool result = boost::spirit::x3::phrase_parse(first, last, grammar, skipper, parser.css_data_);
if (result && first == last && !parser.css_data_.empty())
{