Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

How to display image with a macro?

I am still learning about macros and I can make a basic one to display text, but haven't advanced on from that yet.

However I am stumped with trying to display an image with one. Im using a template from http://eturnerx.blogspot.co.nz/2012/12/how-to-create-custom-macros-in-twine.html

I get in google chrome a javascript error message saying unexpected token!
try {
version.extensions['BlueprintMacro'] = {
major:1, minor:0, revision:0
};
macros['Blueprint'] = {
handler: function(place, macroName, params, parser) {

new Wikifier(place, "<html>img src=Office.jpg height='337' width='640'</html>");

>
},
init: function() { },
};
} catch(e) {
throwError(place,"macrodemo Setup Error: "+e.message);
}
However what I want to do is have a macro that will look and function as little like this. So the code below is pure fiction
because I do not know how to write it properly..so this is merely showing what I would like to do..
try {
version.extensions['BlueprintMacro'] = {
major:1, minor:0, revision:0
};
macros['Blueprint'] = {
handler: function(place, macroName, params, parser) {

try
{
switch (place)
{
case "location001":
result = "<html>img src=ImageA.jpg height='337' width='640'<html>";
break;
case "location002":
result = "<html>img src=ImageB.jpg height='337' width='640'<html>";
break;
case "location003":
result = "<html>img src=ImageC.jpg height='337' width='640'<html>";
break;
}

new Wikifier(place, result);


>
},
init: function() { },
};
} catch(e) {
throwError(place,"macrodemo Setup Error: "+e.message);
}
If anyone can enlighten me how to make this work it would be much appreciated. :)

