Titlecase

Rename scripting lets us use languages like VBScript and JScript to create quite complicated rename presets.

This TitleCase preset/script can do various useful filename cleanup tasks at the same time:

  • Replace %20 with spaces.
  • Remove multiple spaces.
  • Replace _ with a space.
  • Strip leading/trailing spaces.
  • Make extension lower case.
  • Convert to true titlecase.
  • Capitalise after parenthesis.
  • Capitalise after a dash.
  • Capitalise after a full stop.
  • Capitalise after first non-numeric character.

There are two versions of the script:

  1. For Opus 12 & above:

    If you are using Opus 12 or above, use the enhanced version of the script. A number of checkboxes will be added to the Rename dialog to let you toggle the script's options on and off:

    If you change one of the script's checkboxes in Opus 12, and want that to be the default from then on, just re-save the preset. (Quickest way: Ctrl+S in the Rename dialog, after toggling the checkbox.)

  2. For Opus 11 & earlier:

    If you are using the version for Opus 11 & earlier, you can turn options on and off by editing the top of the script. Change the variables from True to False to toggle the options:



Download:


Script code:

If you just want to use the script, download the .orp preset file above. The script code is reproduced below to help people browsing the forum looking for scripting techniques.

This is the "Opus 12 enhanced" version of the script.

Option Explicit
' ********************************************************
'  TitleCase by Steve Banham (tanis@dopus.com) 07-Apr-2007
'  Enhanced for Opus 12 by Leo Davidson, 31-Aug-2017
' ********************************************************

Function OnGetCustomFields(getFieldData)

	' Define checkboxes and initial states
	getFieldData.fields.fOddChars    = True ' Replace %20 with spaces
	getFieldData.fields.fUnderscore  = True ' Replace "_" with a space
	getFieldData.fields.fMultiSpace  = True ' Remove multiple spaces
	getFieldData.fields.fExtLCase    = True ' Make extension lower case
	getFieldData.fields.fTitleCase   = True ' Convert to true titlecase
	getFieldData.fields.fParCap      = True ' Capitalise after parenthesis
	getFieldData.fields.fDashCap     = True ' Capitalise after a dash
	getFieldData.fields.fFullStopCap = True ' Capitalise after a full stop
	getFieldData.fields.fFirstNonNum = True	' Capitalise first non-numeric


	' Set the labels for the checkboxes
	getFieldData.field_labels("fOddChars")    = "Replace ""%20"" with a space"
	getFieldData.field_labels("fUnderscore")  = "Replace ""_"" with a space"
	getFieldData.field_labels("fMultiSpace")  = "Remove multiple spaces"
	getFieldData.field_labels("fExtLCase")    = "Make extension lower case"
	getFieldData.field_labels("fTitleCase")   = "Convert to Title Case"
	getFieldData.field_labels("fParCap")      = "Title Case: Capitalise after parenthesis"
	getFieldData.field_labels("fDashCap")     = "Title Case: Capitalise after a dash"
	getFieldData.field_labels("fFullStopCap") = "Title Case: Capitalise after a full stop"
	getFieldData.field_labels("fFirstNonNum") = "Title Case: Capitalise first non-numeric"

End Function

