]> granicus.if.org Git - graphviz/commitdiff
tests: SvgAnalyzer: add handling of SVG element text node contents
authorMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Mon, 25 Jul 2022 06:49:33 +0000 (08:49 +0200)
committerMagnus Jacobsson <Magnus.Jacobsson@berotec.se>
Tue, 16 Aug 2022 10:21:45 +0000 (12:21 +0200)
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/test_svg_analyzer.cpp

index 9a1e5a106c4d1bc597406141ca3c4f28f4c28217..6e18fc91d7b1d5b86b9c5ba18390e7cc24d3ab08 100644 (file)
@@ -88,6 +88,11 @@ void SVGAnalyzer::enter_element(SVG::SVGElementType type) {
   m_elements_in_process.push_back(&element.children.back());
 }
 
+void SVGAnalyzer::set_text(std::string_view text) {
+  auto &element = current_element();
+  element.text = text;
+}
+
 std::string SVGAnalyzer::svg_string(std::size_t indent_size) const {
   std::string output{};
   output += m_svg.to_string(indent_size);
index 31f9507df3e8d499819dc33c79b284dcf6f6a1e7..208a57b2feeaea283314c0c7c31f5d8885ff4ade 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <cstddef>
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "svg_analyzer_interface.h"
@@ -26,6 +27,7 @@ public:
   void on_enter_element_text() override;
   void on_enter_element_title() override;
   void on_exit_element() 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; };
   std::size_t num_circles() const { return m_num_circles; };
index 57d24ab7405693dd46b20fe77789ab8247de8dcb..7ea80454ab3fbde3bb4cced790ccfd6ecf1efb6f 100644 (file)
@@ -1,5 +1,7 @@
 #pragma once
 
+#include <string_view>
+
 /**
  * @brief The ISVGAnalyzer class is an interface class declaring
  * callbacks that can be implemented by an SVGAnalyzer class. Its
@@ -24,4 +26,5 @@ public:
   virtual void on_enter_element_text() = 0;
   virtual void on_enter_element_title() = 0;
   virtual void on_exit_element() = 0;
+  virtual void set_text(std::string_view text) = 0;
 };
index 20bac09e0b505bc4d6b8f3665ab5406267f42708..df0517f00dc4a5b9ff3d36c1f7453974ad1fdf5b 100644 (file)
@@ -5,6 +5,29 @@
 
 SVG::SVGElement::SVGElement(SVGElementType type) : type(type) {}
 
+static std::string xml_encode(const std::string &text) {
+  std::string out;
+  for (const char &ch : text) {
+    switch (ch) {
+    case '>':
+      out += "&gt;";
+      break;
+    case '<':
+      out += "&lt;";
+      break;
+    case '-':
+      out += "&#45;";
+      break;
+    case '&':
+      out += "&amp;";
+      break;
+    default:
+      out += ch;
+    }
+  }
+  return out;
+}
+
 std::string SVG::SVGElement::to_string(std::size_t indent_size = 2) const {
   std::string output;
   output += R"(<?xml version="1.0" encoding="UTF-8" standalone="no"?>)"
@@ -26,14 +49,20 @@ void SVG::SVGElement::to_string_impl(std::string &output,
   output += "<";
   output += tag(type);
 
-  if (children.empty()) {
+  if (children.empty() && text.empty()) {
     output += "/>\n";
   } else {
-    output += ">\n";
-    for (const auto &child : children) {
-      child.to_string_impl(output, indent_size, current_indent + indent_size);
+    output += ">";
+    if (!text.empty()) {
+      output += xml_encode(text);
+    }
+    if (!children.empty()) {
+      output += "\n";
+      for (const auto &child : children) {
+        child.to_string_impl(output, indent_size, current_indent + indent_size);
+      }
+      output += indent_str;
     }
-    output += indent_str;
     output += "</";
     output += tag(type);
     output += ">\n";
index cd9cc4ecc7b8825a8302e0db508b196df0669914..7ab2210bba5c373c48b6b986bb56ecc14fbcb04f 100644 (file)
@@ -34,6 +34,9 @@ public:
   std::string to_string(std::size_t indent_size) const;
 
   std::vector<SVGElement> children;
+  /// The SVG element text node contents. Not to be confused with an SVG `text`
+  /// element
+  std::string text;
   /// The type of SVG element
   const SVGElementType type;
 
index f3915e6f6f1461eb44d48340d31a62c9c36bb456..e87a5cdbc01f123d90903115688d0962f0916bc1 100644 (file)
@@ -179,7 +179,6 @@ void SvgppContext::set_impl(svgpp::tag::attribute::points &points,
   // ignore for now
 }
 
-void SvgppContext::set_text_impl(const std::any &range) {
-  (void)range;
-  // ignore for now
+void SvgppContext::set_text(boost::iterator_range<const char *> v) {
+  m_svgAnalyzer->set_text({v.begin(), v.end()});
 }
index b086ebce54d03491eb8db329cbf54bc64a2d12ed..d23e57804a83a51e74c67e3d5e94f586d616b72a 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <any>
 
+#include <boost/range/iterator_range_core.hpp>
 #include <svgpp/svgpp.hpp>
 
 class ISVGAnalyzer;
@@ -62,13 +63,10 @@ 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);
-  template <class Range> void set_text(const Range &range) {
-    set_text_impl(range);
-  }
+  void set_text(boost::iterator_range<const char *> v);
 
 private:
   void set_impl(svgpp::tag::attribute::points &points, const std::any &range);
-  void set_text_impl(const std::any &range);
 
   ISVGAnalyzer *m_svgAnalyzer = nullptr;
 };
index aba839a1334b9727caf032366afadf1ec0cb3c49..6e5f57bab2c2d5a799731a22b8a477d7708c0790 100644 (file)
@@ -134,9 +134,12 @@ TEST_CASE(
     CHECK(recreated_svg.find("</svg>") != std::string::npos);
     CHECK(recreated_svg.find("<g>") != std::string::npos);
     CHECK(recreated_svg.find("</g>") != std::string::npos);
-    CHECK(recreated_svg.find("<title/>") != std::string::npos);
+    CHECK(recreated_svg.find("<title>g1</title>") != std::string::npos);
+    CHECK(recreated_svg.find("<title>a</title>") != std::string::npos);
+    CHECK(recreated_svg.find("<title>b</title>") != std::string::npos);
     if (shape != "point") {
-      CHECK(recreated_svg.find("<text/>") != std::string::npos);
+      CHECK(recreated_svg.find("<text>a</text>") != std::string::npos);
+      CHECK(recreated_svg.find("<text>b</text>") != std::string::npos);
     }
     CHECK(recreated_svg.find("<polygon/>") != std::string::npos);
     CHECK(recreated_svg.find("<path/>") != std::string::npos);