title: $:/core/macros/toc
tags: $:/tags/Macro

\define toc-caption()
\whitespace trim
<$set name="tv-wikilinks" value="no">
  <$transclude field="caption">
    <$view field="title"/>
  </$transclude>
</$set>
\end

\define toc-body(tag,sort:"",itemClassFilter,exclude,path)
\whitespace trim
<ol class="tc-toc">
  <$list filter="""[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]""">
    <$let item=<<currentTiddler>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>
      <$set name="excluded" filter="""[enlist<__exclude__>] [<__tag__>]""">
        <$set name="toc-item-class" filter=<<__itemClassFilter__>> emptyValue="toc-item-selected" value="toc-item">
          <li class=<<toc-item-class>>>
            <$list filter="[all[current]toc-link[no]]" emptyMessage="<$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}><$view field='caption'><$view field='title'/></$view></$link>">
              <<toc-caption>>
            </$list>
            <$macrocall $name="toc-body" tag=<<item>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>
          </li>
        </$set>
      </$set>
    </$let>
  </$list>
</ol>
\end

\define toc(tag,sort:"",itemClassFilter:"")
<$macrocall $name="toc-body"  tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> />
\end

\define toc-linked-expandable-body(tag,sort:"",itemClassFilter,exclude,path)
\whitespace trim
<!-- helper function -->
<$qualify name="toc-state" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>
  <$set name="toc-item-class" filter=<<__itemClassFilter__>> emptyValue="toc-item-selected" value="toc-item">
    <li class=<<toc-item-class>>>
    <$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}>
      <$reveal type="nomatch" stateTitle=<<toc-state>> text="open">
        <$button setTitle=<<toc-state>> setTo="open" class="tc-btn-invisible tc-popup-keep">
          {{$:/core/images/right-arrow}}
        </$button>
      </$reveal>
      <$reveal type="match" stateTitle=<<toc-state>> text="open">
        <$button setTitle=<<toc-state>> setTo="close" class="tc-btn-invisible tc-popup-keep">
          {{$:/core/images/down-arrow}}
        </$button>
      </$reveal>
      &#32;
      <<toc-caption>>
    </$link>
    <$reveal type="match" stateTitle=<<toc-state>> text="open">
      <$macrocall $name="toc-expandable" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>
    </$reveal>
    </li>
  </$set>
</$qualify>
\end

\define toc-unlinked-expandable-body(tag,sort:"",itemClassFilter,exclude,path)
\whitespace trim
<!-- helper function -->
<$qualify name="toc-state" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>
  <$set name="toc-item-class" filter=<<__itemClassFilter__>> emptyValue="toc-item-selected" value="toc-item">
    <li class=<<toc-item-class>>>
      <$reveal type="nomatch" stateTitle=<<toc-state>> text="open">
        <$button setTitle=<<toc-state>> setTo="open" class="tc-btn-invisible tc-popup-keep">
          {{$:/core/images/right-arrow}}
          &#32;
          <<toc-caption>>
        </$button>
      </$reveal>
      <$reveal type="match" stateTitle=<<toc-state>> text="open">
        <$button setTitle=<<toc-state>> setTo="close" class="tc-btn-invisible tc-popup-keep">
          {{$:/core/images/down-arrow}}
          &#32;
          <<toc-caption>>
        </$button>
      </$reveal>
      <$reveal type="match" stateTitle=<<toc-state>> text="open">
        <$macrocall $name="toc-expandable" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>
      </$reveal>
    </li>
  </$set>
</$qualify>
\end

\define toc-expandable-empty-message()
<$macrocall $name="toc-linked-expandable-body" tag=<<tag>> sort=<<sort>> itemClassFilter=<<itemClassFilter>> exclude=<<excluded>> path=<<path>>/>
\end

\define toc-expandable(tag,sort:"",itemClassFilter:"",exclude,path)
\whitespace trim
<$let tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>
  <$set name="excluded" filter="""[enlist<__exclude__>] [<__tag__>]""">
    <ol class="tc-toc toc-expandable">
      <$list filter="""[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]""">
        <$list filter="[all[current]toc-link[no]]" emptyMessage=<<toc-expandable-empty-message>> >
          <$macrocall $name="toc-unlinked-expandable-body" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter="""itemClassFilter""" exclude=<<excluded>> path=<<path>> />
        </$list>
      </$list>
    </ol>
  </$set>
</$let>
\end

\define toc-linked-selective-expandable-body(tag,sort:"",itemClassFilter,exclude,path)
\whitespace trim
<$qualify name="toc-state" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>
  <$set name="toc-item-class" filter=<<__itemClassFilter__>> emptyValue="toc-item-selected" value="toc-item" >
    <li class=<<toc-item-class>>>
      <$link to={{{ [<currentTiddler>get[target]else<currentTiddler>] }}}>
          <$list filter="[all[current]tagging[]$sort$limit[1]]" variable="ignore" emptyMessage="<$button class='tc-btn-invisible'>{{$:/core/images/blank}}</$button>">
          <$reveal type="nomatch" stateTitle=<<toc-state>> text="open">
            <$button setTitle=<<toc-state>> setTo="open" class="tc-btn-invisible tc-popup-keep">
              {{$:/core/images/right-arrow}}
            </$button>
          </$reveal>
          <$reveal type="match" stateTitle=<<toc-state>> text="open">
            <$button setTitle=<<toc-state>> setTo="close" class="tc-btn-invisible tc-popup-keep">
              {{$:/core/images/down-arrow}}
            </$button>
          </$reveal>
        </$list>
        &#32;
        <<toc-caption>>
      </$link>
      <$reveal type="match" stateTitle=<<toc-state>> text="open">
        <$macrocall $name="toc-selective-expandable" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>
      </$reveal>
    </li>
  </$set>
