From 3b14e27f55ebf832f1eb64ba6f56be732126e35a Mon Sep 17 00:00:00 2001 From: Dylan Thacker-Smith Date: Thu, 20 Mar 2014 17:05:49 -0400 Subject: [PATCH] Allow newlines in tags and variables. --- History.md | 1 + lib/liquid.rb | 4 ++-- lib/liquid/block.rb | 4 ++-- lib/liquid/context.rb | 6 +++--- lib/liquid/tags/assign.rb | 2 +- lib/liquid/tags/case.rb | 2 +- lib/liquid/tags/cycle.rb | 2 +- lib/liquid/tags/raw.rb | 2 +- lib/liquid/variable.rb | 4 ++-- test/liquid/tags/standard_tag_test.rb | 4 ++++ test/liquid/variable_test.rb | 4 ++++ 11 files changed, 22 insertions(+), 13 deletions(-) diff --git a/History.md b/History.md index d99f7cb..1eadb82 100644 --- a/History.md +++ b/History.md @@ -3,6 +3,7 @@ ## 3.0.0 / not yet released / branch "master" * ... +* Allow newlines in tags and variables * Tag#parse is called after initialize, which now takes options instead of tokens as the 3rd argument. See #321 [Dylan Thacker-Smith, dylanahsmith] * Raise `Liquid::ArgumentError` instead of `::ArgumentError` when filter has wrong number of arguments #309 [Bogdan Gusiev, bogdan] * Add a to_s default for liquid drops, see #306 [Adam Doeler, releod] diff --git a/lib/liquid.rb b/lib/liquid.rb index 272d566..257efc6 100644 --- a/lib/liquid.rb +++ b/lib/liquid.rb @@ -40,8 +40,8 @@ module Liquid Expression = /(?:#{QuotedFragment}(?:#{SpacelessFilter})*)/o TagAttributes = /(\w+)\s*\:\s*(#{QuotedFragment})/o AnyStartingTag = /\{\{|\{\%/ - PartialTemplateParser = /#{TagStart}.*?#{TagEnd}|#{VariableStart}.*?#{VariableIncompleteEnd}/o - TemplateParser = /(#{PartialTemplateParser}|#{AnyStartingTag})/o + PartialTemplateParser = /#{TagStart}.*?#{TagEnd}|#{VariableStart}.*?#{VariableIncompleteEnd}/om + TemplateParser = /(#{PartialTemplateParser}|#{AnyStartingTag})/om VariableParser = /\[[^\]]+\]|#{VariableSegment}+\??/o end diff --git a/lib/liquid/block.rb b/lib/liquid/block.rb index bcac5a8..c53c5c5 100644 --- a/lib/liquid/block.rb +++ b/lib/liquid/block.rb @@ -2,8 +2,8 @@ module Liquid class Block < Tag IsTag = /\A#{TagStart}/o IsVariable = /\A#{VariableStart}/o - FullToken = /\A#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}\z/o - ContentOfVariable = /\A#{VariableStart}(.*)#{VariableEnd}\z/o + FullToken = /\A#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}\z/om + ContentOfVariable = /\A#{VariableStart}(.*)#{VariableEnd}\z/om def blank? @blank || false diff --git a/lib/liquid/context.rb b/lib/liquid/context.rb index 6d06854..1da66a9 100644 --- a/lib/liquid/context.rb +++ b/lib/liquid/context.rb @@ -171,9 +171,9 @@ module Liquid LITERALS[key] else case key - when /\A'(.*)'\z/ # Single quoted strings + when /\A'(.*)'\z/m # Single quoted strings $1 - when /\A"(.*)"\z/ # Double quoted strings + when /\A"(.*)"\z/m # Double quoted strings $1 when /\A(-?\d+)\z/ # Integer and floats $1.to_i @@ -218,7 +218,7 @@ module Liquid # assert_equal 'tobi', @context['hash["name"]'] def variable(markup) parts = markup.scan(VariableParser) - square_bracketed = /\A\[(.*)\]\z/ + square_bracketed = /\A\[(.*)\]\z/m first_part = parts.shift diff --git a/lib/liquid/tags/assign.rb b/lib/liquid/tags/assign.rb index a3bc86f..75301b1 100644 --- a/lib/liquid/tags/assign.rb +++ b/lib/liquid/tags/assign.rb @@ -9,7 +9,7 @@ module Liquid # {{ foo }} # class Assign < Tag - Syntax = /(#{VariableSignature}+)\s*=\s*(.*)\s*/o + Syntax = /(#{VariableSignature}+)\s*=\s*(.*)\s*/om def initialize(tag_name, markup, options) super diff --git a/lib/liquid/tags/case.rb b/lib/liquid/tags/case.rb index ed6e806..c63548e 100644 --- a/lib/liquid/tags/case.rb +++ b/lib/liquid/tags/case.rb @@ -1,7 +1,7 @@ module Liquid class Case < Block Syntax = /(#{QuotedFragment})/o - WhenSyntax = /(#{QuotedFragment})(?:(?:\s+or\s+|\s*\,\s*)(#{QuotedFragment}.*))?/o + WhenSyntax = /(#{QuotedFragment})(?:(?:\s+or\s+|\s*\,\s*)(#{QuotedFragment}.*))?/om def initialize(tag_name, markup, options) super diff --git a/lib/liquid/tags/cycle.rb b/lib/liquid/tags/cycle.rb index ed42995..c86f8a1 100644 --- a/lib/liquid/tags/cycle.rb +++ b/lib/liquid/tags/cycle.rb @@ -13,7 +13,7 @@ module Liquid # class Cycle < Tag SimpleSyntax = /\A#{QuotedFragment}+/o - NamedSyntax = /\A(#{QuotedFragment})\s*\:\s*(.*)/o + NamedSyntax = /\A(#{QuotedFragment})\s*\:\s*(.*)/om def initialize(tag_name, markup, options) super diff --git a/lib/liquid/tags/raw.rb b/lib/liquid/tags/raw.rb index 1fa5153..eafe6d3 100644 --- a/lib/liquid/tags/raw.rb +++ b/lib/liquid/tags/raw.rb @@ -1,6 +1,6 @@ module Liquid class Raw < Block - FullTokenPossiblyInvalid = /\A(.*)#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}\z/o + FullTokenPossiblyInvalid = /\A(.*)#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}\z/om def parse(tokens) @nodelist ||= [] diff --git a/lib/liquid/variable.rb b/lib/liquid/variable.rb index c661d97..3992d2a 100644 --- a/lib/liquid/variable.rb +++ b/lib/liquid/variable.rb @@ -37,9 +37,9 @@ module Liquid def lax_parse(markup) @filters = [] - if match = markup.match(/\s*(#{QuotedFragment})(.*)/o) + if match = markup.match(/\s*(#{QuotedFragment})(.*)/om) @name = match[1] - if match[2].match(/#{FilterSeparator}\s*(.*)/o) + if match[2].match(/#{FilterSeparator}\s*(.*)/om) filters = Regexp.last_match(1).scan(FilterParser) filters.each do |f| if matches = f.match(/\s*(\w+)/) diff --git a/test/liquid/tags/standard_tag_test.rb b/test/liquid/tags/standard_tag_test.rb index 10cc5e3..540d160 100644 --- a/test/liquid/tags/standard_tag_test.rb +++ b/test/liquid/tags/standard_tag_test.rb @@ -297,4 +297,8 @@ class StandardTagTest < Test::Unit::TestCase assigns = {'array' => [ 1, 1, 1, 1] } assert_template_result('1','{%for item in array%}{%ifchanged%}{{item}}{% endifchanged %}{%endfor%}',assigns) end + + def test_multiline_tag + assert_template_result '0 1 2 3', "0{%\nfor i in (1..3)\n%} {{\ni\n}}{%\nendfor\n%}" + end end # StandardTagTest diff --git a/test/liquid/variable_test.rb b/test/liquid/variable_test.rb index 30513c3..10096e7 100644 --- a/test/liquid/variable_test.rb +++ b/test/liquid/variable_test.rb @@ -197,4 +197,8 @@ class VariableResolutionTest < Test::Unit::TestCase } assert_equal "Unknown variable 'test'", e.message end + + def test_multiline_variable + assert_equal 'worked', Template.parse("{{\ntest\n}}").render!('test' => 'worked') + end end # VariableTest