RuntimeError: OH NO!
from user.liquid:3
~> How?
I've introduced a new type: [:newline]. This basically means: "There was a newline here in the source, so there should also be a newline here in the generated code." Please note that this has *nothing* to do with newlines in the rendered string (that would simply be [:static, "\n"]).
To show you some examples:
[:multi,
[:static, "Hello"],
[:dynamic, "world"]]
Because there are no :newlines, this will be put on a single line:
_buf = [] ; _buf << "Hello" ; _buf << (world) ; _buf.join
[:multi,
[:static, "Hello"],
[:newline],
[:dynamic, "world"]]
Here it's a method on line 2 (world), and because there is a :newline above it, it will stay on line 2:
_buf = [] ; _buf << "Hello" ;
; _buf << (world) ; _buf.join
~> What about DynamicInliner?
DynamicInliner is a filter which compiles static and dynamic into a single dynamic string where the dynamic parts are added as interpolation:
[:multi,
[:static, "Hello"],
[:dynamic, "@world"],
[:dynamic, "@yeah"],
[:static, "Nice"]]
After running DynamicInliner, the generated code will be:
_buf = [] ; _buf << ("Hello#{@world}#{@yeah}Nice") ; _buf.join
We just saved 3 method calls and 3 strings which had to be garbage collected :-)
So how does this work with newlines? I think I've found a quite elegant solution:
_buf = [] ; _buf << ("Hello"\
"#{@world}#{@yeah}"\
"Nice") ; _buf.join
Because Ruby supports escaping of newlines and automatically concated strings (try this in IRB: "Hello " "World!"), it's syntactically equal to the previous code, but it's now spread across several lines. Victory!