optimizations
This commit is contained in:
parent
bb21e64a51
commit
48fbaeb3c9
5 changed files with 49 additions and 37 deletions
|
@ -61,8 +61,8 @@ void render_context::tokenize(const std::string& t, std::vector<token>& toks) {
|
||||||
unsigned int del_pos = 0;
|
unsigned int del_pos = 0;
|
||||||
bool ws_only = true;
|
bool ws_only = true;
|
||||||
for (std::string::const_iterator it = t.begin(); it != t.end(); ++it) {
|
for (std::string::const_iterator it = t.begin(); it != t.end(); ++it) {
|
||||||
if(pstate == parse_state::start) {
|
if (pstate == parse_state::start) {
|
||||||
if(*it == delim_start[0]) {
|
if (*it == delim_start[0]) {
|
||||||
pstate = parse_state::in_del_start;
|
pstate = parse_state::in_del_start;
|
||||||
tok_end = it;
|
tok_end = it;
|
||||||
del_pos = 1;
|
del_pos = 1;
|
||||||
|
@ -96,7 +96,8 @@ void render_context::tokenize(const std::string& t, std::vector<token>& toks) {
|
||||||
if (*it == delim_end[del_pos] && ++del_pos == delim_end.size()) {
|
if (*it == delim_end[del_pos] && ++del_pos == delim_end.size()) {
|
||||||
pstate = parse_state::start;
|
pstate = parse_state::start;
|
||||||
toks.push_back({false, false, ws_only, {tok_start, tok_end}});
|
toks.push_back({false, false, ws_only, {tok_start, tok_end}});
|
||||||
toks.push_back({true, false, false, {tok_end, it + 1}});
|
toks.push_back({true, false, false,
|
||||||
|
{tok_end +delim_start.size(), it - delim_end.size() +1}});
|
||||||
ws_only = true;
|
ws_only = true;
|
||||||
tok_start = it + 1;
|
tok_start = it + 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -110,15 +111,15 @@ void render_context::tokenize(const std::string& t, std::vector<token>& toks) {
|
||||||
void render_context::strip_whitespace(std::vector<token>& tokens) {
|
void render_context::strip_whitespace(std::vector<token>& tokens) {
|
||||||
auto line_begin = tokens.begin();
|
auto line_begin = tokens.begin();
|
||||||
bool has_tag = false, non_space = false;
|
bool has_tag = false, non_space = false;
|
||||||
for(auto it = tokens.begin(); it != tokens.end(); ++it) {
|
for (auto it = tokens.begin(); it != tokens.end(); ++it) {
|
||||||
auto type = (*it).token_type();
|
auto type = (*it).token_type();
|
||||||
if(type != token::type::text && type != token::type::variable &&
|
if (type != token::type::text && type != token::type::variable &&
|
||||||
type != token::type::unescaped_variable)
|
type != token::type::unescaped_variable)
|
||||||
has_tag = true;
|
has_tag = true;
|
||||||
else if(!(*it).is_ws_only())
|
else if (!(*it).is_ws_only())
|
||||||
non_space = true;
|
non_space = true;
|
||||||
if((*it).is_eol()) {
|
if ((*it).is_eol()) {
|
||||||
if(has_tag && !non_space)
|
if (has_tag && !non_space)
|
||||||
for (auto line_it = line_begin; line_it != it + 1; ++line_it)
|
for (auto line_it = line_begin; line_it != it + 1; ++line_it)
|
||||||
if ((*line_it).is_ws_only())
|
if ((*line_it).is_ws_only())
|
||||||
(*line_it).mark();
|
(*line_it).mark();
|
||||||
|
@ -126,7 +127,7 @@ void render_context::strip_whitespace(std::vector<token>& tokens) {
|
||||||
line_begin = it + 1;
|
line_begin = it + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(auto it = tokens.begin(); it != tokens.end();)
|
for (auto it = tokens.begin(); it != tokens.end();)
|
||||||
((*it).is_marked())?(it = tokens.erase(it)):(++it);
|
((*it).is_marked())?(it = tokens.erase(it)):(++it);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +140,7 @@ std::string render_context::render(const std::string& tmplt) {
|
||||||
|
|
||||||
std::string render_context::render(const std::vector<token>& tokens) {
|
std::string render_context::render(const std::vector<token>& tokens) {
|
||||||
std::string output;
|
std::string output;
|
||||||
for(auto& token: tokens)
|
for (auto& token: tokens)
|
||||||
output += state.top()->render(*this, token);
|
output += state.top()->render(*this, token);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ std::string state::in_section::render(render_context& ctx, const token& token) {
|
||||||
switch(token.token_type()) {
|
switch(token.token_type()) {
|
||||||
case token::type::section_close:
|
case token::type::section_close:
|
||||||
if(token.content() == section_name && skipped_openings == 0) {
|
if(token.content() == section_name && skipped_openings == 0) {
|
||||||
auto section_node = ctx.get_node(section_name);
|
auto& section_node = ctx.get_node(section_name);
|
||||||
std::string out;
|
std::string out;
|
||||||
if (!boost::apply_visitor(visitor::is_node_empty(), section_node))
|
if (!boost::apply_visitor(visitor::is_node_empty(), section_node))
|
||||||
out = boost::apply_visitor(
|
out = boost::apply_visitor(
|
||||||
|
|
|
@ -26,7 +26,7 @@ std::string state::outside_section::render(
|
||||||
}
|
}
|
||||||
case token::type::comment: break;
|
case token::type::comment: break;
|
||||||
case token::type::text:
|
case token::type::text:
|
||||||
return token.raw();
|
return token.content();
|
||||||
case token::type::partial:
|
case token::type::partial:
|
||||||
return ctx.render_partial(token.content());
|
return ctx.render_partial(token.content());
|
||||||
case token::type::section_close: break;
|
case token::type::section_close: break;
|
||||||
|
|
|
@ -1,36 +1,48 @@
|
||||||
#include "token.hpp"
|
#include "token.hpp"
|
||||||
#include <boost/algorithm/string/trim.hpp>
|
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
|
||||||
|
|
||||||
using namespace mstch;
|
using namespace mstch;
|
||||||
|
|
||||||
std::tuple<int,int,token::type> token::token_info(const std::string& inside) {
|
token::type token::token_info(char c) {
|
||||||
switch (inside.at(0)) {
|
switch (c) {
|
||||||
case '>': return std::make_tuple(1, 0, type::partial);
|
case '>': return type::partial;
|
||||||
case '^': return std::make_tuple(1, 0, type::inverted_section_open);
|
case '^': return type::inverted_section_open;
|
||||||
case '/': return std::make_tuple(1, 0, type::section_close);
|
case '/': return type::section_close;
|
||||||
case '&': return std::make_tuple(1, 0, type::unescaped_variable);
|
case '&': return type::unescaped_variable;
|
||||||
case '#': return std::make_tuple(1, 0, type::section_open);
|
case '#': return type::section_open;
|
||||||
case '!': return std::make_tuple(1, 0, type::comment);
|
case '!': return type::comment;
|
||||||
case '{':
|
default: return type::variable;
|
||||||
if (inside.at(inside.size() - 1) == '}')
|
|
||||||
return std::make_tuple(1, 1, type::unescaped_variable);
|
|
||||||
default: return std::make_tuple(0, 0, type::variable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
token::token(bool is_tag, bool eol, bool ws_only, const std::string& raw_val):
|
token::token(bool is_tag, bool eol, bool ws_only, const std::string& raw_val):
|
||||||
raw_val(raw_val), eol(eol), ws_only(ws_only), marked(false)
|
eol(eol), ws_only(ws_only), marked(false)
|
||||||
{
|
{
|
||||||
if(is_tag) {
|
if(is_tag) {
|
||||||
std::string inside{raw_val.substr(2, raw_val.size() - 4)};
|
auto content_begin = raw_val.begin(), content_end = raw_val.end();
|
||||||
boost::trim(inside);
|
parse_state state = parse_state::prews;
|
||||||
if (inside.size() > 0) {
|
if(*content_begin == '{' && *(content_end - 1) == '}') {
|
||||||
int lpad, rpad;
|
state = parse_state::postws;
|
||||||
std::tie(lpad, rpad, type_val) = token_info(inside);
|
type_val = type::unescaped_variable;
|
||||||
content_val = inside.substr(lpad, inside.size() - lpad - rpad);
|
++content_begin;
|
||||||
boost::trim(content_val);
|
--content_end;
|
||||||
}
|
}
|
||||||
|
for(auto it = content_begin; it != content_end;) {
|
||||||
|
if(state == parse_state::prews && *it != ' ') {
|
||||||
|
state = parse_state::postws;
|
||||||
|
if((type_val = token_info(*it++)) == type::variable) {
|
||||||
|
state = parse_state::content;
|
||||||
|
content_begin = it -1;
|
||||||
|
}
|
||||||
|
} else if(state == parse_state::postws && *it != ' ') {
|
||||||
|
content_begin = it++;
|
||||||
|
state = parse_state::content;
|
||||||
|
} else if(state == parse_state::content && *it == ' ') {
|
||||||
|
content_end = it;
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
content_val = {content_begin, content_end};
|
||||||
} else {
|
} else {
|
||||||
type_val = type::text;
|
type_val = type::text;
|
||||||
content_val = raw_val;
|
content_val = raw_val;
|
||||||
|
|
|
@ -13,19 +13,18 @@ namespace mstch {
|
||||||
token(bool is_tag, bool eol, bool ws_only, const std::string& raw_val);
|
token(bool is_tag, bool eol, bool ws_only, const std::string& raw_val);
|
||||||
type token_type() const { return type_val; };
|
type token_type() const { return type_val; };
|
||||||
const std::string& content() const { return content_val; };
|
const std::string& content() const { return content_val; };
|
||||||
const std::string& raw() const { return raw_val; };
|
|
||||||
bool is_eol() const { return eol; }
|
bool is_eol() const { return eol; }
|
||||||
bool is_ws_only() const { return ws_only; }
|
bool is_ws_only() const { return ws_only; }
|
||||||
bool is_marked() const { return marked; }
|
bool is_marked() const { return marked; }
|
||||||
void mark() { marked = true; };
|
void mark() { marked = true; };
|
||||||
private:
|
private:
|
||||||
|
enum class parse_state { prews, postws, content };
|
||||||
type type_val;
|
type type_val;
|
||||||
std::string content_val;
|
std::string content_val;
|
||||||
std::string raw_val;
|
|
||||||
bool eol;
|
bool eol;
|
||||||
bool ws_only;
|
bool ws_only;
|
||||||
bool marked;
|
bool marked;
|
||||||
std::tuple<int,int,type> token_info(const std::string& inside);
|
type token_info(char c);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue