It looks like you're new here. If you want to get involved, click one of these buttons!
macros["question"] =
{
handler: function(place, macroName, params, parser)
{
if (params.length === 0)
{
throwError(place, "<<" + macroName + ">>: no question id specified");
return;
}
// process the contents of the container macro
var openTag = macroName
, closeTag = "end" + macroName
, start = parser.source.indexOf(">>", parser.matchStart) + 2
, end = -1
, tagBegin = start
, tagEnd = start
, opened = 1;
while ((tagBegin = parser.source.indexOf("<<", tagEnd)) !== -1
&& (tagEnd = parser.source.indexOf(">>", tagBegin)) !== -1)
{
var tagName = parser.source.slice(tagBegin + 2, tagEnd)
, tagDelim = tagName.search(/\s/);
if (tagDelim !== -1)
{
tagName = tagName.slice(0, tagDelim);
}
tagEnd += 2;
switch (tagName)
{
case closeTag:
opened--;
break;
case openTag:
opened++;
break;
}
if (opened === 0)
{
end = tagBegin;
break;
}
}
// if we successfully found an end tag for the macro
if (end !== -1)
{
parser.nextMatch = tagEnd;
// Macrocode
this.a = macroName;
this.b = params[0];
this.c = parser.source.slice(start, end);
this.d = ('<a class="question" id="' + this.b + '">' + this.c + '</a>');
//new Wikifier(place, this.d);
checktweevar = params[1];
if(checktweevar == null){}
else
{
var tweevar = params[1].replace("$","");
}
var value = params[2];
if(value == null){}
else
{
if (value.charAt(0)=="$") {
value = eval(value.replace("$","state.history[0].variables."));
}
}
el = document.createElement('a');
el.className = 'internalLink';
el.href = "javascript:void(0)";
el.innerHTML = this.d;
el.onclick = function(){
state.history[0].variables[tweevar] = value;
};
place.appendChild(el);
}
else
{
throwError(place, "<<" + macroName + ">>: cannot find a matching close tag");
}
},
};
macros["endquestion"] = { handler: function () {} };
Note, this is part of a larger macro, so literally all this allows you to do is click a link but nothing seems to happen, in the background though it will change the variable.<<question 1 $foo "bar">>
Something like this doesn't:
<<question 2 $foo "foo"; $bar "foo">>
In the second example, $foo is set to "foo", but $bar remains unchanged. I expect I need to change how my code works, but I'm not even sure where to start, apart from trying to find the code behind how [[link]]'s work in the twine source code, which is probably where I'll look next.
Comments
With <<set>> I know you can do this: <<set $test = 3; $test2 = 6>>
So I figured I'd look at the in built macro for <<set>> which I think I found here. But, it looks like it's using other inbuilt functions? Alls I could find on fullargs was the description here which states that fullArgs is "Meant to be called by macros, this returns the text passed to the currently executing macro. Unlike TiddlyWikis default mechanism, this does not attempt to split up the arguments into an array, thought it does do some magic with certain Twee operators (like gt, eq, and $variable)." Not sure what the magic is...but it appears to refer to this: So yeah, I think this is way over my head. ???
Something like this:
Bedroom passage: Jumplink passage: I haven't tested that, but it should work. I think. :P
macros.question = {<br /> handler: function(place, macroName, params, parser) {<br /> if (params.length % 2 == 1) {<br /> throwError(place, "<<" + macroName + ">>: odd number of parameters given");<br /> return;<br /> }<br /> var left, right;<br /> for (var index = 0; index < params.length; index i+= 2) {<br /> var s;<br /> if (isNaN(params[index+1])) {<br /> s = "state.active.variables." + params[index] + " = '" + params[index+1] + "'";<br /> } else {<br /> s = "state.active.variables." + params[index] + " = " + params[index+1];<br /> }<br /> eval(s);<br /> }<br /> },<br /> };
The problem with it is that your variables cannot have the dollar sigel in from of them. So this example sets $d, $e and $f.
<<question d 45 e 13 f house>><br /><<print $d + 5>><br /><<print $e>><br /><<print $f>>
Variables seem to extracted from the parameter list for some reason, and I cannot imagine why. However, entering them as text, without the dollar, gets around that.
ETA: Thinking about it, the variables get substituted first, then the macro is invoked, so if I did
<<question $d 45 $e 13 $f house>>
Twee would try to pass the value of $d, etc.
ETA2: This works for sugarcube. For others, "state.active.variables." needs to be "state.history[0].variables." (two changes).
http://strugglingwithtwine.blogspot.co.uk/2014/03/how-to-write-macros.html
@ The Pixie: Thanks for this, though I've tried it in Sugarcane and I just get an error about question not being recognised? I'm using this in a script passage: HTML Example| TWS Example
Re the $ sigil issue, I don't know if I read somewhere else that the $ is used in javascript regular expressions to denote the end of a string, so there might be some conflict. By using something like params[1].replace("$","") I think you can get around it though.
I'll be sure to read through that link in a bit, I've read plenty of macro twine tutorials, but I think they're all aimed way above my level.
There's an erroneous "i" in the loop expression section of the for loop.
FIND: REPLACE WITH:
In SugarCube:
[quote=http://www.motoslave.net/sugarcube/docs/#macros]Note: Variable substitution occurs automatically in SugarCube, so all macros that take arguments can take $variables as arguments.
As evidenced by the above quote, SugarCube is based on the premise that the normal use of $variables as arguments to macros should not require any processing by the macros themselves (i.e. all macros should automatically receive $variable value substitution for free), and so SugarCube's macro formatter does just that. This is why, when using macros in SugarCube where you want to, in essence, pass a reference to the $variable, rather than its value, you must either quote it or give it without the dollar-sign ($) sigil (SugarCube's own <<textbox>> macro spells that out). To use the existing example:
In the vanilla headers:
No automatic $variable value substitution occurs, so there's no need to quote, or otherwise protect, $variable identifiers. Of course, this also means that every single macro which wants to support $variable substitution has to do that processing themselves.
I managed to get The Pixie's code working with my own, and it seems to be working pretty well, so thanks both - I posted a working example in this post.
Oops. I used "i" originally to test, but when I posted it here, the i in square brackets was interpreted as italics by the BBCode, and disappeared, so I quickly changed it to index; guess I missed one.
If I want to do this: <<question var +5>> It will print as 5, regardless of the value of $var. So if $var = 5, I would expect to see 10 when I do <<print $var>> but it just shows 5. Any way around this? I tried to just get it to automatically add the value to the existing total of $var if it was a number using something like this: , and that seems to work (i.e. adds the value of test whenever called) but I couldn't work it into the above macro.
Edit: Posted this as a seperate question here.