Function OnGetNewName(ByRef getNewNameData)

	dim strExt
	dim strNewName
	dim iOldLength
	dim iNewLength
	dim strNameArray
	dim strTmpWord
	dim strTmpName
	dim x
	dim j
	dim i

	'Strip the filename extension for now
	strNewName = getNewNameData.newname_stem_m
	strExt = getNewNameData.newname_ext_m

	' Make extension lower case
	if getNewNameData.custom.fExtLCase then
		strExt = LCase(strExt)
	end if

	' Replace "_" with spaces
	if getNewNameData.custom.fUnderscore then
		strNewName = Replace(strNewName, "_", " ")
	end if
	
	' Replace "%20" with spaces
	if getNewNameData.custom.fOddChars then
		strNewName = Replace(strNewName, "%20"," ")
	end if
	
	' Remove all multiple spaces
	if getNewNameData.custom.fMultiSpace then
		iNewLength = 0
		iOldLength = len(strNewName)
		Do While iOldLength > iNewLength
			iOldLength = len(strNewName)
			strNewName = Replace(strNewName,"  "," ")
			iNewLength = len(strNewName)
		Loop
	end if

	' Trim spaces at start/end of filename (e.g. because it used to start with a an underscore)
	' If this is not done, the split function below may throw an error.
	strNewName = Trim(strNewName)

	' Convert filename to TitleCase
	if getNewNameData.custom.fTitleCase then
		' Create an array from words in the filename
		strNameArray = split(strNewName, " ")

		' Now go through each item in the array and process it
		if ubound(strNameArray) > 0 then
			for x = lbound(strNameArray) to ubound(strNameArray)
	
				' Set all text to lower case to begin with
				strNameArray(x) = LCase(strNameArray(x))

				' Ignore articles, prepositions and conjunctions
				Select Case strNameArray(x)
					Case "a"
					Case "an"
					Case "at"
					Case "and"
					Case "but"
					Case "by"
					Case "for"
					Case "in"
					Case "into"
					Case "is"
					Case "of"
					Case "off"
					Case "on"
					Case "onto"
					Case "or"
					Case "the"
					Case "to"
					Case "it"
					Case else
						if len(strNameArray(x)) > 0 then

							strTmpWord = Ucase(mid(strNameArray(x),1,1)) & mid(strNameArray(x),2,len(strNameArray(x))-1)

							' If the word begins with "(" then capitalise the next letter
							if mid(strNameArray(x),1,1) = "(" then
								if getNewNameData.custom.fParCap then
									strTmpWord = Ucase(mid(strNameArray(x),1,2)) & mid(strNameArray(x),3,len(strNameArray(x))-1)
								end if
							end if
							
							' If the word follows a "-" then it needs to be capitalised
							if mid(strNameArray(x),1,1) = "-" then
								if getNewNameData.custom.fDashCap then
									strTmpWord = Ucase(mid(strNameArray(x),1,2)) & mid(strNameArray(x),3,len(strNameArray(x))-1)
								end if
							end if

							strNameArray(x) = strTmpWord
						end if
				end Select
			next
		Else
			strNameArray(0) = LCase(strNameArray(0))
		End if

		' Make sure the first word is capitalised
		strTmpWord = Ucase(mid(strNameArray(0),1,1)) & mid(strNameArray(0),2,len(strNameArray(0))-1)
		strNameArray(0) = strTmpWord

		' Clear the new name variable
		strNewName = ""

		' Rebuild the array into one string
		For x = lbound(strNameArray) To ubound(strNameArray)
			strNewName = strNewName & strNameArray(x) & " "
		Next

		' Capitalise after - when it's in the middle of words
		' Capitalise after - when it's between words
		if getNewNameData.custom.fDashCap then
			For j = 1 to len(strNewName)
				if mid(strNewName,j,1) = "-" then
					strTmpName = strTmpName & mid(strNewName,j,1)
					j=j+1
					if mid(strNewName,j,1) = " " then
						strTmpName = strTmpName & mid(strNewName,j,1)
						j=j+1
					end if
					strTmpName = StrTmpName & Ucase(mid(strNewName,j,1))			
				else
					strTmpName = strTmpName & mid(strNewName,j,1)
				end if
			Next
			strNewName = strTmpName
			strTmpName = ""
		end if			

		' Capitalise after full stops in the middle of and between words
		if getNewNameData.custom.fFullStopCap then
			For i = 1 To len(strNewName)
				if mid(strNewName,i,1) = "." then
					strTmpName = strTmpName & mid(strNewName,i,1)
					i=i+1
					if mid(strNewName,i,1) = " " then
						strTmpName = strTmpName & mid(strNewName,i,1)
						i=i+1
					end if
					strTmpName = StrTmpName & Ucase(mid(strNewName,i,1))			
				else
					strTmpName = strTmpName & mid(strNewName,i,1)
				end if
			Next
			strNewName = strTmpName
			strTmpName = ""
		end if

		' Capitalise first non-numeric, non-space character.
      		' This is for music files like "07 By My Side.flac" which don't have a dash after their track numbers.
		if getNewNameData.custom.fFirstNonNum then
			For i = 1 to len(strNewName)
         			if (not IsNumeric(mid(strNewName,i,1))) and mid(strNewName,i,1) <> " " then
            				strNewName = mid(strNewName,1,i-1) & Ucase(mid(strNewName,i,1)) & mid(strNewName,i+1)
            				exit for
         			end if
      			Next
		end if
	end if
	
	' Strip leading/trailing spaces
	strExt = Trim(strExt)
	strNewName = Trim(strNewName)
	
	' Rejoin the name and extension and we're finished
	strNewName = strNewName & strExt

	OnGetNewName = strNewName

