Hi, 

DON'T USE IN PRODUCTION. ... THIS IS STILL EXPERIMENTAL CODE!!

Some code, that actually does a real recursion, with infinite recursion 
protection. If you copy paste the code below into a test-tiddler at 
tiddlywiki.com and tag it $:/tags/Macro you can test it with this example 
<https://tiddlywiki.com/prerelease/#Example%20Table%20of%20Contents%3A%20Simple>
!


\define toc-caption() <$view field="caption"><$view field="title"/></$view>
\define getItemClass() [all[current]]-[<tv-history-list>get[current-tiddler
]]

The above 2 lines are helper macros, to display "caption" (if available 
_and_ defined) or the "title"
getItemClass reads some history info, for advanced styling. 


\define toc-body(tag,sort:"")
\whitespace trim
<ol class="tc-toc">
  <$list filter="""[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] 
-[enlist<visited>]""">
    <$set name=visited filter="[enlist<visited>] [<currentTiddler>]">
      <$set name="toc-item-class" filter=<<getItemClass>> emptyValue=
"toc-item-selected" value="toc-item">
        <li class=<<toc-item-class>> title=<<visited>>>
          <$set name="tv-wikilinks" filter="[all[current]get[toc-link]] 
~yes">
            <$link><<toc-caption>></$link>
          </$set>
          <$macrocall $name="toc-body" tag=<<currentTiddler>> 
sort=<<__sort__>>/>
        </li>
      </$set>
    </$set>
  </$list>
</ol>
\end

The above code contains the recursion and will be descussed in more detail. 


\define toc(tag,sort:"",exclude)
\whitespace trim
<$set name=visited filter=<<__exclude__>> >
  <$macrocall $name="toc-body"  tag=<<__tag__>> sort=<<__sort__>>/>
</$set>
\end

The above code is the wrapper, that contains some initialisation functions. 
This macro can be activated like this: 

<div class="tc-table-of-contents">
<<toc "Contents">>
</div>

The sort parameter will be _ignored_ in the whole discussion here. It's not 
important for the recursion function.

 - The toc() macro gets 2 important parameters: tag and exclude as 
 - The tag variable is passed unmodified to the toc-body()
 - The important thing is, that a new variable is introduced: *visited*
     - <$set name=visited filter=<<__exclude__>> >

visited contains the information, which elements of the TOC have already been 
visited. This name hasn't been used by existing toc macros, 
so there should be no naming and interpretation conflict!

visited is initialized with the "exclude" filter. This allows us, to exclude 
certain elements, by marking them as visisted. 


--------------- toc-body in more detail ------------

toc-body(tag,sort:"") is the macro, that is called recursively. 

A) 
The 1st important line is the list-widget. With the very first run, the tag 
will be "Contents" as called in <<toc "Contents">>

<$list filter="""[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] 
-[enlist<visited>]""">

The filter contains 2 runs. 

 - The first run: [all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$]  will 
return all tiddlers tagged: Contents, excluding tiddlers in edit-mode. 
 - The second run: will eliminate all tiddlers, that have been already visited: 
-[enlist<visited>]   
    - With the initial call: <<toc "Contents">> the variable visited will be 
empty. 

B)
The 2nd important line is:
<$set name=visited filter="[enlist<visited>] [<currentTiddler>]">

This line creates a new visited variable. The new value will be visited 
elements from A) PLUS the [<currentTiddler>]  ... 
This is a PUSH ... add new variable to the "stack" of existing variables. 

C)
The line <$set name="toc-item-class" ... is for styling only and not discussed 
here

D) 
<li class=<<toc-item-class>> title=<<visited>> > ... for debugging. If the 
elements are hovered, the visited path whill be shown. 

E)
<$set name="tv-wikilinks" filter="[all[current]get[toc-link]] ~yes">
  <$link><<toc-caption>></$link>
</$set>

Creates the link. no fruther discussion

F)
<$macrocall $name="toc-body" tag=<<currentTiddler>> sort=<<__sort__>>/>

Calls the toc-body() macro with the "new" tag=<<currentTiddler>> ... So we can 
continue with A) -> recursion

IMPORTANT
        </li>
      </$set>
    </$set>
  </$list>
</ol>

Those elements are NOT executed yet, since the "program" jumps recursively 
*into *toc-body(), as long as new  tagged elements are found. 

If no new elements are fund it starts executing the close commands eg: </$set>, 
which is a POP command for 1 visited variable, that has been created. 

I hope this helps a little bit better, since it is using a "real world" 
example. 

The visited variable is the "infinite recursion protection". 

A "path" variable will be needed for the expandable stuff. path is different to 
visited. 

have fun!
mario

-- 
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+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/tiddlywiki/4dc135f2-93bb-4a83-ace9-467f54e594e4%40googlegroups.com.

Reply via email to