diff --git a/include/inja/environment.hpp b/include/inja/environment.hpp index cbcc82e..72b312b 100644 --- a/include/inja/environment.hpp +++ b/include/inja/environment.hpp @@ -106,6 +106,10 @@ public: return result; } + Template parse_file(const std::string &filename) { + return parse_template(filename); + } + std::string render(nonstd::string_view input, const json &data) { return render(parse(input), data); } std::string render(const Template &tmpl, const json &data) { diff --git a/include/inja/node.hpp b/include/inja/node.hpp index 326c454..62707f8 100644 --- a/include/inja/node.hpp +++ b/include/inja/node.hpp @@ -47,7 +47,9 @@ public: virtual void visit(const IncludeStatementNode& node) = 0; }; - +/*! + * \brief Base node class for the abstract syntax tree (AST). + */ class AstNode { public: virtual void accept(NodeVisitor& v) const = 0; diff --git a/include/inja/parser.hpp b/include/inja/parser.hpp index 682a069..ae7b7a1 100644 --- a/include/inja/parser.hpp +++ b/include/inja/parser.hpp @@ -75,12 +75,6 @@ class Parser { current_expression_list->rpn_output.emplace_back(std::make_shared(json::parse(json_text), json_text.data() - content_ptr)); } - -public: - explicit Parser(const ParserConfig &parser_config, const LexerConfig &lexer_config, - TemplateStorage &template_storage, const FunctionStorage &function_storage) - : config(parser_config), lexer(lexer_config), template_storage(template_storage), function_storage(function_storage) { } - bool parse_expression(Template &tmpl, Token::Kind closing) { while (tok.kind != closing && tok.kind != Token::Kind::Eof) { // Literals @@ -521,6 +515,12 @@ public: } } + +public: + explicit Parser(const ParserConfig &parser_config, const LexerConfig &lexer_config, + TemplateStorage &template_storage, const FunctionStorage &function_storage) + : config(parser_config), lexer(lexer_config), template_storage(template_storage), function_storage(function_storage) { } + Template parse(nonstd::string_view input, nonstd::string_view path) { auto result = Template(static_cast(input)); parse_into(result, path); diff --git a/include/inja/renderer.hpp b/include/inja/renderer.hpp index 21bea51..9a4dae0 100644 --- a/include/inja/renderer.hpp +++ b/include/inja/renderer.hpp @@ -140,10 +140,6 @@ class Renderer : public NodeVisitor { return result; } -public: - Renderer(const RenderConfig& config, const TemplateStorage &template_storage, const FunctionStorage &function_storage) - : config(config), template_storage(template_storage), function_storage(function_storage) { } - void visit(const BlockNode& node) { for (auto& n : node.nodes) { n->accept(*this); @@ -567,6 +563,10 @@ public: } } +public: + Renderer(const RenderConfig& config, const TemplateStorage &template_storage, const FunctionStorage &function_storage) + : config(config), template_storage(template_storage), function_storage(function_storage) { } + void render_to(std::ostream &os, const Template &tmpl, const json &data, json *loop_data = nullptr) { output_stream = &os; current_template = &tmpl; diff --git a/include/inja/statistics.hpp b/include/inja/statistics.hpp index c0c33e1..c8be1b3 100644 --- a/include/inja/statistics.hpp +++ b/include/inja/statistics.hpp @@ -11,11 +11,7 @@ namespace inja { /*! * \brief A class for counting statistics on a Template. */ -struct StatisticsVisitor : public NodeVisitor { - unsigned int variable_counter; - - explicit StatisticsVisitor() : variable_counter(0) { } - +class StatisticsVisitor : public NodeVisitor { void visit(const BlockNode& node) { for (auto& n : node.nodes) { n->accept(*this); @@ -58,6 +54,11 @@ struct StatisticsVisitor : public NodeVisitor { } void visit(const IncludeStatementNode&) { } + +public: + unsigned int variable_counter; + + explicit StatisticsVisitor() : variable_counter(0) { } }; } // namespace inja diff --git a/test/test-renderer.cpp b/test/test-renderer.cpp index 51bc350..a25694e 100644 --- a/test/test-renderer.cpp +++ b/test/test-renderer.cpp @@ -74,8 +74,7 @@ TEST_CASE("types") { } SUBCASE("nested loops") { - auto ldata = json::parse( - R"DELIM( + auto ldata = json::parse(R""""( { "outer" : [ { "inner" : [ { "in2" : [ 1, 2 ] }, @@ -91,13 +90,13 @@ TEST_CASE("types") { } ] } -)DELIM"); +)""""); - CHECK(env.render(R"DELIM( + CHECK(env.render(R""""( {% for o in outer %}{% for i in o.inner %}{{loop.parent.index}}:{{loop.index}}::{{loop.parent.is_last}} {% for ii in i.in2%}{{ii}},{%endfor%} {%endfor%}{%endfor%} -)DELIM", +)"""", ldata) == "\n0:0::false\n1,2,\n0:1::false\n\n0:2::false\n\n2:0::true\n3,4,\n2:1::true\n5,6,\n\n"); } @@ -124,19 +123,19 @@ TEST_CASE("types") { } SUBCASE("line statements") { - CHECK(env.render(R"(## if is_happy + CHECK(env.render(R""""(## if is_happy Yeah! -## endif)", - data) == R"(Yeah! -)"); +## endif)"""", + data) == R""""(Yeah! +)""""); - CHECK(env.render(R"(## if is_happy + CHECK(env.render(R""""(## if is_happy ## if is_happy Yeah! ## endif -## endif )", - data) == R"(Yeah! -)"); +## endif )"""", + data) == R""""(Yeah! +)""""); } } @@ -253,11 +252,11 @@ TEST_CASE("other syntax") { env.set_line_statement("$$"); env.set_expression("<%", "%>"); - std::string string_template = R"DELIM(Hello <%name%> + std::string string_template = R""""(Hello <%name%> $$ if name == "Peter" You really are <%name%> $$ endif -)DELIM"; +)""""; CHECK(env.render(string_template, data) == "Hello Peter\n You really are Peter\n"); } diff --git a/test/test-units.cpp b/test/test-units.cpp index 074484d..3a8c82b 100644 --- a/test/test-units.cpp +++ b/test/test-units.cpp @@ -5,13 +5,13 @@ TEST_CASE("source location") { - std::string content = R"DELIM(Lorem Ipsum + std::string content = R""""(Lorem Ipsum Dolor Amid Set ().$ Try this -)DELIM"; +)""""; CHECK(inja::get_source_location(content, 0).line == 1); CHECK(inja::get_source_location(content, 0).column == 1);