Archived
1
0

clang format

This commit is contained in:
Jeff Becker
2017-10-17 10:29:56 -04:00
parent 85248787fc
commit 841c5c6afe
69 changed files with 2381 additions and 2448 deletions

View File

@@ -6,56 +6,48 @@ using namespace mstch;
const mstch::node render_context::null_node;
render_context::push::push(render_context& context, const mstch::node& node):
m_context(context)
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<render_state>(new outside_section));
}
render_context::push::~push() {
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);
}
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<std::string, template_type>& partials):
m_partials(partials), m_nodes(1, node), m_node_ptrs(1, &node)
render_context::render_context(const mstch::node &node, const std::map<std::string, template_type> &partials)
: m_partials(partials), m_nodes(1, node), m_node_ptrs(1, &node)
{
m_state.push(std::unique_ptr<render_state>(new outside_section));
}
const mstch::node& render_context::find_node(
const std::string& token,
std::list<node const*> current_nodes)
const mstch::node &render_context::find_node(const std::string &token, std::list<node const *> 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)});
{&find_node(token.substr(0, token.rfind('.')), current_nodes)});
else
for (auto& node: current_nodes)
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);
}
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 render_context::render(const template_type &templt, const std::string &prefix)
{
std::string output;
bool prev_eol = true;
for (auto& token: templt) {
for (auto &token : templt)
{
if (prev_eol && prefix.length() != 0)
output += m_state.top()->render(*this, {prefix});
output += m_state.top()->render(*this, token);
@@ -64,9 +56,7 @@ std::string render_context::render(
return output;
}
std::string render_context::render_partial(
const std::string& partial_name, const std::string& prefix)
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) : "";
return m_partials.count(partial_name) ? render(m_partials.at(partial_name), prefix) : "";
}

View File

@@ -3,49 +3,45 @@
#include <deque>
#include <list>
#include <sstream>
#include <string>
#include <stack>
#include <string>
#include <mstch/mstch.hpp>
#include "state/render_state.hpp"
#include "template_type.hpp"
#include <mstch/mstch.hpp>
namespace mstch {
namespace mstch
{
class render_context {
public:
class push {
public:
push(render_context& context, const mstch::node& node = {});
class render_context
{
public:
class push
{
public:
push(render_context &context, const mstch::node &node = {});
~push();
std::string render(const template_type& templt);
private:
render_context& m_context;
std::string render(const template_type &templt);
private:
render_context &m_context;
};
render_context(
const mstch::node& node,
const std::map<std::string, template_type>& partials);
const mstch::node& get_node(const std::string& token);
std::string render(
const template_type& templt, const std::string& prefix = "");
std::string render_partial(
const std::string& partial_name, const std::string& prefix);
template<class T, class... Args>
void set_state(Args&& ... args) {
m_state.top() = std::unique_ptr<render_state>(
new T(std::forward<Args>(args)...));
render_context(const mstch::node &node, const std::map<std::string, template_type> &partials);
const mstch::node &get_node(const std::string &token);
std::string render(const template_type &templt, const std::string &prefix = "");
std::string render_partial(const std::string &partial_name, const std::string &prefix);
template <class T, class... Args> void set_state(Args &&... args)
{
m_state.top() = std::unique_ptr<render_state>(new T(std::forward<Args>(args)...));
}
private:
private:
static const mstch::node null_node;
const mstch::node& find_node(
const std::string& token,
std::list<node const*> current_nodes);
const mstch::node &find_node(const std::string &token, std::list<node const *> current_nodes);
std::map<std::string, template_type> m_partials;
std::deque<mstch::node> m_nodes;
std::list<const mstch::node*> m_node_ptrs;
std::list<const mstch::node *> m_node_ptrs;
std::stack<std::unique_ptr<render_state>> m_state;
};
}

View File

@@ -1,19 +1,21 @@
#include "in_section.hpp"
#include "outside_section.hpp"
#include "../visitor/is_node_empty.hpp"
#include "../visitor/render_section.hpp"
#include "outside_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)
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) {
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());
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))
@@ -23,10 +25,10 @@ std::string in_section::render(render_context& ctx, const token& token) {
ctx.set_state<outside_section>();
return out;
} else
}
else
m_skipped_openings--;
else if (token.token_type() == token::type::inverted_section_open ||
token.token_type() == token::type::section_open)
else if (token.token_type() == token::type::inverted_section_open || token.token_type() == token::type::section_open)
m_skipped_openings++;
m_section << token;

View File

@@ -3,22 +3,27 @@
#include <sstream>
#include <vector>
#include "render_state.hpp"
#include "../template_type.hpp"
#include "render_state.hpp"
namespace mstch {
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;
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:
private:
const type m_type;
const token& m_start_token;
const token &m_start_token;
template_type m_section;
int m_skipped_openings;
};
}

