Advanced Topics¶
Adding new XML parser¶
Implementing support for the new XML parser requires creating new specializations for
svgpp::policy::xml::attribute_iterator and svgpp::policy::xml::element_iterator
class templates using one of existing implementations in folder include/svgpp/policy/xml as a sample.
Understanding following types may cause some difficulties:
template<>
struct attribute_iterator<CustomXMLAttribute>
{
typedef /* ... */ string_type;
typedef /* ... */ attribute_name_type;
typedef /* ... */ attribute_value_type;
typedef /* ... */ saved_value_type;
/* ... */
};
string_typeA model of Forward Range, with items of some character type (
char,wchar_t,char16_t,char32_t). Easy solution is to useboost::iterator_range<CharT const *>.attribute_name_typeCopy constructible type, for which exists method
string_type attribute_iterator::get_string_range(attribute_name_type const &). Value ofattribute_name_typeis used only beforeattribute_iteratorgets incremented and may become invalid after that.attribute_value_typeCopy constructible type, for which exists method
string_type attribute_iterator::get_string_range(attribute_value_type const &). Value ofattribute_value_typemust be accessible independently ofattribute_iteratorstate changes.saved_value_typeCopy constructible type, for which exists method
attribute_value_type attribute_iterator::get_value(saved_value_type const &). Object of this type must as efficiently as possible save attribute value that may be not requested. For example XML parser provides access to XML attribute like this:class XmlAttribute { public: std::string getValue() const; };
In this case
saved_value_typemay be defined asXmlAttribute const *, instead ofstd::string, to avoid expenses of creating and copying a string that may not be requested later.
Value Parsers¶
To choose proper value_parser for the attribute, traits::attribute_type metafunction should be used:
template<class Element, class Attribute>
struct attribute_type
{
typedef /*unspecified*/ type;
};
The returned type can be:
One of type tags. E.g. width, as many others attributes has <length> type (corresponds to
tag::type::length):BOOST_MPL_ASSERT(( boost::is_same< traits::attribute_type<tag::element::rect, tag::attribute::width>::type, tag::type::length> ));
Attribute tag. E.g. viewBox has its own syntax:
BOOST_MPL_ASSERT(( boost::is_same< traits::attribute_type<tag::element::svg, tag::attribute::viewBox>::type, tag::attribute::viewBox> ));
Pair <element tag, attribute tag>. E.g. type attribute may get different values in elements animateTransform, feColorMatrix, feTurbulence etc.:
BOOST_MPL_ASSERT(( boost::is_same< traits::attribute_type<tag::element::animateTransform, tag::attribute::type>::type, boost::mpl::pair<tag::element::animateTransform, tag::attribute::type> > ));
Attribute value parsers interface:
template<class ValueType, class Args..>
struct value_parser
{
template<class AttributeTag, class Context, class AttributeValue, class PropertySource>
static bool parse(AttributeTag tag, Context & context, AttributeValue const & attribute_value,
PropertySource source);
};
AttributeTag tagIs passed to context, isn’t used by
value_parseritselfContext & contextReference to the context that will receive parsed value.
AttributeValue const & attribute_valueAttribute string value
PropertySource sourceOne of two possible types:
tag::source::attributeortag::source::css, depending on whether value if from SVG attribute or CSS property.