Recursive filter operators to show all tiddlers beneath a tag and all tags above a tiddler

I’m using these filters to great effect with TiddlyMap for task management. Thanks @Yaisog - faster than Kin. Although Kin is awesome too.

Hi, @Yaisog I only just noticed the tagstree operator finds the items tagging the current one and up (not down)

  • Did you make one that lists all the tiddlers below as in the for TableOfContents? Since this is possibly the most needed to treat complex hierarchies as a single set?
  • This would make things easier for @paulgilbert2000 who is designing some complex hierarchies.
1 Like

One operator is posted in post #1 in this thread and the complementary operator in post #3.
I think you need taggingtree.js from post #1?

Thanks you, sorry, my mistake, and thank you.

In my mind these are good enough to submit to core, if not with minor changes arising from peer review. They are sufficiently light weight I think.

  • Would you consider submitting them?

Also you may be interested in the various nearby discussions (if not already involved) because access to a whole tree in an operator, offers a simplified subset of what the KIN operator offers.

  • Running map after getting a full tree of tiddlers is an easy way to collate a lot of values.

Before I’ll make a PR, I would like to hear what @jeremyruston thinks about adding these filters to the core. I’m not 100% sure that this is core material. After all, these can be easily installed from files.
If he is positive, I’ll make a PR.

Have a nice day
Yaisog

Hi @TW_Tones,
A wikitext solution of nearby was developed by @Yaisog see: Nearby Neighbors: A WikiText Solution - Tips & Tricks - Talk TW (tiddlywiki.org)

1 Like

Apologies @Yaisog I commented on a related GitHub ticket that @kookma opened, but didn’t link it here. The comment was:

Hi @kookma it would indeed be useful to have something like the kin operator in the core. My preferred route is not just to provide a special operator for treewalking, but to extend the filter syntax so that it is straightforward and safe to write recursive functions. Thus, I think the first step is actually the implementation of user defined functions in #6666. That gives us named functions with named parameters, which are the building blocks of recursion in functional languages.

3 Likes

I have being experimenting with @Yaisog’s two operators and yet to fully understand or confirm their operation.

Some examples;

;tags tree about
{{{ [tagstree[About]!is[system]!is[missing]] }}}

;tagging tree about
{{{ [taggingtree[About]!is[system]!is[missing]] }}}
  • note missing tiddlers are included (helpful but not expected)
  • Its listing tiddlers I do not expect

I am getting a different result with the same filter in a list

;tagging tree about list
<$list filter="[taggingtree[About]!is[system]!is[missing]]">
   <$link/> -  {{!!caption}}<br>
</$list>

I think it may be confused as to if it is a selection constructor or a selection modifier

  • I will return when I understand them better.

[Edits]

  • They also follow any tag including system tags
  • It, taggingtree looks more like a filter to retrieve “all related tiddlers” for the nearby project, not just return a list as in a TOC

In your first example, you use it in an inline filter. This would return only the first result.

Also, like I wrote in the OP, "Usage is basically identical to tagging[]". Hence, they don’t take a parameter. The input to the filter determines either the tag(s) for which all downstream children are found (taggingtree) or the tiddler(s) for which all upstream tags are found (tagstree).

Just like tags[] and tagging[] they will return system tiddlers. This is intended, to keep them simple and universal.

2 Likes

When filtered transclusion (aka, an "inline filter) occurs directly in a wikitext context, it renders ALL matching items. It is only when filtered transclusion is used as a widget param value that it only returns the first result.

Thus:
{{{ [enlist[A B C D]] }}} renders as four link items, “ABCD”,
but
<$text text={{{ [enlist[A B C D]] }}}/> renders as just “A”

-e

1 Like

Thanks @Yaisog I have not being so error prone before, sorry, now its working.

  • I was using mistakenly the parameter, so the input to the filter was [all[tiddlers]]
  • now I use [[tiddlername]taggingtree[]] and / or [<currentTiddler>tagsyree[]]

I am learning new things here every day. :grinning:

I find taggingtree and tagstree conceptually straightforward and fast. I think it should be in core!

1 Like

Can you make it a plugin? Or you can allow me to make it a plugin using GitHub - tiddly-gittly/Tiddlywiki-WikiText-Plugin-Template: Simple plugin template, with Github Pages demo site. , and I will add it to the plugin library to receive update.

Sure, I can make it a plugin. Give me a day or so to get some documentation up…

You can find the taggingtree and tagstree filter operators as plugins at https://yaisog.tiddlyhost.com

Have a nice day
Yaisog

6 Likes

Added to the CPL, thanks

https://tw-cpl.netlify.app/#Plugin_202302034048668%201%201:[[Plugin_202302034048668%201%201]]%20[[Plugin_202302034048668%201%201%201]]%20Plugin_202302033851321%20Plugin_202302034048668%20[[Plugin_202302034048668%201]]%20Index

1 Like

I agree we should have a more general filter operator in the core to get tree.

I’m creating a flow chart plugin that can show the tree, and I will allow user to use custom field, not limited to tags field. So I have to copy&paste and do modification to your code, instead of reuse it and just pass-in parameters.

1 Like

Thanks for sharing and its a very useful set of tools.

I do want to point out however; you say in the readme for tagging tree filter

Infinite (or recursive) filters cannot be defined in TiddlyWiki

  • This may be technically true but it is important to note this is only if one restricts oneself to a single filter.

It is true to say;

Infinite (or recursive) code can be defined in TiddlyWiki

  • It is quite easy easy in TiddlyWiki to implement recursive processes using a macro that calls itself.
    • one one hand you may need to add a little code to detect loops if the data is not hierarchical.
    • But on the other hand recursive macros present more possibilities to use and display intermediate values. Including but not limited to
      • counts, totals and calculations for each subtree
      • Separating the nodes (leaves) from branches (folders) and treating each differently
      • Visually representing the hierarchy
  • I have not yet investigated but the MAP filter/filter run, may be also helpful with fixed depth recursion.

It is important to recognise that obtaining a list of tiddlers in a hierarchy from a filter only returns the list of tiddlers in that hierarchy and that intermediate and accumulation of values associated with those tiddlers may very well need to iterate this list of titles one or more times, to extract information that someone is after.

  • Macro based recursive functions can collect this information in a single iteration of the hierarchy.

This is an important distinction to make when designing solutions because along with using two filters and nesting list widgets, it is not always as efficient to cram all functionality into a single filter, when when have other structures that can often provide more efficient solutions depending on the use case.

Not withstanding the above it is true there is a whole class of problems where your traggingtree and tagstree filters are very easy to use and efficient.

  • These filters is perfect for Identifying a list of tiddlers on which to apply a common action or calculation which can only be found “walking a tree”.

What to look for?

  • There is a class of coding cases where if you find yourself using one of your new operators multiple times, or the list of titles so generated by those filters multiple times it may be better to look at this alternative approaches.
  • Designers may consider the kin filter for more complex and non-tag tree filtering or using nested lists and self calling macros for other cases.

I use this plugin a lot in my personal task management plugin. And I found a bug, when two tiddler use taggingtree[], the output will be inconsistent. Do you have a Github repo for this to rise issue?

reproduce link

\define filter-is-not-leaf() [all[current]tagging[]filter<filter-is-new-task>] 

\define filter-non-completed-leaf-tasks() [all[current]debug-log[]taggingtree[]debug-log[]!filter<filter-is-not-leaf>filter<filter-is-new-task>]

try switching to left most tab here to reproduce, see console for log