produce zero padded number using RANGE operator

130 views
Skip to first unread message

Mohammad

unread,
Feb 15, 2019, 11:18:05 AM2/15/19
to TiddlyWiki
Asked by Josiah here:


To produce numbers zero padded like

001
002
003
...

099
100

Here is a macro to do that

\define zeropad-range(n:10)
<$list filter="[range[1,$n$]]" variable=x >
<$reveal type="lteq" default=<<x>> text="9" >
<$text text= {{{[<x>addprefix[00]]}}} />
</$reveal>
<$reveal type="gt" default=<<x>> text="9" >
<$text text= {{{[<x>addprefix[0]]}}} />
</$reveal>
</$list>
\end

Example

001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017018 019 020 021 022 023 024 025

The below macro works up to 1000

\define zeropad-range4(n:10)
<$list filter="[range[1,$n$]]" variable=x >
<$reveal type="lteq" default=<<x>> text="9" >
<$text text= {{{[<x>addprefix[000]]}}} />
</$reveal>
<$reveal type="gt" default=<<x>> text="9" >
<$reveal type="lt" default=<<x>> text="99" >
<$text text= {{{[<x>addprefix[00]]}}} />
</$reveal>
</$reveal>
<$reveal type="gt" default=<<x>> text="99" >
<$text text= {{{[<x>addprefix[0]]}}} />
</$reveal>
</$list>
\end



--Mohammad

Mark S.

unread,
Feb 15, 2019, 11:27:17 AM2/15/19
to TiddlyWiki
Like others in the forum, I'm finding that search links do not work. You had a post earlier (which I can't get to) about new string operators being added in the pre-release. But there's no documentation for string operators -- only the new math operators.

I'm wondering if, with the new string operators, it would be possible to make a simpler, more concise padding macro that could provide any level of padding?

Could you share any information or documentation you've uncovered about the string operators?

Thanks!
-- Mark

Mohammad

unread,
Feb 15, 2019, 11:31:53 AM2/15/19
to TiddlyWiki
Mark,
 String operation are added to TW - prerelease, see below

By the way, please let me know your opinion on the above macros.

--Mohammad

Eric Shulman

unread,
Feb 15, 2019, 12:18:15 PM2/15/19
to TiddlyWiki
On Friday, February 15, 2019 at 8:18:05 AM UTC-8, Mohammad wrote:
To produce numbers zero padded like
001 002 003 ... 099 100
Here is a macro to do that
\define zeropad-range(n:10)
<$list filter="[range[1,$n$]]" variable=x >
<$reveal type="lteq" default=<<x>> text="9" >
<$text text= {{{[<x>addprefix[00]]}}} />
</$reveal>
<$reveal type="gt" default=<<x>> text="9" >
<$text text= {{{[<x>addprefix[0]]}}} />
</$reveal>
</$list>
\end
The below macro works up to 1000
\define zeropad-range4(n:10)
<$list filter="[range[1,$n$]]" variable=x >
<$reveal type="lteq" default=<<x>> text="9" >
<$text text= {{{[<x>addprefix[000]]}}} />
</$reveal>
<$reveal type="gt" default=<<x>> text="9" >
<$reveal type="lt" default=<<x>> text="99" >
<$text text= {{{[<x>addprefix[00]]}}} />
</$reveal>
</$reveal>
<$reveal type="gt" default=<<x>> text="99" >
<$text text= {{{[<x>addprefix[0]]}}} />
</$reveal>
</$list>
\end

The following filter sequence will generate a list of zero-padded numbers 001-999
[range[9]addprefix[00]] [range[10,99]addprefix[0]] [range[100,999]]

Thus, to produce the same *display* output as your macro, we can just write:
{{{ [range[9]addprefix[00]] [range[10,99]addprefix[0]] [range[100,999]] }}}

-e



Mohammad

unread,
Feb 15, 2019, 12:36:26 PM2/15/19
to TiddlyWiki
That's true Eric,
 But we do not know in advance what is the number, and it is given by user!
So if n is a variable, then how we can generate these numbers?

--Mohammad

Mark S.

unread,
Feb 15, 2019, 12:57:41 PM2/15/19
to TiddlyWiki
Hi Mohammad,

Your macros show a deep knowledge of the tools in TW.

I'm a bit concerned that each level of indenture requires another chunk of code, which may be hard to maintain.

The thing is, this sort of thing is easy if you have the right text tools. We need the concat function and a substr function. Unfortunately the new tools lack the substr. How do you feel about using javascript macros (and filters) in TW-commander?

I just thought of another approach. Maybe. You could use a list filter and call it recursively. Each time you prefix a "0". When the length (new math function?) reaches the padded number length, the recursion ends and the result is sent back. The problem here is that I don't the parameters for the length function. The length would have to be compared to the target length and the only comparison tool is the revealwidget.

-- Mark

Mohammad

unread,
Feb 15, 2019, 1:17:54 PM2/15/19
to TiddlyWiki
Thanks Mark, 

