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 use boost::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 of attribute_name_type is used only before attribute_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 of attribute_value_type must be accessible independently of attribute_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 as XmlAttribute const *, instead of std::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 or tag::source::css, depending on whether value if from SVG attribute or CSS property.