View File

@@ -1,32 +1,32 @@
#include "outside_section.hpp"
#include "../render_context.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)
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;
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 "";
}

View File

@@ -2,11 +2,12 @@
#include "render_state.hpp"
namespace mstch {
namespace mstch
{
class outside_section: public render_state {
public:
std::string render(render_context& context, const token& token) override;
class outside_section : public render_state
{
public:
std::string render(render_context &context, const token &token) override;
};
}

View File

@@ -4,14 +4,15 @@
#include "../token.hpp"
namespace mstch {
namespace mstch
{
class render_context;
class render_state {
public:
class render_state
{
public:
virtual ~render_state() {}
virtual std::string render(render_context& context, const token& token) = 0;
virtual std::string render(render_context &context, const token &token) = 0;
};
}

View File

@@ -2,57 +2,58 @@
using namespace mstch;
template_type::template_type(const std::string& str, const delim_type& delims):
m_open(delims.first), m_close(delims.second)
template_type::template_type(const std::string &str, const delim_type &delims)
: m_open(delims.first), m_close(delims.second)
{
tokenize(str);
strip_whitespace();
}
template_type::template_type(const std::string& str):
m_open("{{"), m_close("}}")
template_type::template_type(const std::string &str) : m_open("{{"), m_close("}}")
{
tokenize(str);
strip_whitespace();
}
void template_type::process_text(citer begin, citer end) {
void template_type::process_text(citer begin, citer end)
{
if (begin == end)
return;
auto start = begin;
for (auto it = begin; it != end; ++it)
if (*it == '\n' || it == end - 1) {
if (*it == '\n' || it == end - 1)
{
m_tokens.push_back({{start, it + 1}});
start = it + 1;
}
}
void template_type::tokenize(const std::string& tmp) {
void template_type::tokenize(const std::string &tmp)
{
citer beg = tmp.begin();
auto npos = std::string::npos;
for (std::size_t cur_pos = 0; cur_pos < tmp.size();) {
for (std::size_t cur_pos = 0; cur_pos < tmp.size();)
{
auto open_pos = tmp.find(m_open, cur_pos);
auto close_pos = tmp.find(
m_close, open_pos == npos ? open_pos : open_pos + 1);
auto close_pos = tmp.find(m_close, open_pos == npos ? open_pos : open_pos + 1);
if (close_pos != npos && open_pos != npos) {
if (*(beg + open_pos + m_open.size()) == '{' &&
*(beg + close_pos + m_close.size()) == '}')
if (close_pos != npos && open_pos != npos)
{
if (*(beg + open_pos + m_open.size()) == '{' && *(beg + close_pos + m_close.size()) == '}')
++close_pos;
process_text(beg + cur_pos, beg + open_pos);
cur_pos = close_pos + m_close.size();
m_tokens.push_back({{beg + open_pos, beg + close_pos + m_close.size()},
m_open.size(), m_close.size()});
m_tokens.push_back({{beg + open_pos, beg + close_pos + m_close.size()}, m_open.size(), m_close.size()});
if (cur_pos == tmp.size()) {
if (cur_pos == tmp.size())
{
m_tokens.push_back({{""}});
m_tokens.back().eol(true);
}
if (*(beg + open_pos + m_open.size()) == '=' &&
*(beg + close_pos - 1) == '=')
if (*(beg + open_pos + m_open.size()) == '=' && *(beg + close_pos - 1) == '=')
{
auto tok_beg = beg + open_pos + m_open.size() + 1;
auto tok_end = beg + close_pos - 1;
@@ -61,27 +62,32 @@ void template_type::tokenize(const std::string& tmp) {
m_open = {front_skip, beg + tmp.find(' ', front_skip - beg)};
m_close = {beg + tmp.rfind(' ', back_skip - beg) + 1, back_skip + 1};
}
} else {
}
else
{
process_text(beg + cur_pos, tmp.end());
cur_pos = close_pos;
}
}
}
void template_type::strip_whitespace() {
void template_type::strip_whitespace()
{
auto line_begin = m_tokens.begin();
bool has_tag = false, non_space = false;
for (auto it = m_tokens.begin(); it != m_tokens.end(); ++it) {
for (auto it = m_tokens.begin(); it != m_tokens.end(); ++it)
{
auto type = (*it).token_type();
if (type != token::type::text && type != token::type::variable &&
type != token::type::unescaped_variable)
if (type != token::type::text && type != token::type::variable && type != token::type::unescaped_variable)
has_tag = true;
else if (!(*it).ws_only())
non_space = true;
if ((*it).eol()) {
if (has_tag && !non_space) {
if ((*it).eol())
{
if (has_tag && !non_space)
{
store_prefixes(line_begin);
auto c = line_begin;
@@ -96,9 +102,9 @@ void template_type::strip_whitespace() {
}
}
void template_type::store_prefixes(std::vector<token>::iterator beg) {
void template_type::store_prefixes(std::vector<token>::iterator beg)
{
for (auto cur = beg; !(*cur).eol(); ++cur)
if ((*cur).token_type() == token::type::partial &&
cur != beg && (*(cur - 1)).ws_only())
if ((*cur).token_type() == token::type::partial && cur != beg && (*(cur - 1)).ws_only())
(*cur).partial_prefix((*(cur - 1)).raw());
}

View File

@@ -6,25 +6,26 @@
#include "token.hpp"
#include "utils.hpp"
namespace mstch {
namespace mstch
{
class template_type {
public:
class template_type
{
public:
template_type() = default;
template_type(const std::string& str);
template_type(const std::string& str, const delim_type& delims);
template_type(const std::string &str);
template_type(const std::string &str, const delim_type &delims);
std::vector<token>::const_iterator begin() const { return m_tokens.begin(); }
std::vector<token>::const_iterator end() const { return m_tokens.end(); }
void operator<<(const token& token) { m_tokens.push_back(token); }
void operator<<(const token &token) { m_tokens.push_back(token); }
private:
private:
std::vector<token> m_tokens;
std::string m_open;
std::string m_close;
void strip_whitespace();
void process_text(citer beg, citer end);
void tokenize(const std::string& tmp);
void tokenize(const std::string &tmp);
void store_prefixes(std::vector<token>::iterator beg);
};
}

View File

@@ -3,38 +3,53 @@
using namespace mstch;
token::type token::token_info(char c) {
switch (c) {
case '>': return type::partial;
case '^': return type::inverted_section_open;
case '/': return type::section_close;
case '&': return type::unescaped_variable;
case '#': return type::section_open;
case '!': return type::comment;
default: return type::variable;
token::type token::token_info(char c)
{
switch (c)
{
case '>':
return type::partial;
case '^':
return type::inverted_section_open;
case '/':
return type::section_close;
case '&':
return type::unescaped_variable;
case '#':
return type::section_open;
case '!':
return type::comment;
default:
return type::variable;
}
}
token::token(const std::string& str, std::size_t left, std::size_t right):
m_raw(str), m_eol(false), m_ws_only(false)
token::token(const std::string &str, std::size_t left, std::size_t right) : m_raw(str), m_eol(false), m_ws_only(false)
{
if (left != 0 && right != 0) {
if (str[left] == '=' && str[str.size() - right - 1] == '=') {
if (left != 0 && right != 0)
{
if (str[left] == '=' && str[str.size() - right - 1] == '=')
{
m_type = type::delimiter_change;
} else if (str[left] == '{' && str[str.size() - right - 1] == '}') {
}
else if (str[left] == '{' && str[str.size() - right - 1] == '}')
{
m_type = type::unescaped_variable;
m_name = {first_not_ws(str.begin() + left + 1, str.end() - right),
first_not_ws(str.rbegin() + 1 + right, str.rend() - left) + 1};
} else {
first_not_ws(str.rbegin() + 1 + right, str.rend() - left) + 1};
}
else
{
auto c = first_not_ws(str.begin() + left, str.end() - right);
m_type = token_info(*c);
if (m_type != type::variable)
c = first_not_ws(c + 1, str.end() - right);
m_name = {c, first_not_ws(str.rbegin() + right, str.rend() - left) + 1};
m_delims = {{str.begin(), str.begin() + left},
{str.end() - right, str.end()}};
m_delims = {{str.begin(), str.begin() + left}, {str.end() - right, str.end()}};
}
} else {
}
else
{
m_type = type::text;
m_eol = (str.size() > 0 && str[str.size() - 1] == '\n');
m_ws_only = (str.find_first_not_of(" \r\n\t") == std::string::npos);

View File

@@ -2,30 +2,38 @@
#include <string>
namespace mstch {
namespace mstch
{
using delim_type = std::pair<std::string, std::string>;
class token {
public:
enum class type {
text, variable, section_open, section_close, inverted_section_open,
unescaped_variable, comment, partial, delimiter_change
class token
{
public:
enum class type
{
text,
variable,
section_open,
section_close,
inverted_section_open,
unescaped_variable,
comment,
partial,
delimiter_change
};
token(const std::string& str, std::size_t left = 0, std::size_t right = 0);
token(const std::string &str, std::size_t left = 0, std::size_t right = 0);
type token_type() const { return m_type; };
const std::string& raw() const { return m_raw; };
const std::string& name() const { return m_name; };
const std::string& partial_prefix() const { return m_partial_prefix; };
const delim_type& delims() const { return m_delims; };
void partial_prefix(const std::string& p_partial_prefix) {
m_partial_prefix = p_partial_prefix;
};
const std::string &raw() const { return m_raw; };
const std::string &name() const { return m_name; };
const std::string &partial_prefix() const { return m_partial_prefix; };
const delim_type &delims() const { return m_delims; };
void partial_prefix(const std::string &p_partial_prefix) { m_partial_prefix = p_partial_prefix; };
bool eol() const { return m_eol; }
void eol(bool eol) { m_eol = eol; }
bool ws_only() const { return m_ws_only; }
private:
private:
type m_type;
std::string m_name;
std::string m_raw;
@@ -35,5 +43,4 @@ class token {
bool m_ws_only;
type token_info(char c);
};
}

View File

@@ -1,43 +1,60 @@
#include "utils.hpp"
#include "mstch/mstch.hpp"
mstch::citer mstch::first_not_ws(mstch::citer begin, mstch::citer end) {
mstch::citer mstch::first_not_ws(mstch::citer begin, mstch::citer end)
{
for (auto it = begin; it != end; ++it)
if (*it != ' ') return it;
if (*it != ' ')
return it;
return end;
}
mstch::citer mstch::first_not_ws(mstch::criter begin, mstch::criter end) {
mstch::citer mstch::first_not_ws(mstch::criter begin, mstch::criter end)
{
for (auto rit = begin; rit != end; ++rit)
if (*rit != ' ') return --(rit.base());
if (*rit != ' ')
return --(rit.base());
return --(end.base());
}
mstch::criter mstch::reverse(mstch::citer it) {
return std::reverse_iterator<mstch::citer>(it);
}
mstch::criter mstch::reverse(mstch::citer it) { return std::reverse_iterator<mstch::citer>(it); }
std::string mstch::html_escape(const std::string& str) {
std::string mstch::html_escape(const std::string &str)
{
if (mstch::config::escape)
return mstch::config::escape(str);
std::string out;
citer start = str.begin();
auto add_escape = [&out, &start](const std::string& escaped, citer& it) {
auto add_escape = [&out, &start](const std::string &escaped, citer &it) {
out += std::string{start, it} + escaped;
start = it + 1;
};
for (auto it = str.begin(); it != str.end(); ++it)
switch (*it) {
case '&': add_escape("&amp;", it); break;
case '\'': add_escape("&#39;", it); break;
case '"': add_escape("&quot;", it); break;
case '<': add_escape("&lt;", it); break;
case '>': add_escape("&gt;", it); break;
case '/': add_escape("&#x2F;", it); break;
default: break;
switch (*it)
{
case '&':
add_escape("&amp;", it);
break;
case '\'':
add_escape("&#39;", it);
break;
case '"':
add_escape("&quot;", it);
break;
case '<':
add_escape("&lt;", it);
break;
case '>':
add_escape("&gt;", it);
break;
case '/':
add_escape("&#x2F;", it);
break;
default:
break;
}
return out + std::string{start, str.end()};

View File

@@ -1,23 +1,21 @@
#pragma once
#include <string>
#include <boost/variant/apply_visitor.hpp>
#include <string>
namespace mstch {
namespace mstch
{
using citer = std::string::const_iterator;
using criter = std::string::const_reverse_iterator;
citer first_not_ws(citer begin, citer end);
citer first_not_ws(criter begin, criter end);
std::string html_escape(const std::string& str);
std::string html_escape(const std::string &str);
criter reverse(citer it);
template<class... Args>
auto visit(Args&&... args) -> decltype(boost::apply_visitor(
std::forward<Args>(args)...))
template <class... Args> auto visit(Args &&... args) -> decltype(boost::apply_visitor(std::forward<Args>(args)...))
{
return boost::apply_visitor(std::forward<Args>(args)...);
}
}

View File

@@ -2,34 +2,25 @@
#include <boost/variant/static_visitor.hpp>
#include "mstch/mstch.hpp"
#include "has_token.hpp"
#include "mstch/mstch.hpp"
namespace mstch {
namespace mstch
{
class get_token: public boost::static_visitor<const mstch::node&> {
public:
get_token(const std::string& token, const mstch::node& node):
m_token(token), m_node(node)
{
}
class get_token : public boost::static_visitor<const mstch::node &>
{
public:
get_token(const std::string &token, const mstch::node &node) : m_token(token), m_node(node) {}
template<class T>
const mstch::node& operator()(const T&) const {
return m_node;
}
template <class T> const mstch::node &operator()(const T &) const { return m_node; }
const mstch::node& operator()(const map& map) const {
return map.at(m_token);
}
const mstch::node &operator()(const map &map) const { return map.at(m_token); }
const mstch::node& operator()(const std::shared_ptr<object>& object) const {
return object->at(m_token);
}
const mstch::node &operator()(const std::shared_ptr<object> &object) const { return object->at(m_token); }
private:
const std::string& m_token;
const mstch::node& m_node;
private:
const std::string &m_token;
const mstch::node &m_node;
};
}

View File

@@ -4,28 +4,21 @@
#include "mstch/mstch.hpp"
namespace mstch {
namespace mstch
{
class has_token: public boost::static_visitor<bool> {
public:
has_token(const std::string& token): m_token(token) {
}
class has_token : public boost::static_visitor<bool>
{
public:
has_token(const std::string &token) : m_token(token) {}
template<class T>
bool operator()(const T&) const {
return m_token == ".";
}
template <class T> bool operator()(const T &) const { return m_token == "."; }
bool operator()(const map& map) const {
return map.count(m_token) == 1;
}
bool operator()(const map &map) const { return map.count(m_token) == 1; }
bool operator()(const std::shared_ptr<object>& object) const {
return object->has(m_token);
}
bool operator()(const std::shared_ptr<object> &object) const { return object->has(m_token); }
private:
const std::string& m_token;
private:
const std::string &m_token;
};
}

View File

@@ -4,38 +4,24 @@
#include "mstch/mstch.hpp"
namespace mstch {
namespace mstch
{
class is_node_empty: public boost::static_visitor<bool> {
public:
template<class T>
bool operator()(const T&) const {
return false;
}
class is_node_empty : public boost::static_visitor<bool>
{
public:
template <class T> bool operator()(const T &) const { return false; }
bool operator()(const std::nullptr_t&) const {
return true;
}
bool operator()(const std::nullptr_t &) const { return true; }
bool operator()(const int& value) const {
return value == 0;
}
bool operator()(const int &value) const { return value == 0; }
bool operator()(const double& value) const {
return value == 0;
}
bool operator()(const double &value) const { return value == 0; }
bool operator()(const bool& value) const {
return !value;
}
bool operator()(const bool &value) const { return !value; }
bool operator()(const std::string& value) const {
return value == "";
}
bool operator()(const std::string &value) const { return value == ""; }
bool operator()(const array& array) const {
return array.size() == 0;
}
bool operator()(const array &array) const { return array.size() == 0; }
};
}

View File

@@ -1,56 +1,52 @@
#pragma once
#include <sstream>
#include <boost/variant/static_visitor.hpp>
#include <sstream>
#include "../render_context.hpp"
#include "mstch/mstch.hpp"
#include "../utils.hpp"
#include "mstch/mstch.hpp"
namespace mstch {
namespace mstch
{
class render_node: public boost::static_visitor<std::string> {
public:
enum class flag { none, escape_html };
render_node(render_context& ctx, flag p_flag = flag::none):
m_ctx(ctx), m_flag(p_flag)
class render_node : public boost::static_visitor<std::string>
{
public:
enum class flag
{
}
none,
escape_html
};
render_node(render_context &ctx, flag p_flag = flag::none) : m_ctx(ctx), m_flag(p_flag) {}
template<class T>
std::string operator()(const T&) const {
return "";
}
template <class T> std::string operator()(const T &) const { return ""; }
std::string operator()(const int& value) const {
return std::to_string(value);
}
std::string operator()(const int &value) const { return std::to_string(value); }
std::string operator()(const double& value) const {
std::string operator()(const double &value) const
{
std::stringstream ss;
ss << value;
return ss.str();
}
std::string operator()(const bool& value) const {
return value ? "true" : "false";
}
std::string operator()(const bool &value) const { return value ? "true" : "false"; }
std::string operator()(const lambda& value) const {
template_type interpreted{value([this](const mstch::node& n) {
return visit(render_node(m_ctx), n);
})};
std::string operator()(const lambda &value) const
{
template_type interpreted{value([this](const mstch::node &n) { return visit(render_node(m_ctx), n); })};
auto rendered = render_context::push(m_ctx).render(interpreted);
return (m_flag == flag::escape_html) ? html_escape(rendered) : rendered;
}
std::string operator()(const std::string& value) const {
std::string operator()(const std::string &value) const
{
return (m_flag == flag::escape_html) ? html_escape(value) : value;
}
private:
render_context& m_ctx;
private:
render_context &m_ctx;
flag m_flag;
};
}

View File

@@ -3,55 +3,56 @@
#include <boost/variant/static_visitor.hpp>
#include "../render_context.hpp"
#include "mstch/mstch.hpp"
#include "../utils.hpp"
#include "mstch/mstch.hpp"
#include "render_node.hpp"
namespace mstch {
namespace mstch
{
class render_section: public boost::static_visitor<std::string> {
public:
enum class flag { none, keep_array };
render_section(
render_context& ctx,
const template_type& section,
const delim_type& delims,
flag p_flag = flag::none):
m_ctx(ctx), m_section(section), m_delims(delims), m_flag(p_flag)
class render_section : public boost::static_visitor<std::string>
{
public:
enum class flag
{
none,
keep_array
};
render_section(render_context &ctx, const template_type &section, const delim_type &delims, flag p_flag = flag::none)
: m_ctx(ctx), m_section(section), m_delims(delims), m_flag(p_flag)
{
}
template<class T>
std::string operator()(const T& t) const {
template <class T> std::string operator()(const T &t) const
{
return render_context::push(m_ctx, t).render(m_section);
}
std::string operator()(const lambda& fun) const {
std::string operator()(const lambda &fun) const
{
std::string section_str;
for (auto& token: m_section)
for (auto &token : m_section)
section_str += token.raw();
template_type interpreted{fun([this](const mstch::node& n) {
return visit(render_node(m_ctx), n);
}, section_str), m_delims};
template_type interpreted{fun([this](const mstch::node &n) { return visit(render_node(m_ctx), n); }, section_str),
m_delims};
return render_context::push(m_ctx).render(interpreted);
}
std::string operator()(const array& array) const {
std::string operator()(const array &array) const
{
std::string out;
if (m_flag == flag::keep_array)
return render_context::push(m_ctx, array).render(m_section);
else
for (auto& item: array)
out += visit(render_section(
m_ctx, m_section, m_delims, flag::keep_array), item);
for (auto &item : array)
out += visit(render_section(m_ctx, m_section, m_delims, flag::keep_array), item);
return out;
}
private:
render_context& m_ctx;
const template_type& m_section;
const delim_type& m_delims;
private:
render_context &m_ctx;
const template_type &m_section;
const delim_type &m_delims;
flag m_flag;
};
}