This is a stripped-down version of a single section of Grok TiddlyWiki, optimized for fast loading and readability by search engines. Some features are missing.

## The Finer Points of Macros

17th August 2021 at 8:00pm

We just skimmed the surface of macros in the previous section, and you may be left with quite a few questions. Let's try to tackle some of the most important ones.

Macros have scope

In the Variables section, we learned that after the closing </$set> tag, a variable goes out of scope and is no longer available for use. So you might wonder, what's the scope of a macro? The answer is, generally, the macro is available until the end of the tiddler. It's also possible to define global macros – ones that you can use across any tiddler in your wiki. We'll discuss how to do that later. Macros can have zero parameters It's possible, and even common, to have a macro with no parameters, which is just a different way of writing a variable (potentially with a greater scope). For instance, this is equivalent to the example of the corporate disclaimer previously discussed in the Variables section: \define disclaimer() (This paragraph does not represent the formal opinion of my company.) \end You need to use the Really Annoying Five-Factor Authentication Process to get into the Employee Information System if it is a Tuesday, unless you have also purchased coffee (tea or pastries do not count) in the company cafeteria earlier in the day. <<disclaimer>> You need to use the Really Annoying Five-Factor Authentication Process to get into the Employee Information System if it is a Tuesday, unless you have also purchased coffee (tea or pastries do not count) in the company cafeteria earlier in the day. (This paragraph does not represent the formal opinion of my company.) Macros can have multiple parameters Let's come back to our good old wikipediaLink macro again. Let's say we want the user to be able to specify the text as well as the article we're linking to. Here's how we can do that: \define wikipediaLink(articleName, linkText) [[$linkText$|https://en.wikipedia.org/wiki/$articleName$]] \end <<wikipediaLink Aardvark "Wikipedia on Aardvarks">> Note that parameters are separated by a space in the macro call but by a comma in the macro definition. No, this doesn't really make any sense, but a lot of programming languages do it this way too. Also notice the use of "double quotation marks" when a macro parameter contains spaces. Macros can be called with parameters containing double quotes A moment ago, we saw that you can include spaces in a macro parameter by surrounding it in double quotes. But what happens when the parameter also contains double quotes? Uh-oh: \define wikipediaLink(articleName, linkText) [[$linkText$|https://en.wikipedia.org/wiki/$articleName$]] \end <<wikipediaLink Aardvark "What is an "aardvark"?">> In this case, we can use triple double quotes: \define wikipediaLink(articleName, linkText) [[$linkText$|https://en.wikipedia.org/wiki/$articleName$]] \end <<wikipediaLink Aardvark """What is an "aardvark"?""">> This trick works elsewhere in TiddlyWiki as well, if you ever find yourself needing to quote something that contains quotes. Macros can be called with parameter names If we don't like the order that the macro parameters are specified in, or there are a lot of parameters and it's hard to remember what order they come in, we can list the parameters by name. If we do this, the order becomes unimportant. \define wikipediaLink(articleName, linkText) [[$linkText$|https://en.wikipedia.org/wiki/$articleName$]] \end <<wikipediaLink linkText:"Wikipedia on Aardvarks" articleName:Aardvark>> Sometimes this is called using named parameters, in contrast to using positional parameters. A space may optionally be added after the colon :, but most people find it easier to read without a space. Macros can have optional parameters We can specify a default value for a parameter. Then we only need to provide a value in the macro call if we don't like the default: \define wikipediaLink(articleName, linkText:"Wikipedia Link") [[$linkText$|https://en.wikipedia.org/wiki/$articleName$]] \end <<wikipediaLink Aardvark>> <<wikipediaLink Aardvark "Wikipedia on aardvarks">> Again, a space may optionally be added after the colon. Macros can be defined on a single line You can place short macros that contain only one line on the same line as the \define pragma and omit the \end: \define disclaimer() (This paragraph does not represent the formal opinion of my company.) <<disclaimer>> (This paragraph does not represent the formal opinion of my company.) Macros can be called using a$macrocall widget

In addition to the handy <<double angle bracket>> syntax, it's possible to call a macro using a $macrocall widget. As we discussed in the widgets section, this is a common pattern in TiddlyWiki: anything you can do with convenient wikitext syntax can also be done with HTML tags or widgets, and those forms may offer some additional options for advanced use. Here's how we could create our aardvark link with a widget: \define wikipediaLink(articleName, linkText) [[$linkText$|https://en.wikipedia.org/wiki/$articleName$]] \end <$macrocall $name="wikipediaLink" linkText="Wikipedia on Aardvarks" articleName=Aardvark /> Notice the dollar sign in front of $name, which is easily missed. (This is in case your macro has a parameter called name – then TiddlyWiki can tell them apart.)

The $macrocall widget can take variables as parameters From the above, it was probably not immediately obvious why you would ever want to write out a macro call the long way. Here's the main reason why: you can pass in other variables or macro calls as parameters to the macro. For instance, maybe we want to link to a few different Wikipedia pages, but use the same link name: \define wikipediaLink(articleName, linkText) [[$linkText$|https://en.wikipedia.org/wiki/$articleName$]] \end <$set name="linktext" value="An animal">

* <$macrocall$name="wikipediaLink" linkText=<<linktext>> articleName="Aardvark" />
* <$macrocall$name="wikipediaLink" linkText=<<linktext>> articleName="Bee" />
* <$macrocall$name="wikipediaLink" linkText=<<linktext>> articleName="Cow" />

</$set> ## Exercises Exercise: (m) [Ex:TicketTrackingLink] Write a macro called ticketLink that takes one parameter, called ticketId, and creates a link whose text is Ticket #{ID}, where {ID} represents the ID of the ticket, and which links to the ticket. Assume that the URL of a ticket in the company's ticket-tracking system is https://tix.example.com/ticket/{ID}. Test this macro by putting it at the top of the OnboardingProcess tiddler and calling it at the bottom of the tiddler with the ticket number in the ticketnum field of that tiddler as its argument. go to answer Exercise: (m) [Ex:MacroCallAsParameter] Rewrite the example in The $macrocall widget can take variables as parameters to call a macro animalLinkText to get the value of the linkText parameter to the wikipediaLink macro. In other words, replace the <<linktext>> variable that's currently there with a macro.

The animalLinkText macro should take a letter as a parameter and output the text An animal which begins with {LETTER}, where {LETTER} is the parameter passed. Update the example to display the appropriate link text for each of the three animals.

Take the example The $macrocall widget can take variables as parameters and modify it so that the inner macro calls are surrounded in quotation marks, like so: \define wikipediaLink(articleName, linkText) [[$linkText$|https://en.wikipedia.org/wiki/$articleName$]] \end <$macrocall $name="wikipediaLink" linkText="<<linktext>>" articleName="Aardvark" /> What happens? Why do you think this happened? go to answer Exercise: (m) [Ex:UnclosedMacroCall] Take the example The$macrocall widget can take variables as parameters and modify it so that the \$macrocall tags are unclosed (no / before the >). What happens? Why do you think this happened?