How to do an exact match of tags

437 views
Skip to first unread message

steve

unread,
Nov 28, 2016, 10:00:06 PM11/28/16
to TiddlyWiki
Hi:

Does anyone know of a way to do an exact tag match, i.e., there is a one to one correspondence between the tags specified in the filter and the matching tiddlers.

For example for tidders Tom (tagged A), Dick (tagged A, B) and Harry (tagged A, B and C), a filter search for [tag[A]] would return Tom (but not Dick or Harry) and a filter search for [tag[A]tag[B]] would return Dick (but not Harry). The only way that I can think of so far would be to use javascript to compare the contents of the tags field.

The use case is to be able to generate a list of matching tiddlers for each unique group of tags. I have a macro to do this by first doing sorting the tags in place for each tiddler;  sorting the tiddlers by the tags field (i.e., sort[tags]); and then listing each tiddler name followed by its corresponding tag pills. I am trying to stretch my tiddlywiki horizons by finding a way to do this while listing each unique combination of tags only once followed by list of tiddlers that have that exact combination of tags.

Thanks
Steve


Jed Carty

unread,
Nov 29, 2016, 2:52:40 AM11/29/16
to TiddlyWiki
I wrote a thing about how filter expressions can be represented as logic statements that may help you but I don't have the link on this computer. The quick answer is that you can use this:

<$list filter='[tag[TableOfContents]]'>
<$list filter='[is[current]tags[]]-[[TableOfContents]]' emptyMessage="""<<currentTiddler>>""">
<span/>
</$list>
</$list>

to test it put it in a tiddler on tiddlywiki.com and look at the list, then add another tag to HelloThere and it will be removed from the list. You can change the emptyMessage to whatever you want to display for each tiddler. If you want more than one tag to be tested for you just make the first filter something like [tag[a]tag[b]] and add -[[a]]-[[b]] to the second filter.

There is almost certainly an easier way to do whatever it is you are trying to do.

PMario

unread,
Nov 29, 2016, 6:48:32 AM11/29/16
to TiddlyWiki
Hi Steve,

I think, this could be a feature request (github issue) for a new filter operator. since the number of possible combinations rises non linear. So having nested lists will be not very convenient.

-mario

steve

unread,
Nov 29, 2016, 6:43:03 PM11/29/16
to TiddlyWiki
Jed, PMario

To clarify, what I am trying to do is to list all of the unique sets of tags actually present in the wiki, not all possible combinations. Perhaps an example
would help. I have uploaded a file called "listAsTableSortedByTags Example Output.pdf" that shows an example output showing a listing of tiddlers
sorted by the tags field.

If you look about a third of the way down in the example output, you will notice the "artistTbd" tiddler. It has two tags "artist" and "music". If I used the
typical filter "[tag[artist]tag[music]]" it would list the "artistTbd" tiddler as expected, but it would also list the seven other tiddlers, e.g., "Archie Fisher"
that also have the tags "artist" and "music", but aren't an exact match because they include other tags in addition to "artist" and "music".

Thanks for responding.
Steve Wharton
listAsTableSortedByTags Example Output.pdf

steve

unread,
Nov 29, 2016, 7:21:11 PM11/29/16
to TiddlyWiki
All

Update: I have also attached a listing of the "listAsTableSortedByTags" macro which was used to generate the example output as  shown my previous post.

Steve Wharton

listAsTableSortedByTags Macro Listing.pdf

Mat

unread,
Nov 30, 2016, 2:19:32 AM11/30/16
to TiddlyWiki
Steve, I'd agree with PMario that it is a reasonable github request even if you personally don't need all possible combos in this case. To be able to get an exact tag match seems like a general enough need. I'm surprised such a request hasn't come up before, even if I'm sure the need for it has.

<:-)

Matabele

unread,
Nov 30, 2016, 2:56:41 AM11/30/16
to TiddlyWiki
Hi

There are a few examples of selecting by tag combinations here.

regards

PMario

unread,
Nov 30, 2016, 5:25:53 AM11/30/16
to TiddlyWiki
On Wednesday, November 30, 2016 at 8:56:41 AM UTC+1, Matabele wrote:
There are a few examples of selecting by tag combinations here.

thats interesting. thx for sharing.
-m

steve

unread,
Nov 30, 2016, 1:02:25 PM11/30/16
to TiddlyWiki
Matabele

