changeset 80:7bb5167cffb4

mstch: removal, closes #1713
author David Demelier <markand@malikania.fr>
date Thu, 25 Jul 2019 20:25:00 +0000
parents fa87496ee898
children 7fdaf1411e6f
files CMakeLists.txt LICENSE.libmstch.txt VERSION.libmstch.txt libmstch/CMakeLists.txt libmstch/include/mstch/mstch.hpp libmstch/src/CMakeLists.txt libmstch/src/mstch.cpp libmstch/src/render_context.cpp libmstch/src/render_context.hpp libmstch/src/state/in_section.cpp libmstch/src/state/in_section.hpp libmstch/src/state/outside_section.cpp libmstch/src/state/outside_section.hpp libmstch/src/state/render_state.hpp libmstch/src/template_type.cpp libmstch/src/template_type.hpp libmstch/src/token.cpp libmstch/src/token.hpp libmstch/src/utils.cpp libmstch/src/utils.hpp libmstch/src/visitor/get_token.hpp libmstch/src/visitor/has_token.hpp libmstch/src/visitor/is_node_empty.hpp libmstch/src/visitor/render_node.hpp libmstch/src/visitor/render_section.hpp tests/libmstch/CMakeLists.txt tests/libmstch/main.cpp
diffstat 27 files changed, 0 insertions(+), 983 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Thu Jul 25 20:20:00 2019 +0000
+++ b/CMakeLists.txt	Thu Jul 25 20:25:00 2019 +0000
@@ -29,7 +29,6 @@
 add_subdirectory(tests/libhoedown)
 add_subdirectory(tests/libjansson)
 add_subdirectory(tests/libjson)
-add_subdirectory(tests/libmstch)
 add_subdirectory(tests/libpugixml)
 add_subdirectory(tests/libsqlite)
 add_subdirectory(tests/liburiparser)
