diff --git a/README.md b/README.md index f9428ce..6885415 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -SVG++ library 1.2 +SVG++ library 1.2.1 ======================= Please visit http://svgpp.org/ for description, tutorial and reference. @@ -44,8 +44,9 @@ Take a look at [Tutorial](http://svgpp.org/lesson01.html) to get the idea about ####What's new#### -SVG++ update 1.2 focuses on reducing compiler memory usage by allowing separation -of template heavy Boost.Spirit code to other compilation unit. +* SVG++ update 1.2.1 fixes handling text content inside `` element that is a child of `` element. +* SVG++ update 1.2 focuses on reducing compiler memory usage by allowing separation + of template heavy Boost.Spirit code to other compilation unit. ####How to Help#### diff --git a/include/svgpp/definitions.hpp b/include/svgpp/definitions.hpp index 7dcef5c..8ec47d7 100644 --- a/include/svgpp/definitions.hpp +++ b/include/svgpp/definitions.hpp @@ -143,4 +143,7 @@ namespace length_dimension struct iri_fragment {}; // Prefixes fragment part of IRI in arguments list +struct text_content; // Used in child element sequences together with tag::element::* tags to + // mark elements that should handle character data content + }} // namespace tag diff --git a/include/svgpp/document_traversal.hpp b/include/svgpp/document_traversal.hpp index ff83956..eb09348 100644 --- a/include/svgpp/document_traversal.hpp +++ b/include/svgpp/document_traversal.hpp @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include @@ -191,7 +190,7 @@ class document_traversal static typename boost::enable_if< boost::mpl::and_< boost::mpl::empty::type>, - boost::mpl::not_ > >, bool>::type + boost::mpl::not_ > >, bool>::type load_element_content(XMLElement const &, Context const &, ElementTag) { return true; @@ -201,7 +200,7 @@ class document_traversal static typename boost::disable_if< boost::mpl::or_< boost::mpl::empty::type>, - traits::element_with_text_content >, bool>::type + boost::mpl::has_key >, bool>::type load_element_content(XMLElement const & xml_element, Context & context, ElementTag element_tag) { typedef typename boost::parameter::value_type - static typename boost::enable_if, bool>::type + static typename boost::enable_if, bool>::type load_element_content(XMLElement const & xml_element, Context & context, ElementTag element_tag) { typedef typename boost::parameter::value_type struct child_element_types; template -struct child_element_types, ElementTag> >::type> { typedef boost::mpl::set0<> type; }; +template +struct child_element_types, ElementTag> >::type> +{ + typedef boost::mpl::set1 type; +}; + template struct child_element_types boost::mpl::joint_view< traits::animation_elements, traits::descriptive_elements>, - boost::mpl::set5< + boost::mpl::set6< tag::element::altGlyph, tag::element::textPath, tag::element::tref, tag::element::tspan, - tag::element::a + tag::element::a, + tag::text_content >, boost::mpl::insert >::type type; @@ -114,14 +123,15 @@ struct child_element_types, boost::mpl::insert >::type type; diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index fe38e60..7507d2c 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -34,7 +34,8 @@ add_executable( ParserGTest dictionary_test.cpp attribute_traversal_test.cpp css_style_iterator_test.cpp - clock_value_grammar_test.cpp + clock_value_grammar_test.cpp + document_traversal_a_test.cpp icc_color_grammar_test.cpp length_factory_test.cpp list_of_points_test.cpp diff --git a/src/test/document_traversal_a_test.cpp b/src/test/document_traversal_a_test.cpp new file mode 100644 index 0000000..d0de659 --- /dev/null +++ b/src/test/document_traversal_a_test.cpp @@ -0,0 +1,191 @@ +#include +#include +#include +#include + +#include + +#define TEXT(x) #x + +namespace +{ + struct AInSvgContext; + + struct SvgContext + { + SvgContext(std::ostringstream & log): log(log) { log << ""; } + SvgContext(SvgContext & parent): log(parent.log) { log << ""; } + SvgContext(AInSvgContext & parent); + + void on_exit_element() {} + + std::ostringstream & log; + }; + + struct AInSvgContext + { + AInSvgContext(SvgContext & parent) : log(parent.log) { log << ""; } + void on_exit_element() {} + + std::ostringstream & log; + }; + + struct RectContext + { + RectContext(SvgContext & parent) { parent.log << ""; } + RectContext(AInSvgContext & parent) { parent.log << ""; } + void on_exit_element() {} + }; + + struct EllipseContext + { + EllipseContext(SvgContext & parent) { parent.log << ""; } + EllipseContext(AInSvgContext & parent) { parent.log << ""; } + void on_exit_element() {} + }; + + struct TextContext + { + TextContext(SvgContext & parent): log(parent.log) { parent.log << ""; } + TextContext(AInSvgContext & parent): log(parent.log) { parent.log << ""; } + + void on_exit_element() {} + template + void set_text(TextRange const & text) { log << std::string(boost::begin(text), boost::end(text));} + + std::ostringstream & log; + }; + + struct AInTextContext + { + AInTextContext(TextContext & parent): log(parent.log) { parent.log << ""; } + + void on_exit_element() {} + template + void set_text(TextRange const & text) { log << std::string(boost::begin(text), boost::end(text)); } + + std::ostringstream & log; + }; + + SvgContext::SvgContext(AInSvgContext & parent): log(parent.log) { log << ""; } + + struct context_factories + { + template + struct apply; + }; + + template<> + struct context_factories::apply + { + typedef svgpp::factory::context::on_stack type; + }; + + template<> + struct context_factories::apply + { + typedef svgpp::factory::context::on_stack type; + }; + + template<> + struct context_factories::apply + { + typedef svgpp::factory::context::on_stack type; + }; + + template<> + struct context_factories::apply + { + typedef svgpp::factory::context::on_stack type; + }; + + template<> + struct context_factories::apply + { + typedef svgpp::factory::context::on_stack type; + }; + + template<> + struct context_factories::apply + { + typedef svgpp::factory::context::on_stack type; + }; + + template<> + struct context_factories::apply + { + typedef svgpp::factory::context::on_stack type; + }; + + template<> + struct context_factories::apply + { + typedef svgpp::factory::context::on_stack type; + }; + + template<> + struct context_factories::apply + { + typedef svgpp::factory::context::on_stack type; + }; + + template<> + struct context_factories::apply + { + typedef svgpp::factory::context::on_stack type; + }; + + char const xml1[] = + TEXT() + TEXT() + TEXT() + TEXT( ) + TEXT() + TEXT() + TEXT( ) + TEXT( Some text string) + TEXT( ) + TEXT() + TEXT() + ; +} + +TEST(DocumentTraversal, a) +{ + std::vector modified_xml(xml1, xml1 + strlen(xml1) + 1); + rapidxml_ns::xml_document doc; + doc.parse<0>(&modified_xml[0]); + rapidxml_ns::xml_node const * svg_element = doc.first_node(); + ASSERT_TRUE(svg_element != NULL); + std::ostringstream str; + SvgContext context(str); + EXPECT_TRUE(( + svgpp::document_traversal< + svgpp::processed_elements< + boost::mpl::set< + svgpp::tag::element::svg, + svgpp::tag::element::ellipse, + svgpp::tag::element::rect, + svgpp::tag::element::text, + svgpp::tag::element::a + >::type + >, + svgpp::processed_attributes< + boost::mpl::set<>::type + >, + svgpp::context_factories, + svgpp::basic_shapes_policy + >::load_document(svg_element, context))); + + std::ostringstream expected_str; + { + SvgContext c1(expected_str); + RectContext c2(c1); + AInSvgContext c3(c1); + EllipseContext c4(c3); + TextContext c5(c1); + AInTextContext c6(c5); + c6.set_text(std::string("Some text string")); + } + EXPECT_EQ(expected_str.str(), str.str()); +} \ No newline at end of file