For large documents, I’m creating a companion “reading notes” file in omnioutliner.
I’m trying to automate the process as follows:
- select the document in DTPO
- type a hot key which activates a script (through a KM Macro) to :
- fetch a template oo file at a fixed location in my document folder
- save the oo file in DTPO with the same name as the main file and IN THE SAME GROUP as the orignal file
- open both files side to side.
I’m using the “open two files” script as a starting point.
I’m stuck with identifying the GROUP to which my current selected record belongs. I wanted to do this :
tell application id "DNtp"
activate
set curRec to (item 1 of (selection as list))
set curUuid to (kind of curRec)
set curParent to (parent of curRec)
set dest to curParent
set newRec to (create record with {name:"test", content:"my test", type:txt}) in dest
end tell[
/code]
but it creates the record in my Global Inbox (which is the default new record creation location)
Obviously, I don't understand how the "parent" property works ....
Any ideas ?
Each record can have multiple parents, e.g. if it’s tagged or replicated. Therefore you have to use e.g. “parent 1 of curRec”.
A JavaScript for Automation route to the primary ancestral path of the first selected item:
(() => {
// Primary ancestral path of selected DEVONthink item
const main = () => {
const xs = Application('DEVONthink Pro').selection();
return 0 < xs.length ? (
unlines(
primaryPath(
x => x.name(), // E.G. as name strings
xs[0]
)
)
) : '';
};
// DEVONthink -----------------------------------------
// primaryPath :: (Record -> a) -> Record -> [a]
const primaryPath = (f, item) => {
const go = x => {
const ps = x.parents() || [];
return 0 < ps.length ? (
go(ps[0]).concat(f(x))
) : [];
};
return go(item);
};
// GENERIC --------------------------------------------
// unlines :: [String] -> String
const unlines = xs => xs.join('\n');
// MAIN ---
return main();
})();
Or Applescript
on run
tell application "DEVONthink Pro" to set xs to selection
if xs ≠ {} then
unlines(primaryPath(itemName, item 1 of xs))
else
""
end if
end run
-- primaryPath :: (Record -> a) -> Record -> [a]
on primaryPath(f, x)
script go
property mf : mReturn(f)'s |λ|
on |λ|(x)
using terms from application "DEVONthink Pro"
set ps to parents of x
end using terms from
if ps ≠ {} then
go's |λ|(item 1 of ps) & mf(x)
else
{}
end if
end |λ|
end script
go's |λ|(x)
end primaryPath
-- itemName :: DT Record -> String
on itemName(x)
using terms from application "DEVONthink Pro"
name of x
end using terms from
end itemName
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- unlines :: [String] -> String
on unlines(xs)
set {dlm, my text item delimiters} to ¬
{my text item delimiters, linefeed}
set str to xs as text
set my text item delimiters to dlm
str
end unlines
Thank you both for your answers - I’d solved my problem with a hack but I’m sure it’ll go quicker knowing how to manage parents.
Also, it’s opened a can of worms into JXA for me, of course - good thing I’m on vacation