5.2.0 New Features: Macro Parameters in Filter

One can actually get pretty creative with literal macro parameters in filters.

For the following, assume the existence of a simple global macro as follows:

\define .printf(text) $text$

You can use this to avoid the need for a separate variable for a filter operand as long as it does not contain the character >

For example:

{{{ [tag[HelloThere]filter<.printf "[{!!text}length[]compare:integer:gteq[1000]]">] }}}

instead of:

\define larger-than-1k() [get[text]length[]compare:integer:gteq[1000]]

{{{ [tag[HelloThere]filter<larger-than-1k>] }}}

It gets better, since we are feeding our text into a macro, it means that anything in the $(varname)$ syntax will get replaced by the relevant variable values. Example:

{{{ [<.printf "This is the tiddler $(currentTiddler)$">] }}}

Unfortunately, what wont work is trying to substitute variables that are set by filter run prefixes or operators. So for example, while the :map filter run prefix (in the pre-release) sets the index and length variables the following will not work:

{{{ [tag[HelloThere]] :map[<.printf "$(index)$ of $(length)$ - $(currentTiddler)$">] }}}

Instead we have to do it the old fashioned way:
{{{ [tag[HelloThere]] :map[<currentTiddler>addprefix<length>addprefix[ of ]addprefix<index>] }}}

There might be a way to support these variables in macro params within filters as well, but it would necessitate a low level change to the base Widget class and would therefore need to be considered very carefully.


Personally I have been using a custom printf[] operator which handles this use case well. Syntax:

{{{ [tag[HelloThere]] :map[[$(index)$ of $(length)$ - $(currentTiddler)$]printf[]] }}}


Background: a while back I hacked the filter syntax to allow the characters `` as a delimiter for literal filter operands, which allows characters like []{}<> within them and automatically substitutes variables. It occurred to me that most of that can now be done with literal macro params.