jsoverson / preprocess

Preprocess HTML, JavaScript, and other files with directives based off custom or ENV configuration
Other
366 stars 80 forks source link

Nested directives support #61

Closed Frizi closed 9 years ago

Frizi commented 9 years ago

Added support for nested directives. This includes if, ifdef, ifndef, exclude, foreach. Currently extend is not covered.

// @if true
console.log('a');
// @if false
console.log('b');
// @endif
console.log('c');
// @endif

Will only print a and c.

/* @foreach $ITEMA in LIST */
/* @foreach $ITEMB in LIST */
$ITEMA$ITEMB
/* @endfor */
/* @endfor */

Given {list: ['a', 'b']} produces

aa
ab
ba
bb

Unfortunately it adds a dependency on xregexp.

BendingBender commented 9 years ago

Wow, nice work! I'll take a look at it as soon as I can. What about @extend, did you have any specific problems?

To merge this, I'll have to implement @extend, too. I'll also have to look at why you chose to use xRegexp and whether it is possible to avoid using it (not trying too hard, I was already thinking about using xRegexp, too).

I'll be able to merge it sooner if you could help me with these tasks.

Frizi commented 9 years ago

XRegExp is used for its excelent matchRecursive addon, which exactly matches this use case, as it accepts two regex strings for its left and right delimeters. This happens to be the .start and .end of already defined groups.

One drawback, I had to collapse all if-like directives into one, as each one of them had the same ending delimeter (@endif), which resulted in "unbalanced delimeters" error when they have got mixed together. Nevertheless I think this is a good change, as resulting regex isn't really much more complicated and code happens to be a bit faster (only one replace pass instead of three).

For @extend, I don't remember correctly right now, but had some issues trying to get it to work. Will look into it again shortly.

Qwal commented 9 years ago

Well done!

BendingBender commented 9 years ago

Well, from my point of view, the way you collapsed if/ifdef/ifndef is something that had to be done already for a long time. There was massive duplication going on and I had to add tests for each of these directives separately to make sure that I don't break something accidentally. Now we can collapse all of the tests into one smaller group.

Frizi commented 9 years ago

Nested @extend is now supported. The problem was that @extendable was also matched as @extend tag first. Fixed by introducing negative lookaheads to start pattern.

Also optimized recursion in @foreach out of for loop.

BendingBender commented 9 years ago

Thank you very much!

Alphapage commented 9 years ago

Hello, it doesn't seem to work. For example for this expression:

// @if test = "ok" // @if processtest = true console.log("true"); // @endif // @if processtest = false console.log("false"); // @endif // @endif

The result displays the comments: // @if processtest = true

Am I missing something ?

Thanks in advance for your help.

Alphapage commented 9 years ago

Sorry, I was using the wrong version and even a wrong argument : processtest:'true' instead of processtest:true. My mistake !