Removing chars from tiddler title: issue with tiddler overwritting

140 views
Skip to first unread message

Mohammad

unread,
Feb 17, 2019, 5:37:34 PM2/17/19
to TiddlyWiki
The below code is developed to remove n characters from the beginning of a tiddler title.

Test only on https://tiddlywiki.com/prerelease/


Title: macro/remchars
Tag: $:/tags/Macro
\define remove-from-begining-tiltle-bulk(myfilter, n:"0")
<$list filter="[<__n__>] -0" variable=null>
<$list filter=<<__myfilter__>> variable="item">
<$list filter="""[<item>split[]rest[$n$]join[]]""" variable="newTitle">
<$list filter="[<newTitle>]  -[has[title]] -[[]]" variable="ignore">
  <$action-setfield      $tiddler=<<item>> title=<<newTitle>> />
  <$action-deletetiddler $tiddler=<<item>> />
</$list>  
</$list>
</$list>
</$list>
\end


Assume you have three  tiddlers like below, both tagged with xx

a1
b1
cd


Then call the macro as below

Test
<$button> Do it
<<remove-from-begining-tiltle-bulk myfilter:"[tag[xx]]" n:1>>
</$button>


 
The above code should detect that removing first char will overwrite a1, b1 and so as four list widget in the code (line 5)
is responsible to prevent this!! seems it FAILS to do the job!
It overwrites a1 and b1 and produces tiddler 1.

What is going wrong here?


--Mohammad

Mal

unread,
Feb 18, 2019, 5:53:47 AM2/18/19
to TiddlyWiki
Mohammad,

I've been experimenting to try to figure out why this isn't working, but have not yet succeeded.

It seems that on the second pass through the inner list the filter is not detecting that we've already created a tiddler with the "1" title, so it goes ahead and creates another one that overwrites the first.

Note that I tried an alternative to your "[<newTitle>] -[has[title]] -[[]]" filter, using "[<newTitle>!is[tiddler]]" instead, but it had the same problem.

Hopefully, someone with a better understanding of the inner workings of TiddlyWiki will be able to explain the problem.

Mal

S. S.

unread,
Feb 18, 2019, 6:44:06 AM2/18/19
to TiddlyWiki
Mohammad,

I remember having an issue like this myself once, and this is how I solved it.
I cannot remember WHY it works this way.

\define remove-from-begining-tiltle-bulk(myfilter, n:"0")
<$list filter="[<__n__>] -0" variable=null>
<$list filter=<<__myfilter__>> variable="item">
<$list filter="""[<item>split[]rest[$n$]join[]]""" variable="newTitle">
<$list filter="[<newTitle>]  -[has[title]] -[[]]" variable="ignore">

<<actions1>>
<<actions2>>

</$list></$list></$list></$list>
\end

\define actions1()
<$action-setfield      $tiddler=$(item)$ title=$(newTitle)$ />
\end

\define actions2()
<$action-deletetiddler $tiddler=$(item)$ />
\end


<$button> Do it
<<remove-from-begining-tiltle-bulk myfilter:"[tag[xx]]" n:1>>
</$button>

Hope that helps.

Regards

S. S.

unread,
Feb 18, 2019, 7:28:10 AM2/18/19
to TiddlyWiki
Ha!
This was not the way I solved it.
This won't work.
I'll have to look for it.
Sorry!

Mohammad

unread,
Feb 18, 2019, 7:45:41 AM2/18/19
to TiddlyWiki
Thanks Mal,
 That's correct. 
This line
<$list filter="""[<item>split[]rest[$n$]join[]]""" variable="newTitle">

creates two 1, I expect to send only one as output! Note <$list filter="1 1 2 3"> returns 1 2 3 NOT 1 1 2 3.
Also this line a you said does not detect the tiddler existed

<$list filter="[<newTitle>]  -[has[title]] -[[]]" variable="ignore">

So, as it proceeds, it create tiddler 1 from a1 and in the second loop it overwrites it by removing b from b1  
I tried to display intermediate results and strangely it overwrites the result of previous run!


--Mohammad

Mohammad

unread,
Feb 18, 2019, 7:48:53 AM2/18/19
to TiddlyWiki
Thanks S.S, it does not work.
I explained it above.

Best
Mohammad

Mark S.

unread,
Feb 18, 2019, 10:59:00 AM2/18/19
to TiddlyWiki

List widgets look deceptively like for-next loops in other languages, but they don't work that way (or at least I don't think they do). At the moment you click the button, there is essentially already a list of things -- a snapshot -- that will be activated, and that list is not changed on the fly. So you need to have a complete list of actions you will take before you press the button. Or, another way to look at it, you can't change things in tiddlers that will change the outcome of the filters. From time to time I mention that javascript is easier. This is what I mean. In JS you can run a loop that changes the conditions that terminate the loop.  Oh well.

