Deep Linking Hook

I’m feeling your pain.

Thanks for the explanation, that makes it clearer now. Basically you have to copy/paste the part of the Get Link script that gets the page no, ie
set thePage to current page of theWindow
into the Get Name script and return a value for the name as you see fit. Something like &” page “& thePage at the end of the current definition of the name.

Unfortunately, the variables are named differently in both scripts, so you’d have to figure out what theWindow refers to.

I’m sure is not too complicated, but I’m not going down the AppleScript road.

Rosemary Orchard says in this podcast that she has found situations where the same script command works with Applescript but will not work with JXA due to bugs in the way JXA is implemented by Apple. Thus she prefers Applescript over JXA.

Have you (or others) experienced similar situations? Any specific examples of known situations where Applescript works but the JXA version does not?

1 Like

There are some cases with whose where JS requires more convoluted ways then AS. Also, apparently sometimes parameters get not passed correctly to or from JXA to an application. We’ve seen that with DT record’s data property and also with an array parameter to one method that gets complied emptied out in the JXA version and remains intact in AS. And @mdbraber told me about problems with JavaScript libraries in JXA that are apparently absent with AppleScript libraries.

Then, if we’re talking ObjC, there’s the question of blocks: AS has them, some ObJC methods require them, but I have no idea how to provide them with JXA.

It might actually be worth exploring other JS approaches like node. In any case, when I said “I’m not going down the AppleScript road”, I was more talking about the language as such. The more I look at it, the more painful it gets. And it does not even have a defined grammar (afaik), so is it even a programming language in the proper sense of the term?

PS: The link you posted leads to a website requiring registration. Another road I’m not going down (anymore).

1 Like

Sorry- wrong link

This should work with no registration

Thanks you. I think I need the help from @LucB Any ideas Sir? Thanks in advance

This was the exact reason why I was hesitant to switch to JXA at first - and it still might happen, but so far my experience has mainly pointed out bugs which seem to be fixable if the developer wants to (thanks @cgrunenberg)

@chrillek listed a few of those. My gripe indeed is that Library support in JXA is poorly implemented (e.g. a Library only exports individual functions, not objects). This means having to resort to ‘hacks’ like: Loading other javascript modules? · Issue #1 · JXA-Cookbook/JXA-Cookbook · GitHub (which works and is OK for me).

I’ve often thought what @chrillek was on about when referencing JXA in comparison to AS on this forum. But I’ve completely rewritten 3 of my main scripts from AS and JXA recently and the scripts have become better to read, less error-prone and (much!) more flexible. So although JXA might still pose problems, I’m happy that I’ve switched.

Also, recently I’ve added some iOS specific interactions using Scriptable which is also JS-based and it does help that all my other scripting now is in JS too.

I’d never heard of Obj-C blocks before now, but reading from e.g. Objective-C Blocks it seems they’re basically the same as lambda function in other languages (like Python, which I understand a bit). @chrillek would ObjC-block be helpful, considering you could also bring ObjC into JXA and use anonymous functions there? I’m sure I’m missing something as I haven’t been needing something like ObjC-blocks, but just wondering.

I think being able to keep things as lightweight as possible in things that I use often like Smart Rules using something like Node seems like a heavy-weight solution.

my experience has mainly pointed out bugs which seem to be fixable if the developer wants to

You are referring to a limited range of experience. I generally would not anticipate specific JXA fixes.

Dear @cgrunenberg and @LucB,
There is one issue with this script. Hook can’t get the link from a folder in DT (for PDF file and video file, it works well). Any idea for this issue?

I’m not seeing any issue with getting the reference URL from a group in DEVONthink. However, I also just rewrote the Get Name and Get Address scripts…

