TiddlyWiki5/editions/tw5.com/tiddlers/wikitext/Macro Definitions in WikiTe...

115 lines
5.3 KiB
Plaintext

caption: Macro Definitions
created: 20150220181617000
modified: 20221207094236472
tags: WikiText
title: Macro Definitions in WikiText
type: text/vnd.tiddlywiki
A [[macro|Macros]] is defined using a `\define` [[pragma|Pragma]]. Like any pragma, this can only appear at the start of a tiddler.
The first line of the definition specifies the macro name and any parameters. Each parameter has a name and, optionally, a default value that is used if no value is supplied on a particular call to the macro.
The lines that follow contain the text of the macro text (i.e. the snippet represented by the macro name), until `\end` appears on a line by itself:
<$codeblock code={{$:/editions/tw5.com/macro-examples/say-hi}}/>
Alternatively, the entire definition can be presented on a single line without an `\end` marker:
```
\define sayhi(name:"Bugs Bunny") Hi, I'm $name$.
```
!! Accessing variables and parameters
Inside the macro there are several methods for accessing variables defined outside of the macro or parameters from the macro parameter list.
|syntax|description|h
|`$...$`|Text substitution of a parameter defined in the macro parameters list |
|`<<__...__>>`|Parameter-as-variable access to a parameter defined in the macro parameters list |
|`$(...)$`|Text substitution of a variable defined outside of the macro |
|`<<...>>`|Access to a variable (or other macro) defined outside of the macro |
<br>
!!! Placeholders `$(...)$`
The macro can contain placeholders for parameters. These consist of a parameter name between dollar signs, like `$this$`.
The macro can also contain placeholders for [[variables|Variables]]. These consist of a variable name (or macro name) between dollar signs and round brackets, like `$(this)$`.
The actual value of the parameter or variable is substituted for the placeholder whenever the macro is called:
<$importvariables filter="$:/editions/tw5.com/macro-examples/say-hi-using-variables">
<$codeblock code={{$:/editions/tw5.com/macro-examples/say-hi-using-variables}}/>
<$macrocall $name=".example" n="1"
eg="""<$set name="address" value="Rabbit Hole Hill">
<<say-hi-using-variables>>
</$set>"""/>
</$importvariables>
!!! Parameters as Variables `<<__...__>>`
Parameters in a wikitext macro can be accessed as variables by using the syntax `<<__...__>>`, i.e the parameter name surrounded by double underscores. For example, the example above could also be expressed as:
```
\define sayhi(name:"Bugs Bunny") Hi, I'm <$text text=<<__name__>>/>.
```
Accessing parameters as variables only works in macros that are wikified and not, for example, when a macro is used as an attribute value. The advantage of the technique is that it avoids the parameter value being substituted into the macro as a literal string, which in turn can help avoid issues with parameters that contain quotes.
For example, consider this macro. It invokes another macro using the single parameter as an argument for it:
```
\define film-quote(line) <$macrocall $name="anothermacro" actor="Bugs Bunny" line="""$line$"""/>
```
The code above will fail if the macro is invoked with the argument containing triple double quotes (for example `<<film-quote 'I quote thrice """ - see!?'>>`). Using parameter variables offers a workaround:
```
\define film-quote(line) <$macrocall $name="anothermacro" actor="Bugs Bunny" line=<<__line__>>/>
```
!! Scope
Macros are available to the tiddler that defines them, plus any tiddlers that it transcludes.
To make a macro available to all tiddlers, define it in a tiddler that has the tag <<.tag $:/tags/Macro>>.
It is also possible to write a macro as a [[JavaScript module|https://tiddlywiki.com/dev/index.html#JavaScript%20Macros]]. ~JavaScript macros are available to all tiddlers, and offer the maximum flexibility.
A tiddler can manually import macro definitions from a [[selection|Title Selection]] of other tiddlers by using the <<.wlink ImportVariablesWidget>> widget.
!! Nested Macro Definitions
Macro definitions can be nested to any number of required levels by specifying the name of the macro in the `\end` marker. Nested macro definitions must appear at the start of the definition that contains them. For example:
<<wikitext-example-without-html src:"""\define special-button(caption:"Click me")
\define actions()
<$action-sendmessage $message="tm-notify" $param="HelloThere"/>
\end actions
<$button actions=<<actions>>>
$caption$
</$button>
\end special-button
<<special-button>>
""">>
Note that the textual substitution of macro parameters that occurs when the outer macro is rendered will apply to the nested definitions as well. That generally means that textual substitution of macro parameters should not be used within nested macros.
Parameters of nested macros can also be accessed via the `<<__variablename__>>` syntax. As ordinary variables, these parameters are available within nested child macros (and grandchildren etc).
For the one-liner macro definition, the `\end` remains unnecessary for the inner macro. For example
<<wikitext-example-without-html src:"""\define special-button(caption:"Click me")
\define actions() <$action-sendmessage $message="tm-notify" $param="HelloThere"/>
<$button actions=<<actions>>>
$caption$
</$button>
\end special-button
<<special-button>>
""">>
A more formal [[presentation|Macro Definition Syntax]] of this syntax is also available.