Setting the selection with scripting

Users asking other users for AppleScripts that work with Bookends.
Post Reply
ryanjamurphy
Posts: 20
Joined: Mon May 20, 2019 8:41 pm

Setting the selection with scripting

Post by ryanjamurphy »

What's the best way to select or reveal multiple Bookends references in a script? E.g., given a set of Bookends IDs, is there a way to show all of them in the front library window?

The command:

Code: Select all

set selected publication items
doesn't seem to work, and filters/sql searches just return the data in scripting, rather than manipulate the window to reveal the result.

I imagine I can make a group, but I'm really just looking to display a set of references, so creating groups is a bit more permanent than I'm hoping for.

Here's the use case, in case it helps. I have DEVONthink records with Bookends id metadata, sometimes multiple such IDs (e.g., if a Book file relates to multiple chapters listed as references in Bookends). If a record only has one Bookends id, I can just prepend the Bookends url ("bookends://sonnysoftware.com/") and use open location to reveal that item. The problem is these multi-ID records. It is trivial to build a list of them as either ids or as actual library items or publication items in Bookends, but I can't figure out what to do with those objects to reveal them in a Bookends window.
msteffens
Posts: 37
Joined: Thu Jul 19, 2007 10:04 am
Location: Germany
Contact:

Re: Setting the selection with scripting

Post by msteffens »

Hi Ryan,

I agree it would be useful to be able to set the selected publication item(s) via AppleScript. But currently, the `selected publication items` property of the `library window` class is marked as read only in the Bookends scripting dictionary.

I think that the workarounds that you've suggested for single IDs:

Code: Select all

tell application "Finder" to open location "bookends://sonnysoftware.com/" & pubID
as well as for multiple IDs (display them in a group) are your best bets for now.

Below is a generic script which will take a list of publication IDs, and display them in a group (specified by name at the top of the script). Note that you'd also need to specify the publication IDs within the script.

Hope this helps,
Matthias

Code: Select all

-- Creates a Bookends group and populates it with the publications having the given IDs

-- the name of the Bookends group which will hold the publications with the given IDs
property groupName : "Temp" -- adopt to your needs

-- adopt this to set pubIDs to a list of your Bookends publication item IDs
set pubIDs to {}
copy "72577" to end of pubIDs -- adopt to your needs
copy "79628" to end of pubIDs -- adopt to your needs


-- ----------- you shouldn't need to edit anything below this line -----------

my removePubsFromGroup(groupName)
my addPubsToGroup(groupName, pubIDs)

-- adds the publication items with the given IDs to the group with the given name
on addPubsToGroup(aGroupName, pubIDs)
	if pubIDs is {} then return
	
	my createGroupWithName(aGroupName)
	
	tell application "Bookends"
		tell front library window
			set myGroupNames to name of every group item
			if myGroupNames contains aGroupName then
				set pubList to my pubsByID(pubIDs)
				add pubList to group item aGroupName
			end if
		end tell
	end tell
end addPubsToGroup

-- removes all publication items from the group with the given name
on removePubsFromGroup(aGroupName)
	if aGroupName is "" then return
	
	tell application "Bookends"
		tell front library window
			set myGroupNames to name of every group item
			if myGroupNames contains aGroupName then
				set groupPubs to (publication items of group item aGroupName) as list
				remove groupPubs from group item aGroupName
			end if
		end tell
	end tell
end removePubsFromGroup

-- if necessary, creates a new Bookends group with the given name
on createGroupWithName(aGroupName)
	if aGroupName is "" then return
	
	tell application "Bookends"
		tell front library window
			set myGroupNames to name of every group item
			if myGroupNames does not contain aGroupName then
				make new group item with properties {name:aGroupName}
			end if
		end tell
	end tell
end createGroupWithName

-- returns the Bookends publication items with the given IDs
on pubsByID(pubIDs)
	if pubIDs is {} then return
	
	set pubList to {}
	
	tell application "Bookends"
		tell front library window
			set existingPubIDs to id of every publication item
			repeat with aPubID in pubIDs
				if existingPubIDs contains aPubID then
					set aPub to publication item id aPubID
					copy aPub to end of pubList
				end if
			end repeat
		end tell
	end tell
	
	return pubList
end pubsByID
ryanjamurphy
Posts: 20
Joined: Mon May 20, 2019 8:41 pm

Re: Setting the selection with scripting

Post by ryanjamurphy »

Thanks, Matthias. Indeed, I had given up and resorted to the two options you describe.

This was for a workflow bridging DEVONthink and Bookends. In DEVONthink 3 using custom record metadata of the form (bookendsid#, bookendsid#, bookendsid#, ... , bookendsid#), the script I crafted either opens the record using the bookends URL scheme (if only one id is found) or asks for the name of a group and places them all in that group.

I do like your buffer-style solution, though—keeping a standard quick-reference group and emptying it before refilling it is clever. I may implement that myself.

Here's my script, anyway, for others looking to do this.

Code: Select all

tell application id "DNtp"
	set theRecords to the selection
	set bookendsReferenceList to {}
	repeat with eachRecord in theRecords
		set bookendsIDData to get custom meta data for "bookendsid" from eachRecord
		if bookendsIDData does not contain ", " then
			my openBookendsItem(bookendsIDData)
			return
		end if
		
		set bookendsIDs to my splitText(bookendsIDData, ", ")
		tell application "Bookends"
			tell front library window
				set theItems to {}
				repeat with eachID in bookendsIDs
					if eachID is not "" then
						set nextPublication to (the first item of (get every publication item whose id contains eachID))
						copy nextPublication to the end of theItems
					end if
				end repeat
				
				set targetGroupName to the text returned of (display dialog "Name the group for these items:" default answer "")
				set targetGroup to make new group item with properties {name:targetGroupName}
				
				repeat with eachItem in theItems
					add eachItem to targetGroup
				end repeat
				
			end tell
		end tell
	end repeat
end tell

-- from Apple's scripting guides (https://developer.apple.com/library/archive/documentation/LanguagesUtilities/Conceptual/MacAutomationScriptingGuide/ManipulateText.html#//apple_ref/doc/uid/TP40016239-CH33-SW6)
on splitText(theText, theDelimiter)
	set AppleScript's text item delimiters to theDelimiter
	set theTextItems to every text item of theText
	set AppleScript's text item delimiters to ""
	return theTextItems
end splitText

on openBookendsItem(someBookendsID)
	open location "bookends://sonnysoftware.com/" & someBookendsID
end openBookendsItem
Post Reply