Thanks for the example. I tried out "Checklist Example -- Select by ANDing Tags". Although I can't say that I understood the use of prefixes, the example appeared to perform a similar action as a [tag[A]tag[B]] filter. It also found the additional test tiddler tagded with A, B, and C.

Steve Wharton


Checklist Example -- Select by ANDing Tags

steve

unread,
Nov 30, 2016, 1:04:56 PM11/30/16
to TiddlyWiki
Mario

No quarrel from me that the all combinations functionality would be a reasonable github request.

Steve Wharton

Mark S.

unread,
Nov 30, 2016, 2:35:15 PM11/30/16
to TiddlyWiki
I think there's a way to do this easily assuming:

  • You don't mind pressing a button to update results.
  • None of your tags has a space (this may not be essential)
  • You don't mind hand crafting the tag/label you're looking for. See below

See code below. I added "About" and "Widgets" to some tiddlers at tiddlywiki.com for my tests. First you press a button that will create a field "aratags" that puts the list of sorted tag values for each tiddler into it's own field. I have to do this because the original tag values are not stored sorted.

Then, in the list below, the code filters for aratags field with hand-crafted contents "About Widgets". Only tiddlers matching this exact criteria are selected.

Have fun,
Mark 



<$button>
<$list filter="[tag[About]tag[Widgets]]">
<$action-listops $field="aratags" $filter="[all[current]tags[]sort[]]"/>
</$list>
Populate array
</$button>

<$list filter="[field:aratags[About Widgets]]"/>

PMario

unread,
Nov 30, 2016, 5:46:56 PM11/30/16
to TiddlyWiki
On Wednesday, November 30, 2016 at 7:02:25 PM UTC+1, steve wrote:
Although I can't say that I understood the use of prefixes, the example appeared to perform a similar action as a [tag[A]tag[B]] filter. It also found the additional test tiddler tagded with A, B, and C.

Matabele's example is based on filter runs, which are basically performing a logical AND. IMO it's very close, to what you requested. You just need to tweak it, to your needs.

http://tiddlywiki.com/#Filter%20Run:%5B%5BFilter%20Run%5D%5D%20%5B%5BFilter%20Expression%5D%5D

-mario

steve

unread,
Dec 1, 2016, 9:41:42 AM12/1/16
to TiddlyWiki
PMario

I will get to work to setup an TiddlySpot instance to compare the various solutions that have been suggested. Thanks everybody!


My ultimate use case would be to have a macro, that given the name of an InputTiddler, lists all of the tiddlers that have the exact set of tags
as the Input Tiddler.

