inDesign Font Replacing

I’m upgrading fonts in documents that we build (using appleScripts) and that are produced by others (outside vendor).

The problem is that the vendor provides the documents to us and all their other customers using T1 fonts, which are no longer supported by our system.

Eventually the vendor will switch to the current version of the fonts, but in the meantime we will have to replace the fonts on our end. Basically that means opening the Font Find/Change dialog in inDesign, and swapping out the fonts one by one. (Tedious and error prone).

So I’d like to automate switching fonts using appleScript. Has anyone done this before?

I’m thinking of trying things like

set the font of paragraph style x to y
set the font of character style z to y

Or

set textToFix to every text whose font is x
set the font of text to fix to y

Any better suggestions?

Here’s a starting point:

tell application id "InDn"
	tell active document
		
		set theStyles to all paragraph styles
		repeat with aStyle in theStyles
			if exists applied font of aStyle then if name of applied font of aStyle = ("Helvetica Neue LT Std" & tab & "47 Light Condensed") then set applied font of aStyle to ("Helvetica Neue LT Std" & tab & "47 Light Condensed Oblique")
		end repeat
		
		set theStyles to all character styles
		repeat with aStyle in theStyles
			if exists applied font of aStyle then if name of applied font of aStyle = ("Helvetica Neue LT Std" & tab & "47 Light Condensed") then set applied font of aStyle to ("Helvetica Neue LT Std" & tab & "47 Light Condensed Oblique")
		end repeat
		
		set theRanges to object reference of text style ranges of stories whose name of applied font = ("Fira Sans" & tab & "Light")
		repeat with aRange in theRanges
			set applied font of aRange to ("Fira Sans" & tab & "Bold")
		end repeat

	end tell
end tell
1 Like

Fonts are a major nuisance. I assume you are working in InDesign, as Type1 fonts are going away in Adobe. Here is what I have used for years.

on dpDocFontReplace(nameDocument, listFontReplacements)
– revised 2014-06-05 includes routine to dismiss dialogs.
– This script will manage the replacement of old fonts with new fonts in a document

– listFontReplacements = a list of records indicating the desired font replacements
– nameFind is the old name that is used to search
– nameBad is the applied font name that is used in the replacement code
– nameNew is the font we want to apply to characters with applied font nameBad
– often nameFind and nameBad are the same, but not always, see Avenir
– {nameFind:“Avenir (T1) 65 Medium”, nameBad:“Avenir 65 Medium”, nameNew:“Avenir Medium”}

--	Get a list of the fonts used in the document
tell application id "com.adobe.InDesign"
	activate
	tell document 1
		set listfonts to name of every font
	end tell
end tell
--	Detect and dismiss dialog
tell application "System Events"
	tell (process 1 whose name contains "Adobe InDesign")
		if window "Missing Fonts" exists then
			
			keystroke return
		end if
	end tell
end tell
--	diagnostics
#	set AppleScript's text item delimiters to return
#	set listOfFonts to listfonts as text
#	set AppleScript's text item delimiters to ""
#	libraryUtilities's logEvent2("Activity", "dpDocFontReplace", {"", "", "listfonts contains" & return & listOfFonts})

--	Process each font on the replacement list
repeat with a from 1 to count items of listFontReplacements
	--
	--	Parse the current replacement information
	set nameFontFind to nameFind of item a of listFontReplacements
	set nameFontBad to nameBad of item a of listFontReplacements
	set nameFontNew to nameNew of item a of listFontReplacements
	libraryUtilities's logEvent2("Activity", "dpDocFontReplace:nameFontFind", {"", "", nameFontFind})
	
	--	If the old font is being used, replace it with the new font
	if listfonts contains nameFontFind then
		
		tell application id "com.adobe.InDesign"
			set refFontBad to font nameFontBad
			set refFontNew to font nameFontNew
			tell document 1
				try
					if (every character of every story whose name of applied font is nameFontBad) ≠ {} then
						set (applied font of every character of every story whose name of applied font is nameFontBad) to refFontNew
						libraryUtilities's logEvent2("Activity", "dpDocFontReplace", {"", "", (nameFontBad & " replaced with " & nameFontNew)})
					else if (every character of every story whose name of applied font is nameFontFind) ≠ {} then
						set (applied font of every character of every story whose name of applied font is nameFontFind) to refFontNew
						libraryUtilities's logEvent2("Activity", "dpDocFontReplace", {"", "", (nameFontFind & " replaced with " & nameFontNew)})
					else
						set errorMessage to ("No type found to replace for " & nameFontBad)
						error errorMessage number -9999
						libraryUtilities's logEvent2("Activity", "dpDocFontReplace", {"", "", errorMessage}) -- of libraryUtilities
					end if
				on error errorMessage number errorNumber
					libraryUtilities's logEvent2("Error", "dpDocFontReplace", {errorMessage, errorNumber, "could not replace font " & nameFontBad})
				end try
			end tell --	doc 1
		end tell --	application "Adobe InDesign"
	else
		--logEvent2("Activity", "dpDocFontReplace", {"", "", "listfonts does not contain " & nameFontFind}) of libraryUtilities
	end if
