SQ Filters Plugin and the Printf

For a while I am using the wonderful _printf[] filter from @saqimtiaz.

The plugin can be found here: Saq’s Sandbox — Experimental doodads (saqimtiaz.github.io)

The readme states:

_printf: Substitute variables and operands into strings, a friendler way of constructing strings from components.

It works like Python strings and makes life easy when you need to concatenate strings and create a compound string using macros, addsuffix, addprefix, …

Examples

Example i

<$vars name=Saq age=140>
<$text text={{{ [[My name is $(name)$ and $0$ my age is $(age)$.]_printf[I think]] }}}/>
</$vars>

produces

My name is Saq and I think my age is 140.

Remarks

  • Here name and age are two variables
  • A number in the $ $ can be used to refer to the position of the object passed into the _printf.

Example ii

<$text text={{{ [[My name is $0$ and my age is $1$.]_printf[Saq],[100]] }}}/>

produces

My name is Saq and my age is 100.

Remarks

  • Here $0$ refers to Saq and $1$ refers to 100 in _printf[Saq],[100]
  • so the value /input to _printf can be refered by their positions.

Example iii

<$let baseTiddler=practice
      tempTiddler={{{ [[$:/temp/$1$$0$]_printf<qualify>,<baseTiddler>] }}} >

<$edit-text tiddler=<<tempTiddler>> tag=input placeholder="input box ..."/>



;Debug
: temp tiddler title: <$link to=<<tempTiddler>> />
: temp tiddler content: <$transclude tiddler=<<tempTiddler>> />

</$let>

Remarks

  • The tempTiddler is created from concatenating a string, macro and variable
  • The _printf recives two objects here a macro and a variable: qualify and baseTiddler

To give a try

Note that there is a proposal for a very similar mechanism for the core: Add support for string literal attributes with textual substitution · Issue #6663 · Jermolene/TiddlyWiki5 · GitHub

1 Like

I puzzled over this for a moment… surely there’s a typo / edit glitch, since $1$ should give us 100 (and this version shouldn’t insert the “I think”)?

I’m sure lots of advanced folks will recognize immediately how to use this. But for some of us, just a tiny bit more practical illustration would be amazing.

I began checking this new filter out, thinking it may be very helpful if it can be used dynamically. For example, in a template, I might try to use this filter to grab a couple initial values from a list field like this:

<$text text={{{ [[My name is $0$ and my age is $1$.]_printf{!!list}] }}}/>

But the contents of my list field are treated as one long $0$; I can’t find a way to delimit things within a field so that they get recognized as distinct for the purpose of this filter.

So, I conclude it will be useful only when my template wants to pull on two or more distinct field references:

<$text text={{{ [[My name is $0$ and my age is $1$.]_printf{!!field1},{!!field2] }}}/>

OK, this works… but how is this more than a game of syntactical musical chairs? Does the usefulness here revolve around “pulling” all the moving parts to the end of the expression, so that it’s easier to scan for them and edit/replace them?

Or is there some other use case whose dynamic possibilities are simply off my radar?

And in closing, a trivial question: Can the choice of name _printf be made less baffling for simple folk (even if it’s a just-so-story or an account of how the word “print” still gets used in some programming language)?

Thanks!

-Springer

Ah it is a copy-paste mistake! I corrected the OP. Here I brought the correct example again.

<$text text={{{ [[My name is $0$ and my age is $1$.]_printf[Saq],[100]] }}}/>

produces

My name is Saq and my age is 100.

Sorry for making trouble.

Yes, here you pass one argument while it is an array and printf treats it like a single input!

Instead this works

<$let first={{{ [list[]nth[1]] }}} last={{{ [list[]nth[3]] }}}>
<$text text={{{ [[My name is $0$ and my age is $1$.]_printf<first>,<last>]  }}} />

</$let>

Sure, why not! I changed it to printf for my own use! I assume @saqimtiaz used _printf to indicate it is experimental or internal!

Note that the f in printf stands for formatted , its used for printing with formatted output. This terminology used in C, Python and some other language.

1 Like

Note to this example:

<$text text={{{ [[My age is $0$ and my name is $1$.]_printf[100],[Saq]] }}}/>

look at the number, the position of the object pass! You have control to print the second argument first!

Note that all of the contents of my sandbox site that are marked as experimental were written for my personal use, and shared on the off chance that they might prove useful for others.

My main use case for the _printf[] operator is as an alternative means to the current core affordances for string concatenation and substitution in filters: using addprefix[] and addsuffix[] operators, or by listing the different parts of the string as separate titles in order and calling join[]. The examples provided are very simple in that they just print out the final text, but in particular with more complex filter calculations where the substituted text needs further processing, I find these approaches very brittle and unfriendly.

_printf[] does two things and depending on your usage patterns you may or may not find value in them:

  • substitutes $(variablename)$ with the value of the corresponding variable
  • substitutes $n$ with the nth argument (if any).

This accommodates the two most common patterns in text substitution: substituting a variable value or a text reference. It also makes it easier to reuse the base string in which values are to be substituted. To substitute values from a list field you would need to first set up the individual values as variables.

The name was chosen in part as it is extremely unlikely to ever be used by the core in the future, to avoid clashes when I upgrade my wikis. This is a particular pain point for me when contributing to the core. Any core affordance with similar functionality will surely have a more intuitive name.

4 Likes