As an exercise in heavily caffeinated OCD, I’ve written a script to extract menu items and their keyboard shortcuts from the current application. It’s been amusing, but there’s one aspect of it with which I’m unsatisfied.
The excerpt below shows the basic structure I’ve used to drill down through menus and menu items. It works, but is inelegant. It’s painfully ugly, not least of all because each successive level has to be manually coded. While this isn’t really a problem (sane developers limit the depth of their menu hierarchy), well. Like I said, caffeinated OCD.
A recursive approach seems called for, but I’m not familiar enough with AS to work it out. Perhaps wiser heads might care to provide an “oh, duh” moment?
tell application "System Events"
tell (first process whose frontmost is true) to ¬
set procName to name -- get name of current application
set procName to "Finder" -- DEBUG ONLY
set prevElName to "" -- start fresh
tell process procName -- tell the current application
-- ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ main menu bar for current application
set menuBar to menu bar 1 -- menu bar 1
-- ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ get menu bar items: , Finder, Edit, etc.
set allMenuBarItems to UI elements of menuBar -- get all menu bar items.
set theElements to items 2 through -1 of allMenuBarItems -- .and omit  menu
-- ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ menu bar item: Finder, File, Edit, etc.
repeat with thisElement in theElements
set theElements to Process_Item of me for ¬
thisElement given procName:procName
-- ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ menu: Finder or File or Edit, etc.
repeat with thisElement in theElements
set theElements to Process_Item of me for ¬
thisElement given procName:procName
-- ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ menu item: About Finder, Preferences., etc.
repeat with thisElement in theElements
set theElements to Process_Item of me for ¬
thisElement given procName:procName
-- ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ menu: About Finder or Preferences., etc.
repeat with thisElement in theElements
set theElements to Process_Item of me for ¬
thisElement given procName:procName
-- ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ menu item: Make New Sticky, Upper Case, etc.
repeat with thisElement in theElements
set theElements to Process_Item of me for ¬
thisElement given procName:procName
-- ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ menu: Make New Sticky or Upper Case, etc.
repeat with thisElement in theElements
set theElements to Process_Item of me for ¬
thisElement given procName:procName
-- ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ menu item: Pink, Green, Blue, etc.
repeat with thisElement in theElements
set theElements to Process_Item of me for ¬
thisElement given procName:procName
end repeat
-- ⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯ enough already
end repeat
end repeat
end repeat
end repeat
end repeat
end repeat
end tell
end tell