I need to find all Postscript type 1 fonts located in the user’s fonts folder & duplicate them into a folder on the user’s desktop and then find the remaining fonts in other areas on the Hard Drive & put them in another folder.
Type 1 fonts contain 2 files: the font suitcase & the outline font. I noticed that is taking a long time to process & the Finder completely stops responding. Is there any better way to do this?
set theUserFontFolder to path to fonts from user domain
Tell application "Finder"
make new folder a desktop with properties {name: xxx}
with timeout of 600 seconds
duplicate (every file of entire contents of theUserFontFolder whose kind is "PostScript Type 1 outline font") to folder "xxx" of desktop
end timeout
end tell
As I understand it, most of the time your script spends on searching, not copying. Therefore, the following script may be more efficient.
Unfortunately, the shell’s cp command doesn’t work with a list of Posix paths, so I had to use a repeat loop.
set fonts_folder to POSIX path of (path to fonts folder from user domain)
set dest_folder to POSIX path of (path to desktop folder from user domain) & "PostScriptType1_Fonts"
do shell script "mkdir -p " & quoted form of dest_folder
set theFonts to do shell script "mdfind -onlyin " & quoted form of fonts_folder & " \"kMDItemKind == 'PostScript Type 1 outline font'\""
repeat with aFont in (paragraphs of theFonts)
do shell script "cp " & quoted form of aFont & space & quoted form of dest_folder
end repeat
NOTE:
The -onlyin option forces the mdfind command to search only in the indicated folder and its subfolders. You can grab all PostScript Type 1 font files of your computer removing this option. For example, following script finds all TrueType fonts on your computer:
set TrueTypeFonts to do shell script "mdfind \"kMDItemKind == 'TrueType® font'\""
Well, there’s the problem right there. Entire contents as a Finder command has been broken since the day a scriptable finder was introduced in system 7x or 8x. Even with a relatively small directory it chokes, and most font directories aren’t relatively small.
I’d suggest using Shane’s Filemanager library and do something like this:
use script "FileManagerLib" version "2.3.5"
set theUserFontFolder to path to fonts from user domain
set fontFiles to objects of theUserFontFolder ¬
searching subfolders true ¬
include invisible items true ¬
include folders false ¬
include files true ¬
result type files list
set PS_T1Outlines to {}
set PS_T1suitcases to {}
repeat with thisFile in fontFiles
set itemKind to file_kind of ¬
(parse object thisFile ¬
with HFS results)
if itemKind = "PostScript Type 1 outline font" then
set the end of PS_T1Outlines to thisFile as text
else if itemKind is "Font Suitcase" then
set the end of PS_T1suitcases to thisFile as text
end if
end repeat
I don’t have any such font to test either. I didn’t even find a way to download free one anywhere.
Also, I have a suspicion that the kind of the font is specified by the user inaccurately, and the script does not work precisely because of this, and not because of the entire contents command.
In post #2, I said that the cp command cannot copy multiple files at once. It turns out that it is smarter than me, and the repeat loop no need. cp command can copy multiple files at once.
I’m giving the correct solution here, especially since the example in post #4 (by @Marc Anthony) throws errors. I tested with TrueType fonts, because no any PostscriptType 1 font is installed on my Mac:
set fonts_folder to POSIX path of (path to fonts folder from user domain)
set dest_folder to POSIX path of (path to desktop folder from user domain) & "TrueTypeFonts"
-- create the destination folder
do shell script "mkdir -p " & quoted form of dest_folder
-- find files with Kind metadata
set theFiles to do shell script "mdfind -onlyin " & quoted form of fonts_folder & ¬
" \"kMDItemKind == 'TrueType® font'\""
-- build multiple path arguments for cp command
set {ATID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, return}
set theFiles to text items of theFiles
set AppleScript's text item delimiters to quoted form of space
set theFiles to theFiles as text
set AppleScript's text item delimiters to ATID
-- copy multiple files to destination folder
do shell script "cp '" & theFiles & "' " & quoted form of dest_folder
Wow!! THANK YOU ALL for the responses.
KniazidisR, You are correct the original script I made spent most of the time on searching & not copying. I added an additional line to find the Font Suitcases but I’m not an expert on shell script & obviously it is failing. What is the syntax to find both the Font Suitcase & PostScript Type 1 outline font or do I have to perform 2 different searches? I would like to copy them into the same folder that is being created.
estockly, What’s FileManagerLib?
set fonts_folder to POSIX path of (path to fonts folder from user domain)
set dest_folder to POSIX path of (path to desktop folder from user domain) & "Type 1 Fonts"
-- create the destination folder
do shell script "mkdir -p " & quoted form of dest_folder
--
--Find all outlines kind:metadata
set theFiles to do shell script "mdfind -onlyin " & quoted form of fonts_folder & " \"kMDItemKind == 'PostScript Type 1 outline font'\""
--Find suitcases kind:metadata
set theFiles to do shell script "mdfind -onlyin " & quoted form of fonts_folder & " \"kMDItemKind == 'Font Suitcase'\""
-- build multiple path arguments for cp command
set {ATID, AppleScript's text item delimiters} to {AppleScript's text item delimiters, return}
set theFiles to text items of theFiles
set AppleScript's text item delimiters to quoted form of space
set theFiles to theFiles as text
set AppleScript's text item delimiters to ATID
-- copy multiple files to destination folder
do shell script "cp '" & theFiles & "' " & quoted form of dest_folder
It looks like I placed the first close parenthesis a hair too late in my initial post, but, if this captures the files you’re seeking, it’s a less expensive method. Invoking the shell multiple times is a practice to be avoided.
–confined search
do shell script "mdfind -0 -onlyin " & (path to fonts folder)'s POSIX path's quoted form & space & ("kMDItemKind == " & "PostScript Type 1 outline font")'s quoted form & " | xargs -0J % rsync % " & ((path to desktop as text) & "isFound")'s POSIX path's quoted form
–or search everywhere
do shell script "mdfind -0 " & ("kMDItemKind == " & "PostScript Type 1 outline font")'s quoted form & " | xargs -0J % rsync % " & ((path to desktop as text) & "isFound")'s POSIX path's quoted form
FileManagerLib provides commands for file management tasks like duplicating, copying, moving, renaming, deleting, and trashing files, as well as creating folders and alias files, getting the contents and entire contents of folders, and sorting lists of files. Version 2.3.x adds comparison commands and commands for dealing with date properties. (updated May 27, 2020)
From the very beginning I suspected that this solution is better than mine, only provided by @Marc Anthony snippets doesn’t work - they contain errors with escaping inside the shell command .
Here is how it works correctly (I tested with TrueType fonts of my user domain):
do shell script "mdfind -0 -onlyin " & (path to fonts folder from user domain)'s POSIX path's quoted form & space & "\"kMDItemKind == 'TrueType® font'\" | xargs -0J % rsync % " & ((path to desktop as text) & "TruetypeFonts")'s POSIX path's quoted form
Hi, Kniazidis. The previous edit I made works fine for the postscript font, which the code located elsewhere than my fonts folder for the system-wide search in subsequent testing. You’re searching for an attribute other than what the OP requested, and it appears that double quoting is necessitated, due to the registration symbol.
do shell script "mdfind -0 " & ("kMDItemKind == " & "TrueType® font"'s quoted form)'s quoted form & " | xargs -0J % rsync % " & ((path to desktop as text) & "isFound")'s POSIX path's quoted form