Using transcluded field as argument for a macro

As a follow-up to How to get a regex search-replace yield markup rather than plain text, while the macro is now working when I call it directly with a string (thanks to help from @EricShulman, @Brian_Radspinner and – offline – @telumire) , when I transclude the parameter, the macro seems to have no effect. A demo of the problem is at https://crosseye.github.io/TW5-demos/2023-04-12a/. I’m guessing it’s something easily overcome, but whatever brain rot was affecting me yesterday seems to still be at work. :frowning_face:

The macro is simply a way to allow the tiddler to have data like "H2O" for Water, but display it as H2O. One of my attempted fixes was to replace the macro name “formula” with “chemical-formula” just in case there was some conflict with the field name. As I expected, this made no difference. But that got left in when I made the demo.

Used directly

This demonstrates that the macro is working fine when I hard-code the chemical formula.

Markup

<ul>
<li><$link to="Water">Water (<<chemical-formula "C9H8O4" >>)</$link></li>
<li><$link to="Aspirin">Aspirin (<<chemical-formula "H2O" >>)</$link></li>
</ul>

Result

Used by transclusion

But when I transclude that formula, it’s not showing correctly. Wrapping it in quotes does not matter:

Markup

<ul>
<$set name="currentTiddler" value="Aspirin">
<li><$link>{{!!title}} (<<chemical-formula {{!!formula}} >>)</$link></li>
</$set>
<$set name="currentTiddler" value="Water">
<li><$link>{{!!title}} (<<chemical-formula "{{!!formula}}" >>)</$link></li>
</$set>
</ul>

Result

(Simplified) intended usage

The actual usage will have this running inside a <$list> Widget. The filter is much more complex, but that part is working fine. It’s only a matter of getting the formula to display correctly.

Markup

<ul>
<$list filter=[tag[Compound]]>
<li><$link>{{!!title}} (<<chemical-formula {{!!formula}} >>)</$link></li>
</$list>
</ul>

Result


Any suggestions?

To pass a field value as a macro parameter, use the <$macrocall> widget, like this:

<$macrocall $name="chemical-formula"  form={{!!formula}}/>

I also notice that the output of the “chemical-formula” macro includes a leading space and some output (e.g., “NaCl”) produces a wikilink to a missing tiddler.

If you add these two lines to the beginning of your macro:

\whitespace trim
<$let tv-wikilinks=no>

it will eliminate the extraneous leading space and prevent the output from being treated as a wikilink.

-e

2 Likes

That was it, of course. You know, at least once already, and I think twice, I asked a question for which this was the answer. I apologize for not remembering it.

Definitely a good idea. Thank you.

Thank you. This one confused me a bit, as I’ve always paired <$let ...> with a </$let>. Here that led to the “</$let>” showing up in the output text. (I’m not really looking for explanation. I can go look that up, I’m sure.) And this fixed the problem perfectly – a problem that I hadn’t yet even noticed, so double thanks!

Thank you very much for the help!

This is probably not well-documented, so here’s the explanation anyway :slight_smile:

Normally, <$wikify> would have a closing </$wikify> following the <<out>>, like this:

\define chemical-formula(form)
\whitespace trim
<$wikify name=out mode=inline output=html
   text={{{ [<__form__>search-replace:g:regexp<digits>,<replacement>] }}}>
<<out>>
</$wikify>
\end

However, HERE’S THE “SECRET SAUCE”:

When a macro ends, any widgets that have not been closed are automatically terminated. Thus, it is safe to simply omit the trailing </$wikify>… and the same handling also applies to an unterminated <$let> widget, so instead of writing:

\define chemical-formula(form)
\whitespace trim
<$let tv-wikilinks="no">
<$wikify name=out mode=inline output=html
   text={{{ [<__form__>search-replace:g:regexp<digits>,<replacement>] }}}>
<<out>>
</$wikify>
</$let>
\end

you can omit BOTH the </$wikify> and </$let> syntax, and just write:

\define chemical-formula(form)
<$let tv-wikilinks="no">
<$wikify name=out mode=inline output=html
   text={{{ [<__form__>search-replace:g:regexp<digits>,<replacement>] }}}>
<<out>>
\end

One caveat: omitting the closing widget syntax only applies to “unnested” widgets. So, since the <$wikify> widget is nested “inside” the <$let> widget, you can’t omit just the </$wikify> while still using the </$let>, like this:

\define chemical-formula(form)
<$let tv-wikilinks="no">
<$wikify name=out mode=inline output=html
   text={{{ [<__form__>search-replace:g:regexp<digits>,<replacement>] }}}>
<<out>>
</$let>
\end

because this breaks the proper nesting of widgets and results in the unmatched </$let> being rendered into the output.

Hopefully this doesn’t hurt your brain too much :wink:

-e

5 Likes

Thank you very much! I didn’t even notice the “missing” </$wikify>. I did assume that the end of the macro simply closed these, but this helps me understand why the </$let> was showing up everywhere.

Thank you.