You are not logged in.
Pages: 1
Do you know you can extend ReNamer capabilities by writing (or find) an Script with Pascal syntax?
See our fine Wiki http://www.den4b.com/wiki/ReNamer
Pascal Script
Quick guide
Types
Functions
Script cookbook
Scripts
For a full manual, see the wiki.
- - -
Learn Pascal tutorial
https://www.taoyue.com/tutorials/pascal
- - -
For an short overview and a few basic tricks that are not that obviously, I will post you my collection.
Over the years of trying, I have collected a few how-to's, examples, basics.
Many from Denis and from other forum members.
This are not whole scripts, I put them in code blocks only to prevent the formatting.
And that are not logically ordered blocks, just a quick copy and paste while trying to keep things together.
Hope that helps somebody.
(Please, do not ask here for whole scripts, create an new thread for that. Basic questions may be OK)
- - -
To add a comment for rules, add an extra PascalScipt rule and add your comments there.
You can use either of these commenting styles in PascalScipt:
{ comments }
// comments
(* comments *)
For Regex (RegEx rule) you can put (?#comment) at the beginning of the expression.
- - -
var
bStopScript, Initialized : Boolean;
StringParts, RegExSubPatterns: TStringsArray;
BaseName, Extension, pattern : WideString;
i, x, Count, Pos: Integer;
Procedure Initialize;
BEGIN
//do something only once:
Initialized := True;
END.
begin
if not bStopScript then
begin
//trick to stop whole script (use for debugging scripts)
if DialogYesNo('Would you like to stop whole script execution?') then
begin
bStopScript := True;
Exit;
end;
//////////////////////////////////////////
// Add your code here
//do something only once:
if not Initialized then Initialize;
//////////////////////////////////////////
//Show an message only once:
If Not Initialized Then
ShowMessage('Please');
Initialized := true
//////////////////////////////////////////
//Debug MsgBox:
WideShowMessage( 'var is: ' + #13#10 + var );
//compose new file name:
FileName := BaseName + Extension;
end;
end.
//build-in variable to use:
FileName
FilePath
GetCurrentFileIndex
GetCurrentMarkedFileIndex
GetTotalNumberOfFiles
GetTotalNumberOfMarkedFiles
//set own basic variable:
BaseName := WideExtractBaseName(FileName);
Extension := WideExtractFileExt(FileName);
Count := Count + 1;
//skip for current file if condition is true:
if <Condition> then Exit;
if Count > 25 then Exit;
if GetCurrentFileIndex > 25 then Exit;
if DialogYesNo('Would you like to skip this file?') then Exit;
// split the filename at '-' into parts:
StringParts := WideSplitString( BaseName, ' - ' );
if Length(StringParts) < 1 then Exit;
// Note: parts are numbered from 0 on: StringParts[0],StringParts[1]
for I:=0 to Length(StringParts)-1 do
begin
// access each part via StringParts[i]
if <Condition> then Break;
end;
// split the filename into parts by utilizing regular expressions:
//SubMatchesRegEx create an array of matches from expression in () parentheses:
//SubMatchesRegEx(const Input, Find: WideString;const CaseSensitive: Boolean): TStringsArray;
RegExSubPatterns:=SubMatchesRegEx(BaseName,'(.*?)\[(\d+) by (\d+)\]',false);
if Length(RegExSubPatterns) <=0 then exit;
vBefore := SubPatterns[0]
vDigit1 := SubPatterns[1]
// Get parts of the current file name (default build-in):
// C:\folder\sub folder\file.ext
// WideExtractFileDir(FilePath) ==> C:\folder\sub folder
// WideExtractFilePath(FilePath) ==> C:\folder\sub folder\
// WideExtractFileDrive(FilePath) ==> C:\
// WideExtractFileName(FilePath) ==> file.ext
// WideExtractBaseName(FilePath) ==> file
// WideExtractFileExt(FilePath) ==> ext
vExt_wo_dot := WideReplaceStr( Extension, '.', '');
// Get parts of the current file path by build-in functions:
WideExtractFileName(WideExtractFileDir(FilePath)); => ParentFolder
WideExtractFileName(WideExtractFileDir(WideExtractFileDir(FilePath))); => GrandParent
WideExtractFileName(WideExtractFileDir(WideExtractFileDir(WideExtractFileDir(FilePath)))); => GreatGrand
// Get parts of the current file path by folder array:
var - Folders: TStringsArray;
Folders := WideSplitString(FilePath, '\');
TopMostFolder := Folders[1];
SecondTopMostFolder := Folders[2];
GrandGrandParentFolder := Folders[Length(Folders)-3];
GrandParentFolder := Folders[Length(Folders)-2];
ParentFolder := Folders[Length(Folders)-1];
//get part of filename:
var - Beginning, Ending: WideString;
Beginning := WideCopy(BaseName, 1, 2); // first two signs
Ending := WideCopy(BaseName, Length(BaseName)-3, 3); // last three
Ending := WideCopy(BaseName, 3, 999); // from third till end
var - FirstChar, FirstPart, SecondPart: WideString; Pos1, Pos2:Integer;
Pos1 := WidePos( '-' , BaseName );
if Pos1 <= 0 then Exit;
Pos2 := WidePosEx('-', BaseName, Pos1 + 1);
if Pos2 <= 0 then Exit;
FirstChar := Copy(BaseName,1,1);
FirstPart := Copy(BaseName,1, Pos1);
SecondPart := Copy(BaseName,Pos1 + 1,999);
//MatchesRegEx returns full expression matches:
ReplaceRegEx(const Input, Find, Replace: WideString;const CaseSensitive, UseSubstitution ($0,$2,$3,...): Boolean): WideString;
//MatchesRegEx returns an array of full matches, which matched the entire expression, not the sub-patterns.
MatchesRegEx(const Input, Find: WideString;const CaseSensitive: Boolean): TStringsArray;
WideReplaceStr(const S, OldPattern, NewPattern: WideString): WideString; //(Case Sensitive)
WideReplaceText(const S, OldPattern, NewPattern: WideString): WideString;//(Case Non-Sensitive)
WideCompareStr(const S1, S2: WideString): Integer;//(Case Sensitive)
WideCompareText(const S1, S2: WideString): Integer;//(Case Non-Sensitive)
Returns: < 0 if S1<S2 // 0 if S1=S2 // > 0 if S1>S2
WideSameText(const S1, S2: WideString): Boolean;//(Case Non-Sensitive)
// FileName := WideReplaceStr(FileName, '-', '_');
// find two identical chars in filename and delete one of them:
//(5. Delete double letters: "Madonna" =>"Madona")
FileName := ReplaceRegEx(FileName, '(.)\1', '$1', False, True);
- - -
//Change Case:
WideCaseCapitalize( xxx );
WideUpperCase( xxx );
WideLowerCase( xxx );
WideCaseInvert( xxx );
Rev String
Reverse Name
Reverse String
http://www.den4b.com/forum/viewtopic.php?id=930 - 2010
PascalScript only has bare bones for executing scripts. I define/code all the functions.
No, there is no string reversal function. For the exercise above you can simple use
reverse loop "for..downto..do" or a while loop counting down.
-----
var
name, eman:String;
c: Integer;
begin
name := 'Stefan';
//eman := '';
for c:=length(name) downto 1 do
eman := eman + name[c];
showmessage(eman);
end.
--------------
A correct version of the string reverse function would be:
function WideReverseStr(const S: WideString): WideString;
var
I, Count: Integer;
begin
Count := Length(S);
SetLength(Result, Count);
for I := 1 to Count do
Result[i] := S[Count - I + 1];
end;
----------------------------------------------------------
type
THelloWorld = class
procedure Put;
end;
procedure THelloWorld.Put;
begin
ShowMessage('Hello, World!');
end;
var
HelloWorld: THelloWorld;
begin
HelloWorld := THelloWorld.Create;
HelloWorld.Put;
HelloWorld.Free;
end.
- - -
- - -
IntToStr( integer );
StrToInt( string );
Words := WideSplitString( BaseName, ' ' );
Some function I have found useful, and as base for own work:
//from Denis Encrypt filenames.pas
//ReplaceChar(Result, '/', '=');
procedure ReplaceChar(var Str: String; Find, Replace: Char);
var
I: Integer;
begin
for I:=1 to Length(Str) do
if Str[I] = Find then
Str[I] := Replace;
end;
----------------------------------------------------------
function IsUp(Index: Integer): Boolean;
begin
Result := (Index >= 1) and (Index <= Length(S));
if Result then Result := IsUpCache[Index-1];
end;
function IsLetter(C: Char): Boolean;
begin
Result := UpperCase(C) <> LowerCase(C);
end;
function IsSpace(Index: Integer): Boolean;
begin
Result := (Index >= 1) and (Index <= Length(S));
if Result then Result := IsSpaceCache[Index-1];
end;
function IsUpperCase(C: Char): Boolean;
begin
Result := C = UpperCase(C);
end;
function IsLowerCase(C: Char): Boolean;
begin
Result := C = LowerCase(C);
end;
function BoolToStr(condition : boolean) : WideString;
begin
If condition Then
result := 'True'
Else
result := 'False';
end;
PressedButton: boolean;
UserInput: string;
UserInput := 'defaultstring';
PressedButton := InputQuery('Title', 'Prompt', UserInput);
//if PressedButton=True then OK was pressed, if False then Cancel was pressed.
IF (PressedButton = False) Then
begin
WideShowMessage('Cancel pressed');
exit;
end;
IF (UserInput = '') Then
WideShowMessage('Empty string!')
ELSE
FileName := UserInput + WideExtractFileExt(FileName);
if <condition> then
begin
<Action>
end;
--------
if <condition> then
begin
<Action-1>
end else
begin
<Action-2>
end;
----------
if sVar1 = sVar2 then
----------
if start_pos < Length(BaseName) then
-------
if (I > 1) then
if PosEnd > 0 then
if (Length(Exts) > 0) then
if (IncYear(bday, 1) <= filedt) then
---------
if first > second then
--------
if ((Num > 0) and (5 / Num = 1)) then
--------
if not Initialized then Initialize;
-------------
if sLine <> '' then
if (TridAnalyze <> 0) then
----------
else if WideSameText(WideLowerCase(sUserInput),'stop') then
---------
if (not WideFileExists('TrIDLib.dll'))
Or (WideFileSize('TrIDLib.dll')=0)
Or (not WideFileExists('TrIDDefs.trd'))
Or (WideFileSize('TrIDDefs.trd')=0) then
---------------
if (DialogYesNo('Error! not found!' + #13#10 + 'Do you want to ...?')) then
------------
if IsWideCharDigit(S[i]) then
begin
PosEnd := I;
Break;
end;
-------------------
if Number > MaxNumber then MaxNumber := Number;
--------------
if Copy(dateText, 1, 3) = 'JAN' then iMonth := 1
else if Copy(dateText, 1, 3) = 'FEB' then iMonth := 2
...
else if Copy(dateText, 1, 3) = 'DEC' then iMonth := 12
else iMonth := -1;
-or better-
varX := Copy(dateText, 1, 3);
if varX = 'JAN' then iMonth := 1
else if varX = 'FEB' then iMonth := 2
...
else if varX = 'DEC' then iMonth := 12
------------------
Result := (PosStart > 0) and (PosEnd > 0);
if Result then
-------------
if PADTO > 1 then
while Length(Value) < PADTO do
Value := '0'+Value;
----------
for I:=x to y do
begin
<Action>
end;
---------
for I:=Length(S) downto 1 do
for I:=0 to Length(Files)-1 do
-----------
for I := Length(FileName) downto 1 do
begin
if (FileName[i] = '.') then
--------------
while <condition> do
begin
<Action>
end;
---------
repeat
<Action>
until <condition>;
---------
FormatDateTime
sDate := FormatDateTime( 'yyyy-mm-dd hh.MM.ss', FileTimeModified(FilePath) );
http://www.den4b.com/forum/viewtopic.php?id=1813
FormatDateTime() needs an DateTime object as second parameter, not just an string called DateTime.
The first parameter of FormatDateTime() is a string in single quotes without parentheses, if you not want those in the result.
(The example you have found use parentheses in the first parameter as literal text for the output only)
See help > http://www.den4b.com/wiki/ReNamer:Pasca … e_and_Time
"function FormatDateTime(const Fmt: String; D: TDateTime): String;"
That means:
function FormatDateTime( wanted format as String ; working on a Date as TDateTime object): resulting in a String object;
See help from where you can get a "TDateTime" object for the second FormatDateTime() parameter, for example:
function FileTimeModified(const FileName: WideString): TDateTime;
function Date: TDateTime;
function Time: TDateTime;
function Now: TDateTime;
function EncodeDate(Year, Month, Day: Word): TDateTime;
+++
all this functions gives you a TDateTime object.
So you can use for example:
(To make it more clear, I would name the var "DateTime" rather "dtDateTime")
BEFORE:
French.txt
AFTER:
French26-Mai-2013.txt
USE:
var
dtDateTime :TDateTime;
strDateTime :String;
begin
dtDateTime := Date();
strDateTime := FormatDateTime('dd-mmm-yyyy', dtDateTime);
FileName := WideExtractBaseName(FileName) +
strDateTime +
WideExtractFileExt(FileName);
end.
Or, if you prefer the short form, you can just use the function 'Date()' inside the function 'FormatDateTime()':
begin
FileName := WideExtractBaseName(FileName) +
FormatDateTime( 'dd-mmm-yyyy', Date() ) +
WideExtractFileExt(FileName);
end.
You could even use the function Date() without the parenthesis,
but with () it makes more clear where 'Date' comes from.
- - -
To format the output (the new filename) you can add more literal text in single quotes:
BEFORE:
French.txt
AFTER:
French (26-Mai-2013).txt
USE:
begin
FileName := WideExtractBaseName(FileName) +
' (' + FormatDateTime('dd-mmm-yyyy', Date() ) + ')' +
WideExtractFileExt(FileName);
end.;
BEFORE:
French.txt
AFTER:
French - 26-Mai-2013.txt
USE:
begin
FileName := WideExtractBaseName(FileName) + ' - ' +
FormatDateTime('dd-mmm-yyyy', Date() ) +
WideExtractFileExt(FileName);
end.
BEFORE:
French.txt
AFTER:
2013.05.26 French.txt
USE:
begin
FileName := FormatDateTime('yyyy.mm.dd', Date() ) + ' ' +
WideExtractBaseName(FileName) +
WideExtractFileExt(FileName);
end.
- - -
You may see that it makes sense to use the long form
to do it step-by-step and that way making the code not that confusing ;-)
BEFORE:
French.txt
AFTER:
French (26-Mai-2013).txt
USE:
var
dtDateTime :TDateTime;
strDateTime :String;
begin
dtDateTime := Date();
strDateTime := FormatDateTime('dd-mmm-yyyy', dtDateTime);
FileName := WideExtractBaseName(FileName) +
' (' + strDateTime + ')' +
WideExtractFileExt(FileName);
end.
Last edited by Stefan (2017-02-02 11:35)
Read the *WIKI* for HELP + MANUAL + Tips&Tricks.
If ReNamer had helped you, please *DONATE* to Denis or buy a PRO license. (Read *Lite vs Pro*)
Offline
Stefan:
I really appreciate these many examples you provided of PascalScript Code Basics. This is going to mean a giant step for my understanding of this feature in ReNamer.
RecordMan
Offline
Thank you, RecordMan.
I hope that is useful for starters.
I have learned by searching the forum for "PascalScript" or "var begin end" and learned from the best.
Also there is a collection of example scripts, selected by Denis: http://www.den4b.com/wiki/ReNamer:Scripts
Read the *WIKI* for HELP + MANUAL + Tips&Tricks.
If ReNamer had helped you, please *DONATE* to Denis or buy a PRO license. (Read *Lite vs Pro*)
Offline
Try to clean-up my above first post into dedicated postings...
User Input, Ask User, MsgBox and split File name or path into parts
//Get user input:
* function InputBox(const ACaption, APrompt, ADefault: String): String;
* function WideInputBox(const ACaption, APrompt, ADefault: WideString): WideString;
var
vUserInput: string;
begin
// InputBox(const ACaption, APrompt, ADefault: string): string;
vUserInput := InputBox('My Caption', 'The Description Prompt', 'Default string');
// When user presses Cancel button, the dialog should return EMPTY string.
//If vUserInput = '' Then Continue; // means skip this file only
//If vUserInput = '' Then BREAK; // to stop the whole script.
// (That '' is here an empty '...' string)
// your code here
FileName := vUserInput + WideExtractFileExt(FileName);
end.
//Ask the user:
function InputQuery(const ACaption, APrompt: string; var Value: string): Boolean;
function WideInputQuery(const ACaption, APrompt: WideString; var Value: WideString): Boolean;
They work exactly like InputBox/WideInputBox,
but they will also return TRUE is user presses OK, and FALSE when user presses CANCEL.
var
bAnswer : boolean;
sDefault : string;
//InputQuery(const ACaption, APrompt: String; var Value: String): Boolean;
sDefault := 'defaultstring';
bAnswer := InputQuery('Question', 'Do you want?' , sDefault);
if bAnswer then ...
-or-
sDefault := 'defaultstring';
bAnswer := InputQuery('Question', 'Your new file name:' , sDefault);
IF bAnswer = False then exit
ELSE FileName = Value;
-or-
var
PressedButton: boolean;
UserInput: string;
begin
FilePath := '';
UserInput := 'defaultstring';
PressedButton := InputQuery('Title', 'Prompt', UserInput);
//if PressedButton=True then OK was pressed, if False then Cancel was pressed.
IF (PressedButton = False) Then
begin
WideShowMessage('Cancel pressed');
exit;
end;
IF (UserInput = '') Then
WideShowMessage('Empty string!')
ELSE
FileName := UserInput + WideExtractFileExt(FileName);
end.
-or more simple-
In above example you can even drop the PressedButton variable
cause IF-ELSE clause can simply take the value returned by InputQuery:
IF not InputQuery('Title', 'Prompt', UserInput) Then exit
ELSE FileName := UserInput + WideExtractFileExt(FileName);
Generally they say that it's better not to compare booleans to true/false, but to use syntax:
If PressedButton then ... (which is an equivalent of If (PressedButton = true) then ...)
If not PressedButton then ... (which is an equivalent of If (PressedButton = false) then ...)
bAnswer := WideDialogYesNo('Do you want?');
if bAnswer then ...
// MsgBox
// Show an MessageBox to show all possibles:
var
newPath, oldFileName, oldBaseName, oldFileExt, oldPath, output: WideString;
Folders: TStringsArray;
ParentFolder, GrandParentFolder, GrandGrandParentFolder, TopMostFolder, SecondTopMostFolder: WideString;
begin
////build-in variable to use:
//FilePath (C:\folder\sub folder\file.ext)
//FileName (file.ext)
// Get parts of the current file name:
oldFileName := WideExtractFileName(FileName);
oldBaseName := WideExtractBaseName(FileName);
oldFileExt := WideExtractFileExt(FileName);
//FileExt_no_dot := WideReplaceStr( oldFileExt, '.', '');
oldPath := WideExtractFileDir(FilePath);
////Get parts of the current file path by folder array:
Folders := WideSplitString(FilePath, '\');
TopMostFolder := Folders[1];
SecondTopMostFolder := Folders[2];
GrandGrandParentFolder := Folders[Length(Folders)-3];
GrandParentFolder := Folders[Length(Folders)-2];
ParentFolder := Folders[Length(Folders)-1];
output := 'Default vars' + #13#10;
output := output + 'FilePath: ' + FilePath + #13#10;
output := output + 'FileName: ' + FileName + #13#10 + #13#10;
output := output + 'Extracted parts' + #13#10;
output := output + 'WideExtractFileDrive >>> '+ WideExtractFileDrive(FilePath) + #13#10;
output := output + 'WideExtractFileDir >>> ' + WideExtractFileDir(FilePath) + #13#10;
output := output + 'WideExtractFilePath >>> ' + WideExtractFilePath(FilePath) + #13#10;
output := output + 'WideExtractFileName >>> ' + WideExtractFileName(FilePath) + #13#10;
output := output + 'WideExtractBaseName >>> ' + WideExtractBaseName(FilePath) + #13#10;
output := output + 'WideExtractFileExt >>> ' + WideExtractFileExt(FilePath) + #13#10 + #13#10;
output := output + 'TopMost Folder >>> ' + TopMostFolder + #13#10;
output := output + 'SecondTopMost >>>> ' + SecondTopMostFolder + #13#10;
output := output + 'GrandGrandParent > ' + GrandGrandParentFolder + #13#10;
output := output + 'GrandParent >>>>>> ' + GrandParentFolder + #13#10;
output := output + 'Parent >>>>>>>>>>> ' + ParentFolder + #13#10 + #13#10;
WideShowMessage ( output );
// FilePath > C:\folder\sub folder\file.ext
// FileName > file.ext
// WideExtractFilePath => C:\folder\sub folder\
// WideExtractFileDir ==> C:\folder\sub folder
// WideExtractFileDrive => C:\
// WideExtractFileName ==> file.ext
// WideExtractBaseName ==> file
// WideExtractFileExt ===> ext
// Get parts of the current file path by build-in functions:
WideExtractFileName(WideExtractFileDir(FilePath)); => ParentFolder
WideExtractFileName(WideExtractFileDir(WideExtractFileDir(FilePath))); => GrandParent
WideExtractFileName(WideExtractFileDir(WideExtractFileDir(WideExtractFileDir(FilePath)))); => GreatGrand
//get part of filename:
//Example: "The Beatles - Help him.nb4"
var
Beginning, Ending: WideString;
begin
Beginning := WideCopy(BaseName, 1, 4); // first four signs: 'The '
Ending := WideCopy(BaseName, Length(BaseName)-3, 3); // last three: 'him'
Ending := WideCopy(BaseName, 4, 999); // from fourth till end: 'Beatles - Help him'
-or-
//"The Beatles - Help him.nb4"
var
FirstChar, FirstPart, SecondPart: WideString;
Pos1, Pos2:Integer;
begin
Pos1 := WidePos( '-' , BaseName ); //13
if Pos1 <= 0 then Exit;
Pos2 := WidePosEx('-', BaseName, Pos1 + 1); // nul, not found
if Pos2 <= 0 then Exit;
FirstChar := Copy(BaseName,1,1); // 'T'
FirstPart := Copy(BaseName,1, Pos1); // 'The Beatles '
SecondPart := Copy(BaseName,Pos1 + 1,999); // '- Help him'
//Debug MsgBox:
WideShowMessage( 'My var is: ' + #13#10 + varFirstChar );
Last edited by Stefan (2017-02-02 09:40)
Read the *WIKI* for HELP + MANUAL + Tips&Tricks.
If ReNamer had helped you, please *DONATE* to Denis or buy a PRO license. (Read *Lite vs Pro*)
Offline
Pages: 1