Here's what I've come up with. It worked. Once. It first goes through and makes a list of all the suffixes that will be created by your process. Then it turns that list into a title list. Then it feeds the resulting list into a filter that checks if there are more than one tiddlers (e.g. two tiddlers) that will be impacted. If there are more than 1, than it does nothing. Otherwise it does the changes. It probably needs to be cleaned up, since there's bits I didn't end up using.

HTH

-- Mark

\define suffix-actions()
<$list filter="[tag[xx]suffix<sfx>]" variable="item">
 
<$action-setfield      $tiddler=<<item>> title=<<sfx>> />
  <$action-deletetiddler $tiddler=<<item>> /
>
</$list>
\end
\define makelink() [[$(newTitle)$]]
\define makeregexp() ^.{$(n)$}$(sfx)$$
\define generate-suffixes(myfilter, n:"0")

<$list filter="[<__n__>] -0" variable=null>
<$list filter=<<__myfilter__>> variable="item">
<$list filter="""[<item>split[]rest[$n$]join[]]""" variable="newTitle">
<$text text=<<makelink>>/>
</$list>
</
$list>
</$list>
\end
\define deprefix-title(myfilter,num)
<$button>
Delete $num$ chars
<$vars n="$num$" >
<$wikify text="""<<generate-suffixes myfilter:"$myfilter$" n:"$num$">>""" name="outputs" output="formattedtext" mode="block">
<$list filter="[subfilter<outputs>]" variable="sfx">
<$list filter="$myfilter$ +[suffix<sfx>limit[2]count[]regexp[2]]" emptyMessage=<<suffix-actions>> variable="cnt">
</
$list>
</$list>
</
$wikify>

</$vars>
</
$button>
\end

<<deprefix-title "[tag[xx]]" "1">>



Mohammad

unread,
Feb 18, 2019, 11:21:29 AM2/18/19
to TiddlyWiki
Hi Mark,
Many thanks for your efforts. That works!
Let go into it and see how works! I may have questions.

Cheers
Mohammad


Mohammad

unread,
Feb 18, 2019, 12:32:45 PM2/18/19
to TiddlyWiki
Mark 

  • what does the below line mean?
<$list filter="$myfilter$ +[suffix<sfx>limit[2]count[]regexp[2]]" emptyMessage=<<suffix-actions>> variable="cnt">

I don't understand the filter,how does it work?

  • Seems the below macro is not needed
\define makeregexp() ^.{$(n)$}$(sfx)$$


  • Why we need to makelink in
\define makelink() [[$(newTitle)$]]

and use it here:
<$text text=<<makelink>>/>





--Mohammad

Mark S.

unread,
Feb 18, 2019, 12:46:20 PM2/18/19
to TiddlyWiki


On Monday, February 18, 2019 at 9:32:45 AM UTC-8, Mohammad wrote:
Mark 

  • what does the below line mean?
<$list filter="$myfilter$ +[suffix<sfx>limit[2]count[]regexp[2]]" emptyMessage=<<suffix-actions>> variable="cnt">

I don't understand the filter,how does it work?


It's checking how many items have the same suffix that would be created by eliminating characters. If there are two or more items, no action happens. If there is only 1 item, then the action happens.


 
  • Seems the below macro is not needed
\define makeregexp() ^.{$(n)$}$(sfx)$$



Yes. I mentioned that there was some clean-up. I forgot that I could use the suffix operator to test for the endings.
 
  • Why we need to makelink in
\define makelink() [[$(newTitle)$]]

and use it here:
<$text text=<<makelink>>/>



Try it without and see if it works. But I think it's needed because it's going to be wikified. So if you didn't wrap up the text the output would be generated as pure text. So if you had tiddlers a1, b1, cd and "ab 1" they would get generated as a1 b1 cd ab 1 .  Oh! In your testing, be sure to include a tiddler with spaces in the name. In my testing I added "ab 1". If you could guarantee that your tiddlers never had spaces in their titles than the code could be much simpler.

Thanks!
-- Mark



Mohammad

unread,
Feb 18, 2019, 1:03:02 PM2/18/19
to TiddlyWiki
Thanks Mark,
 I will make some tests and then return to you by my results.

I appreciate if other interested in this, help me with testing the Mark solution.
Also the list "pros and cons" is good to by documented by S.S. in his ongoing project: TW for beginners.


Cheers
Mohammad

Mohammad

unread,
Feb 18, 2019, 1:03:37 PM2/18/19
to TiddlyWiki
S.S,
 Have a look at Mark explanation here