Get Address
tell application id "DNtp"
	if exists content record then
		-- A content record is also a property of the application
		-- Content record applies to all think windows
		-- If a document window is open, there IS a content record
		-- A viewer window requires the view/edit pane to be visible to have a content record
		return reference URL of content record
	end if
	
	if class of think window 1 is equal to viewer window then
		if selection of think window 1 ≠ {} then
			set sel to (selected record 1) -- Get only the first selected record
			return reference URL of sel
		else
			-- The group selected in the Navigate sidebar is the root of the window
			return reference URL of root of think window 1
		end if
	end if
end tell
Get Name
tell application id "DNtp"
	if exists content record then
		-- A content record is also a property of the application
		-- Content record applies to all think windows
		-- If a document window is open, there IS a content record
		-- A viewer window requires the view/edit pane to be visible to have a content record
		return name of content record
	end if
	
	if class of think window 1 is equal to viewer window then
		if selection of think window 1 ≠ {} then
			set sel to (selected record 1) -- Get only the first selected record
			return name of sel
		else
			-- The group selected in the Navigate sidebar is the root of the window
			return name of root of think window 1
		end if
	end if
end tell

Does that work for you?

Dear @BLUEFROG,

Thanks but it is actually not what I wanted. Your new scripts are somehow similar with the default scripts in Hook which means I can retrieve the group or file markdown link (clickable URL) but without deeper parameters in it.

However, what I wanted, also the topic of this discussion here, is that I can retrieve the page link from the PDF file or the frame link from the video file. In addition, the name can be changed accordingly by adding the page number or frame offset time such as [DT Help page 3](x-devonthink-item://<uuid>page=3), something like this.

For group, since there is no parameter of page or frame, just remain like [DT folder](x-devonthink-item://<uuid>).

You can refer to the scripts that @cgrunenberg wrote below.

As to blocks: there are some objc frameworks where they’re needed as kind of callback functions. And I was not able to figure out how to do that in JXA. Anonymous functions don’t work.

The rest (Scriptable, nose) is too off-topic here.

That’s indeed true Jim. So far most JXA issues I’ve encountered come down to bugs, rather than inherent problems with JXA.

That’s quite different to my experience - so far most “fixes” for JXA were just workarounds as it was actually a shortcoming/bug of JXA. E.g. like this one:

DEVONthink will handle this but shouldn’t have to.

I see - we’re talking about the same thing here, from my perspective it seems like a bug, but as a developer from your perspective I now understand they are JXA bugs. Too bad the JXA implementation seems so brittle :frowning:

You mean that DT is actually fixing a JXA shortcoming by use of a workaround?

Exactly.

I did read the manual and support documents but I cannot find a way to link specific Markdown sections or rich text paragraphs. Is there an explanation or link you can point me to so I can create a “deep” link to a specific section of a document? Thank you!

That’s e.g. possible via the contextual menu in the text editor or via the Table of Contents inspector too.

Thank you!

Dear Sheng, I found [johnsidi]'s ( @ hook forum) script worked well for me to get URLs for a specific PDF page using hook. Maybe it will work for you.

tell application id "DNtp"
	if exists (content record of window 1) then
		-- current open item
		if type of (content record of window 1) is PDF document then
			set RecordLink to the reference URL of (content record of window 1)
			set PDFpage to current page of window 1
			set DEVONthinkLink to RecordLink & "?page=" & PDFpage
			return DEVONthinkLink
			
		else
			return reference URL of (content record of window 1)
		end if
	end if
	
	if class of window 1 is in {viewer window, search window} then
		set selected_items to selection of window 1
		if (count of selected_items) = 1 then
			if type of item 1 in selected_items is PDF document then
				
				-- current selected item
				set RecordLink to the reference URL of item 1 in selected_items
				set PDFpage to current page of viewer window 1
				set DEVONthinkLink to RecordLink & "?page=" & PDFpage
				return DEVONthinkLink
			else
				return reference URL of item 1 in selected_items
			end if
			
		end if
	end if
	
	-- selected group
	return reference URL of root of window 1
end tell

Thanks @oriexm
Scripts @cgrunenberg provided above could already get the PDF page through Hook.