Converting depth calculation to asterisks, assistance requested

Hit a small snag on a project which I could probably resolve just by iterating – but thought I’d turn it over here and see if the solution was obvious to anyone:

\define export-row(start_depth:"", separator:"")
\whitespace trim
<$vars linebreak="<br>
">
    <$set name="depth" filter="[<currentTiddler>get-stream-root:includeall[]count[]subtract<start_depth>]">
        <$set name="asterisks" filter="[<depth>subtract[1]][range[1]join[*]]">
            <$set name="regular" filter="[<currentTiddler>get[text]addprefix<asterisks>addprefix[ ]addsuffix<linebreak>]" select="0">
                <$text text=<<regular>> />
                <$list filter="[<currentTiddler>has[stream-list]]" variable="_NULL">
                    <$list filter="[enlist{!!stream-list}is[tiddler]]">
                        <$macrocall $name="export-row" start_depth="$start_depth$" separator="$separator$"/>
                    </$list>
                </$list>
            </$set>
        </$set>
    </$set>
</$vars>
\end

It currently calculates the depth correctly and outputs that as a prefix – however, I would like the depth-1 number of asterisks as the prefix instead.

To clarify: you want to set <<asterisks>> to a number of asterisks equal to [<depth>subtract[1]]? If so, try this:

<$set name="asterisks" filter="[<depth>subtract[1]] :map:flat[range{!!title}] :map[[*]] +[join[]]">

And since <<depth>>, <<asterisks>>, and <<regular>> are all intended to return single values rather than title lists (IMO, the real strength of $set), you should be able to define them all (plus <<linebreak>>) in a single $let rather than three nested $sets and a $vars:

<$let
	linebreak="<br>
"
	depth={{{ [<currentTiddler>get-stream-root:includeall[]count[]subtract<start_depth>] }}}
	asterisks={{{ [<depth>subtract[1]] :map:flat[range{!!title}] :map[[*]] +[join[]] }}}
	regular={{{ [<currentTiddler>get[text]addprefix<asterisks>addprefix[ ]addsuffix<linebreak>] }}}
>
	<$text text=<<regular>> />
	<$list filter="[<currentTiddler>has[stream-list]]" variable="_NULL">
		<$list filter="[enlist{!!stream-list}is[tiddler]]">
			<$macrocall $name="export-row" start_depth="$start_depth$" separator="$separator$"/>
		</$list>
	</$list>
</$let>

Edit: This is assuming you’re using 5.2.1+, of course; for early editions, $set/$vars is indeed your best option.

And if you’re using 5.3.2+, you could go a step further and replace this list…

<$list filter="[<currentTiddler>has[stream-list]]" variable="_NULL">
...
</$list>

with conditional shortcut syntax:

<%if [<currentTiddler>has[stream-list]] %>
...
<%endif%>

Ah, I should have known you’d come to my rescue, @etardiff – I have not wrapped my mind around conditional syntax yet.

For some reason, I always seem to get 1 asterisk when it should math to 0 asterisks…

\define export-row(start_depth:"", separator:"")
\whitespace trim
<$let
    linebreak="<br>
"
    depth={{{ [<currentTiddler>get-stream-root:includeall[]count[]subtract<start_depth>] }}}
    asterisks={{{ [<depth>subtract[1]] :map:flat[range{!!title}] :map[[*]] +[join[]addprefix[ ]] }}}
    regular={{{ [<currentTiddler>get[text]addprefix<asterisks>addsuffix<linebreak>] }}}
>
    <$text text=<<regular>> />
    <%if [<currentTiddler>has[stream-list]] %>
        <$list filter="[enlist{!!stream-list}is[tiddler]]">
            <$macrocall $name="export-row" start_depth="$start_depth$" separator="$separator$"/>
        </$list>
    <%endif%>
</$let>
\end

Other depths/asterisks are calculating correctly.

1 Like

Ah, that’s because I forgot a greater-than-0-depth check. Try replacing [<depth>subtract[1]] with [<depth>subtract[1]compare:number:gt[0]]; this will prevent any results less than 1 from being passed on to the subsequent :map step.

Re: conditional syntax: Essentially, any time you’d use a $list with a null variable to display its contents only when the filter produces at least one result, you can use <%if ... %> with that same filter. The primary advantage is that (in addition to being slightly shorter), you don’t have to set your own variable to preserve the existing value of <<currentTiddler>>.

  • Behind the scenes, <%if [tag[HelloThere]] %>...<%endif%> is translated to <$list filter="[tag[HelloThere]]" limit="1" variable="condition">...</$list>.
  • This means that the first result of the filter (as selected by limit="1") is also available within the conditional as <<condition>>.
1 Like

My hero :slight_smile:

I promise I’ll get it rote one of these days. :grinning_face_with_smiling_eyes: