diff --git a/README.md b/README.md index 5d3875d..d73a679 100644 --- a/README.md +++ b/README.md @@ -167,9 +167,13 @@ render("Hello {{ lower(neighbour) }}!", data); // "Hello peter!" // Range function, useful for loops render("{% for i in range(4) %}{{ index1 }}{% endfor %}", data); // "1234" -// Length function (but please don't combine with range, use list directly...) +// Length function (please don't combine with range, use list directly...) render("I count {{ length(guests) }} guests.", data); // "I count 3 guests." +// Get first and last element in a list +render("{{ first(guests) }} was first.", data); // "Jeff was first." +render("{{ last(guests) }} was last.", data); // "Tom was last." + // Round numbers to a given precision render({{ round(3.1415, 0) }}, data); // 3 render({{ round(3.1415, 3) }}, data); // 3.142 diff --git a/src/inja.hpp b/src/inja.hpp index 6fa5835..611bae1 100644 --- a/src/inja.hpp +++ b/src/inja.hpp @@ -243,6 +243,8 @@ struct Parsed { Lower, Range, Length, + First, + Last, Round, DivisibleBy, Odd, @@ -356,6 +358,14 @@ public: const std::vector list = eval_expression>(element.args[0], data); return list.size(); } + case Parsed::Function::First: { + const std::vector list = eval_expression>(element.args[0], data); + return list.front(); + } + case Parsed::Function::Last: { + const std::vector list = eval_expression>(element.args[0], data); + return list.back(); + } case Parsed::Function::Round: { const double number = eval_expression(element.args[0], data); const int precision = eval_expression(element.args[1], data); @@ -548,6 +558,8 @@ public: {Parsed::Function::Lower, function_regex("lower", 1)}, {Parsed::Function::Range, function_regex("range", 1)}, {Parsed::Function::Length, function_regex("length", 1)}, + {Parsed::Function::First, function_regex("first", 1)}, + {Parsed::Function::Last, function_regex("last", 1)}, {Parsed::Function::Round, function_regex("round", 2)}, {Parsed::Function::DivisibleBy, function_regex("divisibleBy", 2)}, {Parsed::Function::Odd, function_regex("odd", 1)}, diff --git a/test/src/unit-renderer.cpp b/test/src/unit-renderer.cpp index 434582e..623ec8e 100644 --- a/test/src/unit-renderer.cpp +++ b/test/src/unit-renderer.cpp @@ -99,6 +99,16 @@ TEST_CASE("functions") { // CHECK_THROWS_WITH( env.render("{{ length(5) }}", data), "[json.exception.type_error.302] type must be array, but is number" ); } + SECTION("first") { + CHECK( env.render("{{ first(names) }}", data) == "Jeff" ); + // CHECK_THROWS_WITH( env.render("{{ length(5) }}", data), "[json.exception.type_error.302] type must be array, but is number" ); + } + + SECTION("last") { + CHECK( env.render("{{ last(names) }}", data) == "Tom" ); + // CHECK_THROWS_WITH( env.render("{{ length(5) }}", data), "[json.exception.type_error.302] type must be array, but is number" ); + } + SECTION("round") { CHECK( env.render("{{ round(4, 0) }}", data) == "4.0" ); CHECK( env.render("{{ round(temperature, 2) }}", data) == "25.68" );