#include "render_context.hpp" #include "state/outside_section.hpp" #include "visitor/get_token.hpp" using namespace mstch; const mstch::node render_context::null_node; render_context::push::push(render_context& context, const mstch::node& node): m_context(context) { context.m_nodes.emplace_front(node); context.m_node_ptrs.emplace_front(&node); context.m_state.push(std::unique_ptr(new outside_section)); } render_context::push::~push() { m_context.m_nodes.pop_front(); m_context.m_node_ptrs.pop_front(); m_context.m_state.pop(); } std::string render_context::push::render(const template_type& templt) { return m_context.render(templt); } render_context::render_context( const mstch::node& node, const std::map& partials): m_partials(partials), m_nodes(1, node), m_node_ptrs(1, &node) { m_state.push(std::unique_ptr(new outside_section)); } const mstch::node& render_context::find_node( const std::string& token, std::list current_nodes) { if (token != "." && token.find('.') != std::string::npos) return find_node(token.substr(token.rfind('.') + 1), {&find_node(token.substr(0, token.rfind('.')), current_nodes)}); else for (auto& node: current_nodes) if (visit(has_token(token), *node)) return visit(get_token(token, *node), *node); return null_node; } const mstch::node& render_context::get_node(const std::string& token) { return find_node(token, m_node_ptrs); } std::string render_context::render( const template_type& templt, const std::string& prefix) { std::string output; bool prev_eol = true; for (auto& token: templt) { if (prev_eol && prefix.length() != 0) output += m_state.top()->render(*this, {prefix}); output += m_state.top()->render(*this, token); prev_eol = token.eol(); } return output; } std::string render_context::render_partial( const std::string& partial_name, const std::string& prefix) { return m_partials.count(partial_name) ? render(m_partials.at(partial_name), prefix) : ""; }