--- a/LICENSE.libmstch.txt	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2015 Daniel Sipka
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
--- a/VERSION.libmstch.txt	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-1.0.2
--- a/libmstch/CMakeLists.txt	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-#
-# this file was customized it may be different from upstream.
-#
-
-cmake_minimum_required(VERSION 3.0.2)
-project(mstch)
-add_subdirectory(src)
--- a/libmstch/include/mstch/mstch.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-#pragma once
-
-#include <vector>
-#include <map>
-#include <string>
-#include <memory>
-#include <functional>
-
-#include <boost/variant.hpp>
-
-namespace mstch {
-
-struct config {
-  static std::function<std::string(const std::string&)> escape;
-};
-
-namespace internal {
-
-template<class N>
-class object_t {
- public:
-  const N& at(const std::string& name) const {
-    cache[name] = (methods.at(name))();
-    return cache[name];
-  }
-
-  bool has(const std::string name) const {
-    return methods.count(name) != 0;
-  }
-
- protected:
-  template<class S>
-  void register_methods(S* s, std::map<std::string,N(S::*)()> methods) {
-    for(auto& item: methods)
-      this->methods.insert({item.first, std::bind(item.second, s)});
-  }
-
- private:
-  std::map<std::string, std::function<N()>> methods;
-  mutable std::map<std::string, N> cache;
-};
-
-template<class T, class N>
-class is_fun {
- private:
-  using not_fun = char;
-  using fun_without_args = char[2];
-  using fun_with_args = char[3];
-  template <typename U, U> struct really_has;
-  template <typename C> static fun_without_args& test(
-      really_has<N(C::*)() const, &C::operator()>*);
-  template <typename C> static fun_with_args& test(
-      really_has<N(C::*)(const std::string&) const,
-      &C::operator()>*);
-  template <typename> static not_fun& test(...);
-
- public:
-  static bool const no_args = sizeof(test<T>(0)) == sizeof(fun_without_args);
-  static bool const has_args = sizeof(test<T>(0)) == sizeof(fun_with_args);
-};
-
-template<class N>
-using node_renderer = std::function<std::string(const N& n)>;
-
-template<class N>
-class lambda_t {
- public:
-  template<class F>
-  lambda_t(F f, typename std::enable_if<is_fun<F, N>::no_args>::type* = 0):
-      fun([f](node_renderer<N> renderer, const std::string&) {
-        return renderer(f());
-      })
-  {
-  }
-
-  template<class F>
-  lambda_t(F f, typename std::enable_if<is_fun<F, N>::has_args>::type* = 0):
-      fun([f](node_renderer<N> renderer, const std::string& text) {
-        return renderer(f(text));
-      })
-  {
-  }
-
-  std::string operator()(node_renderer<N> renderer,
-      const std::string& text = "") const
-  {
-    return fun(renderer, text);
-  }
-
- private:
-  std::function<std::string(node_renderer<N> renderer, const std::string&)> fun;
-};
-
-}
-
-using node = boost::make_recursive_variant<
-    std::nullptr_t, std::string, int, double, bool,
-    internal::lambda_t<boost::recursive_variant_>,
-    std::shared_ptr<internal::object_t<boost::recursive_variant_>>,
-    std::map<const std::string, boost::recursive_variant_>,
-    std::vector<boost::recursive_variant_>>::type;
-using object = internal::object_t<node>;
-using lambda = internal::lambda_t<node>;
-using map = std::map<const std::string, node>;
-using array = std::vector<node>;
-
-std::string render(
-    const std::string& tmplt,
-    const node& root,
-    const std::map<std::string,std::string>& partials =
-        std::map<std::string,std::string>());
-
-}
--- a/libmstch/src/CMakeLists.txt	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-find_package(Boost 1.54 REQUIRED)
-
-add_library(
-	libmstch
-	state/in_section.cpp
-	state/outside_section.cpp
-	state/render_state.hpp
-	visitor/get_token.hpp
-	visitor/has_token.hpp
-	visitor/is_node_empty.hpp
-	visitor/render_node.hpp
-	visitor/render_section.hpp
-	mstch.cpp
-	render_context.cpp
-	template_type.cpp
-	token.cpp
-	utils.cpp
-)
-
-target_include_directories(
-	libmstch
-	PRIVATE ${mstch_SOURCE_DIR}/src
-	PUBLIC $<BUILD_INTERFACE:${mstch_SOURCE_DIR}/include>
-)
-
-target_link_libraries(libmstch Boost::boost)
-set_target_properties(libmstch PROPERTIES PREFIX "" WINDOWS_EXPORT_ALL_SYMBOLS On)
--- a/libmstch/src/mstch.cpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,20 +0,0 @@
-#include <iostream>
-
-#include "mstch/mstch.hpp"
-#include "render_context.hpp"
-
-using namespace mstch;
-
-std::function<std::string(const std::string&)> mstch::config::escape;
-
-std::string mstch::render(
-    const std::string& tmplt,
-    const node& root,
-    const std::map<std::string,std::string>& partials)
-{
-  std::map<std::string, template_type> partial_templates;
-  for (auto& partial: partials)
-    partial_templates.insert({partial.first, {partial.second}});
-
-  return render_context(root, partial_templates).render(tmplt);
-}
--- a/libmstch/src/render_context.cpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-#include "render_context.hpp"
-#include "state/outside_section.hpp"
-#include "visitor/get_token.hpp"
-
-using namespace mstch;
-
-const mstch::node render_context::null_node;
-
-render_context::push::push(render_context& context, const mstch::node& node):
-    m_context(context)
-{
-  context.m_nodes.emplace_front(node);
-  context.m_node_ptrs.emplace_front(&node);
-  context.m_state.push(std::unique_ptr<render_state>(new outside_section));
-}
-
-render_context::push::~push() {
-  m_context.m_nodes.pop_front();
-  m_context.m_node_ptrs.pop_front();
-  m_context.m_state.pop();
-}
-
-std::string render_context::push::render(const template_type& templt) {
-  return m_context.render(templt);
-}
-
-render_context::render_context(
-    const mstch::node& node,
-    const std::map<std::string, template_type>& partials):
-    m_partials(partials), m_nodes(1, node), m_node_ptrs(1, &node)
-{
-  m_state.push(std::unique_ptr<render_state>(new outside_section));
-}
-
-const mstch::node& render_context::find_node(
-    const std::string& token,
-    std::list<node const*> current_nodes)
-{
-  if (token != "." && token.find('.') != std::string::npos)
-    return find_node(token.substr(token.rfind('.') + 1),
-        {&find_node(token.substr(0, token.rfind('.')), current_nodes)});
-  else
-    for (auto& node: current_nodes)
-      if (visit(has_token(token), *node))
-        return visit(get_token(token, *node), *node);
-  return null_node;
-}
-
-const mstch::node& render_context::get_node(const std::string& token) {
-    return find_node(token, m_node_ptrs);
-}
-
-std::string render_context::render(
-    const template_type& templt, const std::string& prefix)
-{
-  std::string output;
-  bool prev_eol = true;
-  for (auto& token: templt) {
-    if (prev_eol && prefix.length() != 0)
-      output += m_state.top()->render(*this, {prefix});
-    output += m_state.top()->render(*this, token);
-    prev_eol = token.eol();
-  }
-  return output;
-}
-
-std::string render_context::render_partial(
-    const std::string& partial_name, const std::string& prefix)
-{
-  return m_partials.count(partial_name) ?
-      render(m_partials.at(partial_name), prefix) : "";
-}
--- a/libmstch/src/render_context.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-#pragma once
-
-#include <deque>
-#include <list>
-#include <sstream>
-#include <string>
-#include <stack>
-
-#include "mstch/mstch.hpp"
-#include "state/render_state.hpp"
-#include "template_type.hpp"
-
-namespace mstch {
-
-class render_context {
- public:
-  class push {
-   public:
-    push(render_context& context, const mstch::node& node = {});
-    ~push();
-    std::string render(const template_type& templt);
-   private:
-    render_context& m_context;
-  };
-
-  render_context(
-      const mstch::node& node,
-      const std::map<std::string, template_type>& partials);
-  const mstch::node& get_node(const std::string& token);
-  std::string render(
-      const template_type& templt, const std::string& prefix = "");
-  std::string render_partial(
-      const std::string& partial_name, const std::string& prefix);
-  template<class T, class... Args>
-  void set_state(Args&& ... args) {
-    m_state.top() = std::unique_ptr<render_state>(
-        new T(std::forward<Args>(args)...));
-  }
-
- private:
-  static const mstch::node null_node;
-  const mstch::node& find_node(
-      const std::string& token,
-      std::list<node const*> current_nodes);
-  std::map<std::string, template_type> m_partials;
-  std::deque<mstch::node> m_nodes;
-  std::list<const mstch::node*> m_node_ptrs;
-  std::stack<std::unique_ptr<render_state>> m_state;
-};
-
-}
--- a/libmstch/src/state/in_section.cpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-#include "in_section.hpp"
-#include "outside_section.hpp"
-#include "visitor/is_node_empty.hpp"
-#include "visitor/render_section.hpp"
-
-using namespace mstch;
-
-in_section::in_section(type type, const token& start_token):
-    m_type(type), m_start_token(start_token), m_skipped_openings(0)
-{
-}
-
-std::string in_section::render(render_context& ctx, const token& token) {
-  if (token.token_type() == token::type::section_close)
-    if (token.name() == m_start_token.name() && m_skipped_openings == 0) {
-      auto& node = ctx.get_node(m_start_token.name());
-      std::string out;
-
-      if (m_type == type::normal && !visit(is_node_empty(), node))
-        out = visit(render_section(ctx, m_section, m_start_token.delims()), node);
-      else if (m_type == type::inverted && visit(is_node_empty(), node))
-        out = render_context::push(ctx).render(m_section);
-
-      ctx.set_state<outside_section>();
-      return out;
-    } else
-      m_skipped_openings--;
-  else if (token.token_type() == token::type::inverted_section_open ||
-      token.token_type() == token::type::section_open)
-    m_skipped_openings++;
-
-  m_section << token;
-  return "";
-}
--- a/libmstch/src/state/in_section.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-#pragma once
-
-#include <sstream>
-#include <vector>
-
-#include "render_state.hpp"
-#include "template_type.hpp"
-
-namespace mstch {
-
-class in_section: public render_state {
- public:
-  enum class type { inverted, normal };
-  in_section(type type, const token& start_token);
-  std::string render(render_context& context, const token& token) override;
-
- private:
-  const type m_type;
-  const token& m_start_token;
-  template_type m_section;
-  int m_skipped_openings;
-};
-
-}
--- a/libmstch/src/state/outside_section.cpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-#include "outside_section.hpp"
-
-#include "visitor/render_node.hpp"
-#include "in_section.hpp"
-#include "render_context.hpp"
-
-using namespace mstch;
-
-std::string outside_section::render(
-    render_context& ctx, const token& token)
-{
-  using flag = render_node::flag;
-  switch (token.token_type()) {
-    case token::type::section_open:
-      ctx.set_state<in_section>(in_section::type::normal, token);
-      break;
-    case token::type::inverted_section_open:
-      ctx.set_state<in_section>(in_section::type::inverted, token);
-      break;
-    case token::type::variable:
-      return visit(render_node(ctx, flag::escape_html), ctx.get_node(token.name()));
-    case token::type::unescaped_variable:
-      return visit(render_node(ctx, flag::none), ctx.get_node(token.name()));
-    case token::type::text:
-      return token.raw();
-    case token::type::partial:
-      return ctx.render_partial(token.name(), token.partial_prefix());
-    default:
-      break;
-  }
-  return "";
-}
--- a/libmstch/src/state/outside_section.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-#pragma once
-
-#include "render_state.hpp"
-
-namespace mstch {
-
-class outside_section: public render_state {
- public:
-  std::string render(render_context& context, const token& token) override;
-};
-
-}
--- a/libmstch/src/state/render_state.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-#pragma once
-
-#include <memory>
-
-#include "token.hpp"
-
-namespace mstch {
-
-class render_context;
-
-class render_state {
- public:
-  virtual ~render_state() {}
-  virtual std::string render(render_context& context, const token& token) = 0;
-};
-
-}
--- a/libmstch/src/template_type.cpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-#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<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());
-}
--- a/libmstch/src/template_type.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#pragma once
-
-#include <string>
-#include <vector>
-
-#include "token.hpp"
-#include "utils.hpp"
-
-namespace mstch {
-
-class template_type {
- public:
-  template_type() = default;
-  template_type(const std::string& str);
-  template_type(const std::string& str, const delim_type& delims);
-  std::vector<token>::const_iterator begin() const { return m_tokens.begin(); }
-  std::vector<token>::const_iterator end() const { return m_tokens.end(); }
-  void operator<<(const token& token) { m_tokens.push_back(token); }
-
- private:
-  std::vector<token> m_tokens;
-  std::string m_open;
-  std::string m_close;
-  void strip_whitespace();
-  void process_text(citer beg, citer end);
-  void tokenize(const std::string& tmp);
-  void store_prefixes(std::vector<token>::iterator beg);
-};
-
-}
--- a/libmstch/src/token.cpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-#include "token.hpp"
-#include "utils.hpp"
-
-using namespace mstch;
-
-token::type token::token_info(char c) {
-  switch (c) {
-    case '>': return type::partial;
-    case '^': return type::inverted_section_open;
-    case '/': return type::section_close;
-    case '&': return type::unescaped_variable;
-    case '#': return type::section_open;
-    case '!': return type::comment;
-    default: return type::variable;
-  }
-}
-
-token::token(const std::string& str, std::size_t left, std::size_t right):
-    m_raw(str), m_eol(false), m_ws_only(false)
-{
-  if (left != 0 && right != 0) {
-    if (str[left] == '=' && str[str.size() - right - 1] == '=') {
-      m_type = type::delimiter_change;
-    } else if (str[left] == '{' && str[str.size() - right - 1] == '}') {
-      m_type = type::unescaped_variable;
-      m_name = {first_not_ws(str.begin() + left + 1, str.end() - right),
-          first_not_ws(str.rbegin() + 1 + right, str.rend() - left) + 1};
-    } else {
-      auto c = first_not_ws(str.begin() + left, str.end() - right);
-      m_type = token_info(*c);
-      if (m_type != type::variable)
-        c = first_not_ws(c + 1, str.end() - right);
-      m_name = {c, first_not_ws(str.rbegin() + right, str.rend() - left) + 1};
-      m_delims = {{str.begin(), str.begin() + left},
-          {str.end() - right, str.end()}};
-    }
-  } else {
-    m_type = type::text;
-    m_eol = (str.size() > 0 && str[str.size() - 1] == '\n');
-    m_ws_only = (str.find_first_not_of(" \r\n\t") == std::string::npos);
-  }
-}
--- a/libmstch/src/token.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-#pragma once
-
-#include <string>
-
-namespace mstch {
-
-using delim_type = std::pair<std::string, std::string>;
-
-class token {
- public:
-  enum class type {
-    text, variable, section_open, section_close, inverted_section_open,
-    unescaped_variable, comment, partial, delimiter_change
-  };
-  token(const std::string& str, std::size_t left = 0, std::size_t right = 0);
-  type token_type() const { return m_type; };
-  const std::string& raw() const { return m_raw; };
-  const std::string& name() const { return m_name; };
-  const std::string& partial_prefix() const { return m_partial_prefix; };
-  const delim_type& delims() const { return m_delims; };
-  void partial_prefix(const std::string& p_partial_prefix) {
-    m_partial_prefix = p_partial_prefix;
-  };
-  bool eol() const { return m_eol; }
-  void eol(bool eol) { m_eol = eol; }
-  bool ws_only() const { return m_ws_only; }
-
- private:
-  type m_type;
-  std::string m_name;
-  std::string m_raw;
-  std::string m_partial_prefix;
-  delim_type m_delims;
-  bool m_eol;
-  bool m_ws_only;
-  type token_info(char c);
-};
-
-}
--- a/libmstch/src/utils.cpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-#include "utils.hpp"
-#include "mstch/mstch.hpp"
-
-mstch::citer mstch::first_not_ws(mstch::citer begin, mstch::citer end) {
-  for (auto it = begin; it != end; ++it)
-    if (*it != ' ') return it;
-  return end;
-}
-
-mstch::citer mstch::first_not_ws(mstch::criter begin, mstch::criter end) {
-  for (auto rit = begin; rit != end; ++rit)
-    if (*rit != ' ') return --(rit.base());
-  return --(end.base());
-}
-
-mstch::criter mstch::reverse(mstch::citer it) {
-  return std::reverse_iterator<mstch::citer>(it);
-}
-
-std::string mstch::html_escape(const std::string& str) {
-  if (mstch::config::escape)
-    return mstch::config::escape(str);
-  
-  std::string out;
-  citer start = str.begin();
-
-  auto add_escape = [&out, &start](const std::string& escaped, citer& it) {
-    out += std::string{start, it} + escaped;
-    start = it + 1;
-  };
-
-  for (auto it = str.begin(); it != str.end(); ++it)
-    switch (*it) {
-      case '&': add_escape("&amp;", it); break;
-      case '\'': add_escape("&#39;", it); break;
-      case '"': add_escape("&quot;", it); break;
-      case '<': add_escape("&lt;", it); break;
-      case '>': add_escape("&gt;", it); break;
-      case '/': add_escape("&#x2F;", it); break;
-      default: break;
-    }
-
-  return out + std::string{start, str.end()};
-}
--- a/libmstch/src/utils.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#pragma once
-
-#include <string>
-#include <boost/variant/apply_visitor.hpp>
-
-namespace mstch {
-
-using citer = std::string::const_iterator;
-using criter = std::string::const_reverse_iterator;
-
-citer first_not_ws(citer begin, citer end);
-citer first_not_ws(criter begin, criter end);
-std::string html_escape(const std::string& str);
-criter reverse(citer it);
-
-template<class... Args>
-auto visit(Args&&... args) -> decltype(boost::apply_visitor(
-    std::forward<Args>(args)...))
-{
-  return boost::apply_visitor(std::forward<Args>(args)...);
-}
-
-}
--- a/libmstch/src/visitor/get_token.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-#pragma once
-
-#include <boost/variant/static_visitor.hpp>
-
-#include "mstch/mstch.hpp"
-#include "has_token.hpp"
-
-namespace mstch {
-
-class get_token: public boost::static_visitor<const mstch::node&> {
- public:
-  get_token(const std::string& token, const mstch::node& node):
-      m_token(token), m_node(node)
-  {
-  }
-
-  template<class T>
-  const mstch::node& operator()(const T&) const {
-    return m_node;
-  }
-
-  const mstch::node& operator()(const map& map) const {
-    return map.at(m_token);
-  }
-
-  const mstch::node& operator()(const std::shared_ptr<object>& object) const {
-    return object->at(m_token);
-  }
-
- private:
-  const std::string& m_token;
-  const mstch::node& m_node;
-};
-
-}
--- a/libmstch/src/visitor/has_token.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-#pragma once
-
-#include <boost/variant/static_visitor.hpp>
-
-#include "mstch/mstch.hpp"
-
-namespace mstch {
-
-class has_token: public boost::static_visitor<bool> {
- public:
-  has_token(const std::string& token): m_token(token) {
-  }
-
-  template<class T>
-  bool operator()(const T&) const {
-    return m_token == ".";
-  }
-
-  bool operator()(const map& map) const {
-    return map.count(m_token) == 1;
-  }
-
-  bool operator()(const std::shared_ptr<object>& object) const {
-    return object->has(m_token);
-  }
-
- private:
-  const std::string& m_token;
-};
-
-}
--- a/libmstch/src/visitor/is_node_empty.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-#pragma once
-
-#include <boost/variant/static_visitor.hpp>
-
-#include "mstch/mstch.hpp"
-
-namespace mstch {
-
-class is_node_empty: public boost::static_visitor<bool> {
- public:
-  template<class T>
-  bool operator()(const T&) const {
-    return false;
-  }
-
-  bool operator()(const std::nullptr_t&) const {
-    return true;
-  }
-
-  bool operator()(const int& value) const {
-    return value == 0;
-  }
-
-  bool operator()(const double& value) const {
-    return value == 0;
-  }
-
-  bool operator()(const bool& value) const {
-    return !value;
-  }
-
-  bool operator()(const std::string& value) const {
-    return value == "";
-  }
-
-  bool operator()(const array& array) const {
-    return array.size() == 0;
-  }
-};
-
-}
--- a/libmstch/src/visitor/render_node.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +0,0 @@
-#pragma once
-
-#include <sstream>
-#include <boost/variant/static_visitor.hpp>
-
-#include "render_context.hpp"
-#include "mstch/mstch.hpp"
-#include "utils.hpp"
-
-namespace mstch {
-
-class render_node: public boost::static_visitor<std::string> {
- public:
-  enum class flag { none, escape_html };
-  render_node(render_context& ctx, flag p_flag = flag::none):
-      m_ctx(ctx), m_flag(p_flag)
-  {
-  }
-
-  template<class T>
-  std::string operator()(const T&) const {
-    return "";
-  }
-
-  std::string operator()(const int& value) const {
-    return std::to_string(value);
-  }
-
-  std::string operator()(const double& value) const {
-    std::stringstream ss;
-    ss << value;
-    return ss.str();
-  }
-
-  std::string operator()(const bool& value) const {
-    return value ? "true" : "false";
-  }
-
-  std::string operator()(const lambda& value) const {
-    template_type interpreted{value([this](const mstch::node& n) {
-      return visit(render_node(m_ctx), n);
-    })};
-    auto rendered = render_context::push(m_ctx).render(interpreted);
-    return (m_flag == flag::escape_html) ? html_escape(rendered) : rendered;
-  }
-
-  std::string operator()(const std::string& value) const {
-    return (m_flag == flag::escape_html) ? html_escape(value) : value;
-  }
-
- private:
-  render_context& m_ctx;
-  flag m_flag;
-};
-
-}
--- a/libmstch/src/visitor/render_section.hpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +0,0 @@
-#pragma once
-
-#include <boost/variant/static_visitor.hpp>
-
-#include "render_context.hpp"
-#include "mstch/mstch.hpp"
-#include "utils.hpp"
-#include "render_node.hpp"
-
-namespace mstch {
-
-class render_section: public boost::static_visitor<std::string> {
- public:
-  enum class flag { none, keep_array };
-  render_section(
-      render_context& ctx,
-      const template_type& section,
-      const delim_type& delims,
-      flag p_flag = flag::none):
-      m_ctx(ctx), m_section(section), m_delims(delims), m_flag(p_flag)
-  {
-  }
-
-  template<class T>
-  std::string operator()(const T& t) const {
-    return render_context::push(m_ctx, t).render(m_section);
-  }
-
-  std::string operator()(const lambda& fun) const {
-    std::string section_str;
-    for (auto& token: m_section)
-      section_str += token.raw();
-    template_type interpreted{fun([this](const mstch::node& n) {
-      return visit(render_node(m_ctx), n);
-    }, section_str), m_delims};
-    return render_context::push(m_ctx).render(interpreted);
-  }
-
-  std::string operator()(const array& array) const {
-    std::string out;
-    if (m_flag == flag::keep_array)
-      return render_context::push(m_ctx, array).render(m_section);
-    else
-      for (auto& item: array)
-        out += visit(render_section(
-            m_ctx, m_section, m_delims, flag::keep_array), item);
-    return out;
-  }
-
- private:
-  render_context& m_ctx;
-  const template_type& m_section;
-  const delim_type& m_delims;
-  flag m_flag;
-};
-
-}
--- a/tests/libmstch/CMakeLists.txt	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-#
-# CMakeLists.txt -- test project for mstch
-#
-# Copyright (c) 2016-2018 David Demelier <markand@malikania.fr>
-#
-# Permission to use, copy, modify, and/or distribute this software for any
-# purpose with or without fee is hereby granted, provided that the above
-# copyright notice and this permission notice appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
-# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-#
-
-cmake_minimum_required(VERSION 3.7)
-project(test-mstch)
-add_subdirectory(../../libmstch mstch-build-dir)
-add_executable(test-mstch main.cpp)
-target_link_libraries(test-mstch libmstch)
--- a/tests/libmstch/main.cpp	Thu Jul 25 20:20:00 2019 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-/*
- * main.cpp -- main file
- *
- * Copyright (c) 2016-2018 David Demelier <markand@malikania.fr>
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <mstch/mstch.hpp>
-
-int main()
-{
-	mstch::map map;
-	mstch::render("test", map);
-}