End Function
3 Likes

[quote="myarmor"]Just a small question.

Isn't the script supposed to upcase the character following ( in this filename?

"this_is_really(some test).mp3"

currently resulting in:

"This Is Really(some Test).mp3"

Very useful script :slight_smile:[/quote]

The script doesn't upper case the 'some' because it's all seen as one word with the really - "Really(some".

[quote="nate_dawg"]How can this be modified to skip any leading numbers as in the case of music files?

Example:03 The Curse.flac is currently renamed to 03 the Curse.flac when it shouldn't be changed at all since "the" is the start of the filename (practically speaking).[/quote]

The root post now has a modified version of the script which does that. Steve also added a new setting near the top of the script for anyone who wants to turn it off and get the old behaviour.

Can I add in a line which deletes leading "The " or A " from files. For example changing "The Beatles" to "Beatles" or "A Collection of" to "Collection Of"

You can do that without modifying the script itself by applying a regular expression to the names before they are passed to the script.

To do that simply select the preset as usual, then set:

Type: Regular Expressions

Old name: (The |A |)(.*)

New name: \2

(If you always want the preset to use those values then you should save over it after making the changes.)


I've updated the root post with a version which fixes that.

(For those interested, I just added strNewName = Trim(strNewName) before the part where it splits the name into words.)

Hi Steve,
Up front: thanks for this beautiful script. Like to ask, is there a way to make it skip renaming abbreviations, like HQ, CD, DVD (i.e. often words consisting of 2-3 'consonants', B,C,D,F,G) and/or sometimes followed by a number, like MP3.
It is just an idea, but maybe the script will become way too complicated...

The root post has been updated with a version of the TitleCase script enhanced for Opus 12.

This version adds checkboxes to the Rename dialog to control the script's options:

200dpi_wc10294_dopus

It also handles multi-part extensions better than before (e.g. .part1.rar files).

I've consolidated and cleaned-up some posts in the thread to make things a bit easier for first-time users. Bug reports that have been fixed in the root post have been removed, etc.

1 Like

can you please add the option to remove numbers?
I tied add this option from this script but not succussed.

Delete numbers.orp (23.3 KB)

I have just installed this script on Directory Opus 12 but seem to be having issues getting it to apply capitilization changes. It identifies that capitilization changes are required to the filename and proposed new filename is correct, but it will not apply the changes.

If, however, there's other changes such as removing a double space, or converting %20 to space character as well, then it will apply those changes, as well as the necessary capitalization changes.

Looks like you installed the version for Opus 11. Or did you rename the script?

Sorry yes I renamed. I have been troubleshooting further and the issue seems to be related to Windows - it doesn't recognise a change in case as a change in filename on drives formatted FAT32 or exFAT.

Yes, ExFAT is case-insensitive and will ignore such a rename command.