I tried to do not touch JS in Tiddler Commander and also keep code simple! (Of course I know very little java script) 
but seems I have to use JS. For example TW has nothing with string search/replace and the JS code you provided do the job very well.

The macro I proposed above works for me but, modifying the bulk tiddler creator makes code complex and difficult to understand.

--Mohammad

@TiddlyTweeter

unread,
Feb 15, 2019, 1:52:47 PM2/15/19
to TiddlyWiki
Mohammad,

Some of the JS code in this may be helpful?

https://ibnishak.github.io/Tesseract/pluginsandmacros/index.html#Action-JSONtid

This utility by Riz was created to auto-name and number with padded prefix. It was specifically aimed to convert JSON collections of Tiddlers without title fields to be imported.

Maybe parts of it are useful?

Best
Josiah

Mark S.

unread,
Feb 15, 2019, 1:52:52 PM2/15/19
to TiddlyWiki
D'oh ... could use regexp operator to compare the length. Maybe.

-- Mark

Eric Shulman

unread,
Feb 15, 2019, 2:01:43 PM2/15/19
to tiddl...@googlegroups.com
On Friday, February 15, 2019 at 9:36:26 AM UTC-8, Mohammad wrote:
 But we do not know in advance what is the number, and it is given by user!
So if n is a variable, then how we can generate these numbers?

If we DID know the number in advance, we could just use it in the operand of the range[...]

For example, suppose the desired number is, say, 256.  Then we could just modify the filter be:
[range[9]addprefix[00]] [range[10,99]addprefix[0]] [range[100,256]]