</$qualify>
\end

\define toc-unlinked-selective-expandable-body(tag,sort:"",itemClassFilter,exclude,path)
\whitespace trim
<$qualify name="toc-state" title={{{ [[$:/state/toc]addsuffix<__path__>addsuffix[-]addsuffix<currentTiddler>] }}}>
  <$set name="toc-item-class" filter=<<__itemClassFilter__>> emptyValue="toc-item-selected" value="toc-item">
    <li class=<<toc-item-class>>>
      <$list filter="[all[current]tagging[]$sort$limit[1]]" variable="ignore" emptyMessage="<$button class='tc-btn-invisible'>{{$:/core/images/blank}}</$button> <$view field='caption'><$view field='title'/></$view>">
        <$reveal type="nomatch" stateTitle=<<toc-state>> text="open">
          <$button setTitle=<<toc-state>> setTo="open" class="tc-btn-invisible tc-popup-keep">
            {{$:/core/images/right-arrow}}
            &#32;
            <<toc-caption>>
          </$button>
        </$reveal>
        <$reveal type="match" stateTitle=<<toc-state>> text="open">
          <$button setTitle=<<toc-state>> setTo="close" class="tc-btn-invisible tc-popup-keep">
            {{$:/core/images/down-arrow}}
            &#32;
            <<toc-caption>>
          </$button>
        </$reveal>
      </$list>
      <$reveal type="match" stateTitle=<<toc-state>> text="open">
        <$macrocall $name="toc-selective-expandable" tag=<<currentTiddler>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<__exclude__>> path=<<__path__>>/>
      </$reveal>
    </li>
  </$set>
</$qualify>
\end

\define toc-selective-expandable-empty-message()
<$macrocall $name="toc-linked-selective-expandable-body" tag=<<tag>> sort=<<sort>> itemClassFilter=<<itemClassFilter>> exclude=<<excluded>> path=<<path>>/>
\end

\define toc-selective-expandable(tag,sort:"",itemClassFilter,exclude,path)
\whitespace trim
<$let tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> path={{{ [<__path__>addsuffix[/]addsuffix<__tag__>] }}}>
  <$set name="excluded" filter="[enlist<__exclude__>] [<__tag__>]">
    <ol class="tc-toc toc-selective-expandable">
      <$list filter="""[all[shadows+tiddlers]tag<__tag__>!has[draft.of]$sort$] -[<__tag__>] -[enlist<__exclude__>]""">
        <$list filter="[all[current]toc-link[no]]" variable="ignore" emptyMessage=<<toc-selective-expandable-empty-message>> >
          <$macrocall $name="toc-unlinked-selective-expandable-body" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter=<<__itemClassFilter__>> exclude=<<excluded>> path=<<path>>/>
        </$list>
      </$list>
    </ol>
  </$set>
</$let>
\end

\define toc-tabbed-external-nav(tag,sort:"",selectedTiddler:"$:/temp/toc/selectedTiddler",unselectedText,missingText,template:"")
\whitespace trim
<$tiddler tiddler={{{ [<__selectedTiddler__>get[text]] }}}>
  <div class="tc-tabbed-table-of-contents">
    <$linkcatcher to=<<__selectedTiddler__>>>
      <div class="tc-table-of-contents">
        <$macrocall $name="toc-selective-expandable" tag=<<__tag__>> sort=<<__sort__>> itemClassFilter="[all[current]] -[<__selectedTiddler__>get[text]]"/>
      </div>
    </$linkcatcher>
    <div class="tc-tabbed-table-of-contents-content">
      <$reveal stateTitle=<<__selectedTiddler__>> type="nomatch" text="">
        <$transclude mode="block" tiddler=<<__template__>>>
          <h1><<toc-caption>></h1>
          <$transclude mode="block">$missingText$</$transclude>
        </$transclude>
      </$reveal>
      <$reveal stateTitle=<<__selectedTiddler__>> type="match" text="">
        $unselectedText$
      </$reveal>
    </div>
  </div>
</$tiddler>
\end

\define toc-tabbed-internal-nav(tag,sort:"",selectedTiddler:"$:/temp/toc/selectedTiddler",unselectedText,missingText,template:"")
\whitespace trim
<$linkcatcher to=<<__selectedTiddler__>>>
  <$macrocall $name="toc-tabbed-external-nav" tag=<<__tag__>> sort=<<__sort__>> selectedTiddler=<<__selectedTiddler__>> unselectedText=<<__unselectedText__>> missingText=<<__missingText__>> template=<<__template__>>/>
</$linkcatcher>
\end
