Skip to main content

Pascal Script: Library

TODOTODO: Test all scripts.

This page provides curated, ready-to-use scripts for common renaming tasks and integrations with third-party tools. Each script can be copied directly into the Pascal Script rule and adapted by adjusting the constants at the top.

Using console applications

Several scripts in this library work by running an external command-line tool, capturing its output, and parsing the result to produce a new filename. This is done with the ExecConsoleApp function:

ExecConsoleApp(const Command: String; out Output: String): Cardinal

It executes the command string, blocks until the program finishes, captures everything written to standard output into Output, and returns the program's exit code. An exit code of 0 indicates success for all tools covered here.

Console applications typically write output using the OEM character encoding (the legacy DOS code page). Unless the tool provides its own UTF-8 output option, convert the output with OemToWide before using it in a filename:

UnicodeOutput := OemToWide(Output);

Always enclose both the executable path and the file path in double quotes within the command string, to handle spaces in paths correctly:

Command := '"' + ExePath + '" [options] "' + FilePath + '"';

ExifTool

ExifTool is a powerful, actively maintained tool for reading and writing metadata in a very wide range of file formats, including JPEG, RAW (CRW, CR2, NEF, ARW, and many others), HEIF, TIFF, PNG, video files, and more. It supports EXIF, IPTC, XMP, and many vendor-specific tag namespaces.

Setup

  1. Download the ExifTool Windows package and extract it into ReNamer's folder.
  2. The archive contains a file named exiftool(-k).exe. Rename it to exiftool.exe before use. The (-k) suffix causes the tool to wait for the user to press Enter before closing — ReNamer cannot send that input, so the application will freeze if this step is skipped.

Script

The script below renames files using the Date/Time Original EXIF tag. Adjust the TAG constant to extract any other tag.

const
  EXE = 'exiftool.exe -t -charset filename=utf8';
  TAG = 'Date/Time Original' + #9 + '(.*?)[\r\n]';

var
  Command, Output: String;
  Matches: TWideStringArray;

begin
  Command := EXE + ' "' + FilePath + '"';
  if ExecConsoleApp(Command, Output) = 0 then
  begin
    Matches := SubMatchesRegEx(Output, TAG, False);
    if Length(Matches) > 0 then
      FileName := Matches[0] + WideExtractFileExt(FileName);
  end;
end.

The -t flag produces tab-delimited output (TagName<tab>Value), which the TAG regex captures reliably. #9 is the tab character. The -charset filename=utf8 flag tells ExifTool to interpret filenames as UTF-8, which is necessary for Unicode paths.

Discovering available tags

Run exiftool.exe <file> from the command line to list all tags and their values for any given file. Paste the tag name into the TAG constant, replacing the example.

The raw tag value is used as the filename and may contain characters that are invalid in Windows filenames (colons are common in date strings, for example). Add a Replace or Clean Up rule after the Pascal Script rule to sanitise the result if needed.

Tested with ReNamer 7.4 and ExifTool 12.52.

Exiv2

Exiv2 is a lightweight open-source library for reading and writing EXIF, IPTC, and XMP metadata from JPEG and RAW image formats (including CRW, CR2, and many others).

Setup

  1. Download the Exiv2 Windows package and extract its bin folder contents into ReNamer's folder. The required file is exiv2.exe along with any DLLs it ships with.
  2. Exiv2 is distributed in several build variants with different runtime dependencies. If you see errors about missing DLLs, install the matching Microsoft Visual C++ Redistributable.

Script — extract any tag

The script below extracts the camera model (Exif.Image.Model) and prepends it to the filename. Change the TAG constant to extract any other Exiv2 key.

const
  TAG        = 'Exif.Image.Model';
  EXECUTABLE = 'exiv2.exe';
  PARAMETERS = '-Pt -K ' + TAG;

var
  Command, Output: String;
  UnicodeOutput: WideString;

begin
  Command := '"' + EXECUTABLE + '" ' + PARAMETERS + ' "' + FilePath + '"';
  if ExecConsoleApp(Command, Output) = 0 then
  begin
    UnicodeOutput := WideTrim(OemToWide(Output));
    if UnicodeOutput <> '' then
      FileName := UnicodeOutput + ' ' + FileName;
  end;
end.

The -Pt flag prints the tag value only (no label or formatting). The -K flag filters output to a specific key, so Output contains just the value followed by a newline. OemToWide handles the encoding conversion.

Script — extract and reformat EXIF date

EXIF date values are formatted as yyyy:mm:dd hh:mm:ss, which contains colons that are illegal in Windows filenames. This variant extracts the date and reformats it cleanly. Adjust DATE_TAG and DATE_FORMAT as needed.

const
  EXECUTABLE  = 'exiv2.exe';
  DATE_TAG    = 'Exif.Photo.DateTimeOriginal';
  DATE_FORMAT = 'yyyy-mm-dd hh.nn.ss';

var
  Command, Output: String;
  DateTime: TDateTime;

