[TW5] in a macro: achieve if / else

1,307 views
Skip to first unread message

Tobias Beer

unread,
Nov 23, 2014, 7:20:00 AM11/23/14
to tiddl...@googlegroups.com
Hi everyone,

I'd like to be able to follow optional routes in a macro, for example...
  • if it's value is defined take <<variable>>
  • else take $parameter$
I can certainly play with options to achieve this and
once I figured something out myself, I will post here.

Regardless, I'd love to know the possible ways
you know or can think of in which to tackle this problem, so...

If you've have something new in in mind,
start your reply with a line that summarizes your concept:

"CONCEPT: use foo bar..."

That way it's easier to spot possible solutions.

Could even be an idea for a new widget that doesn't even exist yet, e.g. IfElseWidget...
sketch out the design for it, someone might just jump at its implementation.

Best wishes, Tobias.

Jed Carty

unread,
Nov 23, 2014, 12:29:51 PM11/23/14
to tiddl...@googlegroups.com
I have been trying to find a way to do this as well. I think that there may be a way to do this using the updated set widget in the prerelease and something like the combination lock in the Safe tiddler in the interactive fiction thing I am working on (http://zorklike.tiddlyspot.com/). I haven't had any success in actually getting it to work, but I have been poking it.

The tiddler EventTriggerTemplate from the zork-like wiki has an example of some simple nested reveal widgets that could probably be modified by using set, and you could put them in a macro that allows them to take different parameters.
You can use this to put if/elseif/else functionality into displayed content using reveal widgets by using a filter and set to pick the state used by the reveal widget. But this is just for revealing content.

That is my progress on the problem, I have been lazily learning javascript, hopefully I will just make a plugin. So if you do get a good structure for the widget worked out I will at least try to implement it. It would be a good thing to learn with, but I just started teaching myself so don't expect anything too amazing.

Stephan Hradek

unread,
Nov 23, 2014, 1:02:03 PM11/23/14
to tiddl...@googlegroups.com
Try this:

\define tobilogic(parameter)  <$list filter="[[$(variable)$]]"><$view field="title">$parameter$</$view></$list>

!variable not defined
<<tobilogic "Okay! variable not defined">>

!variable defined
<$set name="variable" value="OK! variable defined">
<<tobilogic "Wrong! variable not defined">>
</$set>



Message has been deleted

Stephan Hradek

unread,
Nov 23, 2014, 1:06:41 PM11/23/14
to tiddl...@googlegroups.com
Should you want the other logic: Use the variable as a fallback:

\define otherlogic(parameter)  <$list filter="[[$parameter$]]"><$view field="title">$(variable)$</$view></$list>

<$set name="variable" value="Variable used">

!No Parameter
<<otherlogic>>

!With Parameter
<<otherlogic "Okay! Parameter found">>
</$set>

Please note that the usual caveats in regards to square brackets in variable or parameter apply.

Tobias Beer

unread,
Nov 23, 2014, 1:54:56 PM11/23/14
to tiddl...@googlegroups.com
Ok, I fear I wasn't quite clear about the idea and I don't even know whether any of those patterns make much sense the way I liked to play it through, but here it goes...

In a way, I wanted to make a macro agnostic to whether or not it is fed a variable or a parameter... don't ask me why, that was the ball being played :)

Something like (watch out, pseudo-syntax)...

\define macro(foo)
<$if $foo$>
do this
   
<$else>
       
<$if <<foo>>>
           
do that
           
<$else>
                otherwise
this
           
</$else>
        </
$if>
    </$else>
</
$if>
\end


...but that other usecase where a single variable or parameter has different values is a lot more interesting...

\define macro(foo)
<$if match="$foo$" value="bar">
do this
   
<$else>
       
<$if match="$foo$" value="baz">
           
do that
           
<$else>
                otherwise
this
           
</$else>
        </
$if>
    </$else>
</
$if>
\end

So, that's two entirely different games being played :)

Something tells me that that's almost like the reveal widget, except that reveal only works by checking against states, rather than checking a param or variable against something else.

Best wishes, Tobias.

Jed Carty

unread,
Nov 23, 2014, 2:28:32 PM11/23/14
to tiddl...@googlegroups.com
Tobias,

Your first example seems like it would require some sort of type checking, I have no idea how you would achieve that or if it is really possible.

For the second part I think that you could get that functionality with something like the reveal widget that is able to send widget messages based on the reveal state. In your example, if I understand correctly, you would take the input and immediately send a widget message to set a state field, then the if/else statements would act similarly to the reveal widget based on this field. The problem is that this sort of message that isn't tied to an event like a button press may get sent many times as the wiki refreshes and could be sending conflicting messages.

If this makes any sense:

\define macro(foo)
<$action-setfield field='stateField' value=$foo$/>
<$if state='stateField' type='match' value='bar'>
do this
</$if>
<$if state='stateField' type='nomatch' value='bar'>
    <$if state='stateField' type='match' value='baz'>
        do this other thing
    </$if>
    <$if state='stateField' type='nomatch' value='baz'>
       do yet another thing
    </$if>
</$if>

To get a real if/else sort of widget that fits with the current wikitext syntax I think you would need something like:

<$ifelse state=<<someState>> condition=<<someCondition>> match=<<macroToCallIfMatched>> nomatch=<<macroToCallIfNotMatched>>/>

The problem with both of those is that unless there is a way to allow widget messages or something similar without a triggering event I don't think they can be done. And allowing messages without a triggering event may break everything. Like having a select widget that sets a field, and a button that sets the field to a value that isn't allowed by the select widget. If you have some function that depends on the state of the select widget pressing the button will just break it. And if you allow the field to be set without the button or select widget than the two will both try to edit the same thing simultaneously.

If in your second example you disallow content that would violate this than you are left with something identical to using nested reveal widgets.

I would like to find a way around this, but because the wiki may be re-rendered unpredictably I don't think that you could define consistent behaviour in these cases.

Stephan Hradek

unread,
Nov 23, 2014, 2:36:28 PM11/23/14
to tiddl...@googlegroups.com
First problem first including pseudo code:

\define macro(foo)
<!-- if $foo$ ; begin --><$reveal type="nomatch" state=" non existing tiddlre " text="$foo$">
   
do this
<!-- end --></$reveal>
<!-- else ; begin --><$reveal type="match" state=" non existing tiddlre " text="$foo$">
   
<!-- if <<foo>> ; begin --><$reveal type="nomatch" state=" non existing tiddlre " text="$(foo)$">
       
do that
   
<!-- end --></$reveal>
   
<!-- else ; begin --><$reveal type="match" state=" non existing tiddlre " text="$(foo)$">
        otherwise
this
   
<!-- end --></$reveal>
<!-- end --></$reveal>
\end

! No Param, No Var

<<macro>>

! Param, No Var

<<macro "foo param">>

<$set name="foo" value="foo var">

! No Param, Var

<<macro>>

! Param, Var

<<macro "foo param">>



Note: Despite the fact that I used blanks as first and las character in the stet tiddler's name, this does not keep help the " non existing tiddler "  from being created as the state tiddler's name gets trimmed by tiddlywiki. So the whole logic will fail as soon as you have a non-empty tiddler called "non existing tiddler".

Jeremy Ruston

unread,
Nov 23, 2014, 3:07:19 PM11/23/14
to TiddlyWiki
We've already got facilities for conditional rendering via the reveal and list widget; we may need to extend them but they've been sufficient so far.

The proposal here is for macro definitions that include conditional elements. It's important that we implement this at the right layer.

Using the <$reveal> widget as suggested by Stephan in another thread has the disadvantage of incurring a rendering penalty. Ideally, we'd incorporate the new conditional syntax in the macro definition syntax.

The simplest proposal is for new \ifdef and \ifndef pragmas:

\define myMacro(param)
\ifdef param
The parameter is defined as $param$
\else
The parameter is not defined
\endif
\end

That syntax has the benefit of great simplicity. Tobias's original example could be done like this:

\define myMacro(param)
\ifdef param
<$set name="myvariable" value="""$param$""">
\else
<$set name="myvariable" value=<<myDefaultValue>>>
\endif
The value of myvariable is <<myvariable>>
</$set>

What do you think?

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 http://groups.google.com/group/tiddlywiki.
For more options, visit https://groups.google.com/d/optout.



--
Jeremy Ruston
mailto:jeremy...@gmail.com

Tobias Beer

unread,
Nov 23, 2014, 5:53:33 PM11/23/14
to tiddl...@googlegroups.com, jeremy...@gmail.com
The simplest proposal is for new \ifdef and \ifndef pragmas...

Have not thought about that but pragmas offer a door to making structured code principles available, be they if / else or other.

Maybe that's more simplistic than we can make use of...

\ifdef param

Instead, we could do things like...

\if param (mode:value)

for example...

\if param (equals:<<foo>)

Best wishes, Tobias.

Tobias Beer

unread,
Nov 23, 2014, 5:54:40 PM11/23/14
to tiddl...@googlegroups.com, jeremy...@gmail.com
\if param (equals:<<foo>)

\if param (equals:<<foo>>)
 
;-)

