aboutsummaryrefslogtreecommitdiff
path: root/lib/mstch/src/state
diff options
context:
space:
mode:
authorMistivia <i@mistivia.com>2025-01-16 15:43:04 +0800
committerMistivia <i@mistivia.com>2025-01-16 15:53:58 +0800
commit8689a7c78c50676ea739f52fbcee9f091709f5c0 (patch)
treebbb72c68e5e1753f751133941a402caa43e29a16 /lib/mstch/src/state
parent00afb767ae37488d99f78363d031b898b1932354 (diff)
add mstch
Diffstat (limited to 'lib/mstch/src/state')
-rw-r--r--lib/mstch/src/state/in_section.cpp34
-rw-r--r--lib/mstch/src/state/in_section.hpp24
-rw-r--r--lib/mstch/src/state/outside_section.cpp32
-rw-r--r--lib/mstch/src/state/outside_section.hpp12
-rw-r--r--lib/mstch/src/state/render_state.hpp17
5 files changed, 119 insertions, 0 deletions
diff --git a/lib/mstch/src/state/in_section.cpp b/lib/mstch/src/state/in_section.cpp
new file mode 100644
index 0000000..a139913
--- /dev/null
+++ b/lib/mstch/src/state/in_section.cpp
@@ -0,0 +1,34 @@
+#include "in_section.hpp"
+#include "outside_section.hpp"
+#include "visitor/is_node_empty.hpp"
+#include "visitor/render_section.hpp"
+
+using namespace mstch;
+
+in_section::in_section(type type, const token& start_token):
+ m_type(type), m_start_token(start_token), m_skipped_openings(0)
+{
+}
+
+std::string in_section::render(render_context& ctx, const token& token) {
+ if (token.token_type() == token::type::section_close)
+ if (token.name() == m_start_token.name() && m_skipped_openings == 0) {
+ auto& node = ctx.get_node(m_start_token.name());
+ std::string out;
+
+ if (m_type == type::normal && !visit(is_node_empty(), node))
+ out = visit(render_section(ctx, m_section, m_start_token.delims()), node);
+ else if (m_type == type::inverted && visit(is_node_empty(), node))
+ out = render_context::push(ctx).render(m_section);
+
+ ctx.set_state<outside_section>();
+ return out;
+ } else
+ m_skipped_openings--;
+ else if (token.token_type() == token::type::inverted_section_open ||
+ token.token_type() == token::type::section_open)
+ m_skipped_openings++;
+
+ m_section << token;
+ return "";
+}
diff --git a/lib/mstch/src/state/in_section.hpp b/lib/mstch/src/state/in_section.hpp
new file mode 100644
index 0000000..14ca2f7
--- /dev/null
+++ b/lib/mstch/src/state/in_section.hpp
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <sstream>
+#include <vector>
+
+#include "render_state.hpp"
+#include "template_type.hpp"
+
+namespace mstch {
+
+class in_section: public render_state {
+ public:
+ enum class type { inverted, normal };
+ in_section(type type, const token& start_token);
+ std::string render(render_context& context, const token& token) override;
+
+ private:
+ const type m_type;
+ const token& m_start_token;
+ template_type m_section;
+ int m_skipped_openings;
+};
+
+}
diff --git a/lib/mstch/src/state/outside_section.cpp b/lib/mstch/src/state/outside_section.cpp
new file mode 100644
index 0000000..c9817b1
--- /dev/null
+++ b/lib/mstch/src/state/outside_section.cpp
@@ -0,0 +1,32 @@
+#include "outside_section.hpp"
+
+#include "visitor/render_node.hpp"
+#include "in_section.hpp"
+#include "render_context.hpp"
+
+using namespace mstch;
+
+std::string outside_section::render(
+ render_context& ctx, const token& token)
+{
+ using flag = render_node::flag;
+ switch (token.token_type()) {
+ case token::type::section_open:
+ ctx.set_state<in_section>(in_section::type::normal, token);
+ break;
+ case token::type::inverted_section_open:
+ ctx.set_state<in_section>(in_section::type::inverted, token);
+ break;
+ case token::type::variable:
+ return visit(render_node(ctx, flag::escape_html), ctx.get_node(token.name()));
+ case token::type::unescaped_variable:
+ return visit(render_node(ctx, flag::none), ctx.get_node(token.name()));
+ case token::type::text:
+ return token.raw();
+ case token::type::partial:
+ return ctx.render_partial(token.name(), token.partial_prefix());
+ default:
+ break;
+ }
+ return "";
+}
diff --git a/lib/mstch/src/state/outside_section.hpp b/lib/mstch/src/state/outside_section.hpp
new file mode 100644
index 0000000..8617dce
--- /dev/null
+++ b/lib/mstch/src/state/outside_section.hpp
@@ -0,0 +1,12 @@
+#pragma once
+
+#include "render_state.hpp"
+
+namespace mstch {
+
+class outside_section: public render_state {
+ public:
+ std::string render(render_context& context, const token& token) override;
+};
+
+}
diff --git a/lib/mstch/src/state/render_state.hpp b/lib/mstch/src/state/render_state.hpp
new file mode 100644
index 0000000..e44a956
--- /dev/null
+++ b/lib/mstch/src/state/render_state.hpp
@@ -0,0 +1,17 @@
+#pragma once
+
+#include <memory>
+
+#include "token.hpp"
+
+namespace mstch {
+
+class render_context;
+
+class render_state {
+ public:
+ virtual ~render_state() {}
+ virtual std::string render(render_context& context, const token& token) = 0;
+};
+
+}