begin
  Command := '"' + EXECUTABLE + '" -Pt -K ' + DATE_TAG + ' "' + FilePath + '"';
  if ExecConsoleApp(Command, Output) = 0 then
  begin
    Output := WideTrim(OemToWide(Output));
    if TryScanDateTime('yyyy:mm:dd hh:nn:ss', Output, DateTime) then
      FileName := FormatDateTime(DATE_FORMAT, DateTime) + WideExtractFileExt(FileName);
  end;
end.

TryScanDateTime parses the EXIF date string according to the format pattern. If parsing fails — for example, because the tag is absent — the script leaves FileName unchanged without raising an error.

Discovering available tags

Run exiv2.exe -pa <file> to list all metadata keys and their values for any given file. Keys follow the dotted namespace format (Exif.Image.Model, Iptc.Application2.Headline, etc.).

Tested with ReNamer 6.9 and Exiv2 0.26.

MediaInfo

MediaInfo extracts technical and descriptive metadata from a wide variety of audio and video formats, including MP4, MKV, AVI, MP3, FLAC, and many others. It can report codec names, duration, bitrate, encoding date, track titles, and more.

Setup

  1. Download the MediaInfo CLI package (the command-line interface version, not the GUI) and extract it anywhere on your system.
  2. Set the MediaInfoExe constant in the script to the full path of the MediaInfo.exe executable.

Script

The script below renames files using the Encoded_Date tag. Adjust OutputParameter to extract any other supported tag.

const
  MediaInfoExe    = 'C:\Tools\MediaInfoCLI\MediaInfo.exe';
  OutputParameter = 'General;%Encoded_Date%';

var
  Command: WideString;
  Output: String;

begin
  Command :=
    '"' + MediaInfoExe + '"' +
    ' --output="' + OutputParameter + '"' +
    ' "' + FilePath + '"';
  if ExecConsoleApp(Command, Output) = 0 then
    FileName := WideTrim(OemToWide(Output)) + WideExtractFileExt(FilePath);
end.

The --output parameter uses a template format: Section;%TagName%. The General section covers file-level properties; other sections include Video, Audio, Text, and Image. For example, 'Video;%Format%' extracts the video codec name.

Discovering available tags

Use these built-in help commands from the command line to explore available tags:

  • MediaInfo.exe --Help — general help.
  • MediaInfo.exe --Help-Output — documentation for the output template format.
  • MediaInfo.exe --Info-Parameters — full list of supported tag names.

Tested with ReNamer 6.8.

Xpdf

Xpdf provides a suite of PDF processing tools. The pdfinfo.exe utility extracts document properties such as Title, Author, Subject, Creator, and creation date from PDF files.

Setup

  1. Download Xpdf tools and copy pdfinfo.exe into ReNamer's folder.

Script

The script below renames PDF files using their Title tag. Change the TAG constant to extract any other property.

const
  EXE = 'pdfinfo.exe -enc UTF-8';
  TAG = 'Title\s*\:\s*(.*?)[\r\n]';

var
  Command, Output: String;
  Matches: TWideStringArray;

begin
  Command := EXE + ' "' + FilePath + '"';
  if ExecConsoleApp(Command, Output) = 0 then
  begin
    Matches := SubMatchesRegEx(Output, TAG, False);
    if Length(Matches) > 0 then
      FileName := Matches[0] + WideExtractFileExt(FileName);
  end;
end.

The -enc UTF-8 flag instructs pdfinfo.exe to write its output in UTF-8, so no OemToWide conversion is needed. The TAG regex captures the value following the property label and colon; replace Title in the pattern to target a different property.

Discovering available tags

Run pdfinfo.exe <file> from the command line to list all properties available for a given PDF. Common tags include Author, Subject, Keywords, Creator, CreationDate, and ModDate.

Tested with ReNamer 7.1 and Xpdf tools 4.01.01.

TrID

TrID identifies the true type of a file by analysing its binary content, independently of the existing extension. It is useful for correcting mislabelled files or assigning extensions to files that have none.

Unlike the other tools in this library, TrID is integrated via DLL import rather than as a console application. See Importing external functions in the Examples article for background on this mechanism.

Unicode limitation: TrID library processes file paths as ANSI strings. Files with non-ASCII characters in their paths will not be handled correctly and are therefore skipped by the script.

Setup

Download and place both files into ReNamer's folder:

  1. TrIDLib.dll — the identification library. See the TrIDLib product page for version history and additional notes.
  2. TrIDDefs.TRD — the file type definitions database. TrID's identification quality depends on using an up-to-date database file, so re-download it periodically to pick up newly added file types.

Script

The script identifies the file type, applies a confidence cutoff of 20% to filter low-confidence matches, and sets the extension to the best match (or multiple candidates separated by | when several types score above the cutoff). It loads the definitions database once at initialisation and errors if the database file is missing.

{ TrID — file type detection by content }

const
  // Minimum confidence percentage for the detected
  // file extensions to be included in the result.
  TargetConfidenceCutoff = 20;

function TridLoadDefsPack(szPath: PChar): Integer;
  external 'TrID_LoadDefsPack@TrIDLib.dll stdcall';
function TridSubmitFileA(szFileName: PChar): Integer;
  external 'TrID_SubmitFileA@TrIDLib.dll stdcall';
