You are not logged in.
Elsewhere it was written that Renamer belonged to the top 3 file renaming tools. I think this is a precise qualification; i.e., one cannot put any of the top 3 on the unique place 1. Actually I know of only one other program in the top 3 but presumably that is because I use Windows only. That other program is Nummerieren und Ändern (and its predecessor Eine schnelle Nummer), which I used for several years but for which there is absolutely no Vista support (its basics work fine but it would too shortshighted to rely on only one program that might not be continued in the long run).
Let me make a quick comparison, ++ / + / - = (great) advantage / disadvantage.
Renamer:
+ plainly simple front level of the GUI
+ memorized rulesets
+ almost arbitrary user extensions
- restricted hardcoded abilities
- not so simple deep level GUI
Nummerieren und Ändern
++ all hardcoded abilities for file renaming and folder creation one might wish
- somewhat tricky deep level GUI
Summary:
Nummerieren und Ändern offers quite some more hardcoded abilities than Renamer, where one has to use scripts. E.g., mighty alphanumeric serialization is simply already present in Nummerieren und Ändern (but every time one has to think afresh how to use the related GUI).
Hint: Renamer has the potential to reach place 1 if it hardcodes more features in a then still simple GUI. :):)
Offline
prologician, although our scripts are very good POCs, they are lacking a thorough validation, error handling, and do not fit completely to the whole current Serialize dialog yet. The other question of which script to rely on is even trickier; they all have their great merits. I.e., it feels like that the advantages of all should be offered but that requires 2 or 3 further options in the dialog and the related programming.
Offline
To be honest I haven't notice the difference... Just tested, and prologician's script (with pattern 'BBb' and initial string 'Z9x') gives ZA0 after Z9z...
Ah, that's the vital difference right there! 'Z9x' is "upper case, digit, lower case", i.e. pattern 'Lnl'. Try it now and you'll get '0A0a' after 'Z9z'.
It looks a bit funny with 'a' as initial string and 'A' as overflow char (or other way round). It's quite strange with digits as overflow... It seems to work the other work round then. x,y,z, 0a, 0b, 0c... 9x, 9y, 9z, 00a, 00b, 00c...
Well, prologician's script has digits overflow by default as well, though that can be changed easily. A matter of choice, I guess.
However, if one restricts the letterset to, say, {a, b} by lcase_high = 98 and then uses an initstring with also other letters, say, MyNamea, then one is reminded of Pacman: The name is eaten up in a peculiar manner:( Such does not happen with prologician's or my scripts.
I suppose you're referring to your script here? Interesting use case... Let's check it out, shall we? You want to restrict the lower case charset to just 'ab', and use 'MyNamea' as the initial string. The other charsets like upper case and digits are to be left untouched.
Now the changes to my code are:
lcase_high = 98; // =b, instead of 122=z
initstr = 'MyNamea';
The output is:
MyNamea
MyNameb
MyNbbba
MyNbbbb
MyOaaaa
MyOaaab
MyOaaba
MyOaabb
MyOabaa
MyOabab
MyOabba
Whoops! I see what you mean about Pacman! (The output is correct BTW, in the sense that it follows the code logic faithfully. Whether it is absurd or not is for the user to decide.)
Now the changes to your script:
INITIAL_STRING = 'MyNamea';
LETTERS_L = 'ab';
And the corresponding output is:
000AAaa
000AAab
000AAba
000AAbb
000ABaa
000ABab
000ABba
000ABbb
000ACaa
000ACab
000ACba
Umm, how is that any better? Way I see it, both scripts make various assumptions about alphanumeric serialization and behave weirdly when fed with weird inputs. A simple case of GIGO, i.e. Garbage In Garbage Out my friend!
I agree though that more options for where to insert or the extension should be added but do not like your selective choice here. It is more a proof of concept so far.
I never said it wasn't! And if you don't like my choices, feel free to edit the code! It's completely open source and has no restrictions (or guarantees!) whatsoever.
Practically speaking, users will find editing letterset strings easier than ascii code numbers. But... when alphaserialize becomes hardcoded, such does not matter any longer.
Meh. I wanted to improve my skills and write code that would be able to increment an alphanumeric sequence in the same way as numbers, i.e. units place first, then tens, then hundreds etc. In numbers, when 9 is reached at a particular position, it rolls over to 0 and the next higher position starts off with 1 if it doesn't exist already, else the existing value is incremented by 1. I managed to write code that does just that for an alphanumeric sequence, so that's about it. I have no practical use for the code, so I'm not tempted to go on adding new features or more robust error-checking etc. That is an exercise for someone who will actually use it!
The other question of which script to rely on is even trickier; they all have their great merits. I.e., it feels like that the advantages of all should be offered but that requires 2 or 3 further options in the dialog and the related programming.
Oh that's really easy! In the absence of an inbuilt feature, the script that should be used is one that best does what the user wants. The user should try each one and then decide. In fact, I feel having different scripts is in a way better, for the end result is not confined to what one person feels should be the implementation, but instead there is a choice available which is generally a good thing to have.
Last edited by Andrew (2009-02-19 16:50)
Offline
Summary of all Pascal scripts in their latest versions:
Arbitrarily many filenames are possible. The initial constants in the scripts can be altered, e.g., one might change a letterset to produce hexadecimal numbers by specifying it as '0123456789ABCDEF'. In particular, one should modify the initial string and can modify the step size. One should be reasonable though; e.g., using letters in the initial string that are not in the used letterset(s) may lead to strange behaviour.
prologician's script:
Requires specification in ALPHA_FORMAT of the used letterset per digit of the initial string. If a particular character mismatches, it is replaced with the first character in the letterset specified by the format string (that is, if initial string and format string don't agree, format string wins.) Mixed lettersets (counting numbers and letters per digit) are possible. Uses variable, increasing length like a..z then aa..az... Excess leading digits are numbers. The new filename appends serialization after the old filename but before the extension.
const
ALPHA_FORMAT = 'lL';
STEP_SIZE = 1;
INITIAL_STRING = 'bA';
LETTERS_L = 'abcdefghijklmnopqrstuvwxyz';
LETTERS_U = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
NUMBERS = '0123456789';
BOTH_NL = '0123456789abcdefghijklmnopqrstuvwxyz';
BOTH_NU = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// For each digit in ALPHA_FORMAT, use
// l for lower case letters,
// L for upper case letters,
// n for numbers,
// b for both numbers and lower case letters,
// B for both numbers and upper case letters.
// Excess leading digits are filled with numbers.
var
SerialCount: Array of Integer; // 0-indexed thingamabob
function NthInFormatToLetterset(const Format: String; const I: Integer): WideString;
var
format_char: Char;
begin
if (I >= length(Format)) then
begin
result := NUMBERS;
exit
end;
format_char := Format[length(Format) - I];
case format_char of
'l': result := LETTERS_L;
'L': result := LETTERS_U;
'n': result := NUMBERS;
'b': result := BOTH_NL;
'B': result := BOTH_NU;
else result := NUMBERS
end;
end;
function IndexInString(const letter: WideChar; const wholestring: WideString): Integer;
var
I: Integer;
begin
result := 1; //Not correct in general, but useful for this program
for I := 1 to length(wholestring) do
begin
if (wholestring[i] = letter) then
begin
result := I;
exit
end;
end;
end;
procedure TranslateToArray(const initial: WideString);
var
I: Integer;
letterset: WideString;
begin
for I := 0 to length(SerialCount)-1 do
begin
letterset := NthInFormatToLetterset(ALPHA_FORMAT, I);
SerialCount[i] := IndexInString(initial[length(initial) - i], letterset) - 1;
end;
end;
procedure CheckCarries();
var
I: Integer;
letterset: WideString;
begin
for I := 0 to length(SerialCount)-1 do
begin
letterset := NthInFormatToLetterset(ALPHA_FORMAT, I);
if (SerialCount[i] >= length(letterset)) then
begin
if (I = length(SerialCount) - 1) then
begin
SetLength(SerialCount, length(SerialCount) + 1);
SerialCount[I+1] := -1
end;
SerialCount[I+1] := SerialCount[I+1] + (SerialCount[i] div length(letterset));
SerialCount[i] := SerialCount[i] mod length(letterset);
end;
end;
end;
function AlphaSerialize(): WideString;
var
I: Integer;
letterset: WideString;
begin
result := '';
for I := 0 to length(SerialCount)-1 do
begin
letterset := NthInFormatToLetterset(ALPHA_FORMAT, I);
result := letterset[SerialCount[i] + 1] + result;
end;
end;
var
Initialized: Boolean;
InitString: WideString;
begin
if not Initialized then
begin
InitString := INITIAL_STRING;
if (length(InitString) = 0) then
begin
SetLength(SerialCount, 1);
SerialCount[0] := 0;
end
else
begin
SetLength(SerialCount, length(InitString));
TranslateToArray(InitString);
end;
Initialized := True;
end;
CheckCarries();
FileName := WideExtractBaseName(FileName) + AlphaSerialize() + WideExtractFileExt(FileName);
SerialCount[0] := SerialCount[0] + STEP_SIZE;
end.
report's script:
Changes prologician's script so that the letterset is derived automatically from the initial string. Each digit is either a lower case letter, upper case letter, or number. If the initial string is long enough, then one gets a fixed width of all filenames; otherwise excess leading digits are numbers. The new filename appends serialization after the old filename but before the extension.
const
STEP_SIZE = 1;
INITIAL_STRING = 'aa';
LETTERS_L = 'abcdefghijklmnopqrstuvwxyz';
LETTERS_U = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
NUMBERS = '0123456789';
// Excess leading digits are filled with numbers.
var
SerialCount: Array of Integer; // 0-indexed
function IsLowerCaseLetter(const TestedChar: String): Boolean;
var
I: Integer;
begin
result := FALSE;
for I := 1 to length(LETTERS_L) do
begin
if (TestedChar = LETTERS_L[i]) then
begin
result := TRUE;
exit;
end;
end;
end;
function IsUpperCaseLetter(const TestedChar: String): Boolean;
var
I: Integer;
begin
result := FALSE;
for I := 1 to length(LETTERS_U) do
begin
if (TestedChar = LETTERS_U[i]) then
begin
result := TRUE;
exit;
end;
end;
end;
function IsNumber(const TestedChar: String): Boolean;
var
I: Integer;
begin
result := FALSE;
for I := 1 to length(NUMBERS) do
begin
if (TestedChar = NUMBERS[i]) then
begin
result := TRUE;
exit;
end;
end;
end;
function GetAlphaFormat(const wholestring: WideString): String;
var
I: Integer;
begin
result := '';
for I := 1 to length(wholestring) do
begin
// Only one of these conditions can be true because there are no mixed lettersets.
if (IsLowerCaseLetter(wholestring[i])) then result := result + 'l';
if (IsUpperCaseLetter(wholestring[i])) then result := result + 'u';
if (IsNumber(wholestring[i])) then result := result + 'n';
end;
end;
function NthInFormatToLetterset(const Format: String; const I: Integer): WideString;
var
format_char: Char;
begin
if (I >= length(Format)) then
begin
result := NUMBERS;
exit
end;
format_char := Format[length(Format) - I];
case format_char of
'l': result := LETTERS_L;
'u': result := LETTERS_U;
'n': result := NUMBERS;
end;
end;
function IndexInString(const letter: WideChar; const wholestring: WideString): Integer;
var
I: Integer;
begin
result := 1; //Not correct in general, but useful for this program
for I := 1 to length(wholestring) do
begin
if (wholestring[i] = letter) then
begin
result := I;
exit
end;
end;
end;
procedure TranslateToArray(const initial: WideString; const Format: String);
var
I: Integer;
letterset: WideString;
begin
for I := 0 to length(SerialCount)-1 do
begin
letterset := NthInFormatToLetterset(Format, I);
SerialCount[i] := IndexInString(initial[length(initial) - i], letterset) - 1;
end;
end;
procedure CheckCarries(const Format: String);
var
I: Integer;
letterset: WideString;
begin
for I := 0 to length(SerialCount)-1 do
begin
letterset := NthInFormatToLetterset(Format, I);
if (SerialCount[i] >= length(letterset)) then
begin
if (I = length(SerialCount) - 1) then
begin
SetLength(SerialCount, length(SerialCount) + 1);
SerialCount[I+1] := -1
end;
SerialCount[I+1] := SerialCount[I+1] + (SerialCount[i] div length(letterset));
SerialCount[i] := SerialCount[i] mod length(letterset);
end;
end;
end;
function AlphaSerialize(const Format: String): WideString;
var
I: Integer;
letterset: WideString;
begin
result := '';
for I := 0 to length(SerialCount)-1 do
begin
letterset := NthInFormatToLetterset(Format, I);
result := letterset[SerialCount[i] + 1] + result;
end;
end;
var
Initialized: Boolean;
InitString: WideString;
AlphaFormat: String;
begin
if not Initialized then
begin
InitString := INITIAL_STRING;
if (length(InitString) = 0) then
begin
SetLength(SerialCount, 1);
SerialCount[0] := 0;
end
else
begin
SetLength(SerialCount, length(InitString));
AlphaFormat := GetAlphaFormat(InitString);
TranslateToArray(InitString, AlphaFormat);
end;
Initialized := True;
end;
CheckCarries(AlphaFormat);
FileName := WideExtractBaseName(FileName) + AlphaSerialize(AlphaFormat) + WideExtractFileExt(FileName);
SerialCount[0] := SerialCount[0] + STEP_SIZE;
end.
krtek's script:
If the letterset is 'abc', serialization is a..z, then aa..az ba..bz.. Only the defined letterset is used. No excess leading digits are added. The new filename appends serialization after the old filename but before the extension.
CONST
LETTERS_L = 'abcdefghijklmnopqrstuvwxyz';
LETTERS_U = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
NUMBERS = '0123456789';
BOTH_NL = '0123456789abcdefghijklmnopqrstuvwxyz';
BOTH_NU = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
TEST = 'abcde';
//CONTROLS FOR THE SCRIPT:
SERIALIZE = LETTERS_L; //setting the letterset for serialization
START_PATTERN = 'a'; //anything you want to start with, eg. 'bba'
STEP = 1; //step MUST be lower than length of SERIALIZE string
var
i, k: Integer;
Pad: Array of Integer; //Pad array is 0 based, but it stores values only from index 1
Initialized: Boolean;
Start, Serialization : WideString;
procedure Initialize;
begin
Initialized := True;
Start:='';
Start:=Start+START_PATTERN;
SetLength(Pad, Length(Start)+1);
Pad[0] := -1; // just in case, we won't use that cell
if Length(Pad) < 2 then
ShowMessage('Error:'+#13+'START_PATTERN constant not defined.'+#13+'Set START_PATTERN constant to '+#39+'a'+#39)
else if Length(Pad) = 2 then
begin
Pad[1] := WidePos(Start[1], SERIALIZE);
If Pad[1] = 0 then
ShowMessage('Error:'+#13+'START_PATTERN constant contains a char ('+#39+Start[1]+#39+'), that is not present in SERIALIZE constant!');
end
else
for k:=1 to Length(Pad)-1 do
begin
Pad[k] := WidePos(Start[k], SERIALIZE);
if Pad[k] = 0 then
ShowMessage('Error:'+#13+'START_PATTERN constant contains a char ('+#39+Start[k]+#39+'), that is not present in SERIALIZE constant!');
end;
;
i := WidePos(Start[Length(Pad)-1], SERIALIZE);
end;
procedure CheckZ(p:Integer);
begin
if Pad[p] > Length(SERIALIZE) then
begin
Pad[p]:=1;
if p > 1 then
begin
Pad[p-1]:=Pad[p-1]+1;
CheckZ(p-1);
end
else
SetLength(Pad, Length(Pad)+1);
end;
end;
begin
if not Initialized then Initialize;
Pad[Length(Pad)-1]:=i;
if i > Length(SERIALIZE) then
begin
CheckZ(Length(Pad)-1);
i:=i-Length(SERIALIZE);
Pad[Length(Pad)-1]:=i;
end;
Serialization:='';
for k:=1 to Length(Pad)-1 do
Serialization:=Serialization + SERIALIZE[Pad[k]];
FileName := WideStripExtension(FileName)+ Serialization + WideExtractFileExt(FileName);
i := i + STEP;
end.
Andrew's script:
Defines lettersets by upper and lower ascii codes. Allows to append or not and to skip file extension or not.
{ Alphanumeric Serialization Script }
// v1 - Original script by Andrew
const
digit_low = 48; // 0
digit_high = 57; // 9
ucase_low = 65; // A
ucase_high = 90; // Z
lcase_low = 97; // a
lcase_high = 122; // z
initstr = 'a'; // Set initial string here
overflow = lcase_low; // Set overflow char here
step = 1; // Set step value here
append = True; // Append serialized string?
skipext = True; // Skip file extension?
var
s1,s2: String;
i,low,high,val: Integer;
initialized,carry: Boolean;
procedure SetFileName;
begin
if(append) then
begin
if(skipext) then
FileName := WideExtractBaseName(FileName) + s2 + WideExtractFileExt(FileName)
else
FileName := FileName + s2;
end
else
FileName := s2 + FileName;
end;
begin
if(Not initialized) then
begin
s2 := initstr;
for i := 1 to Length(s2) do
s1 := s2[i] + s1;
SetFileName;
initialized := True;
Exit;
end;
for i := 1 to Length(s1) do
begin
if((i>1) And (Not carry)) then
Break;
val := Ord(s1[i]);
if(val >= lcase_low) then // Lower-case
begin
low := lcase_low;
high := lcase_high;
end
else if(val >= ucase_low) then // Upper-case
begin
low := ucase_low;
high := ucase_high;
end
else if(val >= digit_low) then // Digit
begin
low := digit_low;
high := digit_high;
end;
if(Not carry) then
val := val + step;
carry := False;
if(val > high) then
begin
while(val > high) do
val := low + (val mod high) - 1;
if(i = Length(s1)) then
begin
SetLength(s1, Length(s1)+1);
s1[i+1] := Chr(overflow);
end
else
begin
s1[i+1] := Chr(Ord(s1[i+1]) + 1);
carry := True;
end;
end;
s1[i] := Chr(val);
end;
s2 := '';
for i := 1 to Length(s1) do
s2 := s1[i] + s2;
SetFileName;
end.
UserInput | Options | Load from report's text file:
The 702 letters a..z, then aa..az, ba..bz,..., za..zz are created:
a
b
c
d
e
f
g
h
i
j
k
l
m
n
o
p
q
r
s
t
u
v
w
x
y
z
aa
ab
ac
ad
ae
af
ag
ah
ai
aj
ak
al
am
an
ao
ap
aq
ar
as
at
au
av
aw
ax
ay
az
ba
bb
bc
bd
be
bf
bg
bh
bi
bj
bk
bl
bm
bn
bo
bp
bq
br
bs
bt
bu
bv
bw
bx
by
bz
ca
cb
cc
cd
ce
cf
cg
ch
ci
cj
ck
cl
cm
cn
co
cp
cq
cr
cs
ct
cu
cv
cw
cx
cy
cz
da
db
dc
dd
de
df
dg
dh
di
dj
dk
dl
dm
dn
do
dp
dq
dr
ds
dt
du
dv
dw
dx
dy
dz
ea
eb
ec
ed
ee
ef
eg
eh
ei
ej
ek
el
em
en
eo
ep
eq
er
es
et
eu
ev
ew
ex
ey
ez
fa
fb
fc
fd
fe
ff
fg
fh
fi
fj
fk
fl
fm
fn
fo
fp
fq
fr
fs
ft
fu
fv
fw
fx
fy
fz
ga
gb
gc
gd
ge
gf
gg
gh
gi
gj
gk
gl
gm
gn
go
gp
gq
gr
gs
gt
gu
gv
gw
gx
gy
gz
ha
hb
hc
hd
he
hf
hg
hh
hi
hj
hk
hl
hm
hn
ho
hp
hq
hr
hs
ht
hu
hv
hw
hx
hy
hz
ia
ib
ic
id
ie
if
ig
ih
ii
ij
ik
il
im
in
io
ip
iq
ir
is
it
iu
iv
iw
ix
iy
iz
ja
jb
jc
jd
je
jf
jg
jh
ji
jj
jk
jl
jm
jn
jo
jp
jq
jr
js
jt
ju
jv
jw
jx
jy
jz
ka
kb
kc
kd
ke
kf
kg
kh
ki
kj
kk
kl
km
kn
ko
kp
kq
kr
ks
kt
ku
kv
kw
kx
ky
kz
la
lb
lc
ld
le
lf
lg
lh
li
lj
lk
ll
lm
ln
lo
lp
lq
lr
ls
lt
lu
lv
lw
lx
ly
lz
ma
mb
mc
md
me
mf
mg
mh
mi
mj
mk
ml
mm
mn
mo
mp
mq
mr
ms
mt
mu
mv
mw
mx
my
mz
na
nb
nc
nd
ne
nf
ng
nh
ni
nj
nk
nl
nm
nn
no
np
nq
nr
ns
nt
nu
nv
nw
nx
ny
nz
oa
ob
oc
od
oe
of
og
oh
oi
oj
ok
ol
om
on
oo
op
oq
or
os
ot
ou
ov
ow
ox
oy
oz
pa
pb
pc
pd
pe
pf
pg
ph
pi
pj
pk
pl
pm
pn
po
pp
pq
pr
ps
pt
pu
pv
pw
px
py
pz
qa
qb
qc
qd
qe
qf
qg
qh
qi
qj
qk
ql
qm
qn
qo
qp
qq
qr
qs
qt
qu
qv
qw
qx
qy
qz
ra
rb
rc
rd
re
rf
rg
rh
ri
rj
rk
rl
rm
rn
ro
rp
rq
rr
rs
rt
ru
rv
rw
rx
ry
rz
sa
sb
sc
sd
se
sf
sg
sh
si
sj
sk
sl
sm
sn
so
sp
sq
sr
ss
st
su
sv
sw
sx
sy
sz
ta
tb
tc
td
te
tf
tg
th
ti
tj
tk
tl
tm
tn
to
tp
tq
tr
ts
tt
tu
tv
tw
tx
ty
tz
ua
ub
uc
ud
ue
uf
ug
uh
ui
uj
uk
ul
um
un
uo
up
uq
ur
us
ut
uu
uv
uw
ux
uy
uz
va
vb
vc
vd
ve
vf
vg
vh
vi
vj
vk
vl
vm
vn
vo
vp
vq
vr
vs
vt
vu
vv
vw
vx
vy
vz
wa
wb
wc
wd
we
wf
wg
wh
wi
wj
wk
wl
wm
wn
wo
wp
wq
wr
ws
wt
wu
wv
ww
wx
wy
wz
xa
xb
xc
xd
xe
xf
xg
xh
xi
xj
xk
xl
xm
xn
xo
xp
xq
xr
xs
xt
xu
xv
xw
xx
xy
xz
ya
yb
yc
yd
ye
yf
yg
yh
yi
yj
yk
yl
ym
yn
yo
yp
yq
yr
ys
yt
yu
yv
yw
yx
yy
yz
za
zb
zc
zd
ze
zf
zg
zh
zi
zj
zk
zl
zm
zn
zo
zp
zq
zr
zs
zt
zu
zv
zw
zx
zy
zz
Offline
FYI here's another possible solution for this...
Use numbers for serializing (with appropriate padding), then Transliterate to letters.
Here are the .txt files. Put them in your Prog Files/ReNamer/Translit folder...
https://docs.google.com/open?id=0BwtnO5 … VExanQ0QVk
It's nice because you can use the various serialize options (such as "start over at folder change" etc.)
-steve
Offline
ReNamer v6.7.0.2 Beta:
Added a selection of numeral systems to the Serialize rule: Decimal digits (0..9), English letters (a..z), Roman numerals (I,II,III,IV,...), Simplified Chinese, Custom alphabetic and Custom numeric.
Offline