Adrian Nier Code

Back to overview

Organize fonts by location

Last modification: Sunday, February 28, 2010 05:03 am

Puts all font families managed by the Font Book application into groups that correspond to the folders they are contained in.

Implementation

tell application "Font Book"
   
   -- OPTIONS -----------------------------------------------------------
   
   -- Set wether to use full paths or just the names of the folders
   set _useFullPath to true
   
   -- Set a common prefix for all the group names created in Font Book
   set _groupPrefix to ""
   
   -- Set wether to only organize the fonts in the home folder
   set _userFontsOnly to false
   
   -- Set wether to use the parent's parent
   set _useParentsParent to false -- (e.g. /Library instead of /Library/Fonts)
   
   ----------------------------------------------------------------------
   
   
   
   -- Get the path to the home folder to replace with tilde later on
   set _homeFolderPath to POSIX path of (path to home folder as string)
   
   -- Go through all font familes
   set _families to font families
   
   
   
   
   repeat with _family in _families
      
      -- Get the path to the first file for this family
      set _familyFiles to (files of _family)
      set _familyFile to (first item of _familyFiles) as string
      
      set _processThisFont to true
      if _userFontsOnly then
         if _useParentsParent then
            tell application "System Events" to set _containerPath to path of container of container of file _familyFile
         else
            tell application "System Events" to set _containerPath to path of container of file _familyFile
         end if
         set _containerName to POSIX path of _containerPath
         if _containerName does not start with _homeFolderPath then
            set _processThisFont to false
         end if
      end if
      
      if _processThisFont then
         
         if _useFullPath then
            -- Get the path of the containing folder
            if _userFontsOnly is false then
               if _useParentsParent then
                  tell application "System Events" to set _containerPath to path of container of container of file _familyFile
               else
                  tell application "System Events" to set _containerPath to path of container of file _familyFile
               end if
               set _containerName to POSIX path of _containerPath
            end if
            
            -- Remove trailing slash
            if character -1 of _containerName is "/" then
               set _prvDlmt to AppleScript's text item delimiters
               set AppleScript's text item delimiters to "/"
               set _containerName to text items 1 thru -2 of _containerName as string
               set AppleScript's text item delimiters to _prvDlmt
            end if
            
            -- Replace the path to the home folder with a tilde
            if _containerName starts with _homeFolderPath then
               set _prvDlmt to AppleScript's text item delimiters
               set AppleScript's text item delimiters to ""
               set _containerName to "~/" & characters ((count of _homeFolderPath) + 1) thru (count of _containerName) of _containerName as string
               set AppleScript's text item delimiters to _prvDlmt
            end if
            
         else -- _useFullPath is false
            
            -- Get the name of the containing folder
            if _useParentsParent then
               tell application "System Events" to set _containerName to name of container of container of file _familyFile
            else
               tell application "System Events" to set _containerName to name of container of file _familyFile
            end if
            
         end if -- _useFullPath
         
         -- Add the prefix if necessary
         if _groupPrefix is not false and _groupPrefix is not "" then
            set _containerName to _groupPrefix & _containerName
         end if
         
         -- Create the font collection if necessary
         my createFontCollection(_containerName)
         
         -- Add this family to the group
         add _family to font collection _containerName
         
      end if
      
   end repeat
   
end tell

on createFontCollection(_collectionName)
   (* Creates a collection in Font Book using the name
      specified as an argument to this function. *)

   
   tell application "Font Book"
      
      (* BUGFIX: Font Book v2.2.1 creates additional unnamed
                 collection when making new one. *)

      -- Snapshot collection names for later clean up
      set _expectedCollectionNames to name of font collections
      set end of _expectedCollectionNames to _collectionName
      (* BUGFIX END *)
      
      if (exists font collection _collectionName) is false then
         
         make new font collection at the end of font collections with properties {name:_collectionName}
         -- Wait until the font collection actually exists
         repeat
            try
               get font collection _collectionName
               if (exists font collection _collectionName) then exit repeat
            end try
            delay 0.1
         end repeat
      end if
      
      (* BUGFIX: Font Book v2.2.1 creates additional unnamed
                 collection when making new one. *)

      -- Clean up garbage collections
      set _collectionNames to name of font collections
      repeat with _i from 1 to count of _collectionNames
         if item _i of _collectionNames is not in _expectedCollectionNames then
            delete font collection (item _i of _collectionNames)
         end if
      end repeat
      (* BUGFIX END *)
      
      repeat
         try
            return font collection _collectionName
         end try
         delay 0.1
      end repeat
   end tell
   
end createFontCollection