2015-04-16 06:49:45 +08:00
|
|
|
#include "template_type.hpp"
|
|
|
|
|
|
|
|
using namespace mstch;
|
|
|
|
|
|
|
|
template_type::template_type(const std::string& str) {
|
2015-04-23 18:54:08 +08:00
|
|
|
tokenize(str);
|
|
|
|
strip_whitespace();
|
2015-04-16 06:49:45 +08:00
|
|
|
}
|
|
|
|
|
2015-04-24 06:35:13 +08:00
|
|
|
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) {
|
|
|
|
tokens.push_back({{start, it + 1}});
|
|
|
|
start = it + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-27 20:14:21 +08:00
|
|
|
void template_type::tokenize(const std::string& tmp) {
|
|
|
|
std::string open{"{{"}, close{"}}"};
|
|
|
|
citer beg = tmp.begin();
|
|
|
|
auto npos = std::string::npos;
|
|
|
|
|
|
|
|
for (unsigned long cur_pos = 0; cur_pos < tmp.size();) {
|
|
|
|
auto open_pos = tmp.find(open, cur_pos);
|
|
|
|
auto close_pos = tmp.find(
|
2015-04-27 20:29:12 +08:00
|
|
|
close, open_pos == npos ? open_pos : open_pos + 1);
|
2015-04-27 20:14:21 +08:00
|
|
|
|
|
|
|
if (close_pos != npos && open_pos != npos) {
|
|
|
|
if (*(beg + open_pos + open.size()) == '{' &&
|
|
|
|
*(beg + close_pos + close.size()) == '}')
|
|
|
|
++close_pos;
|
|
|
|
|
|
|
|
process_text(beg + cur_pos, beg + open_pos);
|
|
|
|
cur_pos = close_pos + close.size();
|
|
|
|
tokens.push_back({{beg + open_pos, beg + close_pos + close.size()},
|
|
|
|
open.size(), close.size()});
|
2015-05-04 20:12:51 +08:00
|
|
|
|
2015-05-04 18:57:01 +08:00
|
|
|
if(cur_pos == tmp.size()) {
|
|
|
|
tokens.push_back({{""}});
|
2015-05-04 20:12:51 +08:00
|
|
|
tokens.back().eol(true);
|
2015-05-04 18:57:01 +08:00
|
|
|
}
|
2015-04-27 20:14:21 +08:00
|
|
|
|
|
|
|
if (*(beg + open_pos + open.size()) == '=' &&
|
|
|
|
*(beg + close_pos - 1) == '=')
|
|
|
|
{
|
2015-05-04 17:27:51 +08:00
|
|
|
auto tok_beg = beg + open_pos + open.size() + 1;
|
|
|
|
auto tok_end = beg + close_pos - 1;
|
|
|
|
auto front_skip = first_not_ws(tok_beg, tok_end);
|
|
|
|
auto back_skip = first_not_ws(reverse(tok_end), reverse(tok_beg));
|
|
|
|
open = {front_skip, beg + tmp.find(' ', front_skip - beg)};
|
|
|
|
close = {beg + tmp.rfind(' ', back_skip - beg) + 1, back_skip + 1};
|
2015-04-23 18:54:08 +08:00
|
|
|
}
|
2015-04-24 06:35:13 +08:00
|
|
|
} else {
|
2015-04-27 20:14:21 +08:00
|
|
|
process_text(beg + cur_pos, tmp.end());
|
|
|
|
cur_pos = close_pos;
|
2015-04-16 06:49:45 +08:00
|
|
|
}
|
2015-04-23 18:54:08 +08:00
|
|
|
}
|
2015-04-16 06:49:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void template_type::strip_whitespace() {
|
2015-04-27 20:14:21 +08:00
|
|
|
auto line_begin = tokens.begin();
|
2015-04-23 18:54:08 +08:00
|
|
|
bool has_tag = false, non_space = false;
|
2015-04-27 20:14:21 +08:00
|
|
|
|
2015-04-23 18:54:08 +08:00
|
|
|
for (auto it = tokens.begin(); it != tokens.end(); ++it) {
|
|
|
|
auto type = (*it).token_type();
|
|
|
|
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;
|
2015-04-27 20:14:21 +08:00
|
|
|
|
2015-04-23 18:54:08 +08:00
|
|
|
if ((*it).eol()) {
|
2015-05-04 20:12:51 +08:00
|
|
|
if (has_tag && !non_space) {
|
2015-05-05 14:49:42 +08:00
|
|
|
store_prefixes(line_begin);
|
2015-05-04 20:12:51 +08:00
|
|
|
|
2015-04-27 20:14:21 +08:00
|
|
|
for (auto cur = line_begin; it != cur - 1;
|
2015-04-27 20:29:12 +08:00
|
|
|
cur = (*cur).ws_only() ? tokens.erase(cur) : cur + 1)
|
2015-04-27 20:14:21 +08:00
|
|
|
it = (*cur).eol() ? cur - 1 : it;
|
2015-05-04 20:12:51 +08:00
|
|
|
}
|
2015-04-27 20:14:21 +08:00
|
|
|
|
2015-04-23 18:54:08 +08:00
|
|
|
non_space = has_tag = false;
|
2015-04-27 20:14:21 +08:00
|
|
|
line_begin = it + 1;
|
2015-04-16 06:49:45 +08:00
|
|
|
}
|
2015-04-23 18:54:08 +08:00
|
|
|
}
|
2015-04-16 06:49:45 +08:00
|
|
|
}
|
2015-05-05 14:49:42 +08:00
|
|
|
|
|
|
|
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())
|
|
|
|
(*cur).partial_prefix((*(cur - 1)).raw());
|
|
|
|
}
|