Tobias Beer has a "contains" plugin (http://tobibeer.github.io/tw5-plugins/#contains) that comes close in that it supports a programmatic way
to specify that all of the tags to be matched, i.e., by setting the list variable in the snippet below.

For example consider the modified snippet from one of Tobias' examples as follows:

<$vars list="music genre">
<dl>
<$list filter="[contains:tags $all<list>]">
<dt><$link><$view field="title"/></$link></dt>
<dd>''field:'' {{!!tags}}</dd>
</$list>
</dl>
</$vars>

As expected this returns all tidders that have both the "music" and "genre" tag including tiddlers that have other tags in addition to "music" and "genre".

A possible "what if" solution to my question would be to imagine something like an "only" option which
would match tiddlers that contained only the "music" and "genre" tags. For example:

<$vars list="music genre">
<dl>
<$list filter="[contains:tags $only<list>]">
<dt><$link><$view field="title"/></$link></dt>
<dd>''field:'' {{!!tags}}</dd>
</$list>
</dl>
</$vars>

Steve Wharton

steve

unread,
Dec 5, 2016, 8:45:28 AM12/5/16
to TiddlyWiki
An Update:

Thanks to everything that has responded. Alas, thus far, I have been unable to find or develop an exact match function.

Here is the macro I promised that generates a table which lists tiddlers in order of their respective tags field.
Each unique set of tags is listed on a separate line of the table, followed by the list of tiddlers that possess those tags.

Writing the plugin was made much easier thanks to Tobias Beer's ''contains'' plugin, which can be found at http://tobibeer.github.io/tw5-plugins/#contains.
I am having difficulties in setting up an example on tiddyspot. As an alternative a listing of the macro is given below.

Steve Wharton

```
\define listAsTableSortedByTagField(filter:"[!is[system]]" titleText captionText)

<!-- By Stephen Wharton (last revised Dec 3, 2016)

      Generate a table of tiddlers listed in order of their unique sets of tags.
      * first column is the unique set of tags formatted as pills
      * second column is the list of tiddlers that match the tags from the first column
-->

<!-- Optionally sort the tags in place for each tiddler
-->
<$button>Sort Tags In Place (Ascending Order)
<$list filter="[!is[system]!has[draft.of]] +$filter$">
<$set name=TagsString filter='[<currentTiddler>tags[]sort[]]'>
<$action-setfield tags=<<TagsString>>/>
</$set>
</$list>
</$button>


<!-- Sort the tiddlers according to their (sorted) tags.
       Generate the table by listing the tiddler title, followed by tag pills.
-->
<table>
<tr>
<th>Unique Sets of Tags</th>
<th>Matching Tiddlers per Tag Set</th>
</tr>
<$list filter="$filter$ +[each[tags]] +[sort[tags]]">
<$set name=currentTags filter='[<currentTiddler>tags[]sort[]]'>
<tr><td class="cellWidth4Pills"><$list filter="[all[current]tags[]]" template="$:/core/ui/TagTemplate" storyview="pop"/></td>
<td class="cellWidth4Titles"><<listViaContains>></td>
</tr>
</$set>
</$list>
</table>

\end

<!-- Example Application
-->
<<listAsTableSortedByTagField filter:"[tag[music]]" titleText:"listSortedByTagField - example application">>
```







Message has been deleted

cmari

unread,
Dec 8, 2016, 4:18:50 PM12/8/16
to TiddlyWiki
Hi Steve,
Is there another tiddler that contains the macro <<listViaContains>>? Sorry if I overlooked something in your post.
The table is really useful - thanks!
cmari

steve

unread,
Dec 9, 2016, 8:10:33 AM12/9/16
to TiddlyWiki
Cmari

Yes there is and I somehow managed to not include it. Here it is ...

Steve Wharton

```
\define listViaContains()

<!--
       List all tiddlers that match the tags in the variable "currentTags".

       The "contain" plugin from Tobias Beer makes this very easy to do.
       (His plugin can be found at http://tobibeer.github.io/tw5-plugins/#contains)
-->

<$list filter="[contains:tags $all<currentTags>]">
<$link><$view field="title"/></$link>, </$list>

\end

<!-- Show an example to find all tiddlers that have the same tags as the
       "macroDef: listViaContains" tiddler.
-->

<$set name=currentTags filter='[<currentTiddler>tags[]sort[]]'>
<<listViaContains>>
</$set>
```

steve

unread,
Dec 9, 2016, 11:35:00 AM12/9/16
to TiddlyWiki
All

The listViaContains macro shown in an previous post does not identify exact matches.
The xMatchTags macro listed below does return exact matches.  It uses the "contain and
"count" macros from Tobias Beer.

My thanks to Tobias and the folks that kindly responded to my question.

Steve Wharton



```
\define xMatchTags(inputTiddler)
<!-- Create a comma separated list of tiddlers whose tags
       are an EXACT match of the the tags for the inputTiddler.

        Features:
        * list all of the tag combinations and the list of tidders per
          combination without having to enumerate each combination
          in advance;
        * tag matches are exact.

       A tidder is an exact match if:
       1.  it has all of the tags that the refTiddler has; and
       2.  it has the same number of tags that the refTiddler
 
       Note: the second check is necessary to eliminate tiddlers that
       have a SUPERSET of the reference tags. For example refTags
       (music, genre) would match Blues (tagged: music, genre) and
       aboutBlues (tagged: music, genre, description).

       Example:
        * <<xMatchTags "blues">>  
        * list all of the tiddlers that have the same tags (e.g., music, genre) as "blues"
        * Returns: afroPop, altCountry, alternative, bluegrass, blues, ... singerSongwriter,

       ------------------------------------------------------------------------------------
       Many thanks to Tobias Beer who developed  the "contains" and
       "count" macros used below. See http://tobibeer.github.io/tw5-plugins/
       ------------------------------------------------------------------------------------
-->

<!-- Make a "copy" of the input tiddler, its tags and its number of tags.
-->
<$set name="refTiddler" value="""$inputTiddler$""">
<$set name="refTagList" filter="[<refTiddler>tags[]sort[]]">
<$set name="refTagCount" filter="[<refTiddler>tags[]count[]]">

<!-- First Filter: Find tiddlers that contain ALL of the tags in refTagList.
       Second Filter: Find tiddlers that have the refTagCount number of tags.
-->
<$list filter="[contains:tags $all<refTagList>] +[sort[title]]" variable="nextMatchingTiddler">
<$list filter="[<nextMatchingTiddler>tags[]count<refTagCount>]">
    <$link to=<<nextMatchingTiddler>> ><<nextMatchingTiddler>></$link>,
    </$list>
</$list>
</$set></$set></$set>
\end
```

Tobias Beer

unread,
Dec 9, 2016, 12:52:26 PM12/9/16
to TiddlyWiki
Hi steve,

May I ask, other than: because I wanted to see if I can,
what's the point of this "[taggedOnly[foo]]" exercise?

Best wishes,

Tobias.

steve

unread,
Dec 9, 2016, 3:02:40 PM12/9/16
to TiddlyWiki
Tobias

I'm glad you asked...

My use case is to be able to do a quick visual scan of the tags for a particular subcategory of my wikis.
For example, the attachment from my Nov 29 email shows the tagging patterns for music related tiddlers.
I could do the same thing for action items, event logs, budget summaries, project summaries.

In short, it makes curation of the tiddlers much easier because I can easily see patterns, inconsistencies,
or poorly tagged tiddlers. It is easier because I do not have to specify the specific tagging patterns a prior
but just run a report and see what is there. Otherwise I would lose track of tiddlers, and worse, unknowingly
repeat them.

Also I think it might be useful to (eventually) create a list filter macro that does the exact matching.

Since I have you "on the line" so to speak is there any way to combine the contains and count macros
into a single filter (instead of two)?

Thanks
Steve Wharton

Tobias Beer

unread,
Dec 11, 2016, 12:36:48 PM12/11/16
to TiddlyWiki
Hi Steve,
 
Thanks for your reply. I still have no idea why you want a list of tiddlers that are "only tagged foo" but not any other tag ...about the process you imagine where this would be useful.

Since I have you "on the line" so to speak is there any way to combine the contains and count macros
into a single filter (instead of two)?

There always is a way, but as things stand, there is no motivation I can think of. Do you experience any problems with chaining the filters you need?

Best wishes,

Tobias. 

steve

unread,
Dec 12, 2016, 10:11:21 AM12/12/16
to TiddlyWiki
Tobias

Hmmm - I see that I am not explaining myself very well.  I am not trying to do a "[taggedOnly[foo]]" exercise, i.e., show all tag combinations for tiddlers that
only have the "foo" tag (this would be meaningless as there is only one such combination).  The exercise is <<listAsTableSortedByTagField filter:"[tag[music]]">>
which is to generate a list all of the unique combination of tags for the "music" tiddlers (i.e., tiddlers that have the tag "music", not the tiddlers that only have
the tag music).

Let's say that I have changed my tagging scheme for music tiddlers several times and I need to check to make sure that the current set of tags is correct, i.e.,
conforms to the current scheme. Rather than have to examine each tiddler by hand I can generate the listAsTableSortedByTagField table which would show
all of the actual  combinations currently in use (see attached file for example).

Features:
* don't have to specify each tag combination a priori in order to view the tiddlers that have that combination;
* only need to look at the actual combinations (rather than all possible combinations of all tags)
* sorting the tags alphabetically and listing them in a table makes it easier to see changes in tagging from one line to the next
* I can focus my attention on the music tiddlers rather than having to sort through all of the tag combinations

Thanks for your persistence in asking questions.

Steve Wharton
all tag combinations for music tiddlers.pdf

Tobias Beer

unread,
Dec 12, 2016, 1:04:52 PM12/12/16
to TiddlyWiki
Hi Steve,


with an option that goes:

contains:<listfield> $exactly[<list>]

In other words, give me all tiddlers where the field <listfield> contains exactly and only the titles specified via <list>.

Would that help?

Best wishes,

Tobias.

steve

unread,
Dec 12, 2016, 4:23:41 PM12/12/16
to TiddlyWiki
Tobias

I think that could work very nicely.

Thanks
Steve Wharton.

Tobias Beer

unread,
Dec 19, 2016, 2:11:16 PM12/19/16
to TiddlyWiki
Hi Steve,
 
I think that could work very nicely.

steve

unread,
Dec 20, 2016, 2:46:23 PM12/20/16
to TiddlyWiki
Tobias

It worked just fine on my initial test case.
I will also try some of the other features that you described in your announcement.

Thanks
Steve Wharton
Reply all
Reply to author
Forward
0 new messages