Test for existence of macro

256 views
Skip to first unread message

David Nebauer

unread,
Feb 25, 2019, 7:34:19 AM2/25/19
to TiddlyWiki
As I understand it, if you attempt to call an undefined macro the call fails silently, with nothing displaying in the tiddler to alert users. This occurs regardless of the calling method, i.e., 

<<not-a-real-macro>>
or
<$macrocall $name="not-a-real-macro"/>

Is there a technique for checking whether a macro is defined, and displaying a message in the tiddler if the macro is not defined?

Ideally, the test would not just check for output from the macro, since there might be valid circumstances where a macro produces no output.

-David

Jeremy Ruston

unread,
Feb 25, 2019, 8:09:23 AM2/25/19
to tiddl...@googlegroups.com
Hi David

I think you’re right: there is no way to test for the existence of a variable whose value is blank. I’ve added an [is[variable]] subfilter operator for v5.1.20 to address this:


Best wishes

Jeremy.


--
You received this message because you are subscribed to the Google Groups "TiddlyWiki" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywiki+...@googlegroups.com.
To post to this group, send email to tiddl...@googlegroups.com.
Visit this group at https://groups.google.com/group/tiddlywiki.
To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywiki/1ecc0c93-5932-41bb-9634-3eca9daf26c1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

David Nebauer

unread,
Feb 25, 2019, 3:49:15 PM2/25/19
to TiddlyWiki
Thanks, Jeremy. For future reference, would you mind showing how that subfilter could be used to test for the existence of a particular variable or macro, say 'VAR_NAME', and display the text "Undefined variable or macro 'VAR_NAME'" if it is not found.

-David

Jeremy Ruston

unread,
Feb 25, 2019, 3:55:58 PM2/25/19
to tiddl...@googlegroups.com
Hi David

Try:

[[VAR_NAME]] +[is[variable]addsuffix[ is a variable]] ~[[Undefined variable or macro 'VAR_NAME']]