function TridAnalyze: Integer;
  external 'TrID_Analyze@TrIDLib.dll stdcall';
function TridGetInfo(lInfoType: Integer; lInfoIdx: Integer; sBuf: PChar): Integer;
  external 'TrID_GetInfo@TrIDLib.dll stdcall';

const
  TRID_GET_RES_NUM     = 1;
  TRID_GET_RES_FILEEXT = 3;
  TRID_GET_RES_POINTS  = 4;
  TRID_BUFFER_SIZE     = 4096;

function GetExtensions(ConfidenceCutoff: Integer): WideString;
var
  Buffer, Extension: String;
  I, NumMatches, NumPoints, TotalPoints: Integer;
begin
  Result := '';
  SetLength(Buffer, TRID_BUFFER_SIZE);
  NumMatches := TridGetInfo(TRID_GET_RES_NUM, 0, PChar(Buffer));
  if NumMatches > 0 then
  begin
    TotalPoints := 0;
    // Count total points for all matches
    for I := 1 to NumMatches do
      TotalPoints := TotalPoints + TridGetInfo(TRID_GET_RES_POINTS, I, PChar(Buffer));
    // Iterate through all matches
    for I := 1 to NumMatches do
    begin
      // Check if a match passes the minimum confidence level
      NumPoints := TridGetInfo(TRID_GET_RES_POINTS, I, PChar(Buffer));
      if (NumPoints * 100 / TotalPoints) >= ConfidenceCutoff then
      begin
        // Include the detected file extension
        if TridGetInfo(TRID_GET_RES_FILEEXT, I, PChar(Buffer)) > 0 then
        begin
          Extension := LowerCase(String(PChar(Buffer)));
          if (Length(Extension) > 0) and (Pos(Extension, Result) = 0) then
          begin
            if Length(Result) > 0 then Result := Result + '|';
            Result := Result + Extension;
          end;
        end;
      end;
    end;
    // Normalize the delimiter between file extensions
    if Length(Result) > 0 then
      Result := WideReplaceStr(Result, '/', '|');
  end;
end;

var
  Initialized: Boolean;
  AppPath, FileExtensions: WideString;

begin
  if not Initialized then
  begin
    Initialized := True;
    AppPath := WideExtractFilePath(GetApplicationPath);
    if TridLoadDefsPack(AppPath) = 0 then
      Error('TrID database file not found in the application folder.');
  end;

  // Skip Unicode filenames, because TrID library only works with ANSI filenames
  if FilePath <> UTF8Decode(WinCPToUTF8(UTF8ToWinCP(UTF8Encode(FilePath)))) then
    Exit;

  if TridSubmitFileA(PChar(FilePath)) <> 0 then
  begin
    if TridAnalyze <> 0 then
    begin
      FileExtensions := GetExtensions(TargetConfidenceCutoff);
      if FileExtensions <> '' then
        FileName := WideStripExtension(FileName) + '.' + FileExtensions;
    end;
  end;
end.

TridLoadDefsPack is called once and receives the application folder path, from which it locates TrIDDefs.TRD. TridSubmitFileA submits the file for analysis and TridAnalyze runs the identification. GetExtensions collects all results above the confidence cutoff, converting them to lowercase and joining multiple candidates with |, which is an invalid filename character and will require the end user to remove alternative candidates before renaming using other renaming rules.

Tested with ReNamer 5.60+ and TrIDLib.

Renaming folders using file metadata

This script renames folders by reading a metadata tag from a representative file inside each folder, and appending the tag value to the folder name. It requires no third-party tools — only ReNamer's built-in CalculateMetaTag and WideScanDirForFiles functions.

A typical use case is music library organisation: given an album folder named "Artist - Title" containing MP3 files with an ID3 Year tag, the script produces "Artist - Title (1993)".

Setup

Add the folders you want to rename to ReNamer's file list (not the files inside them). Use Add Folder in ReNamer to add the folder entries themselves.

Script

Adjust MASK to match the type of files to search for inside each folder, and TAG to the metadata tag to extract. The full list of supported tag names is in the Meta Tags reference.

const
  MASK = '*.mp3';
  TAG  = 'ID3_Year';

function FindFirstFile(const Folder: WideString): WideString;
var
  Files: TWideStringArray;
begin
  Result := '';
  SetLength(Files, 0);
  WideScanDirForFiles(Folder, Files, False, False, False, MASK);
  if Length(Files) > 0 then
    Result := Files[0];
end;

var
  MasterFile, TagValue: WideString;

begin
  if not WideDirectoryExists(FilePath) then
    Exit;

  MasterFile := FindFirstFile(FilePath);
  if MasterFile = '' then
    Exit;

  TagValue := WideTrim(CalculateMetaTag(MasterFile, TAG));
  if TagValue <> '' then
    FileName := FileName + ' (' + TagValue + ')';
end.

WideScanDirForFiles scans the folder non-recursively for files matching MASK and returns their full paths. The first match is used as the source for the metadata tag. The WideDirectoryExists guard ensures the script acts only on folder entries and skips any regular files that may be in the list.

Tested with ReNamer 5.74.4.