0 votes
by (1.3k points)
In JS:

setup.letSlip = function () {
	$(output).wiki("Cry 'Havoc!', and let slip the //ponies// of ''friendship''.");

In passage:
<<run setup.letSlip()>>

And it's as simple as that. It doesn't work. It doesn't print anything to the screen (that I'm aware of).

But, if I use the same code in a <<script>><</script>> sequence, like so:

	$(output).wiki("Cry 'Havoc!', and let slip the //ponies// of ''friendship''.");

And have that just in the main passage, it does output.

What might I be doing wrong here? I've been trying to work this out for hours and hours. Just this. Not working.

1 Answer

0 votes
by (68.6k points)
selected by
Best answer

The <<script>> macro provides a predefined variable named output, which is a reference to the current render buffer.  The <<run>> macro does not provide such a reference.

by (1.3k points)

OK, cool. Let's say, for instance, I wanted to print out "hello world" from a simple JS function to the #passages element.

I've already tried this kinds of things:

$('#passages').wiki("Cry 'Havoc!', and let slip the //ponies// of ''friendship''.");
$('#story').wiki("Cry 'Havoc!', and let slip the //ponies// of ''friendship''.");

No dice.

The only thing I've been able to print with is:

$('html').wiki("Cry 'Havoc!', and let slip the //ponies// of ''friendship''.");

But that only puts it in the bottom left corner.

Instead of a generic JS function, am I supposed to be playing with Macro.adds? Would that allow me to use output and such?

by (159k points)

How you call that wiki() function greatly depends on when & where you are using it, but never the less the HTML element you are associating it with has to exist. which generally means you need to either wait until the page has stopped rending or you need to use it within the context of the rendering process.

eg. Using it within a link to append content to the end of the current passage.

<<link "update page">>
\<<run $('.passage').wiki("Cry 'Havoc!', and let slip the //ponies// of ''friendship''.")>>

note: as shown in the SugarCube 2 HTML documentation, the div element that contains the HTML output for the Passage has a .passage CSS class.

eg. Using it within a postrender task handler.

postrender["Some Task Name"] = function (content, taskName) {
    $(content).wiki("Cry 'Havoc!', and let slip the //ponies// of ''friendship''.");


by (68.6k points)

I do not suggest trying to go around the standard render pipeline, so there are two ways, using functions, to output that I'd recommend.

  1. Using output in <<script>>.
  2. Returning a string to one of the <<print>> variants.  Obviously, you cannot use this to output DOM elements, so this is only useful when you're able to output strings—e.g. plain text or markup.

FUNCTIONS : Using output in <<script>>

Using the <<script>> macro, you simply need to use output.  For example:

$(output).wiki("Cry 'Havoc!', and let slip the //ponies// of ''friendship''.");

To do that from within a function, you'll have to pass output into the function somehow.  There are a couple ways to do that.

  1. Pass it in as a parameter:
    setup.letSlip = function (out) {
    	$(out).wiki("Cry 'Havoc!', and let slip the //ponies// of ''friendship''.");


  2. Invoke the function via <Function>.call() or <Function>.apply() and set the function's this to output:
    setup.letSlip = function () {
    	$(this).wiki("Cry 'Havoc!', and let slip the //ponies// of ''friendship''.");



    NOTE: This technique will not work with ES6 arrow functions, as they have an intrinsically bound this.

I listed #2 solely for the sake of completeness, you probably don't want to use that method.


FUNCTIONS : Returning a string to one of the <<print>> variants

Write your function to return a string.  For example:

setup.letSlip = function () {
	return "Cry 'Havoc!', and let slip the //ponies// of ''friendship''.";


<<= setup.letSlip()>


Macros do have access to the render buffer.  Whether or not you choose to write JavaScript macros, rather than widgets or functions, is up you to.  If that's what you decided to do, then you'd, obviously, need to become familiar with the Macro API.

As an example of the same thing I showed above, but done as a macro:

Macro.add('letslip', {
	handler : function () {
			.wiki("Cry 'Havoc!', and let slip the //ponies// of ''friendship''.");


by (1.3k points)
Ah right cool.

I really only was seeking to print stuff out because I need to debug a function I'm working on. I was getting errors for the <<run>> macro and I want to determine exactly what bits my code is generating. Hence the std:cout << "hello word"; idea. I think that postrender one will work for intended debugging.

Thanks a lot! I can go back to playing!


Oh right! You answered too tme. I'll read up on what you suggested. Since, I may need to purposely use a function or something to add actual text to the story at some point.
by (1.3k points)
I'll copy and preserve these techniques, since they're exactly what I wanted to find out. I guess I'll be using the <<= >> print function, since it seems easy. I'll go back to writing stuff now. Thanks a lot! I was stuck with this for a fair while.