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_type
- A 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_type
- Copy constructible type, for which exists method
string_type attribute_iterator::get_string_range(attribute_name_type const &)
. Value ofattribute_name_type
is used only beforeattribute_iterator
gets incremented and may become invalid after that. attribute_value_type
- Copy constructible type, for which exists method
string_type attribute_iterator::get_string_range(attribute_value_type const &)
. Value ofattribute_value_type
must be accessible independently ofattribute_iterator
state changes. saved_value_type
Copy 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_type
may 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 tag
- Is passed to context, isn’t used by
value_parser
itself Context & context
- Reference to the context that will receive parsed value.
AttributeValue const & attribute_value
- Attribute string value
PropertySource source
- One of two possible types:
tag::source::attribute
ortag::source::css
, depending on whether value if from SVG attribute or CSS property.