I am expanding Zach’s (Aliases zvh) “Autolinking Bookends and DEVONthink records” script to create tags in Devonthink that correspond to the Bookends groups that a given publication item belongs to. For that I need a list of all of those groups.
It is possible to see list I need in Bookends as a groups column
I have written a script to do this, by searching through each group for the publication item.
tell application "Bookends"
tell front library window
set theAllBEGroupIDs to get (id of group items)
set BEGroupList to {"ASTest1"}
repeat with BEGroup in BEGroupList
set theBEIDs to get (id of publication items of group item BEGroup whose date modified comes after lastRunTime)
if theBEIDs is not {} then
repeat with theBEID in theBEIDs
try
set thisReference to first item of (publication items whose id is theBEID)
set {theBEID, theBEPaths, theBEAuthor, theBEEditor, theBETitle, theBEPublicationDate} to {id, path of attachment items, authors, editors, title, publication date string} of thisReference
-- get a list of groups that the reference belongs to
set theGroupsThatReferenceBelongsToList to {}
repeat with theBEGroupID in theAllBEGroupIDs
try
set currentGroup to first item of (group items whose id is theBEGroupID)
--search Bookends Group to see if the current publication item belongs to it
set inCurrentGroup to first item of (publication items of currentGroup whose id is theBEID)
if inCurrentGroup is not {} then
set end of theGroupsThatReferenceBelongsToList to currentGroup
end if
end try
end repeat
end try
end repeat
end if
end repeat
end tell
end tell
Is there a more efficient way to get this information?
Not sure if this is any faster (I would personally tend to do this in JS, which makes some of these things a bit easier and faster), but here FWIW is a variant approach in AppleScript:
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
-- Rob Trew @2020
on run
set groupIDLists to itemIDGroupZip()
tell application "Bookends"
tell front library window
set publication to item 1 of ((its selected publication items) as list)
my groupsForReference(groupIDLists, publication)
end tell
end tell
end run
------------------------- BOOKENDS -----------------------
-- itemIDGroupZip :: Bookends () -> [[(String, [String])]]
on itemIDGroupZip()
-- A list of group names paired with lists of reference IDs
tell application "Bookends"
tell front library window
tell (a reference to group items)
my zip(name, id of publication items)
end tell
end tell
end tell
end itemIDGroupZip
-- groupsForReference :: [[(String, [String])]] ->
-- Publication -> [String]
on groupsForReference(groupZip, publication)
-- A list of names of the groups of which
-- the given publication is a member
set idString to id of publication
script f
on |λ|(pair)
if item 2 of pair contains idString then
{item 1 of pair}
else
{}
end if
end |λ|
end script
concatMap(f, groupZip)
end groupsForReference
------------------------- GENERIC ------------------------
-- https://github.com/RobTrew/prelude-applescript
-- concatMap :: (a -> [b]) -> [a] -> [b]
on concatMap(f, xs)
set lng to length of xs
set acc to {}
tell mReturn(f)
repeat with i from 1 to lng
set acc to acc & (|λ|(item i of xs, i, xs))
end repeat
end tell
if {text, string} contains class of xs then
acc as text
else
acc
end if
end concatMap
-- min :: Ord a => a -> a -> a
on min(x, y)
if y < x then
y
else
x
end if
end min
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
-- 2nd class handler function lifted into 1st class script wrapper.
if script is class of f then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- zip :: [a] -> [b] -> [(a, b)]
on zip(xs, ys)
-- A list of step-wise pairs drawn from xs and ys
-- up to the length of the shorter of those lists.
set lng to min(length of xs, length of ys)
set zs to {}
repeat with i from 1 to lng
set end of zs to {item i of xs, item i of ys}
end repeat
return zs
end zip