--Mohammad

Mohammad

unread,
Feb 18, 2019, 1:11:18 PM2/18/19
to TiddlyWiki
Mark, I think I need to removing the leading and trailing spaces.
Having space in the title may cause in leading or trailing spaces and this make confusion and is meaningless
like having a title like " test"   or "test ".


-Mohammad

Mohammad

unread,
Feb 18, 2019, 2:34:02 PM2/18/19
to TiddlyWiki
Mark,
 I changed the below line
<$list filter="""[<item>split[]rest[$n$]join[]]""" variable="newTitle">



as

<$list filter="""[<item>split[]rest[$n$]join[]trim[]]""" variable="newTitle">

seems I can overcome leading and trailing spaces! Thanks to TW5.1.20 string operators.

--Mohammad

Mohammad

unread,
Feb 18, 2019, 5:05:51 PM2/18/19
to TiddlyWiki
See this in action:


Thanks Mark.

--Mohammad

S. S.

unread,
Feb 18, 2019, 6:30:38 PM2/18/19
to TiddlyWiki

Thanks Mohammad.
It looks like we will need an Advanced TiddlyWiki series to incorporate Mark's explanation!
I will make a note of it for future reference.

TonyM

unread,
Feb 18, 2019, 9:18:41 PM2/18/19
to TiddlyWiki
Mohammad,

From previous experience, given the title of a tiddler is its key, and when editing anything about a tiddler especially its title it is handled with a draft.of tiddler and draft.of title until commiting changes. I would recommend simply cloning the old tiddler to the newly named tiddler using an appropriate new tiddler action which will add an increment if the result already exists, and you can freely delete the original tiddler. You can even take steps to preserve the created date if you must.

Regards
Tony

Mal

unread,
Feb 18, 2019, 11:41:30 PM2/18/19
to TiddlyWiki
Actually, this raises an interesting point - the split[] operator with no argument produces a space delimited list of single characters, but this list does not have the usual uniqueness property of other filter lists and it can include a space as an item .  How can a space be an item in a space delimited list?  This behaviour can be demonstrated in the following examples:

<$list filter="[[a string with spaces]split[]join[]]"/>

Produces: "a string with spaces", with spaces and duplicate characters preserved, and:

<$list filter="[[a string with spaces ]split[]join[-]]"/>

Produces: "a- -s-t-r-i-n-g- -w-i-t-h- -s-p-a-c-e-s- ", including the space on the end.  Hence Mohammad's need to add the trim[] operator.

[[1111]split[]sum[]]

Gives an answer of 4, while:

"1 1 1 1" +[sum[]]

Gives an answer of 1 because duplicates are eliminated from the list.

I wonder if this behaviour is by design, or could it change in the 5.1.20 release or future versions, thus causing these types of hacks to fail.

Mal

Mohammad

unread,
Feb 18, 2019, 11:53:20 PM2/18/19
to TiddlyWiki
Mal,

 Many thanks for clarification. Hope Jeremy see this post and notify us if it is by design.

Cheers
Mohammad

Mohammad

unread,
Feb 19, 2019, 12:02:36 AM2/19/19
to TiddlyWiki
Your point is added to TW-Scripts
[Highlighted point below]

On Monday, February 18, 2019 at 2:23:47 PM UTC+3:30, Mal wrote:

Mohammad

unread,
Feb 19, 2019, 12:17:19 AM2/19/19
to TiddlyWiki
Tony
Your solution seems working. The problem is, I need to see how to duplicate all tags and fields from old one to the new one and does this process is shorter and more efficient than previous one or not. But seems simpler from logic point of view.

Thank you for your help.
Mohammad

TonyM

unread,
Feb 19, 2019, 2:15:25 AM2/19/19
to TiddlyWiki
Mohammad,

You need to pass named existing values to the new tiddler or treat the source tiddler as the template, I will try and share the code. Alternativly you can itterate all fields[] and transfer each field or selectivly.

I never quite suceeded in replicating and modifying the clone button.

I am currently finalising a new tiddler from template macro I can share soon.

Regards
Tony

Mohammad

unread,
Feb 19, 2019, 3:18:01 AM2/19/19
to TiddlyWiki
Tony!
It absolutely worth to have a clone button to use a tiddler template.

--Mohammad

Mohammad

unread,
Feb 20, 2019, 1:39:27 PM2/20/19
to TiddlyWiki
Mark,
 Do I need to keep output="formattedtext" mode="block"
What is the objective of mode="block" in this cae?

--Mohammad

On Monday, February 18, 2019 at 7:29:00 PM UTC+3:30, Mark S. wrote:
Reply all
Reply to author
Forward
0 new messages