20 :
msg(
"crow::mustache error: " +
msg)
23 virtual const char*
what()
const throw()
71 return {
true, *stack.back()};
73 int dotPosition =
name.find(
".");
74 if (dotPosition == (
int)
name.npos)
76 for(
auto it = stack.rbegin(); it != stack.rend(); ++it)
80 if ((*it)->count(
name))
81 return {
true, (**it)[
name]};
87 std::vector<int> dotPositions;
88 dotPositions.push_back(-1);
89 while(dotPosition != (
int)
name.npos)
91 dotPositions.push_back(dotPosition);
92 dotPosition =
name.find(
".", dotPosition+1);
94 dotPositions.push_back(
name.size());
95 std::vector<std::string> names;
96 names.reserve(dotPositions.size()-1);
97 for(
int i = 1; i < (int)dotPositions.size(); i ++)
98 names.emplace_back(
name.substr(dotPositions[i-1]+1, dotPositions[i]-dotPositions[i-1]-1));
100 for(
auto it = stack.rbegin(); it != stack.rend(); ++it)
104 for(
auto jt = names.begin(); jt != names.end(); ++jt)
109 view = &(*view)[*jt];
118 return {
true, *view};
125 return {
false, empty_str};
128 void escape(
const std::string& in, std::string& out)
130 out.reserve(out.size() + in.size());
131 for(
auto it = in.begin(); it != in.end(); ++it)
135 case '&': out +=
"&";
break;
136 case '<': out +=
"<";
break;
137 case '>': out +=
">";
break;
138 case '"': out +=
""";
break;
139 case '\'': out +=
"'";
break;
140 case '/': out +=
"/";
break;
141 default: out += *it;
break;
146 void render_internal(
int actionBegin,
int actionEnd, std::vector<context*>& stack, std::string& out,
int indent)
148 int current = actionBegin;
151 out.insert(out.size(), indent,
' ');
153 while(current < actionEnd)
165 std::string partial_name =
tag_name(action);
166 auto partial_templ =
load(partial_name);
167 int partial_indent = action.pos;
168 partial_templ.render_internal(0, partial_templ.fragments_.size()-1, stack, out, partial_indent?indent+partial_indent:0);
175 auto& ctx = optional_ctx.second;
188 throw std::runtime_error(
"not implemented tag type" + boost::lexical_cast<std::string>((
int)ctx.t()));
196 if (!optional_ctx.first)
198 stack.emplace_back(&nullContext);
202 auto& ctx = optional_ctx.second;
206 if (ctx.l && !ctx.l->empty())
207 current = action.pos;
209 stack.emplace_back(&nullContext);
213 stack.emplace_back(&nullContext);
216 current = action.pos;
224 if (!optional_ctx.first)
226 current = action.pos;
230 auto& ctx = optional_ctx.second;
235 for(
auto it = ctx.l->begin(); it != ctx.l->end(); ++it)
237 stack.push_back(&*it);
241 current = action.pos;
247 stack.push_back(&ctx);
251 current = action.pos;
254 throw std::runtime_error(
"{{#: not implemented context type: " + boost::lexical_cast<std::string>((
int)ctx.t()));
263 throw std::runtime_error(
"not implemented " + boost::lexical_cast<std::string>((
int)action.t));
270 void render_fragment(
const std::pair<int, int> fragment,
int indent, std::string& out)
274 for(
int i = fragment.first; i < fragment.second; i ++)
277 if (
body_[i] ==
'\n' && i+1 != (
int)
body_.size())
278 out.insert(out.size(), indent,
' ');
282 out.insert(out.size(),
body_, fragment.first, fragment.second-fragment.first);
288 std::vector<context*> stack;
289 stack.emplace_back(&empty_ctx);
297 std::vector<context*> stack;
298 stack.emplace_back(&ctx);
309 std::string tag_open =
"{{";
310 std::string tag_close =
"}}";
312 std::vector<int> blockPositions;
317 size_t idx =
body_.find(tag_open, current);
318 if (idx ==
body_.npos)
326 idx += tag_open.size();
327 size_t endIdx =
body_.find(tag_close, idx);
332 if (endIdx ==
body_.npos)
337 current = endIdx + tag_close.size();
342 while(
body_[idx] ==
' ') idx++;
343 while(
body_[endIdx-1] ==
' ') endIdx--;
344 blockPositions.emplace_back(
actions_.size());
349 while(
body_[idx] ==
' ') idx++;
350 while(
body_[endIdx-1] ==
' ') endIdx--;
352 auto& matched =
actions_[blockPositions.back()];
353 if (
body_.compare(idx, endIdx-idx,
354 body_, matched.start, matched.end - matched.start) != 0)
357 body_.substr(matched.start, matched.end - matched.start) +
", " +
358 body_.substr(idx, endIdx-idx));
363 blockPositions.pop_back();
367 while(
body_[idx] ==
' ') idx++;
368 while(
body_[endIdx-1] ==
' ') endIdx--;
369 blockPositions.emplace_back(
actions_.size());
378 while(
body_[idx] ==
' ') idx++;
379 while(
body_[endIdx-1] ==
' ') endIdx--;
383 if (tag_open !=
"{{" || tag_close !=
"}}")
387 if (
body_[endIdx+2] !=
'}')
391 while(
body_[idx] ==
' ') idx++;
392 while(
body_[endIdx-1] ==
' ') endIdx--;
398 while(
body_[idx] ==
' ') idx++;
399 while(
body_[endIdx-1] ==
' ') endIdx--;
407 if (
body_[endIdx] !=
'=')
410 while(
body_[idx] ==
' ') idx++;
411 while(
body_[endIdx] ==
' ') endIdx--;
414 bool succeeded =
false;
415 for(
size_t i = idx; i < endIdx; i++)
419 tag_open =
body_.substr(idx, i-idx);
420 while(
body_[i] ==
' ') i++;
421 tag_close =
body_.substr(i, endIdx-i);
422 if (tag_open.empty())
424 if (tag_close.empty())
427 if (tag_close.find(
" ") != tag_close.npos)
439 while(
body_[idx] ==
' ') idx++;
440 while(
body_[endIdx-1] ==
' ') endIdx--;
447 for(
int i =
actions_.size()-2; i >= 0; i --)
453 bool is_last_action = i == (int)
actions_.size()-2;
454 bool all_space_before =
true;
456 for(j = fragment_before.second-1;j >= fragment_before.first;j--)
460 all_space_before =
false;
464 if (all_space_before && i > 0)
466 if (!all_space_before &&
body_[j] !=
'\n')
468 bool all_space_after =
true;
469 for(k = fragment_after.first; k < (
int)
body_.size() && k < fragment_after.second; k ++)
473 all_space_after =
false;
477 if (all_space_after && !is_last_action)
479 if (!all_space_after &&
484 k + 1 < (
int)
body_.size() &&
485 body_[k+1] ==
'\n')))
489 actions_[i].pos = fragment_before.second - j - 1;
491 fragment_before.second = j+1;
492 if (!all_space_after)
494 if (
body_[k] ==
'\n')
498 fragment_after.first = k;
516 static std::string template_base_directory =
"templates";
517 return template_base_directory;
524 if (!(path.back() ==
'/' || path.back() ==
'\\'))
527 std::ifstream inf(path);
530 return {std::istreambuf_iterator<char>(inf), std::istreambuf_iterator<char>()};
537 static std::function<std::string (std::string)> loader =
default_loader;
546 if (
base.back() !=
'\\' &&
553 inline void set_loader(std::function<std::string(std::string)> loader)
Action(ActionType t, int start, int end, int pos=0)
Definition: mustache.h:47
Definition: mustache.h:41
std::vector< std::pair< int, int > > fragments_
Definition: mustache.h:503
type t() const
Definition: json.h:1090
int end
Definition: mustache.h:44
void set_loader(std::function< std::string(std::string)> loader)
Definition: mustache.h:553
std::string default_loader(const std::string &filename)
Definition: mustache.h:521
invalid_template_exception(const std::string &msg)
Definition: mustache.h:19
std::string dump(const wvalue &v)
Definition: json.h:1426
Definition: block_queue.cpp:41
Definition: mustache.h:52
std::string msg
Definition: mustache.h:27
void set_base(const std::string &path)
Definition: mustache.h:542
template_t load(const std::string &filename)
Definition: mustache.h:558
std::function< std::string(std::string)> & get_loader_ref()
Definition: mustache.h:535
declaration and default definition for the functions used the API
std::vector< Action > actions_
Definition: mustache.h:504
int pos
Definition: mustache.h:45
std::string & get_template_base_directory_ref()
Definition: mustache.h:514
std::string render(context &ctx)
Definition: mustache.h:295
std::string body_
Definition: mustache.h:505
void render_fragment(const std::pair< int, int > fragment, int indent, std::string &out)
Definition: mustache.h:270
void parse()
Definition: mustache.h:307
std::string tag_name(const Action &action)
Definition: mustache.h:63
void render_internal(int actionBegin, int actionEnd, std::vector< context *> &stack, std::string &out, int indent)
Definition: mustache.h:146
template_t(std::string body)
Definition: mustache.h:55
std::string render()
Definition: mustache.h:285
int start
Definition: mustache.h:43
virtual const char * what() const
Definition: mustache.h:23
ActionType
Definition: mustache.h:30
ActionType t
Definition: mustache.h:46
template_t compile(const std::string &body)
Definition: mustache.h:508
int bool
Definition: stdbool.h:36
const char * name
Definition: simplewallet.cpp:180
Definition: mustache.h:16
void escape(const std::string &in, std::string &out)
Definition: mustache.h:128
auto find_context(const std::string &name, const std::vector< context *> &stack) -> std::pair< bool, context &>
Definition: mustache.h:67
int count(const std::string &str)
Definition: json.h:1295