reformat
This commit is contained in:
parent
3b4580186c
commit
e31207b9cf
17 changed files with 160 additions and 93 deletions
|
@ -7,7 +7,8 @@ namespace mstch {
|
|||
std::string render(
|
||||
const std::string& tmplt,
|
||||
const object& context,
|
||||
const std::map<std::string,std::string>& partials = std::map<std::string,std::string>());
|
||||
const std::map<std::string,std::string>& partials =
|
||||
std::map<std::string,std::string>());
|
||||
}
|
||||
|
||||
#endif // _MSTCH_H_
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
using namespace mstch;
|
||||
|
||||
std::string strip_whitespace(std::string tmplt) {
|
||||
tmplt = std::regex_replace(tmplt, std::regex("\\{\\{![^\\}]*\\}\\}"), "{{!}}");
|
||||
std::regex comment_match("\\{\\{![^\\}]*\\}\\}");
|
||||
tmplt = std::regex_replace(tmplt, comment_match, "{{!}}");
|
||||
std::ostringstream out;
|
||||
std::istringstream in(tmplt);
|
||||
std::string line;
|
||||
|
@ -29,5 +30,6 @@ std::string mstch::render(
|
|||
const std::string& tmplt, const object& root_object,
|
||||
const std::map<std::string,std::string>& partials)
|
||||
{
|
||||
return render_context(root_object, partials).render(strip_whitespace(tmplt));
|
||||
return render_context(root_object, partials)
|
||||
.render(strip_whitespace(tmplt));
|
||||
}
|
||||
|
|
|
@ -8,14 +8,18 @@ using namespace mstch;
|
|||
|
||||
const mstch::node render_context::null_node;
|
||||
|
||||
render_context::render_context(const mstch::object &object, const std::map<std::string,std::string>& partials):
|
||||
render_context::render_context(
|
||||
const mstch::object &object,
|
||||
const std::map<std::string,std::string>& partials):
|
||||
partials(partials),
|
||||
objects{object},
|
||||
state(new state::outside_section)
|
||||
{
|
||||
}
|
||||
|
||||
render_context::render_context(const mstch::object& object, const render_context& context):
|
||||
render_context::render_context(
|
||||
const mstch::object& object,
|
||||
const render_context& context):
|
||||
partials(context.partials),
|
||||
objects(context.objects),
|
||||
state(new state::outside_section)
|
||||
|
@ -23,10 +27,16 @@ render_context::render_context(const mstch::object& object, const render_context
|
|||
objects.push_front(object);
|
||||
}
|
||||
|
||||
const mstch::node& render_context::find_node(const std::string &token, const std::deque<object> ¤t_objects) {
|
||||
const mstch::node& render_context::find_node(
|
||||
const std::string &token,
|
||||
const std::deque<object> ¤t_objects)
|
||||
{
|
||||
if(token != "." && token.find('.') != std::string::npos) {
|
||||
return find_node(token.substr(token.rfind('.') + 1),
|
||||
{boost::get<object>(find_node(token.substr(0, token.rfind('.')), current_objects))});
|
||||
return find_node(
|
||||
token.substr(token.rfind('.') + 1),
|
||||
{boost::get<object>(find_node(
|
||||
token.substr(0, token.rfind('.')),
|
||||
current_objects))});
|
||||
} else {
|
||||
for (auto& object: current_objects)
|
||||
if (object.count(token) != 0)
|
||||
|
|
|
@ -12,18 +12,24 @@ namespace mstch {
|
|||
class render_context {
|
||||
private:
|
||||
static const mstch::node null_node;
|
||||
const mstch::node& find_node(const std::string& token, const std::deque<object>& current_objects);
|
||||
const mstch::node& find_node(
|
||||
const std::string& token,
|
||||
const std::deque<object>& current_objects);
|
||||
const std::map<std::string,std::string>& partials;
|
||||
std::deque<mstch::object> objects;
|
||||
std::unique_ptr<state::render_state> state;
|
||||
public:
|
||||
render_context(const mstch::object& object, const std::map<std::string,std::string>& partials);
|
||||
render_context(const mstch::object& object, const render_context& context);
|
||||
render_context(
|
||||
const mstch::object& object,
|
||||
const std::map<std::string,std::string>& partials);
|
||||
render_context(
|
||||
const mstch::object& object, const render_context& context);
|
||||
const mstch::node& get_node(const std::string& token);
|
||||
std::string render(const std::string& tmplt);
|
||||
template<class T, class... Args>
|
||||
void set_state(Args&&... args) {
|
||||
state = std::unique_ptr<state::render_state>(new T(std::forward<Args>(args)...));
|
||||
state = std::unique_ptr<state::render_state>(
|
||||
new T(std::forward<Args>(args)...));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -7,36 +7,43 @@
|
|||
|
||||
using namespace mstch;
|
||||
|
||||
state::in_inverted_section::in_inverted_section(const std::string& section_name):
|
||||
state::in_inverted_section::in_inverted_section(
|
||||
const std::string& section_name):
|
||||
section_name(section_name),
|
||||
skipped_openings(0)
|
||||
{
|
||||
}
|
||||
|
||||
std::string state::in_inverted_section::render(render_context& context, const token& token) {
|
||||
std::string state::in_inverted_section::render(
|
||||
render_context& ctx,
|
||||
const token& token)
|
||||
{
|
||||
switch(token.type()) {
|
||||
case token_type::section_close:
|
||||
if(token.content() == section_name && skipped_openings == 0) {
|
||||
std::ostringstream out;
|
||||
if(boost::apply_visitor(visitor::is_node_empty(), context.get_node(section_name)))
|
||||
out << render_context(mstch::object{}, context).render(section_text.str());
|
||||
context.set_state<outside_section>();
|
||||
return out.str();
|
||||
} else {
|
||||
skipped_openings--;
|
||||
section_text << token.raw();
|
||||
case token_type::section_close:
|
||||
if(token.content() == section_name && skipped_openings == 0) {
|
||||
std::ostringstream out;
|
||||
auto& section_node = ctx.get_node(section_name);
|
||||
if(boost::apply_visitor(visitor::is_node_empty(), section_node)) {
|
||||
auto empty = mstch::object{};
|
||||
out << render_context(empty, ctx).render(section_text.str());
|
||||
}
|
||||
break;
|
||||
case token_type::inverted_section_open:
|
||||
case token_type::section_open:
|
||||
skipped_openings++;
|
||||
case token_type::text:
|
||||
case token_type::variable:
|
||||
case token_type::unescaped_variable:
|
||||
case token_type::comment:
|
||||
case token_type::partial:
|
||||
ctx.set_state<outside_section>();
|
||||
return out.str();
|
||||
} else {
|
||||
skipped_openings--;
|
||||
section_text << token.raw();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case token_type::inverted_section_open:
|
||||
case token_type::section_open:
|
||||
skipped_openings++;
|
||||
case token_type::text:
|
||||
case token_type::variable:
|
||||
case token_type::unescaped_variable:
|
||||
case token_type::comment:
|
||||
case token_type::partial:
|
||||
section_text << token.raw();
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -6,14 +6,16 @@
|
|||
|
||||
namespace mstch {
|
||||
namespace state {
|
||||
class in_inverted_section : public render_state, public std::enable_shared_from_this<in_inverted_section> {
|
||||
class in_inverted_section: public render_state {
|
||||
private:
|
||||
const std::string section_name;
|
||||
std::ostringstream section_text;
|
||||
int skipped_openings;
|
||||
public:
|
||||
in_inverted_section(const std::string §ion_name);
|
||||
std::string render(render_context &context, const token &token) override;
|
||||
std::string render(
|
||||
render_context &context,
|
||||
const token &token) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,34 +5,40 @@
|
|||
|
||||
using namespace mstch;
|
||||
|
||||
state::in_section::in_section(const std::string& section_name): section_name(section_name), skipped_openings(0) {
|
||||
state::in_section::in_section(const std::string& section_name):
|
||||
section_name(section_name), skipped_openings(0)
|
||||
{
|
||||
}
|
||||
|
||||
std::string state::in_section::render(render_context& context, const token& token) {
|
||||
std::string state::in_section::render(
|
||||
render_context& ctx,
|
||||
const token& token)
|
||||
{
|
||||
switch(token.type()) {
|
||||
case token_type::section_close:
|
||||
if(token.content() == section_name && skipped_openings == 0) {
|
||||
auto section_node = context.get_node(section_name);
|
||||
std::string out("");
|
||||
if (!boost::apply_visitor(visitor::is_node_empty(), section_node))
|
||||
out = boost::apply_visitor(visitor::render_section(context, section_text.str()), section_node);
|
||||
context.set_state<outside_section>();
|
||||
return out;
|
||||
} else {
|
||||
skipped_openings--;
|
||||
section_text << token.raw();
|
||||
}
|
||||
break;
|
||||
case token_type::inverted_section_open:
|
||||
case token_type::section_open:
|
||||
skipped_openings++;
|
||||
case token_type::text:
|
||||
case token_type::variable:
|
||||
case token_type::unescaped_variable:
|
||||
case token_type::comment:
|
||||
case token_type::partial:
|
||||
case token_type::section_close:
|
||||
if(token.content() == section_name && skipped_openings == 0) {
|
||||
auto section_node = ctx.get_node(section_name);
|
||||
std::string out("");
|
||||
if (!boost::apply_visitor(visitor::is_node_empty(), section_node))
|
||||
out = boost::apply_visitor(visitor::render_section(
|
||||
ctx, section_text.str()), section_node);
|
||||
ctx.set_state<outside_section>();
|
||||
return out;
|
||||
} else {
|
||||
skipped_openings--;
|
||||
section_text << token.raw();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case token_type::inverted_section_open:
|
||||
case token_type::section_open:
|
||||
skipped_openings++;
|
||||
case token_type::text:
|
||||
case token_type::variable:
|
||||
case token_type::unescaped_variable:
|
||||
case token_type::comment:
|
||||
case token_type::partial:
|
||||
section_text << token.raw();
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -13,7 +13,9 @@ namespace mstch {
|
|||
int skipped_openings;
|
||||
public:
|
||||
in_section(const std::string& section_name);
|
||||
std::string render(render_context& context, const token& token) override;
|
||||
std::string render(
|
||||
render_context& context,
|
||||
const token& token) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,26 +6,30 @@
|
|||
|
||||
using namespace mstch;
|
||||
|
||||
std::string state::outside_section::render(render_context& context, const token& token) {
|
||||
std::string state::outside_section::render(
|
||||
render_context& ctx,
|
||||
const token& token)
|
||||
{
|
||||
switch(token.type()) {
|
||||
case token_type::section_open:
|
||||
context.set_state<in_section>(token.content());
|
||||
break;
|
||||
case token_type::inverted_section_open:
|
||||
context.set_state<in_inverted_section>(token.content());
|
||||
break;
|
||||
case token_type::variable:
|
||||
case token_type::unescaped_variable:
|
||||
return boost::apply_visitor(visitor::render_node(token.type() == token_type::variable),
|
||||
context.get_node(token.content()));
|
||||
case token_type::comment: break;
|
||||
case token_type::text:
|
||||
return token.raw();
|
||||
case token_type::partial:
|
||||
break;//render_context(mstch::object{{".", i}}, context).render(section);
|
||||
case token_type::section_close:
|
||||
// TODO ERROR
|
||||
break;
|
||||
case token_type::section_open:
|
||||
ctx.set_state<in_section>(token.content());
|
||||
break;
|
||||
case token_type::inverted_section_open:
|
||||
ctx.set_state<in_inverted_section>(token.content());
|
||||
break;
|
||||
case token_type::variable:
|
||||
case token_type::unescaped_variable:
|
||||
return boost::apply_visitor(
|
||||
visitor::render_node(token.type() == token_type::variable),
|
||||
ctx.get_node(token.content()));
|
||||
case token_type::comment: break;
|
||||
case token_type::text:
|
||||
return token.raw();
|
||||
case token_type::partial:
|
||||
break;//render_context(mstch::object{{".", i}}, ctx).render(section);
|
||||
case token_type::section_close:
|
||||
// TODO ERROR
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
|
||||
namespace mstch {
|
||||
namespace state {
|
||||
class outside_section : public render_state {
|
||||
class outside_section: public render_state {
|
||||
public:
|
||||
std::string render(render_context &context, const token &token) override;
|
||||
std::string render(
|
||||
render_context &context,
|
||||
const token &token) override;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@ namespace mstch {
|
|||
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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
using namespace mstch;
|
||||
|
||||
token::token(const std::string& raw_token): raw_val(raw_token) {
|
||||
if(std::regex_match(raw_token, std::regex("\\{{2}[^\\}]*\\}{2}|\\{{3}[^\\}]*\\}{3}"))) {
|
||||
std::regex token_match("\\{{2}[^\\}]*\\}{2}|\\{{3}[^\\}]*\\}{3}");
|
||||
if(std::regex_match(raw_token, token_match)) {
|
||||
std::string inside = raw_token.substr(2, raw_token.size() - 4);
|
||||
inside = trim(inside);
|
||||
if (inside.size() > 0 && inside.at(0) == '#') {
|
||||
|
@ -24,7 +25,9 @@ token::token(const std::string& raw_token): raw_val(raw_token) {
|
|||
} else if (inside.size() > 0 && inside.at(0) == '&') {
|
||||
type_val = token_type::unescaped_variable;
|
||||
content_val = inside.substr(1);
|
||||
} else if (inside.size() > 0 && inside.at(0) == '{' && inside.at(inside.size() - 1) == '}') {
|
||||
} else if (inside.size() > 0 && inside.at(0) == '{' &&
|
||||
inside.at(inside.size() - 1) == '}')
|
||||
{
|
||||
type_val = token_type::unescaped_variable;
|
||||
content_val = inside.substr(1, inside.size() - 2);
|
||||
} else if (inside.size() > 0 && inside.at(0) == '!') {
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
|
||||
namespace mstch {
|
||||
enum class token_type {
|
||||
text, variable, section_open, section_close, inverted_section_open, unescaped_variable, comment, partial
|
||||
text, variable, section_open, section_close, inverted_section_open,
|
||||
unescaped_variable, comment, partial
|
||||
};
|
||||
|
||||
class token {
|
||||
|
|
|
@ -3,12 +3,18 @@
|
|||
#include <algorithm>
|
||||
|
||||
std::string& mstch::ltrim(std::string& s) {
|
||||
s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
s.erase(s.begin(), std::find_if(
|
||||
s.begin(),
|
||||
s.end(),
|
||||
std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string& mstch::rtrim(std::string& s) {
|
||||
s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
|
||||
s.erase(std::find_if(
|
||||
s.rbegin(),
|
||||
s.rend(),
|
||||
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -16,7 +22,11 @@ std::string& mstch::trim(std::string& s) {
|
|||
return ltrim(rtrim(s));
|
||||
}
|
||||
|
||||
std::string mstch::replace_all(std::string str, const std::string& from, const std::string& to) {
|
||||
std::string mstch::replace_all(
|
||||
std::string str,
|
||||
const std::string& from,
|
||||
const std::string& to)
|
||||
{
|
||||
size_t start_pos = 0;
|
||||
while((start_pos = str.find(from, start_pos)) != std::string::npos) {
|
||||
str.replace(start_pos, from.length(), to);
|
||||
|
|
|
@ -7,7 +7,10 @@ namespace mstch {
|
|||
std::string& ltrim(std::string& s);
|
||||
std::string& rtrim(std::string& s);
|
||||
std::string& trim(std::string& s);
|
||||
std::string replace_all(std::string str, const std::string& from, const std::string& to);
|
||||
std::string replace_all(
|
||||
std::string str,
|
||||
const std::string& from,
|
||||
const std::string& to);
|
||||
std::string html_escape(std::string str);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
|
||||
using namespace mstch;
|
||||
|
||||
visitor::render_node::render_node(bool html_escaped): html_escaped(html_escaped) {
|
||||
visitor::render_node::render_node(bool html_escaped):
|
||||
html_escaped(html_escaped)
|
||||
{
|
||||
}
|
||||
|
||||
std::string visitor::render_node::operator()(const boost::blank& blank) const {
|
||||
|
|
|
@ -3,13 +3,17 @@
|
|||
|
||||
using namespace mstch;
|
||||
|
||||
visitor::render_section::render_section(render_context& context, const std::string& section):
|
||||
visitor::render_section::render_section(
|
||||
render_context& context,
|
||||
const std::string& section):
|
||||
context(context),
|
||||
section(section)
|
||||
{
|
||||
}
|
||||
|
||||
std::string visitor::render_section::operator()(const boost::blank& blank) const {
|
||||
std::string visitor::render_section::operator()(
|
||||
const boost::blank& blank) const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue