autosave TextEdit file as docx

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 :slight_smile:

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! :slight_smile: 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! :slight_smile: