Scrivener 3 and Hook

Hey @RobTrew, thanks for your work on this, here’s the script we ended up including in Hook, a modified version of what you’ve done

set the clipboard to ""
tell application "System Events"
	tell process "Scrivener"
		tell menu bar 1
			
			-- check if binder is hidden
			click menu item 3 of menu 1 of menu item "Move Focus To" of menu "Navigate"
			set isHidden to not enabled of menu item "Copy Document as External Link" of menu 1 of menu item "Copy Special" of menu "Edit"
			
			-- show binder, select item in binder, move focus to binder
			click menu item "Reveal in Binder" of menu "Navigate"
			click menu item 3 of menu 1 of menu item "Move Focus To" of menu "Navigate"
			
			-- get address
			click menu item "Copy Document as External Link" of menu 1 of menu item "Copy Special" of menu "Edit"
			delay 0.1
			set scrivAddr to the clipboard
			
			-- get name
			click menu item "Copy" of menu "Edit"
			delay 0.1
			set scrivName to the clipboard
			
			-- hide binder
			if isHidden then
				click menu item 5 of menu "View"
			end if
			
			return "[" & scrivName & "](" & scrivAddr & ")"
		end tell
	end tell
end tell

some notes:

We don’t check that the process exists. If it doesn’t exist then the script will throw an error which Hook will catch and log.

We set the clipboard to “” because if the “Copy” commands fail, the script will return a markdown link with whatever is in the clipboard, and if a URL is in the clipboard, Hook will believe that a valid link was returned, if []() is returned Hook will discard it as garbage.

As you noticed, the “Hide/Show Binder” menu item label changes. The “Move Focus To>Binder” also changes, so for both of those we access the menu items by index number.

Navigate>Reveal in Binder is better for showing the binder than “Show Binder” because

  1. It works whether or not binder is hidden, no need to check
  2. It selects the current item in the binder

#1 is actually a moot point because we check whether the binder is hidden so that we can re-hide it again later

But #2 handles an edge case in which two documents are open, in top and bottom editor, and the binder selection and the focused editor don’t match. Reveal in Binder will move the selection to the correct item.

As mentioned above, we track whether the binder was hidden at the start, and re-hide it at finish.

After clicking “Move Focus To>Binder”, “Edit>Copy” doesn’t work until the UI updates with the new focus and selected item, which requires a delay. But “Copy Document as External Link” works immediately. So by getting the address before the name, we’re able to remove a delay because the delay for the clipboard after copying the address serves dual purpose as delay for the UI to update for “Edit>Copy”

Delays in UI scripting are more of an art than a science but, knock on wood, 0.1 is enough for the clipboard