end repeat
delay 4 --	allow document to update.

end dpDocFontReplace

my logEvent2 is something I picked up from some AS book years ago, maybe Mark Munro’s? Use any log function you want.

Hope that helps

1 Like

Thanks guys, I’ll try both!

After trying mulitple versions of both suggestions I couldn’t get either to work. I think the issue was with the particular fonts I was using, because I could get something working with other fonts. Usually it was an issue of not finding the font family.

So then I stumbled on this, basically including the fonts as part of the application’s find and replace.

So far, so good.

set fontReplacements to {¬
   ({findFontName:"Benton Gothic" & tab & "Bold", findFontStyle:"Bold", changeFontName:"BentonGothic-Bold   Bold", changeFontStyle:"Bold"}), ¬
   ({findFontName:"Benton Gothic" & tab & "Regular", findFontStyle:"Regular", changeFontName:"BentonGothic-Regular   Regular", changeFontStyle:"Regular"}) ¬
      }
tell application "Adobe InDesign 2023"
   --  settings and option
   set properties to {find text preferences:nothing, change text preferences:nothing}
   set properties of find change text options to {include footnotes:true, include master pages:true, include hidden layers:true, whole word:false}
   
   repeat with thisReplacement in fontReplacements
      set fontToFind to findFontName of thisReplacement
      set fontToFindStyle to findFontStyle of thisReplacement
      set changeFont to changeFontName of thisReplacement
      set changeFontStyle to changeFontStyle of thisReplacement
      set properties of find text preferences to {applied font:fontToFind, font style:fontToFindStyle}
      set properties of change text preferences to {applied font:changeFont, font style:changeFontStyle}
      change text active document
   end repeat
end tell

I guess your doc does not have any paragraph or character style defined with those fonts?

These documents usually have both paragraph and character styles with those fonts.

Then, there is a problem with your script: all text content will be changed but the styles will not.
In consequence, if you apply a paragraph style after running this script, the font will revert to the old one.
(Not sure I’m very clear…)

You’re right. Not sure how I will handle that, but for the first set of documents that won’t be an issue.

The problem is that there are a number of inDesign and Illustrators users in the organization with an unknown number of documents, templates and graphics that contain Type 1 fonts that will need to be replaced, and likely a good number will use style sheets.

What I’m toying with now is creating a set of styless with each of the new fonts, and nothing else, then reading the styles from the target document, apply all the settings from the ones with bad fonts to the ones with just fonts, apply the new style sheets to the text range, then deleting the old style sheet.

Either that or figure out how to get past the font family issue.

The way InDesign handles fonts is sometimes weird.
The name displayed in the UI is not always the one Applescript can see.

If you want me too have a look, you can pm me a sample doc with a type1 used font.
(Don’t expect an answer in the next hours, It’s about midnight here)

Just sent one. As for the fonts name I’ve been pulling the names for the old fonts and the replacement fonts directly from the font names as they appear in the inDesign Dictionary explorer.

This script will replace the font in every style sheet as well as in every text with no style applied.

tell application id "InDn"
	
	set thePairs to {{("Belizio" & tab & "Bold"), ("Arial" & tab & "Bold")}, ¬
		{("Belizio" & tab & "Regular"), ("Arial" & tab & "Regular")}, ¬
		{("Belizio" & tab & "RegularItalic"), ("Arial" & tab & "Italic")}, ¬
		{("BentonGothic-Bold" & tab & "Bold"), ("Arial Narrow" & tab & "Bold")}, ¬
		{("BentonGothic-Regular" & tab & "Regular"), ("Arial Narrow")}}
	
	tell active document
		
		repeat with aPair in thePairs
			
			set {oldFont, newFont} to aPair
			
			set theStyles to all paragraph styles
			repeat with aStyle in theStyles
				if exists applied font of aStyle then if name of applied font of aStyle = oldFont then set applied font of aStyle to newFont
			end repeat
			
			set theStyles to all character styles
			repeat with aStyle in theStyles
				if exists applied font of aStyle then if name of applied font of aStyle = oldFont then set applied font of aStyle to newFont
			end repeat
			
			if exists (text style ranges of stories whose name of applied font = oldFont) then
				set theRanges to object reference of (text style ranges of stories whose name of applied font = oldFont)
				repeat with aRange in theRanges
					set applied font of aRange to newFont
				end repeat
			end if
			
		end repeat
		
	end tell
end tell
1 Like

Thanks, and it works and is incorporated into a couple work flows.

I’ve got one version that uses this exclusively, but on bigger files using the find/replace method works faster on text so I combine the two. On most files this does the trick just fine.

It’s odd that with some fonts the order the fonts are replaced matters.

Thanks!

Glad it helped.

You know you can use the InDesign do script command to make your code run faster.
In addition, you will be able to group all the steps of the script in one undo history.

1 Like