Hello, I would like to copy a link to the clipboard according to the following scheme:
[name of file extension] Name of file without extension: item Link
like
[pdf] annual balance: x-devonthink-item://xxxx
I’ve put something together, but I’m missing the variable for the extension.
Can someone help me how to return the extension and include it in the script?
Unfortunately I have almost no programming experience.
Thanks.
set theLinks to {}
set theRecords to selected records
repeat with thisRecord in (selected records)
copy ("[" & (??name extension??) & "]" (name without extension of thisRecord) & ": " & (reference URL of thisRecord) & return) to end of theLinks
end repeat
if theLinks ≠ {} then
set the clipboard to (theLinks as string)
end if
end tell
For AppleScript, you must first select the application you’re going to work with:
tell Application id "DNtp"
set theLinks to {}
…
end tell
Next, it is pointless to define a variable you’re not using. Change
repeat with thisRecord in (selected records)
to
repeat with thisRecord in theRecords
As to your question: I have no idea how one would do that with AppleScript. Probably a winded way. In JavaScript, I’d do something like this:
const app = Application("DEVONthink 3");
app.includeStandardAdditions = true; /* needed for clipboard methods */
const links = app.selectedRecords.map( r => {
return `[${r.name().replace(/.*\.(.*)$/,"$1")] ${r.nameWithoutExtension()}: ${r.referenceURL()}`;
})
if (links.length) app.setTheClipboardTo(links.join('\n');
Since it’s a weekend, I deliberately used a lot of brackets, parenthesis and such, to enlighten @Blanc.
Some explanations might be in order, though.
app.selectedRecords.map(...) executes a function for every element in the array (list in AS parlance). It returns an array again, hence links is an array.
r => {...} is a shorthand for function(r) {...}. r is the function’s argument, the function body is included in the curly braces.
`…` is a string template in JavaScript: A string that may contain elements which are evaluated
Such an element is ${name().replace(…)}: Take the record’s name, replace everything in it with the extension (assuming that the extension is the stuff after the last dot).
The replace method uses a regular expression: Match anything (.*) up to and including the last dot (\\.). Then collect everything ((.*)) up to the end of the string ($) in a capturing group (hence the parenthesis) and replace it which the first capturing group ("$1"). Which is the only one, in this case.
The rest of the map function is straight forward, kind of.
At the end, we check if links.length is “something” (in particular not 0). If so, we set the clipboard to the string obtained by joining the elements of the links arraywith newlines. Which is the equivalent of adding a return to every element of the links list in your AppleScript.
I’m not seeing a shortcut solution, so I would use a handler
something like
copy ("[" & my GetExtension(name of thisRecord) ...
on GetExtension(theFileName)
... insert code
return theExtension
end GetExtension
As to the code required
The brute force method would be to start at the end of the filename, extracting characters until "." is required
Here is a simple AppleScript method to get the extension of a filename…
set recordName to "this is a test.file.jpg"
set extensionOffset to (offset of "." in (reverse of characters of recordName as string)) - 1
set fileExtension to (characters -1 through -extensionOffset of recordName) as string
--> "jpg"
set recordName to "this is a test"
set {TIDs, AppleScript's text item delimiters} to {AppleScript's text item delimiters, "."}
set e to last text item of recordName
if e = recordName then set e to ""
set AppleScript's text item delimiters to TIDs
e --> ""