X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=lib%2Fmstch%2Ftemplate_type.cpp;fp=lib%2Fmstch%2Ftemplate_type.cpp;h=5b40e4062afcb9ac1a55074c48287a7a9ce8d60b;hb=2e142df11d6f312a2a2b5097b8da73571ed523e8;hp=0000000000000000000000000000000000000000;hpb=61b3659afe961ed248f30e26f9ca8f28fcfafddc;p=cpPlugins.git diff --git a/lib/mstch/template_type.cpp b/lib/mstch/template_type.cpp new file mode 100644 index 0000000..5b40e40 --- /dev/null +++ b/lib/mstch/template_type.cpp @@ -0,0 +1,104 @@ +#include "template_type.hpp" + +using namespace mstch; + +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("}}") +{ + tokenize(str); + strip_whitespace(); +} + +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) { + m_tokens.push_back({{start, it + 1}}); + start = it + 1; + } +} + +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();) { + auto open_pos = tmp.find(m_open, cur_pos); + 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()) == '}') + ++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()}); + + 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) == '=') + { + auto tok_beg = beg + open_pos + m_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)); + m_open = {front_skip, beg + tmp.find(' ', front_skip - beg)}; + m_close = {beg + tmp.rfind(' ', back_skip - beg) + 1, back_skip + 1}; + } + } else { + process_text(beg + cur_pos, tmp.end()); + cur_pos = close_pos; + } + } +} + +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) { + 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; + + if ((*it).eol()) { + if (has_tag && !non_space) { + store_prefixes(line_begin); + + auto c = line_begin; + for (bool end = false; !end; (*c).ws_only() ? c = m_tokens.erase(c) : ++c) + if ((end = (*c).eol())) + it = c - 1; + } + + non_space = has_tag = false; + line_begin = it + 1; + } + } +} + +void template_type::store_prefixes(std::vector::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()); +}