Matabele

unread,
Nov 24, 2014, 1:54:42 AM11/24/14
to tiddl...@googlegroups.com
Hi

I used a slightly different mechanism for my button widgets -- in this case, the test case resulted in different widget messages being issued. Don't know if this idea will be of any use.

See the <$iftid> and <$iftref> widgets at: http://gwiz.tiddlyspot.com/

regards

Tobias Beer

unread,
Nov 24, 2014, 4:27:33 AM11/24/14
to tiddl...@googlegroups.com
Hi Metablele,

See the <$iftid> and <$iftref> widgets at: http://gwiz.tiddlyspot.com/

Thanks for the example. Seems quite a constraint, thought, to be only able to check if a tiddler title exists.

Best wishes, Tobias.

Jeremy Ruston

unread,
Nov 24, 2014, 4:30:09 AM11/24/14
to Tobias Beer, TiddlyWiki
Hi Tobias

Instead, we could do things like...

\if param (mode:value)

for example...

\if param (equals:<<foo>)

The trouble with that approach is that it requires us to implement yet another, new syntax for the expression handling. We've already got a number of parsers in place within TiddlyWiki, and I'd be reluctant to add another non-standard one. The advantage of the ifdef/ifndef syntax is that there's no need to introduce a conditional expression syntax.

Best wishes

Jeremy

 

Best wishes, Tobias.

Tobias Beer

unread,
Nov 24, 2014, 4:31:42 AM11/24/14
to tiddl...@googlegroups.com
A solution to the if / else problem will definitely also answer the question of how to make a tagging macro that can do both of...
  • <<tagging>>
    • get tagging for current tiddler
  • <<tagging foo>>
    • get tagging for tiddler foo

...and I am thkning that it shoud not require any reveal states as the conditions to check are far more generic than those currently implemented, thus not requiring additional states.

Best wishes, Tobias.

Mat

unread,
Nov 25, 2014, 6:19:46 PM11/25/14
to tiddl...@googlegroups.com
Side note: I just stumbled over IFTTT. Figure it may be of interest to take a peek at. How relevant, I don't know.

It is a (not new) tool totally based on the formula "If <this> then <that>". I'm guessing this is a piece of cake in TW - but it's interesting to note that they've made a full service around this single concept.

<:-)
Reply all
Reply to author
Forward
0 new messages