Revision of Twine macro: <<else if>>, an improvement to <<if>> from Tue, 05/07/2013 - 05:00

This is not strictly a new macro, but a replacement version of the <<if>> macro. You might have noticed that nesting the <<if>> macro can get a bit messy:

<<if $fire eq "warm">>
The fire isn't hot yet.
<<else>>
<<if $medal eq "water">>
You medal protects you.
<<else>>
<<if $dead gt 0>>
Not again!
<<else>>
You died!
<<endif>>
<<endif>>
<<endif>>

The <<else if>> macro allows you to have multiple <<else>> macros within a single <<if>> construction, without needing to nest an entire other pair of <<if>> and <<endif>> macro tags:

<<if $fire eq "warm">>
The fire isn't hot yet.
<<else if $medal eq "water">>
You medal protects you.
<<else if $dead gt 0>>
Not again!
<<else>>
You died!
<<endif>>

The macro code is here:

version.extensions.ifMacros={major:2,minor:0,revision:0};macros["if"]={handler:function(place,macroName,params,parser){var conditions=[],clauses=[],srcOffset=parser.source.indexOf(">>",parser.matchStart)+2,src=parser.source.slice(srcOffset),endPos=-1,currentCond=parser.fullArgs(),currentClause="",t=0,nesting=0;
for(var i=0;i<src.length;i++){if(src.substr(i,9)=="<<endif>>"){nesting--;if(nesting<0){endPos=srcOffset+i+9;
conditions.push(currentCond);clauses.push(currentClause);break;}}if((src.substr(i,6)=="<<else")&&nesting==0){conditions.push(currentCond);
clauses.push(currentClause);currentClause="";t=src.indexOf(">>",i+6);if(src.substr(i+6,4)==" if "){currentCond=Wikifier.parse(src.slice(i+10,t));
}else{currentCond="true";}i=t+2;}if(src.substr(i,5)=="<<if "){nesting++;}currentClause+=src.charAt(i);
}try{if(endPos!=-1){parser.nextMatch=endPos;for(i=0;i<clauses.length;i++){if(eval(conditions.shift())){new Wikifier(place,clauses[ i ].trim());
break;}}}else{throwError(place,"can't find matching endif");}}catch(e){throwError(place,"bad condition: "+e.message);
}}};macros["elseif"]=macros["else"]=macros["endif"]={handler:function(){}};

Feel free to report any bugs to @webbedspace.

pensive-mosquitoes