Comments


  • version.extensions['blueprintMacro'] = { major: 1, minor: 0, revision: 0 };
    macros['blueprint'] =
    {
    handler: function (place, macroName, params, parser)
    {
    if (params.length === 0)
    {
    throwError(place, "<<" + macroName + ">>: missing location argument", parser.fullMatch());
    return;
    }

    var result;
    switch (params[0])
    {
    case "location001":
    result = '<img src="ImageA.jpg" height="337" width="640" />';
    break;
    case "location002":
    result = '<img src="ImageB.jpg" height="337" width="640" />';
    break;
    case "location003":
    result = '<img src="ImageC.jpg" height="337" width="640" />';
    break;
    default:
    throwError(place, "<<" + macroName + '>>: unknown location "' + params[0] + '"', parser.fullMatch());
    return;
    }
    new Wikifier(place, result);
    }
    };
  • Import you images into passages in your story and then just:
    $img["locimage"]
    at the top of each passage (or in your entry macro - trigger via <<entry>> or <<display entry>>).

    Put a naming convention in and you can:
    <<print '$img[img_' + passage() + ']'>>
    in your entry macro.
  • TheMadExile wrote:

    version.extensions['blueprintMacro'] = { major: 1, minor: 0, revision: 0 };
    macros['blueprint'] =
    {
    handler: function (place, macroName, params, parser)
    {
    if (params.length === 0)
    {
    throwError(place, "<<" + macroName + ">>: missing location argument", parser.fullMatch());
    return;
    }

    var result;
    switch (params[0])
    {
    case "location001":
    result = '<img src="ImageA.jpg" height="337" width="640" />';
    break;
    case "location002":
    result = '<img src="ImageB.jpg" height="337" width="640" />';
    break;
    case "location003":
    result = '<img src="ImageC.jpg" height="337" width="640" />';
    break;
    default:
    throwError(place, "<<" + macroName + '>>: unknown location "' + params[0] + '"', parser.fullMatch());
    return;
    }
    new Wikifier(place, result);
    }
    };


    Thanks MadExile and myKael for your replies. MadExile when I run this i get that "missing location argument" displaying in red. Then I wondered whether i was suppose to be putting a variable into the macro like <<bluepring locationpassagename>> but this throws the unknown location error message.

    If you remember my thread for my map that uses object properties (http://twinery.org/forum/index.php/topic,45.msg3537.html#msg3537), this relates to that, and i am wondering whether instead of checking the locationname and matching it, perhaps be better to use a value from $CurrentPos.LocId instead. This way i can keep reusing images to represent new locations that have the same layout, which in the long run is better than having a long list of matching passage names where a lot of double handling would occur.

    So I had a go at adding the variable to the macro caller (er whatever you call that) but alas it didnt work. Error is unknown location as per error check in the script.

    The macro was called with this
    <<blueprint $CurrentPos.LocId>>
    which should hold the value "Loc020" i would of thought, that value should be correct because in my passage it meets the condition to run the macro. Discovering how to display a variable in a script as a debug check with
    document.write(params[0]);
    its shows $CurrentPos.LocId as if that is the text string i am wanting to carry across. Its probably something really obvious I am not getting here. But that is part of learning i guess lol. I thought params was the value of what has been included with the macro to be passed on, which seems to be partly working i guess, except its not taking on the value inside that variable. Understanding how would be another step in understanding macros.
  • From your example up thread, I just assumed you'd be passing the location in as an argument.  And I keep forgetting that vanilla macros have to process $variables themselves.


    Here's an updated version, which takes a string (e.g. "Loc001") or a $variable:

    version.extensions['blueprintMacro'] = { major: 1, minor: 0, revision: 0 };
    macros['blueprint'] =
    {
    handler: function (place, macroName, params, parser)
    {
    if (params.length === 0)
    {
    throwError(place, "<<" + macroName + ">>: missing location argument", parser.fullMatch());
    return;
    }

    try
    {
    var locId = /^\$\w+/.test(params[0]) ? eval(Wikifier.parse(params[0])) : params[0]
    , result;
    switch (locId)
    {
    default:
    throwError(place, "<<" + macroName + '>>: unknown location "' + locId + '"', parser.fullMatch());
    return;
    case "Loc001":
    result = '<img src="ImageA.jpg" height="337" width="640" />';
    break;
    case "Loc002":
    result = '<img src="ImageB.jpg" height="337" width="640" />';
    break;
    case "Loc003":
    result = '<img src="ImageC.jpg" height="337" width="640" />';
    break;
    // et cetera...
    }
    new Wikifier(place, result);
    }
    catch (e)
    {
    throwError(place, "<<" + macroName + ">>: " + e.message, parser.fullMatch());
    }
    }
    };
    Usage:

    <<blueprint "Loc001">>
    /% or %/
    <<blueprint $CurrentPos.LocId>>

    On the other hand, if you did want to call it without arguments, then you'll need to access the location internally, like so:

    version.extensions['blueprintMacro'] = { major: 1, minor: 0, revision: 0 };
    macros['blueprint'] =
    {
    handler: function (place, macroName, params, parser)
    {
    var locId = state.history[0].variables["CurrentPos"]["LocId"]
    , result;
    switch (locId)
    {
    default:
    throwError(place, "<<" + macroName + '>>: unknown location "' + locId + '"', parser.fullMatch());
    return;
    case "Loc001":
    result = '<img src="ImageA.jpg" height="337" width="640" />';
    break;
    case "Loc002":
    result = '<img src="ImageB.jpg" height="337" width="640" />';
    break;
    case "Loc003":
    result = '<img src="ImageC.jpg" height="337" width="640" />';
    break;
    // et cetera...
    }
    new Wikifier(place, result);
    }
    };
    Usage:

    /% hard coded to use: $CurrentPos.LocId %/
    <<blueprint>>
    [EDIT] Fixed code cockup.
  • Thanks again with that update it looks really good. However i'm getting a javascript error (with google chrome) saying (unexpected token ,) so it wont recognise the macro, macro not found when its time to run it.

  • And that's what I get for not testing it beforehand.  I had a spurious semi-colon in there.  Try it now (I updated the code in the post above).
  • TheMadExile wrote:

    And that's what I get for not testing it beforehand.  I had a spurious semi-colon in there.  Try it now (I updated the code in the post above).


    Its working now :) I feel like i have just discovered flint and fire for the first time! lol I will be able to implement other uses for this type of macro. So thanks a lot of your help.  The initializing the variable part internally via
    var locId = state.history[0].variables["CurrentPos"]["LocId"]
    makes more sense to me than the other example
    var locId = /^\$\w+/.test(params[0]) ? eval(Wikifier.parse(params[0])) : params[0]
    they both work of course.  Having another example of how to do the same thing is good. I will look those expressions up.

    the line
    , result;
    the follows it- is that just initializing the variable 'result' on the end of that line above it- opposed to a new line with var result =""; or something? or you do not need to place an empty value into it either an integer or string?

    Thanks again MadExile  :D


  • Dazakiwi38 wrote:

    The initializing the variable part internally via
    var locId = state.history[0].variables["CurrentPos"]["LocId"]
    makes more sense to me than the other example var locId = /^\$\w+/.test(params[0]) ? eval(Wikifier.parse(params[0])) : params[0]
    they both work of course.  Having another example of how to do the same thing is good. I will look those expressions up.


    To break that down a bit.  First off, ?: is the ternary (or conditional) operator, which you can think of as an inline if statement.  It works like this:
    condition ? expression-if-true : expression-if-false
    That in mind, the entire expression works like this: (RegExp object & RegExp test() method)

    /^\$\w+/.test(params[0]) Regular expression literal calling the test() method, checks whether the passed in text looks like a $variable
    ? (1st part of a ternary operator)
    eval(Wikifier.parse(params[0])) (true-case) Passed text looks like a $variable, so run it though Wikifier.parse() to convert it to pure JavaScript and eval() to return its value
    : (2nd part of a ternary operator)
    params[0] (false-case) Passed text did not look like a $variable, so just use it as-is

    Dazakiwi38 wrote:

    the line
    , result;
    the follows it- is that just initializing the variable 'result' on the end of that line above it- opposed to a new line with var result =""; or something? or you do not need to place an empty value into it either an integer or string?


    It declares the variable result, but does not initialize it to any value.  In this case assigning it a value upon declaration isn't necessary as the immediately following switch statement either assigns it a value, before it's used in the following Wikifier() call, or tosses an error and returns, bypassing the Wikifier() call.
  • Thanks for sharing that, very informative. Makes more sense now. :)
  • Holy crap I'm gonna have to sign up for Java Script classes I think.
  • TheMadExile wrote:

    From your example up thread, I just assumed you'd be passing the location in as an argument.  And I keep forgetting that vanilla macros have to process $variables themselves.


    On the other hand, if you did want to call it without arguments, then you'll need to access the location internally, like so:

    version.extensions['blueprintMacro'] = { major: 1, minor: 0, revision: 0 };
    macros['blueprint'] =
    {
    handler: function (place, macroName, params, parser)
    {
    var locId = state.history[0].variables["CurrentPos"]["LocId"]
    , result;
    switch (locId)
    {
    default:
    throwError(place, "<<" + macroName + '>>: unknown location "' + locId + '"', parser.fullMatch());
    return;
    case "Loc001":
    result = '<img src="ImageA.jpg" height="337" width="640" />';
    break;
    case "Loc002":
    result = '<img src="ImageB.jpg" height="337" width="640" />';
    break;
    case "Loc003":
    result = '<img src="ImageC.jpg" height="337" width="640" />';
    break;
    // et cetera...
    }
    new Wikifier(place, result);
    }
    };
    Usage:

    /% hard coded to use: $CurrentPos.LocId %/
    <<blueprint>>
    [EDIT] Fixed code cockup.


    I'm trying to convert this to sugarcube, going off another script you altered for me where you changed the beginning, I also changed the state.active.variables this is what i have...
    macros.add("blueprint", {
    version: { major: 2, minor: 0, revision: 0 },
    handler: function ()
    {
    var locId = state.active.variables["CurrentPos"]["LocId"]
    , result;
    switch (locId)
    {
    default:
    throwError(place, "<<" + macroName + '>>: unknown location "' + locId + '"', parser.fullMatch());
    return;
    case "Loc0120":
    result = '<img src="OfficeBluePrint_SpyGame01_wiremeshstyleMaster2.jpg" height="337" width="640" />';
    break;
    case "Loc002":
    result = '<img src="ImageB.jpg" height="337" width="640" />';
    break;
    case "Loc003":
    result = '<img src="ImageC.jpg" height="337" width="640" />';
    break;
    // et cetera...
    }
    new Wikifier(place, result);
    }
    };
    I get an error Unexpected token ;

    There is three open brackets so there needs to be three closing brackets right? so somewhere there is an extra ; where it should be unless it something else a miss here? maybe the parser.fullMatch() needs to be declared first?
  • Dazakiwi38 wrote:

    I get an error Unexpected token ;


    That is from missing the closing parenthesis for macros.add().

    There were a few other issues as well.

    Try this:

    macros.add("blueprint", {
    version: { major: 2, minor: 0, revision: 0 },
    handler: function ()
    {
    var locId = state.active.variables["CurrentPos"]["LocId"]
    , result;
    switch (locId)
    {
    default:
    return this.error('unknown location "' + locId + '"');
    case "Loc0120":
    result = '<img src="OfficeBluePrint_SpyGame01_wiremeshstyleMaster2.jpg" height="337" width="640" />';
    break;
    case "Loc002":
    result = '<img src="ImageB.jpg" height="337" width="640" />';
    break;
    case "Loc003":
    result = '<img src="ImageC.jpg" height="337" width="640" />';
    break;
    // et cetera...
    }
    new Wikifier(this.output, result);
    }
    });
  • Doh  :o I missed that ) bracket right at the end,  i should of spotted that because the beginning of the script has one remaining opened, the error message about the semi-colon threw me off. I will double check with noteplus++ in future which is handy to catch missing brackets. It would be cool if there was a plugin for Twine in noteplus++ so other syntax could be checked also. 

    Anyway thanks again. That's another script converted and working in sugarcube now. :)
Sign In or Register to comment.