The applescript below is a modified version of Leopard’s shipped script “Create Font Sample.scpt”. It creates samples of all fonts currently selected within FontBook and as soon as its done this it saves and closes the text file automatically. However, I would like to modify this further to save the file as a “Word 2007 (docx)” file, which is an option in Leopard’s TextEdit.
Does anyone know how to modify the code appropriately (the saving part is found at the bottom of the script): hopefully without writing key strokes, but if so, all well and good!
P.S. I’ve discovered the solution isn’t as easy as writing:
set filepath to folderpath & filename & ".docx"
instead of
set filepath to folderpath & filename & ".rtf"
I found that Word 08 still had to spend time converting the file during opening it, and when it did, the document window was headed as “Compatibility Mode”. This scenario doesn’t occur when manually saving the TextEdit file as .docx format from within the application.
Model: Macbook Pro
OS X 10.5.2
ActionScript 2.0
The full script is shown below:
set sampleString to "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789" & " “ "
tell application "Font Book"
tell application "System Events"
set wasTextEditRunning to (name of processes) contains "TextEdit"
end tell
-- tell application TextEditApp to activate
set selectedFamilies to selected font families
set selectedTypefaces to selection
set numFamilies to count selectedFamilies
set numFaces to count selectedTypefaces
tell application "TextEdit"
if wasTextEditRunning then
make new document at the end of documents of it
end if
tell the front document
set paragraph 1 to "Font Samples - " & ¬
numFamilies & " families " & ¬
numFaces & " typefaces" & return & return & return
set size to 8
end tell
end tell
-- asuuming that items in selection are sorted in font family.
set paraIndex to 3
repeat while selectedTypefaces is not {}
set thisFace to first item of selectedTypefaces
set familyName to family name of thisFace
set selectedTypefaces to the rest of selectedTypefaces
set postScriptNames to {PostScript name of thisFace}
repeat while selectedTypefaces is not {}
set anotherFace to first item of selectedTypefaces
if family name of anotherFace is familyName then
set the end of postScriptNames to PostScript name of anotherFace
set selectedTypefaces to the rest of selectedTypefaces
else
exit repeat
end if
end repeat
tell the front document of application "TextEdit"
tell paragraph paraIndex
set font to "LucidaGrande"
set size to 9
set characters to familyName & return & return
set the color of every word to {32867, 32867, 32867} -- 50% gray
end tell
set paraIndex to paraIndex + 1
repeat with psName in postScriptNames
set success to true
try
tell paragraph paraIndex
set font to psName
set size to 13
-- set characters to tab & sampleString & psName & return & return
set characters to sampleString & psName & return & return
end tell
on error
set success to false
end try
if success then
set paraIndex to paraIndex + 1
end if
end repeat
set paragraph paraIndex to return & return
set paraIndex to paraIndex + 1
end tell
end repeat
tell application "TextEdit" to activate
-- save
tell application "TextEdit"
set filename to "font-cat"
set folderpath to "Macintosh HD:Users:username:Desktop:"
set filepath to folderpath & filename & ".rtf"
close document 1 saving yes saving in filepath
end tell
end tell
Hi,
you can do this only with GUI scripting
activate application "TextEdit"
tell application "System Events" to tell process "TextEdit"
keystroke "s" using {command down, shift down}
tell window 1
repeat until exists sheet 1
delay 0.1
end repeat
tell sheet 1
keystroke "font-cat"
keystroke "d" using command down
tell pop up button 1 of group 1 of group 1
click
delay 0.5
click menu item "Word 2007 Format (docx)" of menu 1
end tell
click button "Save"
end tell
end tell
end tell
Thanks very much for the help StefanK! I would have been stuck on this for ages. Because my knowledge of applescript is very limited, I’m not sure how to exactly attach your code to mine to make it work.
Presumably your script replaces all my code following the “–save” comment, apart from the final “end tell” for Font Book.
If this is the case, you’ll notice that my last statement before the “–save” comment is an activate TextEdit statement, and your script also starts with an activate TextEdit statement. Do I need these two statements, one after the other?
I’d be grateful if you could show the complete actionscript as it should look.
try this, I removed the nested tell blocks
set sampleString to "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789" & " “ "
tell application "Font Book" to set {selectedFamilies, selectedTypefaces} to {selected font families, selection}
set numFamilies to count selectedFamilies
set numFaces to count selectedTypefaces
tell application "TextEdit"
if not (exists document 1) then make new document at the end of documents
tell the front document
set paragraph 1 to "Font Samples - " & ¬
numFamilies & " families " & ¬
numFaces & " typefaces" & return & return & return
set size to 8
end tell
end tell
-- asuuming that items in selection are sorted in font family.
set paraIndex to 3
repeat while selectedTypefaces is not {}
tell application "Font Book"
set thisFace to first item of selectedTypefaces
set familyName to family name of thisFace
set selectedTypefaces to the rest of selectedTypefaces
set postScriptNames to {PostScript name of thisFace}
repeat while selectedTypefaces is not {}
set anotherFace to first item of selectedTypefaces
if family name of anotherFace is familyName then
set the end of postScriptNames to PostScript name of anotherFace
set selectedTypefaces to the rest of selectedTypefaces
else
exit repeat
end if
end repeat
end tell
tell the front document of application "TextEdit"
tell paragraph paraIndex
set font to "LucidaGrande"
set size to 9
set characters to familyName & return & return
set the color of every word to {32867, 32867, 32867} -- 50% gray
end tell
set paraIndex to paraIndex + 1
repeat with psName in postScriptNames
set success to true
try
tell paragraph paraIndex
set font to psName
set size to 13
-- set characters to tab & sampleString & psName & return & return
set characters to sampleString & psName & return & return
end tell
on error
set success to false
end try
if success then
set paraIndex to paraIndex + 1
end if
end repeat
set paragraph paraIndex to return & return
set paraIndex to paraIndex + 1
end tell
end repeat
activate application "TextEdit"
tell application "System Events" to tell process "TextEdit"
keystroke "s" using {command down, shift down}
tell window 1
repeat until exists sheet 1
delay 0.1
end repeat
tell sheet 1
keystroke "d" using command down
tell pop up button 1 of group 1 of group 1
click
delay 0.2
click menu item "Word 2007 Format (docx)" of menu 1
delay 1
end tell
set value of text field 1 to "font-cat.docx"
click button "Save"
end tell
end tell
end tell
Wow thats amazing! It does indeed save the file as a docx , opening up without conversion in Word '08. Thanks very much! I see that GUI scripting may be a necessary solution for lots of situations and certainly worth learning.
Many thanks
I’ve also tried to see if I could alter the format of the font sample output so that it doesn’t output Font Family headers, only the Postscript names on a separate line directly above the relevant sample output. Like this:
ArnoPro-Bold
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789
ArnoPro-BoldCaption
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789
ArnoPro-BoldDisplay
abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789
etc…
With the Postscript names all in the same plain font. Currently the Postcript name is tagged on to the end of each line of sample text often making the whole thing span two or more lines, so adopting the above format would look a lot neater.
The looping in the original script doesn’t seem that straightforward to me in order to do achieve this. I know I’d need to count all of the fonts currently selected in Font Book and put that number in a variable, say x, and use that in a repeat loop (repeat with x), but the original script seems more complicated that this. I’m basically not quite sure how to simplify it to this.
You can also use textutil to convert the files into docx.
For Leopard and Tiger
-- get the rft
set theFile to POSIX path of (choose file of type "public.rtf" without invisibles)
-- convert file to docx
do shell script "textutil -convert docx " & quoted form of theFile
-- resulting new file will be place in the same directory as the old one
Thanks very much Mark. Thats a good thing to know. I’ve come across POSIX before but will have to do some reading up on it. A
global paraIndex
property black : {0, 0, 0}
property grey : {32867, 32867, 32867}
set sampleString to "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789" & " “ "
tell application "Font Book" to set {selectedFamilies, selectedTypefaces} to {selected font families, selection}
set numFamilies to count selectedFamilies
set numFaces to count selectedTypefaces
set paraIndex to 1
tell application "TextEdit"
if not (exists document 1) then make new document at the end of documents with properties {text:return}
my insert_Paragraph("Font Samples - " & numFamilies & " families " & numFaces & " typefaces", "LucidaGrande", 10, black, 3)
end tell
-- assuming that items in selection are sorted in font family.
repeat while selectedTypefaces is not {}
tell application "Font Book"
set thisFace to first item of selectedTypefaces
set familyName to family name of thisFace
set selectedTypefaces to the rest of selectedTypefaces
set postScriptNames to {PostScript name of thisFace}
repeat while selectedTypefaces is not {}
set anotherFace to first item of selectedTypefaces
if family name of anotherFace is familyName then
set the end of postScriptNames to PostScript name of anotherFace
set selectedTypefaces to the rest of selectedTypefaces
else
exit repeat
end if
end repeat
end tell
tell the front document of application "TextEdit"
my insert_Paragraph(familyName, "LucidaGrande", 14, grey, 2)
repeat with psName in postScriptNames
my insert_Paragraph(psName, "LucidaGrande", 10, black, 2)
my insert_Paragraph(sampleString, psName, 13, black, 3)
end repeat
set paragraph paraIndex to return & return
set paraIndex to paraIndex + 1
end tell
end repeat
activate application "TextEdit"
tell application "System Events" to tell process "TextEdit"
keystroke "s" using {command down, shift down}
tell window 1
repeat until exists sheet 1
delay 0.1
end repeat
tell sheet 1
keystroke "d" using command down
tell pop up button 1 of group 1 of group 1
click
delay 0.2
click menu item "Word 2007 Format (docx)" of menu 1
delay 1
end tell
set value of text field 1 to "font-cat.docx"
click button "Save"
end tell
end tell
end tell
on insert_Paragraph(theText, theFont, theSize, theColor, numberOfReturns)
local ret
set ret to ""
repeat numberOfReturns times
set ret to ret & return
end repeat
tell the front document of application "TextEdit"
count paragraphs
try
tell paragraph paraIndex
set font to theFont
set size to theSize
set characters to theText & ret
set color of every word to theColor
set paraIndex to paraIndex + numberOfReturns - 1
return true
end tell
on error
return false
end try
end tell
end insert_Paragraph
Thanks Stefan. Just wondering if you could make it so that the script doesn’t output Font Family headers, just the individual font postscript names.
comment out the second line like
.
tell the front document of application "TextEdit"
-- my insert_Paragraph(familyName, "LucidaGrande", 14, grey, 2)
repeat with psName in postScriptNames
.
Doh! Embarrassingly simple. Thank you. Just tested it and that works, only there seems to be random return spacing between each output pair of font name and text sample. Sometimes 1 line inbetween others two lines.
not random, there is an extra line feed after each font family,
if you don’t want it, comment out
-- set paragraph paraIndex to return & return
-- set paraIndex to paraIndex + 1
Sorry about that. I realise its not random return spacing now. There are two line spaces at the end/beginning of each font family output, and only 1 line space between font outputs in the same family. I’ll have a look at the loop to see if I can make every paired output have one line space inbetween. But can you tell me if I take out a return command from the script, do I have to also alter paragraph indexes?
I spoke to soon! Stefan you are an absolute hero! I really appreciate all the help here. At last, a really efficient way to catalog fonts. I think its beats a lot of commercial font management applications for outputting a font catalog. I’ll be able to learn a lot from looking at the script too. Many thanks!
I realise I need to add something back to the script as it sometimes generates blank output followed by the GUI scripted Save As prompt. Sometimes it does work okay though.
Do I need to add back something like this?
tell application "System Events"
set wasTextEditRunning to (name of processes) contains "TextEdit"
end tell
and if so, right at the top of the script?
I realise what the problem is. It doesn’t generate blank output if I uncomment the parts commented below:
-- my insert_Paragraph(familyName, "LucidaGrande", 14, grey, 2)
repeat with psName in postScriptNames
my insert_Paragraph(psName, "LucidaGrande", 9, black, 2)
my insert_Paragraph(sampleString, psName, 12, black, 3)
end repeat
-- set paragraph paraIndex to return & return
-- set paraIndex to paraIndex + 1
So I assume theres something else involved in order to achieve the required output format.
alternatively
.
tell application "TextEdit"
close documents
make new document with properties {text:return}
my insert_Paragraph("Font Samples - " & numFamilies & " families " & numFaces & " typefaces", "LucidaGrande", 10, black, 3)
end tell
.
Thanks Stefan. Thats cracked it!