Microsoft Word and deep linking?(Available in script version 281 and up)

These are the scripts I use, but they could doubtless be improved (in particularly using a random number as a unique id is obviously bad, but for purely personal use the risk of collisions is too low to justify the time investment in writing something better).

Open Item

This text will be hidden

use framework "Foundation"

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

on urlDecode(input)
	tell current application's NSString to set urlString to stringWithString_(input)
	set theDecodedURL to urlString's stringByRemovingPercentEncoding -- 4 is NSUTF8StringEncoding
	return theDecodedURL as Unicode text
end urlDecode


set fullURL to "$0"
set bkName to ""

set AppleScript's text item delimiters to "#"
set urlPath to text item 1 of fullURL
if (count of text items of fullURL) is greater than 1 then
	set fragment to text item 2 of fullURL
	set AppleScript's text item delimiters to "&"
	set kvs to text items of fragment
	repeat with kv in kvs
		set AppleScript's text item delimiters to "="
		set k to text item 1 of kv
		set v to text item 2 of kv
		if k = "bkName" then
			set bkName to v as string
		end if
	end repeat
end if

set fpath to urlDecode(urlPath)
set text item delimiters to "/"
set fn to text item -1 of fpath
set len to length of fpath
set fpath to text 8 through len of fpath

tell application "Microsoft Word"
	open fpath
delay 0.1
	set bkMark to bookmarks of active document whose name is bkName
	try
		select (item 1 of bkMark)
	end try
end tell
Get Name
tell application "Microsoft Word" to get name of active document
Get Address
use framework "Foundation"

use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions

property NSMutableCharacterSet : a reference to current application's NSMutableCharacterSet

on urlEncode(input)
	tell current application's NSString to set rawUrl to stringWithString_(input)
	set charset to NSMutableCharacterSet's URLQueryAllowedCharacterSet's mutableCopy
	charset's removeCharactersInString:"?"
	set theEncodedURL to rawUrl's stringByAddingPercentEncodingWithAllowedCharacters:charset
	return theEncodedURL as Unicode text
end urlEncode

tell application "Microsoft Word"
	set n to name of active document
	set f to full name of active document
	set ppf to POSIX path of f
	set selectedText to selection
	set bkName to "AS" & ((random number from 0 to 1.0E+8) as integer)
	make new bookmark at active document with properties {name:bkName, text object:text object of selectedText}
end tell

set x to "[" & n & " bkMark: " & bkName & "](" & "file://" & urlEncode(ppf) & "#bkName=" & bkName & ")"

@LucB Three points more generally:

  1. As with my PDF Expert script I’ve had to use a ‘Get Name’ script even though I’m returning a markdown link from the ‘Get Address’ script.
  2. Lots of the scripts end up having to roll their own URL- and key-value- coding procedures; it might be worth looking into whether it’s possible to let the scripts take/return a record with the relevant parameters, and then have Hook do the URL handling itself?
  3. One disadvantage of deep-linking is that currently you lose the context of what has been hooked to other parts of the document (or to the document as a whole). This is particularly severe here, because the granularity of the deep-link is a particular text range (not even a page, as with the PDF scripts). It might be useful if the interface could show both hooks to the link itself and other hooks with the same base URL? (I have toyed with having the ‘Get Address’ script itself create a non-deep-linked hook, and then hooking that and the new deep link together, but unsurprisingly calling Hook’s AppleScript dictionary from within a Get Address script seems unreliable!)
2 Likes