InDesign custom menu generator

An applescript that creates a custom menu in the top bar in InDesign using scripts found in a folder you specify.

Using a menu sanitises the use of scripts a bit, making them appear indistinguishable from proper InDesign commands for less-techy users.

I use it to distribute the scripts I write for work to the other team members under a menu with our company name as the title, which seems to impress those who are easily impressed (ie. the boss).

This is a rewrite from the more-custom version I use, so it’s had a bit less testing. Post if you have issues with it.

This file structure in the script folder:

Will create this menu:

Installation instructions in the comments at the start of the script.


(*
version 1.0
fatboy


If you save this in a file called "01_Macscripter_menu.scpt"
and place it in the startup scripts folder for InDesign:

"/Applications/Adobe InDesign CS5/Scripts/startup scripts"

it will generate a menu in InDesign called "Macscripter".

It will search a folder specified in the property scriptFolderPath and add the 
scripts in that folder to a menu in InDesign.
	
Change the filename to change the menu name, but follow
the above name pattern.

The names of the menu items in InDesign are dictated by the file names
of the scripts in Finder.

Any filetype suffixes are removed from the names (.scpt, .scptd, .jsx etc.) by
knocking off the final dot and anything after.

The names can have prefixes of digits followed by an underscore
to dictate the order they appear in InDesign. eg
	
01_My Script Name.scpt
02_Another Script Name.scpt

Add dividers by having any file with a name like this one:

03_div

Sub folders are searched recursively, adding submenus with the
name of the folder. eg 

a folder named:

04_Sub Menu

will make a submenu named "Sub Menu", whose contents will be the
contents of the folder in Finder.

*)


-- Change the value of this property to the path to your scripts folder.
property scriptFolderPath : alias POSIX file "/Users/fatboy/Desktop/Scripts Temp"

set oldDelims to AppleScript's text item delimiters

-- Generate the menu name from the filename of this file
tell application "Finder"
	set myPath to path to me as string
	set menuName to name of (alias myPath)
end tell
set AppleScript's text item delimiters to "_menu."
set menuName to text item 1 of menuName
set AppleScript's text item delimiters to "_"
set menuName to text item 2 of menuName

tell application "Adobe InDesign CS5"
	try
		-- delete the menu if it already exists so it can start afresh
		tell submenu menuName of menu "$ID/Main" to delete
	end try
end tell

tell application "Finder"
	set scriptDetails to my makeScriptDetails()
end tell

repeat with oneItem in scriptDetails
	tell application "Adobe InDesign CS5"
		my addMenu(menu "$ID/Main", menuName, oneItem)
	end tell
end repeat

set AppleScript's text item delimiters to oldDelims






-- Subroutines

on makeScriptDetails()
	tell application "Finder"
		set temp to items of scriptFolderPath
		set theResult to {}
		repeat with i from 1 to (count temp)
			
			-- Loop through the items found in scriptFolderPath, creating
			-- records with the details of each item
			set end of theResult to my getFinderItemDetails(item i of temp)
			
		end repeat
		return theResult
	end tell
end makeScriptDetails

on getFinderItemDetails(theItem)
	-- Create records for the found items
	tell application "Finder"
		set oldDelims to AppleScript's text item delimiters
		set theName to name of theItem
		try
			set AppleScript's text item delimiters to "_"
			set theName to text items 2 thru -1 of theName as string
		end try
		try
			set AppleScript's text item delimiters to "."
			set theName to text items 1 thru -2 of theName
		end try
		set AppleScript's text item delimiters to ""
		set theName to theName as string
		set theRecord to {subContents:{} ¬
			, itemName:missing value ¬
			, itemType:missing value ¬
			, itemPath:missing value}
		
		set itemName of theRecord to theName
		set itemPath of theRecord to theItem as string
		if class of theItem is folder then
			set itemType of theRecord to "sub_menu"
			set temp to (items of theItem)
			repeat with oneContents in temp
				oneContents
				set end of subContents of theRecord to my getFinderItemDetails(oneContents)
			end repeat
		else if itemName of theRecord is "div" then
			set itemType of theRecord to "divider"
		else
			set itemType of theRecord to "script"
		end if
		
		theRecord
		set AppleScript's text item delimiters to oldDelims
		return theRecord
	end tell
end getFinderItemDetails

on addMenu(parentMenu, menuName, menuItem)
	set oldDelims to AppleScript's text item delimiters
	tell application "Adobe InDesign CS5"
		set AppleScript's text item delimiters to ""
		tell parentMenu
			if not (exists submenu menuName) then
				set currentMenu to (make submenu with properties {title:menuName})
			else
				set currentMenu to (submenu menuName)
			end if
			tell currentMenu
				if itemType of menuItem is "divider" then
					make menu separator
				else if itemType of menuItem is "sub_menu" then
					repeat with i from 1 to (count subContents of menuItem)
						my addMenu(currentMenu, itemName of menuItem, item i of subContents of menuItem)
					end repeat
					
				else if itemType of menuItem is "script" then
					make menu item with properties {associated menu action:my MakeMenuAction(itemName of menuItem, itemPath of menuItem)}
				end if
			end tell
		end tell
	end tell
	set AppleScript's text item delimiters to oldDelims
end addMenu

on MakeMenuAction(theTitle, theScriptPath)
	tell application "Adobe InDesign CS5"
		try
			set menuAction to script menu action theTitle
		on error
			set menuAction to make script menu action with properties {title:theTitle}
		end try
		tell menuAction
			--If the script menu action already existed,
			--remove the existing event listeners.
			if (count every event listener) > 0 then
				tell every event listener to delete
			end if
			set myEventListener to make event listener with properties {event type:"onInvoke", handler:theScriptPath}
		end tell
	end tell
	menuAction
	return menuAction
end MakeMenuAction


Is it possible to add keyboard shortcuts to the items in the menus?

Yes, choose Edit → Keyboard Shortcuts.

Then, under “Product Area” choose “Scripts”.

Anything in the menus should be listed in there.

Great thank you. Btw thanks for sharing this script, it’s very useful for me.

Great =]

I’m pleased it’s useful.