[TW5] Using conditional assignment mode of SetWidget to check empty strings

108 views
Skip to first unread message

mauloop

unread,
Jul 11, 2017, 7:21:41 PM7/11/17
to TiddlyWiki

I was in need of checking if a macro parameter was empty. The following is a extremely simplified version of the actual code:


\define isStringEmpty(str)
<$set name="answer" filter="""$str$""" value="no" emptyValue="yes">
<<answer>>
</$set>
\end


The result was not as I expected:


Macro callResult
<<isStringEmpty "something">>no
<<isStringEmpty "">>no


After a lot of attempts I realized that this one: <$set name="answer" filter="" value="no" emptyValue="yes">

... behaves just like: <$set name="answer" value="no">


I mean it seems that having the filter parameter of the SetWidget set to an empty string, is just like not having it at all, therefore the emptyValue parameter is ignored and it falls back to the basic syntax (namevalue).


It is probably obvious for the one more experienced with Tiddlywiki and HTML, I think it's a consequence of the way the widgets are parsed (as I could understand, quite like normal HTML tags). For me and the ones used with traditional programming languages, a variable set to an empty string is... an empty value!


I found a workaround and I decided to share my experience for who should fall in the same trouble, since I spent a lot of time to understand what happend, why and how to resolve.


\define isStringEmpty(str)
<$set name="answer" filter="""[enlist[$str$]]""" value="no" emptyValue="yes">
<<answer>>
</$set>
\end


Passing the string as a parameter of enlist filter operator do the trick. [enlist[]] evaluates to an empty list (it could be easily tested in AdvancedSearch), as expected by the SetWidget while using conditional assignment:


Macro callResult
<<isStringEmpty "something">>no
<<isStringEmpty "">>yes


Hope this could help someone.



Mat

unread,
Jul 11, 2017, 9:22:21 PM7/11/17
to TiddlyWiki
In deed confusing, and this has tripped me several times. 

I came up with a small trick for NON-BRACKETED arguments:

\define test(arg)
<$set name=answer filter=" $arg$" value="full" emptyValue="empty" >
ans:<<answer>>
</$set>
\end

NOTE the space character in the filter!!!! I marked it yellow here just so you see it. 

And again, no brackets. Putting in filter="[[$arg$]]" always returns "full".

ATM its bedtime so I won't hypothesize on why this works.

<:-)

mauloop

unread,
Jul 12, 2017, 4:12:14 AM7/12/17
to TiddlyWiki
Thanks, Mat. Your way is easier than mine. 

It means that evaluating $arg$ as a list, a blank is considered as an empty list.

Thomas Elmiger

unread,
Jul 13, 2017, 5:44:24 PM7/13/17
to TiddlyWiki
Hi all

My solution and explanation – tested in advanced search:

[[x]suffix[]] returns 0 results while

[[]suffix[]] returns 1

So you can actually test the other way round: if the suffix is empty, the value is empty and the resulting value=true (emptyvalue=false).

My tests led me to the conclusion that [[$test$]] does not test anything really. I think it checks if the title of $test$ is $test$, which always will be true, even if $test$ is empty. Does that make sense? It is bedtime in Switzerland too.

Good night!
Thomas

mauloop

unread,
Jul 13, 2017, 6:49:12 PM7/13/17
to TiddlyWiki
Thank you, Thomas. That's an interesting approach.

I see that filters are intended to provide sequences of (supposed) titles and count them. [[$test$]] probably is recognised as a list of 1 (empty) title, while [[x]suffix[]] or [enlist[]] evaluate to lists of 0 elements.

I had to test the string in a macro that recursively called itself. For that purpose, assuming that I cannot previously know the number of recursions, Mat's solution il less sophisticated, but maybe it performs better.

P.S.: I discovered your TW5 Hacks Tiddlywiki just few days ago and immediatly bookmarked it, Lots of useful suggestions. Titles with numbers and IfAisB impressed me. Thanks for sharing.
Reply all
Reply to author
Forward
0 new messages