Identifying and Manipulating Fonts

Hello All- I come from BASH territory but I am looking to learn Applescript to expand my capabilities. So here’s my first project: I would like to write a script for Keynote 6 that can Identify, in a specified document, what fonts are being used, what pages those fonts are on. A bonus would be the ability replace one font with another.

SO here is my puny start:

tell application "SystemUIServer" to return POSIX path of (choose file)

which allows me to define the file I want to use, it appears. So down to the nuts and bolts… How do I scan that document and Identify what fonts are being used, and what pages they are used on? I am flexible but ideally the output would look like this:

Page 1 - Helvetica, Comic Sans
Page 2 - new times
etc

Thanks for the insight.

Hi,

this is a starting point. It retrieves the fonts of every text item of every slide.


set theFile to choose file of type "key"

set {TID, text item delimiters} to {text item delimiters, ", "}
set resultList to {}
tell application "Keynote"
	open theFile
	tell document 1
		repeat with aSlide from 1 to count slides
			set fontList to {}
			repeat with aTextItem in text items of slide aSlide
				set usedFont to font of object text of aTextItem
				if fontList does not contain usedFont then set end of fontList to usedFont
			end repeat
			set end of resultList to {(aSlide as text) & tab & fontList as text}
		end repeat
	end tell
end tell
set text item delimiters to return
set resultList to resultList as text
set text item delimiters to TID

Here is a slightly enhanced version.


set theFile to choose file of type "key"

set {TID, text item delimiters} to {text item delimiters, ", "}

set resultList to {}
# Extract the localized translation of "Slide"
path to application "Keynote" as text
result & "Contents:Resources:"
set Slide_loc to localized string "Slide" from table "Keynote" in bundle file result

tell application "Keynote"
	open theFile
	tell document 1
		repeat with aSlide from 1 to count slides
			set fontList to {}
			repeat with anItem in iWork items of slide aSlide
				# We may have object texts in text items and in shapes
				# It may be good to add a loop treating groups which may be embedding text items and/or shapes
				if class of anItem is in {text item, shape} then
					set usedFonts to font of every character of object text of anItem
					repeat with aFont in usedFonts
						set aFont to aFont as text
						if fontList does not contain aFont then set end of fontList to aFont
					end repeat
				end if
			end repeat
			set end of resultList to {Slide_loc & space & aSlide & tab & fontList}
		end repeat
	end tell
end tell
set text item delimiters to return
set resultList to resultList as text
set text item delimiters to TID
resultList

It take care of :
application localisation
the fact that we may have object texts in text items and/or shapes
the fact that an object text is not guaranteed to use a single font

I leave as an exercise the treatment of possible groups.
These objects don’t embed object text at their first level but they may contain text items and/or shapes and or groups containing.

I know that we may have text datas in cells of tables but the current version doesn’t allow us to reach them.

Yvan KOENIG (VALLAURIS, France) jeudi 18 septembre 2014 14:32:44

Thanks for reply, this is a great start. To advance the interface with the user I have created a dialog output and the option to “re-check” the document and copy to clipboard. I thought a subroutine (function) would serve this purpose, but I cannot get the variable “resultList” to work outside the subroutine. " The variable resultList is not defined. "

Any thoughts?

If I didn’t want to RE-RUN the script, then the subroutine would not be needed and the if statement sees the listResult just fine.

on function1()
	
	set theFile to choose file of type "key"
	
	set {TID, text item delimiters} to {text item delimiters, ", "}
	
	set resultList to {}
	# Extract the localized translation of "Slide"
	path to application "Keynote" as text
	result & "Contents:Resources:"
	set Slide_loc to localized string "Slide" from table "Keynote" in bundle file result
	
	tell application "Keynote"
		open theFile
		tell document 1
			repeat with aSlide from 1 to count slides
				set fontList to {}
				repeat with anItem in iWork items of slide aSlide
					# We may have object texts in text items and in shapes
					# It may be good to add a loop treating groups which may be embedding text items and/or shapes
					if class of anItem is in {text item, shape} then
						set usedFonts to font of every character of object text of anItem
						repeat with aFont in usedFonts
							set aFont to aFont as text
							if fontList does not contain aFont then set end of fontList to aFont
						end repeat
					end if
				end repeat
				set end of resultList to {Slide_loc & space & aSlide & tab & fontList}
			end repeat
		end tell
	end tell
	set text item delimiters to return
	set resultList to resultList as text
	set text item delimiters to TID
	resultList
end function1

-- Code execution:

function1()
display dialog resultList buttons {"Copy Results", "OK", "Check Again"}
if result = {button returned:"Copy Results"} then
	set the clipboard to resultList
	display dialog "Font output copied to clipboard" buttons "OK"
else if result = {button returned:"Check Again"} then
	function1()
end if

Hello

I edited the code but didn’t ran it.

on function1(Slide_loc)
	
	set theFile to choose file of type "key"
	
	set {TID, text item delimiters} to {text item delimiters, ", "}
	
	set resultList to {}
	
	tell application "Keynote"
		open theFile
		tell document 1
			set dName to its name # ADDED
			repeat with aSlide from 1 to count slides
				set fontList to {}
				repeat with anItem in iWork items of slide aSlide
					# We may have object texts in text items and in shapes
					# It may be good to add a loop treating groups which may be embedding text items and/or shapes
					if class of anItem is in {text item, shape} then
						set usedFonts to font of every character of object text of anItem
						repeat with aFont in usedFonts
							set aFont to aFont as text
							if fontList does not contain aFont then set end of fontList to aFont
						end repeat
					end if
				end repeat
				set end of resultList to {dName & space & space & Slide_loc & space & aSlide & tab & fontList} # EDITED
			end repeat
		end tell
	end tell
	set text item delimiters to return
	set resultList to resultList as text
	set text item delimiters to TID
	return resultList
end function1

-- Code execution:

# Extract only once the localized translation of "Slide"
path to application "Keynote" as text
result & "Contents:Resources:"
set Slide_loc to localized string "Slide" from table "Keynote" in bundle file result

repeat
	set resultList to my function1(Slide_loc)
	display dialog resultList buttons {"Copy Results", "OK", "Check Again"}
	if result = {button returned:"Copy Results"} then
		set the clipboard to resultList
		display dialog "Font output copied to clipboard" buttons "OK"
		exit repeat
	else if result ≠ {button returned:"Check Again"} then
		exit repeat
	end if
end repeat

I hope that I made no mistake.

Yvan KOENIG (VALLAURIS, France) jeudi 18 septembre 2014 21:26:14

No mistake that I can identify, works great. :cool: How would you output the file name as a header on the output field?

Like:

Keynote Document.key

Slide 1 - Helvetica
Slide 2 - Comic Sans
etc

I added the feature in the script embedded in my late message.

Yvan KOENIG (VALLAURIS, France) vendredi 19 septembre 2014 11:10:42