]> granicus.if.org Git - graphviz/commitdiff
tests: SvgAnalyzer: add handling of the 'class' attribute
authorMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Sat, 23 Jul 2022 10:50:06 +0000 (12:50 +0200)
committerMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Tue, 16 Aug 2022 10:21:45 +0000 (12:21 +0200)
This will be used in an upcoming commit to identify Graphviz graphs,
nodes and edges.

tests/svg_analyzer.cpp
tests/svg_analyzer.h
tests/svg_analyzer_interface.h
tests/svg_element.cpp
tests/svg_element.h
tests/svgpp_context.cpp
tests/svgpp_context.h
tests/svgpp_document_traverser.cpp
tests/test_svg_analyzer.cpp

index 239ea91ff55aaac008998159b8e0d41ecb1a3b06..e688b7825fe1b9f457b1c09211ccee9d6e8b8811 100644 (file)
@@ -111,6 +111,10 @@ void SVGAnalyzer::enter_element(SVG::SVGElementType type) {
   m_elements_in_process.push_back(&element.children.back());
 }
 
+void SVGAnalyzer::set_class(std::string_view class_) {
+  current_element().attributes.class_ = class_;
+}
+
 void SVGAnalyzer::set_text(std::string_view text) {
   auto &element = current_element();
   element.text = text;
index 6a005876ccc5d7c05d1507380f392f6fb1d10cf9..f8e7a4c9de6b5fd8012fb2dd5dc9e32c6b6ef01b 100644 (file)
@@ -27,6 +27,7 @@ public:
   void on_enter_element_text() override;
   void on_enter_element_title() override;
   void on_exit_element() override;
+  void set_class(std::string_view) override;
   void set_text(std::string_view text) override;
   std::size_t num_svgs() const { return m_num_svgs; };
   std::size_t num_groups() const { return m_num_groups; };
index 7ea80454ab3fbde3bb4cced790ccfd6ecf1efb6f..a81a5804b9c989caf40ae76ead52a9a13d0e33ec 100644 (file)
@@ -26,5 +26,6 @@ public:
   virtual void on_enter_element_text() = 0;
   virtual void on_enter_element_title() = 0;
   virtual void on_exit_element() = 0;
+  virtual void set_class(std::string_view) = 0;
   virtual void set_text(std::string_view text) = 0;
 };
index c842a4b90106895296357862a739db4f98f58f85..97c4545ef507caf581c735b6a4a1582965d56b41 100644 (file)
@@ -1,3 +1,5 @@
+#include <stdexcept>
+
 #include <fmt/format.h>
 
 #include "svg_element.h"
@@ -57,6 +59,41 @@ void SVG::SVGElement::to_string_impl(std::string &output,
   output += "<";
   output += tag(type);
 
+  std::string attributes_str{};
+  switch (type) {
+  case SVG::SVGElementType::Ellipse:
+    // ignore for now
+    break;
+  case SVG::SVGElementType::Group:
+    attributes_str += fmt::format(R"(class="{}")", attributes.class_);
+    break;
+  case SVG::SVGElementType::Path:
+    // ignore for now
+    break;
+  case SVG::SVGElementType::Polygon:
+    // ignore for now
+    break;
+  case SVG::SVGElementType::Polyline:
+    // ignore for now
+    break;
+  case SVG::SVGElementType::Svg:
+    // ignore for now
+    break;
+  case SVG::SVGElementType::Text:
+    // ignore for now
+    break;
+  case SVG::SVGElementType::Title:
+    // Graphviz doesn't generate attributes on 'title' elements
+    break;
+  default:
+    throw std::runtime_error{fmt::format(
+        "Attributes on '{}' elements are not yet implemented", tag(type))};
+  }
+  if (!attributes_str.empty()) {
+    output += " ";
+  }
+  output += attributes_str;
+
   if (children.empty() && text.empty()) {
     output += "/>\n";
   } else {
index 6ef88f1e510c84cd88ce50a01df4f426ce3299f1..bf3e206b0f5280b62f2e2fee9849f00423ce2477 100644 (file)
@@ -22,6 +22,10 @@ enum class SVGElementType {
 
 std::string_view tag(SVG::SVGElementType type);
 
+struct SVGAttributes {
+  std::string class_;
+};
+
 /**
  * @brief The SVGElement class represents an SVG element
  */
@@ -33,6 +37,7 @@ public:
 
   std::string to_string(std::size_t indent_size) const;
 
+  SVGAttributes attributes;
   /// The Graphviz build date
   std::string graphviz_build_date;
   std::vector<SVGElement> children;
index e87a5cdbc01f123d90903115688d0962f0916bc1..f09ec6d449d3be713dde7019f2f8a211a5f4c797 100644 (file)
@@ -172,6 +172,11 @@ void SvgppContext::set(svgpp::tag::attribute::height a, const double v) {
   (void)v;
 }
 
+void SvgppContext::set(svgpp::tag::attribute::class_,
+                       boost::iterator_range<const char *> v) {
+  m_svgAnalyzer->set_class({v.begin(), v.end()});
+}
+
 void SvgppContext::set_impl(svgpp::tag::attribute::points &points,
                             const std::any &range) {
   (void)points;
index d23e57804a83a51e74c67e3d5e94f586d616b72a..c66abb169f4f6e0497ba92f8b4d2af440c63fdcd 100644 (file)
@@ -63,6 +63,8 @@ public:
   void set(svgpp::tag::attribute::y y, double v);
   void set(svgpp::tag::attribute::width width, double v);
   void set(svgpp::tag::attribute::height height, double v);
+  void set(svgpp::tag::attribute::class_ a,
+           boost::iterator_range<const char *> v);
   void set_text(boost::iterator_range<const char *> v);
 
 private:
index 93f941f13a1d3a44de960f61a8d158c9fad9347e..c22cfd2967426f8cda1292143f078284b86e3419 100644 (file)
@@ -24,10 +24,14 @@ void traverseDocumentWithSvgpp(SvgppContext &context, char *text) {
         svgpp::tag::element::rect, svgpp::tag::element::text,
         svgpp::tag::element::title>::type;
 
+    using processed_attributes_t =
+        boost::mpl::set<svgpp::traits::shapes_attributes_by_element,
+                        svgpp::tag::attribute::class_ //
+                        >::type;
+
     svgpp::document_traversal<
         svgpp::processed_elements<processed_elements_t>,
-        svgpp::processed_attributes<
-            svgpp::traits::shapes_attributes_by_element>,
+        svgpp::processed_attributes<processed_attributes_t>,
         svgpp::basic_shapes_policy<svgpp::policy::basic_shapes::raw>>::
         load_document(xml_root_element, context);
   }
index 84a2f37ee19659acfb1fb0f73ee45bf763741add..fb97d6ae223ca68e9750dec1231d60989da69ca0 100644 (file)
@@ -135,7 +135,9 @@ TEST_CASE(
     // yet compare with the original SVG
     CHECK(recreated_svg.find("<svg>") != std::string::npos);
     CHECK(recreated_svg.find("</svg>") != std::string::npos);
-    CHECK(recreated_svg.find("<g>") != std::string::npos);
+    CHECK(recreated_svg.find("<g class=\"graph\">") != std::string::npos);
+    CHECK(recreated_svg.find("<g class=\"node\">") != std::string::npos);
+    CHECK(recreated_svg.find("<g class=\"edge\">") != std::string::npos);
     CHECK(recreated_svg.find("</g>") != std::string::npos);
     CHECK(recreated_svg.find("<title>g1</title>") != std::string::npos);
     CHECK(recreated_svg.find("<title>a</title>") != std::string::npos);