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);
#include <cstddef>
#include <string>
+#include <string_view>
#include <vector>
#include "svg_analyzer_interface.h"
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; };
#pragma once
+#include <string_view>
+
/**
* @brief The ISVGAnalyzer class is an interface class declaring
* callbacks that can be implemented by an SVGAnalyzer class. Its
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;
};
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 += ">";
+ break;
+ case '<':
+ out += "<";
+ break;
+ case '-':
+ out += "-";
+ break;
+ case '&':
+ out += "&";
+ 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"?>)"
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";
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;
// 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()});
}
#include <any>
+#include <boost/range/iterator_range_core.hpp>
#include <svgpp/svgpp.hpp>
class ISVGAnalyzer;
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;
};
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);