[[currentTiddler]] +[is[variable]addsuffix[ is a variable]] ~[[Undefined variable or macro ‘currentTiddler']]

You can try out these examples in the “filter” tab of advanced search in the prerelease:


Best wishes

Jeremy.

David Nebauer

unread,
Feb 25, 2019, 4:27:14 PM2/25/19
to TiddlyWiki
Thanks, Jeremy, but I'm still not clear on how to use this. For newbs, i.e., me, what complete line (or lines) would you add to the top of a tiddler to display an error message if a particular macro is undefined, and do nothing if it does exist?

My use case is to add this to a tiddler where I am using a non-core macro, which is defined in another tiddler, to alert me if the macro is ever deleted/uninstalled.

David.


On Tuesday, 26 February 2019 06:25:58 UTC+9:30, Jeremy Ruston wrote:
Hi David

Mal

unread,
Feb 25, 2019, 9:06:07 PM2/25/19
to TiddlyWiki
Jeremy,

I was going to suggest this:

{{{ [[myMacro]] +[!is[variable]addsuffix[ is not defined]] }}}

But the "!" does not seem to be working as expected.  Am I missing something here?

Regards,

Mal

Mohammad

unread,
Feb 26, 2019, 6:51:44 AM2/26/19
to TiddlyWiki
Jeremy!
 Is it possible to use this operator for checking if the parameter has been passed to a macro or not!

--Mohammad

Mohammad

unread,
Feb 26, 2019, 6:57:50 AM2/26/19
to TiddlyWiki
Hello again Jeremy,

Look at below code

\define macro(VAR_NAME)
test
\end

<$list filter="[[macro]] +[is[variable]addsuffix[ is a variable]] ~[[Undefined variable or macro 'VAR_NAME']]">
<<currentTiddler>>
</$list>


Why the syntax needs variable like Tiddler title, I expect to have macro or variable as below


<$list filter="[<macro>] +[is[variable]addsuffix[ is a variable]] ~[[Undefined variable or macro 'VAR_NAME']]">
<
<currentTiddler>>
</$list>

I mean, using angle bracket.

--Mohammad

Jeremy Ruston

unread,
Feb 26, 2019, 7:08:07 AM2/26/19
to tiddl...@googlegroups.com
Hi Mohammad

The reason that we don’t use the “[<macro>]” formulation here is because we don’t want to retrieve the value of the macro, we want to get its name as a string.

Best wishes

Jeremy

Jeremy Ruston

unread,
Feb 26, 2019, 7:34:53 AM2/26/19
to tiddl...@googlegroups.com
Hi Mohammad,

 Is it possible to use this operator for checking if the parameter has been passed to a macro or not!

Sadly not. One might hope this would work:

\define macro(param)
I'm a macro. Param is <$list filter="[[__param__]!is[variable]]">not</$list> provided
\end

<<macro param:provided>>

<<macro>>

But in fact, the “__param__” variable is defined whether or not a parameter value is provided. It may be possible to tweak things so that this trick works, I’ll give it some more thought.

Best wishes

Jeremy


Mohammad

unread,
Feb 26, 2019, 9:51:26 AM2/26/19
to TiddlyWiki
Thanks Jeremy,
 I use the below method and it works, but it is NOT semantic!

\define macro2(param)
I'm a macro. Param is <$list filter="[<__param__>minlength[1]]">not</$list> provided
\end


<<macro2 param:provided>>


<
<macro2>>


--Mohammad

Mohammad

unread,
Feb 26, 2019, 10:01:28 AM2/26/19
to TiddlyWiki
Thanks for clarification!

--Mohammad

David Nebauer

unread,
Feb 26, 2019, 1:49:06 PM2/26/19
to tiddl...@googlegroups.com
I'm glad my question has led to something useful for others. Unfortunately, my original question has not been answered. Is there any way to use Jeremy's new subfilter to display an error message if a specified macro is undefined? (Thanks, Mal, for your efforts.)

Alternately, if it is still not possible, even with the new subfilter, I'd appreciate having that confirmed.

David.

You received this message because you are subscribed to a topic in the Google Groups "TiddlyWiki" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/tiddlywiki/4rEuAWc4EpM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to tiddlywiki+...@googlegroups.com.

To post to this group, send email to tiddl...@googlegroups.com.
Visit this group at https://groups.google.com/group/tiddlywiki.

Mohammad

unread,
Feb 26, 2019, 2:27:42 PM2/26/19
to TiddlyWiki
Hello David,
 Yes, the new subfilter operator can check if a macro/variable is defined (exist) or not!
It works in TW5.1.20pr.

Example

\define VAR_NAME() This is a test macro


<$list filter="[[VAR_NAME]] +[is[variable]addsuffix[ is a variable]] ~[[Undefined variable or macro 'VAR_NAME']]">
<<currentTiddler>>
</$list>

<$list filter="[[VAR_NAME2]] +[is[variable]addsuffix[ is a variable]] ~[[Undefined variable or macro 'VAR_NAME2']]">
<<currentTiddler>>
</$list>


Results:


VAR_NAME is a variable



Undefined variable or macro 'VAR_NAME2'



So, it works. Note that, VAR_NAME2 is not existed!


--Mohammad

David Nebauer

unread,
Feb 26, 2019, 8:37:17 PM2/26/19
to tiddl...@googlegroups.com
Thanks very much, Mohammad and Jeremy. For future reference, here is what I was seeking:

<$list filter="[[VAR_OR_MACRO_NAME]] +[is[variable]addsuffix[ is a variable]] ~[[Undefined variable or macro 'VAR_OR_MACRO_NAME']]">
<<currentTiddler>>
</$list>

If anyone else sees the option for marking this topic complete, please feel free to click it. (For whatever reason, I've never seen that option.)

Also, I'm not seeing the usual button for inserting code, hence the fixed width text above, which I hope renders sensibly when I press Send. This is new for me.

Mohammad

unread,
Feb 27, 2019, 1:52:52 AM2/27/19
to TiddlyWiki
Thanks David!
Added to TW-Scripts.

--Mohammad

David Nebauer

unread,
Feb 27, 2019, 8:46:51 AM2/27/19
to TiddlyWiki
Hmm, I may have declared success prematurely. Is there a way to reformulate the test so that if the macro is defined, the <$list> displays nothing. I really only want output if the error condition -- a missing macro -- occurs. Otherwise I want it to do nothing while the rest of the tiddlyscript in the tiddler executes.

-David

TonyM

unread,
Feb 27, 2019, 5:44:27 PM2/27/19
to TiddlyWiki
Rather than use the else ~ for the error message use emptyMessage on the list widget.

Tony

S. S.

unread,
Feb 27, 2019, 8:32:47 PM2/27/19
to TiddlyWiki
This seems to work for me.

\define variable-test(var)
<$list filter="[[$var$]] +[is[variable]]" emptyMessage="''$var$'' - Undefined variable or macro">
</$list>
\end

1. <<variable-test list-links>>

2. <<variable-test list-linkss>>

It uses a single line return with nothing else in the results area before the closing tag </$list>  to give an empty looking result. I don't know if this is an undocumented feature, or if it's a bug that will be fixed at some point causing this macro to break down. If that bothers you, just use an unused macro such as <<emptyMessage>> in the result area.

Regards

Mal

unread,
Feb 27, 2019, 10:57:31 PM2/27/19
to tiddl...@googlegroups.com
David,

On Wednesday, 27 February 2019 23:46:51 UTC+10, David Nebauer wrote:
Hmm, I may have declared success prematurely. Is there a way to reformulate the test so that if the macro is defined, the <$list> displays nothing. I really only want output if the error condition -- a missing macro -- occurs. Otherwise I want it to do nothing while the rest of the tiddlyscript in the tiddler executes.


This is what I was trying to achieve with my earlier post.  The following:

{{{ [[myMacro]] +[!is[variable]addsuffix[ is not defined]] }}}

Should produce "myMacro is not defined" or nothing if the macro or variable is defined - achieving what you are after in a clear and concise way, but the "!" does not seem to be working.  If you try a similar arrangement to test for non-existence of a tiddler, using "!is[tiddler]", it does work as expected.

I think I will raise this as a GitHub issue.

Regards,

Mal

David Nebauer

unread,
Feb 28, 2019, 9:37:30 AM2/28/19
to tiddl...@googlegroups.com
Thanks S. S. That does just what I wanted. I'll call that success.

Incidentally, this method fails gracefully in TW < 5.1.19 by displaying nothing whether the test variable or macro is defined or not, so you can begin using it now.

Regards,
David.

David Nebauer

unread,
Feb 28, 2019, 9:41:26 AM2/28/19
to TiddlyWiki
Thanks, Mal. Your proposed solution would certainly be a more concise and elegant way to achieve the same outcome. If you don't mind, perhaps you could keep this topic updated with developments and/or include a pointer to the github issue you raise.

Regards,
David.

PMario

unread,
Feb 28, 2019, 9:56:14 AM2/28/19
to TiddlyWiki
On Thursday, February 28, 2019 at 4:57:31 AM UTC+1, Mal wrote:
.... but the "!" does not seem to be working.  If you try a similar arrangement to test for non-existence of a tiddler, using "!is[tiddler]", it does work as expected.

I think I will raise this as a GitHub issue.

This issue has be fixed in the meanwhile.
-m

David Nebauer

unread,
Feb 28, 2019, 4:12:19 PM2/28/19
to tiddl...@googlegroups.com
Okay, in summary, here are two ways of using the [is[variable]] subfilter operator to display an error message if a specific variable or macro is undefined.

* As a macro:

\define check-var-or-macro(var)
<$list filter="[[$var$]] +[is[variable]]" emptyMessage="Undefined variable or macro '$var$'">
<<emptyNonExistentMessage>>
</$list>
\end

<<check-var-or-macro VAR-OR-MACRO-NAME>>

* As a transcluded filter:

{{{ [[VAR-OR-MACRO-NAME]] +[!is[variable]addprefix[Undefined variable or macro ']addsuffix[']] }}}

If used in 5.1.19 calling the macro results in no output, while using the transluded filter results in the error message: Undefined variable or macro 'Filter Error: Unknown operand for the 'is' filter operator'

I want to thank everyone who helped with this. What I assumed would be a trivial question turned into a rather sizable topic and a new subfilter operator for TW!

Regards,
David.

S. S.

unread,
Feb 28, 2019, 10:46:51 PM2/28/19
to TiddlyWiki
David, it was an interesting question. Could you share what happened for you to want that feature, and how you are using it?

On a similar track - the code in the <<dumpvariables>> macro can show the values of all variables and macros that exist at that position in the widget tree. I wonder if it would it be useful for developers (or even users who type macros) to be able to have a way to check against that list to see if ANY variable that is in the widget tree is undefined, and that could be used to trigger a warning on any refresh and display the undefined macros/variables?

Regards

David Nebauer

unread,
Mar 2, 2019, 3:50:18 AM3/2/19
to TiddlyWiki
S. S., no problem. I touched on it in a post earlier in the topic. My use case is that I've been using TW for a couple of months now and am starting to include some macros in my tiddlers that are either defined in standalone macro tiddlers or in non-core plugins. One example is Mohammad's <<dbadge>> macro which I rolled into a home-made plugin. When I realised that a call to a missing macro does not result in any error display in the tiddler, it occurred to me that there would be no warning if a macro tiddler was deleted or, if it is defined in a plugin, disappeared or was renamed in a plugin upgrade. That got me to wondering if I could include a tiddlyscript snippet at the top of any tiddlers which rely on non-core macros to check for the existence of said macros and display a warning if the macro is not defined.

I realise this is worrying about a very unlikely scenario but, if I'm going to be using TW as a personal notebook for years, and likely across multiple computers in that time, I tend to be paranoid about "future-proofing" and chains of dependency.

There may be better ways to approach this issue; if so, I'd love to hear about them.

Regards,
David.

Jeremy Ruston

unread,
Mar 2, 2019, 9:12:18 AM3/2/19
to tiddl...@googlegroups.com
Hi David

I think the problem you’re describing is the possibility that ones delicate arrangements of customisations might break, perhaps through an upgrade or human error. That’s certainly something I can relate to, and I’m interested in how we can address the brittleness of complex wikis.

The primary defence is to keep continuous backups. Given that TiddlyWiki is reasonably small by the standards of modern digital photos, and disk space/cloud storage is fairly cheap, it’s reasonable to keep a backup of every change we make to our wikis. I use git for some wikis, and for some personal stuff in standalone HTML files I rely on a Dropbox Pro feature whereby every previous version of a file is backed up and available for restore.

With continuous backups one can rewind time to find and fix problems made in the past.

Further defences include making your customisations into a plugin. That makes it easier to move the customisations between wikis, but it also lets you keep track of any modifications to them.

Best wishes

Jeremy.


-- 
You received this message because you are subscribed to the Google Groups "TiddlyWiki" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywiki+...@googlegroups.com.
To post to this group, send email to tiddl...@googlegroups.com.
Visit this group at https://groups.google.com/group/tiddlywiki.

David Nebauer

unread,
Mar 2, 2019, 7:59:38 PM3/2/19
to tiddl...@googlegroups.com
What you say is correct, Jeremy, and I'm already version controlling my wiki and keeping my personal customisations in plugins, and yet... your comments trigger a couple of thoughts.

The first is that TW is "marketed" as a personal notebook as much as a personal wiki. The second sentence at tiddlywiki.com is "Welcome to TiddlyWiki, a unique non-linear notebook for capturing, organising and sharing complex information." If TW is intended for use by ordinary computer users, as opposed to software experts or power users, it may not be reasonable to expect them to be git wizards able to use git bisect and others techniques to track down a breakage.

The other thought is that I've seen several suggestions in this group that TW is in the first stages of an explosion of creativity/development/customisation now that it has reached a sufficient degree of maturity. If true, this is going to expose a great deal more of the brittleness you refer to as multiple plugins and components interact with each other. For example, a recent topic reported that two plugins both replaced the same core tiddler, breaking one (or was it both?) of them. As another example, AFAIK TW won't warn a user if they create or import a tiddler, or install or upgrade a plugin, that overwrites a variable, macro or filter defined in an existing tiddler/plugin; nor is there a canonical list available anywhere that lists variables, macros and filters provided by custom plugins, so developers of new plugins (or just personal customisations) can avoid name collisions. (This risk can obviously be minimised by plugin- or user-specific prefixes.)

These comments are made as a recent convert to, and huge fan of, TW(5).

Regards,
David.

On Sat, 2 Mar 2019 at 23:42, Jeremy Ruston <jeremy...@gmail.com> wrote:
I think the problem you’re describing is the possibility that ones delicate arrangements of customisations might break, perhaps through an upgrade or human error. That’s certainly something I can relate to, and I’m interested in how we can address the brittleness of complex wikis.

The primary defence is to keep continuous backups.

Jeremy Ruston

unread,
Mar 3, 2019, 9:21:35 AM3/3/19
to tiddl...@googlegroups.com
Hi David

I wasn't suggesting that git was a universal solution, more that it's one of many techniques that users with different prior experience can use to manage multiple revisions of their files. Dropbox doesn't require any prior technical experience.

TiddlyWiki's single file format means that anybody who understands how files work can easily make a backup just by copying their files to a safe location.

As to the plugin clash you refer to, it's relevant that Tobias's plugin makes use of an incredibly dangerous technique that we have long implored people to avoid: the plugin overwrites one of the core JavaScript modules. I appreciate that there is no way of knowing that if you encounter the plugin today, but there it has a somewhat controversial history.

When the project started the idea was that community plugins would be encouraged to migrate to the official plugin library. As it's turned out, that's quite a lot of hassle for developers and so instead we have the current situation where plugins are dispersed and there's no easy way to find out their provenance.

(Thinking about it now, we could indeed add a big red banner that appears whenever a core JS module is overwritten... Harder to extend that to non-JS tiddlers since quite a few of them are designed to be overwritten if required).

Best wishes

Jeremy.
--
You received this message because you are subscribed to the Google Groups "TiddlyWiki" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywiki+...@googlegroups.com.
To post to this group, send email to tiddl...@googlegroups.com.
Visit this group at https://groups.google.com/group/tiddlywiki.
Reply all
Reply to author
Forward
0 new messages