However, since you want the number to be "given by user", we need to use a different approach.  Instead of hard-coding the number, we can use the limit[...] filter.  Let's suppose the desired number is in variable called "max".  Then we could write:
[range[9]addprefix[00]] [range[10,99]addprefix[0]] [range[100,999] +[limit<max>]

and if the desired number is in a tiddler (e.g. $:/temp/input/userlimit, as a result of user input), we could write:
[range[9]addprefix[00]] [range[10,99]addprefix[0]] [range[100,999] +[limit{$:/temp/input/userlimit}]

-e

note: edited to fix missing syntax in last two examples.

Mohammad

unread,
Feb 15, 2019, 2:25:59 PM2/15/19
to TiddlyWiki
Hi Eric,
 You are amazing!
Yep, that's the solution using limit[] or first[] operators.

I did the solution by storing the padded number in a list field of a tiddler and then using enlist.
See here: file:///G:/TW/TW-Scripts/Scripts%20in%20TW%205.1.20-pre.html#100.50

But your solution is much superior. You did the magic!


Thank you INDEED!

-- Mohammad

Mohammad

unread,
Feb 15, 2019, 2:28:24 PM2/15/19
to TiddlyWiki
Added to TW-Scripts.

Mark S.

unread,
Feb 15, 2019, 2:34:30 PM2/15/19
to TiddlyWiki
A little late to the party. Here's my version, that takes any number (or character) for padding:

\define padder-reg() ^$(len)$$
\define padder(str,len,chr:"0")
<$vars len=<<__len__>>>
<$list filter="[<__str__>addprefix<__chr__>]" variable="padstr">
<$list filter="[<padstr>length[]!regexp<padder-reg>]" emptyMessage=<<padstr>>>
<$macrocall $name="padder" str=<<padstr>> len=<<__len__>> chr=<<__chr__>>/>
</
$list>
</$list>
</
$vars>
\end

<<padder "25" "15">>

The weakness is if the starting number has more characters than the pad number, it will never complete.

-- Mark

Mohammad

unread,
Feb 15, 2019, 2:59:05 PM2/15/19
to TiddlyWiki
Thanks Mark.
I enjoyed this discussion and learned alot!

--Mohammad

Mal

unread,
Feb 15, 2019, 10:56:33 PM2/15/19
to TiddlyWiki
This seems to work in tiddlywiki.com/prerelease/:

<$vars number="256" length="5">
{{{ [
<number>addprefix[000000]split[]last<length>join[]] }}}
</$vars>


Note that it will left truncate the number if it is already longer than the desired length.

Mal

Mark S.

unread,
Feb 15, 2019, 11:51:36 PM2/15/19
to TiddlyWiki
That's very clever. Splitting on "nothing". And apparently, somewhat surprisingly, the resulting array doesn't collapse like it frequently does in filters.

-- Mark

Mal

unread,
Feb 16, 2019, 1:05:27 AM2/16/19
to TiddlyWiki


On Saturday, 16 February 2019 14:51:36 UTC+10, Mark S. wrote:
That's very clever. Splitting on "nothing". And apparently, somewhat surprisingly, the resulting array doesn't collapse like it frequently does in filters.


Yes, I'm not sure why this works, given the usual uniqueness property of filter lists, as discussed in issue #3757.

It would be nice to have some sort of substring operator to be able to do this without the gymnastics.  On the other hand, a padding operator or even a number formatting operator would also be nice, but I think Jeremy has already commented on keeping the list of mathematics/string operators to a minimum.

Mal

Mohammad

unread,
Feb 16, 2019, 1:21:01 AM2/16/19
to TiddlyWiki
Mal,

This is really short and beautiful, I don't understand the logic!

--Mohammad

Jeremy Ruston

unread,
Feb 16, 2019, 3:16:07 AM2/16/19
to tiddl...@googlegroups.com
Hi Mal

It would be nice to have some sort of substring operator to be able to do this without the gymnastics.  On the other hand, a padding operator or even a number formatting operator would also be nice, but I think Jeremy has already commented on keeping the list of mathematics/string operators to a minimum.

Just to add that that was particularly with reference to adding statistics functions. My concern was that there potentially a lot of them, and so I think it makes more sense for statistics to be in their own plugin.

I've no objection to adding a padding operator. I think we should support padding with any character, not just zeros, and somehow should support both left and right padding.

Best wishes

Jeremy.


Mal

--
You received this message because you are subscribed to the Google Groups "TiddlyWiki" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywiki+...@googlegroups.com.
To post to this group, send email to tiddl...@googlegroups.com.
Visit this group at https://groups.google.com/group/tiddlywiki.
To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywiki/674bd29e-6e4d-4087-bb9e-8481ce85a1a8%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

TonyM

unread,
Feb 16, 2019, 6:41:51 AM2/16/19
to TiddlyWiki
Mohammad,

I am sorry, I am so late to this conversation. But I had requested such zero fill, previously on github to prerelease of the Range operator, but found a solution that suited me. I planned to make make no claim for it to be better or worse than other examples, but perhaps I can :)

<$list filter="[range[.00001,.00100,.00001]removeprefix[0.]]">

</$list>


Do I win?

Regards
Tony

Mohammad

unread,
Feb 16, 2019, 7:29:23 AM2/16/19
to tiddl...@googlegroups.com
Hello Tony!
You solution is a clever one! I wrapped it in a macro and got the correct results as below

\define mac(n)
<$list filter="[range[.0001,.1,.0001]removeprefix[0.]limit[$n$]]">
<<currentTiddler>>
</$list>
\end



Examples

<<mac 5>>

0001 0002 0003 0004 0005




Example ii

<<mac 200>>



0001 0002 0003 0004 0005 0006 0007 0008 0009 0010 0011 0012 0013 00140015 0016 0017 0018 0019 0020 0021 0022 0023 0024 0025 0026 0027 00280029 0030 0031 0032 0033 0034 0035 0036 0037 0038 0039 0040 0041 00420043 0044 0045 0046 0047 0048 0049 0050 0051 0052 0053 0054 0055 00560057 0058 0059 0060 0061 0062 0063 0064 0065 0066 0067 0068 0069 00700071 0072 0073 0074 0075 0076 0077 0078 0079 0080 0081 0082 0083 00840085 0086 0087 0088 0089 0090 0091 0092 0093 0094 0095 0096 0097 00980099 0100 0101 0102 0103 0104 0105 0106 0107 0108 0109 0110 0111 01120113 0114 0115 0116 0117 0118 0119 0120 0121 0122 0123 0124 0125 01260127 0128 0129 0130 0131 0132 0133 0134 0135 0136 0137 0138 0139 01400141 0142 0143 0144 0145 0146 0147 0148 0149 0150 0151 0152 0153 01540155 0156 0157 0158 0159 0160 0161 0162 0163 0164 0165 0166 0167 01680169 0170 0171 0172 0173 0174 0175 0176 0177 0178 0179 0180 0181 01820183 0184 0185 0186 0187 0188 0189 0190 0191 0192 0193 0194 0195 01960197 0198 0199 0200




It simply works up to 999!


Cheers
Mohammad

Mal

unread,
Feb 16, 2019, 8:15:59 PM2/16/19
to TiddlyWiki


On Saturday, 16 February 2019 18:16:07 UTC+10, Jeremy Ruston wrote:
 
I've no objection to adding a padding operator. I think we should support padding with any character, not just zeros, and somehow should support both left and right padding.

A generic padding function implemented as a filter operator presents some challenges to pass in the necessary arguments: padded width, left or right padding, padding character.  Maybe, as an alternative we could have a format filter operator that uses something similar to the Python string format function, so we could have:
  • ...format[":<06d"] number - left align - right padded with "0".
  • ...format[":>06d"] number - right align - left padded with "0"
  • ...format[":>10s"] string right aligned - padded with spaces.
  • ...format[":>_10s"] string right aligned - padded with "_".
  • etc.
Given that our numbers are already strings, we may not really need "d" or "s" and just default to string type.

I would be interested in any other suggestions.

Mal


S. S.

unread,
Feb 16, 2019, 9:59:16 PM2/16/19
to TiddlyWiki

Very nifty!
Reply all
Reply to author
Forward
0 new messages