Macro Resolving Problem

135 views
Skip to first unread message

Lisa Wasserman

unread,
Apr 29, 2020, 4:42:49 PM4/29/20
to TiddlyWiki
I'm getting closer to my ultimate goal of creating a tiddler that contains a list of journal entries, where today's  entry is editable.  I'm dynamically generating today's entry with a macro, then have buttons that will hide and reveal an editor.  The editor works, as do the hide and reveal buttons, and typing into the editor creates the entry tiddler if it doesn't exist.  Unfortunately, while the macro that generates the name of the new tiddler doesn't appear to resolve, always.

\define journalTiddlerName( ) <<now DD-MMM-YYYY>> $(project)$
\define state() $:/state/$(currentTiddler)$
<$set name="project" value={{!!project}}>
<$set name=state value=<<state>>>
   <$reveal type="nomatch" state=<<state>> text="show">
      <p><h2>
        Today
        <$button set=<<state>> setTo="show" class="tc-btn-invisible">{{$:/core/images/edit-button}}</$button>
      </h2></p>
      <p><$transclude tiddler=<<journalTiddlerName>> mode="block" /></p>
   </$reveal>
   <$reveal type="match" state=<<state>> text="show">
      <p><h2>
        Today
        <$button set=<<state>> setTo="hide" class="tc-btn-invisible">{{$:/core/images/done-button}}</$button>
      </h2></p>
<<journalTiddlerName>>
        <p><$tiddler tiddler=<<journalTiddlerName>>>
        {{||$:/core/ui/EditTemplate/body/editor}}
      </$tiddler></p>
   </$reveal>
</$set>
</$set>

There are three calls to <<journalTiddlerName>>.  The first and third return "<<now DD-MMM-YYYY>> WR-38972", while the second returns "29-April-2020 WR-38972".  For some reason, the Now macro is only working part of the time.  Thoughts?

Eric Shulman

unread,
Apr 29, 2020, 5:55:56 PM4/29/20
to tiddl...@googlegroups.com
On Wednesday, April 29, 2020 at 1:42:49 PM UTC-7, Lisa Wasserman wrote:
\define journalTiddlerName( ) <<now DD-MMM-YYYY>> $(project)$

Macros are text-substitution processors.  As such, they only do two things:

1) replace parameters -- $paramname$ -- with the values passed to the macro
2) replace variables -- $(variablename)$ -- with the values currently assigned by the calling context

After completing those replacements, the result is then inserted into the calling context which determines how the macro result is handled.

In your code, you have three instances of the <<journalTiddlerName>> macro:

1) <$transclude tiddler=<<journalTiddlerName>> mode="block" />
2) <<journalTiddlerName>>
3) <$tiddler tiddler=<<journalTiddlerName>>>

In both the 1st and 3rd instances, the macro output is used as the value for the "tiddler" parameter in a widget call and the macro output is simply passed along to the widget for further handling.
In the 2nd instance, the macro output is actually being *displayed* and it is directly parsed and rendered.

For your purposes, you want to actually evaluate the <<now ...>> macro and then substitute it's output into the macro.

Here's a modified version of your code that should do what you want:
\define journalTiddlerName( ) $(when)$ $(project)$
\define state() $:/state/$(currentTiddler)$
<$vars project={{!!project}} when=<<now DD-MMM-YYYY>>>

   
<$reveal type="nomatch" state=<<state>> text="show">
     
<p><h2>Today <$button set=<<state>> setTo="show" class="tc-btn-invisible">{{$:/core/images/edit-button}}</$button></h2></p>
     
<p><$transclude tiddler=<<journalTiddlerName>> mode="block" /></p>
   
</$reveal>
   <$reveal type="match" state=<<state>> text="show">
      <p><h2>Today <$button set=<<state>> setTo="hide" class="tc-btn-invisible">{{$:/
core/images/done-button}}</$button></h2></p>
     
