[TW5] A bug in list-after field behavior

85 views
Skip to first unread message

Arkady Grudzinsky

unread,
Nov 25, 2017, 8:26:08 PM11/25/17
to TiddlyWiki

This TiddlyWiki is an example of a bug in the tagged tiddler sorting algorithm. I created 4 tiddlers: New TiddlerNew Tiddler 1New Tiddler 2, and New Tiddler 3 tagging this tiddler.


Now I use the <$list> widget to show a list of these tiddlers:

<ol>
<$list filter="[is[current]tagging[]]">
<li>
<$link to=<<currentTiddler>>>{{!!title}}</$link>
<$list filter="[is[current]has[list-before]]">list-before: {{!!list-before}}</$list>
<$list filter="[is[current]has[list-after]]">list-after: {{!!list-after}}</$list>
</li>
</$list>
</ol>

This code also shows list-before and list-after fields if they are present.


Now I want the <$list> widget to show the tiddlers in the reverse order. So I created an empty field list-before in New Tiddler 3 to list New Tiddler 3 at the top and added list-after fields to New Tiddler 2 and New Tiddler 1 respectively. The result is below:

  1. New Tiddler 3
  2. New Tiddler list-after: New Tiddler 1
  3. New Tiddler 1 list-after: New Tiddler 2
  4. New Tiddler 2 list-after: New Tiddler 3

Apparently, list-after field does not work in this case as advertised. This behavior is not consistent. In this example, the list-after field works properly. The failure has something to do with the chain of list-after fields. I was trying this on a list of 11 tiddlers, and some tiddlers were ordered properly, and some were not.


By the way, the filter [is[current]has[list-before]] does not show the empty list-before value in New Tiddler 3 although, technically, New Tiddler 3 has the list-before field.

Jed Carty

unread,
Nov 26, 2017, 4:53:44 AM11/26/17
to TiddlyWiki
I think that the list-before and list-after mechanism need to be updated. I spent the last few minutes looking at it and from what I can tell it is a problem with the sorting algorithm. It isn't an appropriate method for sorting lists like this.

Each step does exactly what is expected but it happens one step at a time, it isn't a set of rules for finding an acceptable solution. That is why it doesn't give the output you expect.

A rule-based ordering like you are expecting is a significantly more complex operation than handling each 

What happens in your example: 

The items are processed in the order they appear in the original list.

Original list: New Tiddler, New Tiddler 1, New Tiddler 2, New Tiddler 3

First step: Move New Tiddler to the position after New Tiddler 1 (list after) ->  New Tiddler 1, New Tiddler, New Tiddler 2, New Tiddler 3

Second step: Move New TIddler 1 to the position after New Tiddler 2 (list after) -> New Tiddler, New Tiddler 2, New Tiddler 1, New Tiddler 3

Third step: Move New Tiddler 2 to the position after New Tiddler 3 (list after) -> New Tiddler, New Tiddler 1, New Tiddler 3, New Tiddler 2

Fourth step: Move New Tiddler 3 to the first position (empty list before) -> New Tiddler 3, New Tiddler, New Tiddler 1, New Tiddler 2


I don't know of a way to make a rule-based sorting algorithm that isn't very processor intensive so I don't think there is much we can do to fix the problem.

Arkady Grudzinsky

unread,
Nov 26, 2017, 12:57:59 PM11/26/17
to TiddlyWiki

Thanks. This is a very good explanation. I felt that it has to do with the sequential use of list-after. So, list-after can be reliably used only once within a list. Each subsequent list-after instruction would potentially disrupt the results of the previous instructions. At the very least, it needs to be explained in the “Order of Tagged Tiddlers“ tiddler on TiddlyWiki.

I am not sure how difficult it is to implement, but it appears to me that after each step, the tiddlers should be “linked” and in all subsequent operations moved together:

    • Original list: New Tiddler, New Tiddler 1, New Tiddler 2, New Tiddler 3
    • First step: Move New Tiddler to the position after New Tiddler 1 (list after) -> [New Tiddler 1, New Tiddler], New Tiddler 2, New Tiddler 3. New Tiddler 1 and New Tiddler now form a block for the remaining operations.
    • Second step: Move the block starting with New Tiddler 1 to the position after New Tiddler 2 -> [New Tiddler 2, [New Tiddler 1, New Tiddler]], New Tiddler 3.
    • Third step: Move the block starting with New Tiddler 2 to the position after New Tiddler 3 -> [New Tiddler 3, [New Tiddler 2, [New Tiddler 1, New Tiddler]]]
    • Fourth step: Move New Tiddler 3 to the beginning of the list (no change)

    Cases when list-before or list-after attempt to insert elements inside a block formed by previous instructions may be complicated.  It seems to be an interesting and challenging problem. Perhaps, someone would take this challenge for the fun of it.

    Fortunately, there are other ways to order tiddlers in the lists. In my use case, I build genealogy trees where each tiddler tags two parents and each tiddler shows a tree of ancestors and a tree of descendants. I want the siblings to be shown in the order of seniority. I started adding a birthdate field and use it to sort siblings. But I did not have birthdates for all of the 11 children of my grand grandma who lived in the XIX century. I thought of using the list field to enter the children in the proper order. But these lists must be duplicated for the father and the mother, and the father and the mother may not have the same list of children. The grand grandma had 2 husbands. So, the order information must be stored inside the sibling tiddlers. This is when I tried to use the list-after field and encountered this problem. I ended up creating a special field order in sibling tiddlers and use it to sort the lists of descendants.

    Thanks again for looking into it.

    -- Arkady

    Reply all
    Reply to author
    Forward
    0 new messages