Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/pompom454/tea/llms.txt

Use this file to discover all available pages before exploring further.

When Tea calls a macro’s handler function, it sets this to a MacroContext instance that provides everything the handler needs: the parsed argument list, the DOM output element to write into, the inner content of container macros, and methods for rendering wiki markup, reporting errors, and navigating the ancestor macro chain.
MacroContext is not instantiated directly. You receive one as this inside every handler function passed to Macro.add().

Properties

this.argsArray<any>

An array of discrete arguments parsed from the macro’s argument string. TwineScript operators and expressions are evaluated before parsing.
// Given: <<someMacro "a" "b" "c">>
this.args.length  // 3
this.args[0]      // 'a'
this.args[1]      // 'b'
this.args[2]      // 'c'

this.args.fullstring

The argument string after all TwineScript syntax elements have been converted to their native JavaScript equivalents.
// Given: <<if $score is 10>>
this.args.full  // 'State.variables.score === 10'

this.args.rawstring

The raw, unprocessed argument string exactly as it appeared in the passage.
// Given: <<if "a" is "b">>
this.args.raw  // '"a" is "b"'

this.namestring

The canonical name of the macro (resolves alias chains to the original name).
// Given: <<someMacro …>>
this.name  // 'someMacro'

this.outputHTMLElement

The DOM element into which the macro should render its output. Pass this to jQuery() or new Wikifier() to write content.
// Using jQuery
jQuery(this.output).wiki('Some //awesome// markup!');

// Using Wikifier directly
new Wikifier(this.output, 'Some //awesome// markup!');

this.parentObject | null

The MacroContext of the immediately enclosing macro, or null if this macro has no parent.
if (this.parent !== null) {
  console.log('enclosed by:', this.parent.name);
}

this.parserWikifier

The Wikifier parser instance that triggered this macro call.

this.payloadArray<Object> | null

For container macros (those with tags in their definition), this is an array of payload objects — one per tag block. For self-closing macros it is null. Each payload object has:
name
string
The name of this tag block (the opening tag name, or a child tag name such as "else").
args
Array<any>
Discrete arguments for this tag block. Includes args.full and args.raw sub-properties.
contents
string
The raw wiki-markup text between this tag and the next tag.
// Given: <<myMacro>>...first block...<</myMacro>>
// payload[0].name     → 'myMacro'
// payload[0].contents → '...first block...'

this.selfObject

The macro’s definition object — the same object passed to Macro.add(). Useful for reading custom properties you placed on the definition.

Methods

this.error(message)boolean

Renders an error message prefixed with the macro’s name into the output element and returns false. Use a return this.error(...) pattern to abort handler execution on bad input.
message
string
required
The error message to display.
returns
boolean
Always returns false.
// Given: <<someMacro …>>
return this.error('expected at least one argument');
// Outputs: <<someMacro>>: expected at least one argument

this.wiki(sources…)

Parses one or more wiki-markup strings and appends the rendered result to this.output. Shorthand for creating a Wikifier against the output element.
sources
string
required
One or more wiki-markup strings to render in sequence.
this.wiki('Who //are// you?');
// Outputs: Who <em>are</em> you?

this.wiki(
  'Goodnight… ',
  'sweet prince.'
);
// Outputs: Goodnight… sweet prince.

this.contextFilter(predicate)Array<Object>

Returns an array of all ancestor MacroContext objects (walking up the parent chain) for which predicate returns true. Returns an empty array if none match.
predicate
Function
required
A function that receives each ancestor context and returns a boolean.
returns
Array<Object>
Array of matching ancestor MacroContext objects.
var isInclude = function (ctx) { return ctx.name === 'include'; };
this.contextFilter(isInclude);
// Returns all <<include>> macro ancestors

this.contextFind(predicate)Object | undefined

Returns the first ancestor MacroContext for which predicate returns true, or undefined if none match.
predicate
Function
required
A function that receives each ancestor context and returns a boolean.
returns
Object | undefined
The first matching ancestor context, or undefined.
var isInclude = function (ctx) { return ctx.name === 'include'; };
var nearest = this.contextFind(isInclude);

this.contextSome(predicate)boolean

Returns true if any ancestor MacroContext satisfies the predicate.
predicate
Function
required
A function that receives each ancestor context and returns a boolean.
returns
boolean
true if at least one ancestor passes.
var isInclude = function (ctx) { return ctx.name === 'include'; };
if (this.contextSome(isInclude)) {
  // this macro is nested inside an <<include>>
}

this.shadowHandler(callback [, doneCallback [, startCallback]])Function

Returns a wrapper function that gives the callback access to variable shadows established by the <<capture>> macro. Use this whenever you need an asynchronous callback — such as a DOM event handler — to correctly read or write story/temporary variables that have been captured.
Only needed when your macro attaches asynchronous callbacks that touch variables shadowed by <<capture>>. If you don’t use <<capture>>, you can ignore this method.
callback
Function
required
The main asynchronous function. Receives access to shadowed variables.
doneCallback
Function
Optional cleanup function called after callback returns. Does not receive shadow access.
startCallback
Function
Optional initialization function called before callback runs. Does not receive shadow access.
returns
Function
A wrapped function suitable for use as an event handler or async callback.
$someElement.on('click', this.shadowHandler(function (ev) {
  // access $capturedVar correctly here
}));

Complete handler example

The following custom <<counted>> macro renders its contents and records how many times it has been visited:
Macro.add('counted', {
  tags : null,
  handler : function () {
    if (this.args.length === 0) {
      return this.error('a counter variable name is required');
    }

    var varName = this.args[0];

    // Validate it looks like a story variable
    if (varName[0] !== '$') {
      return this.error('argument must be a $variable');
    }

    var key = varName.slice(1);
    State.variables[key] = (State.variables[key] || 0) + 1;

    // Render the inner contents
    this.wiki(this.payload[0].contents);
  }
});
Usage in a passage:
<<counted "$visitCount">>
  You have read this block $visitCount times.
<</counted>>

Build docs developers (and LLMs) love