<<journalTiddlerName>>
     
<p><$tiddler tiddler=<<journalTiddlerName>>>{{||$:/core/ui/EditTemplate/body/editor}}</$tiddler></p>
   
<
/$reveal>
</
$vars>

notes:
* I used the <$vars> widget instead of separate <$set> widgets.  It does the same thing as $set (assigns values to variables), but is a more compact syntax.
* I omitted the setting of the state variable, since it was just setting the value to itself.  
* I added a variable, "when" which captures the output of the <<now ...>> macro.
* The "journalTiddlerName" macro then uses the $(when)$ reference to substitute the captured "now" value into the desired result.

Give it a try and let me know how it goes...

enjoy,
-e
Eric Shulman
TiddlyTools.com: "Small Tools for Big Ideas!" (tm)

TonyM

unread,
Apr 29, 2020, 8:11:05 PM4/29/20
to TiddlyWiki
Eric,

Genius. For the first time you have explicitly stated why I have experienced repeated "fragility" when designing solutions in TiddlyWiki. 

Please confirm or correct my interpretation below;


Macros are text-substitution processors.  As such, they only do two things:

1) replace parameters -- $paramname$ -- with the values passed to the macro
2) replace variables -- $(variablename)$ -- with the values currently assigned by the calling context

After completing those replacements, the result is then inserted into the calling context which determines how the macro result is handled. 
 
...
With this example
\define journalTiddlerName( ) <<now DD-MMM-YYYY>> $(project)$

1) <$transclude tiddler=<<journalTiddlerName>> mode="block" />
2) <<journalTiddlerName>>
3) <$tiddler tiddler=<<journalTiddlerName>>>


I think an easy to make error, is that <<journalTiddlerName>> renders as expected in wikitext (2nd example above), but if it contains "anything" other than substitutions (macros or widgets) it will not work as a parameter (as used in 1 & 3).

Can we also say?
  • If it must be used as a parameter, it should first be wikified?
  • Wikification with the wikify widget needs to be done on a whole macro, you can't rely on the wikify widget inside a macro definition, because this will not work in a parameter because of the wikify widget itself.
  • This means that the wikify widget is of limited use inside macros which you may wish to use as a parameter.
Please confirm or clarify this an I will publish this lesson in my own words for the larger community.

Thanks in advance
Tony

TonyM

unread,
Apr 29, 2020, 8:20:45 PM4/29/20
to TiddlyWiki
Further to my last post;

When setting a variable using $set or $vars you may also be using a macro to set a value, 
eg
<$vars when=<<now DD-MMM-YYYY>> >

Once again this macro can only be used as a parameter if we;
  • Use substitutions in its definition
  • OR be defined using javascript, as the NOW macro is.
Please confirm this as well.

Regards
Tony

Lisa Wasserman

unread,
Apr 29, 2020, 9:24:55 PM4/29/20
to TiddlyWiki
That did it.  Thank you very much.  I'll keep this in mind when using macros.

--Lisa

tony

unread,
Apr 29, 2020, 9:50:10 PM4/29/20
to TiddlyWiki
What a cool macro! 

It's all Klingon to me, but i wrapped the modified version from Eric in a logger tiddler,
{{logger}}
and typed text is passed to a new journal tiddler in real time. I don't even have to hit ctrl-return to 'save'.

Very nice for journaling !

Thank you very much,
tony

TonyM

unread,
Apr 29, 2020, 10:01:22 PM4/29/20
to TiddlyWiki
Tony

You have discovered the ease of editing one tiddler from another by using a transclude, and how tiddlers and fields can be silently created just by editing them
it is quite an elegant solution. Thanks for sharing back

I think I may extend your idea. On any tiddler we could have a Today Button, that the view template will transclude if selected. Thus you can update your Journal with a selected tiddler in view without taking any other actions to reach your Journal.

Regards
Tony
Reply all
Reply to author
Forward
0 new messages