Name of file extension for Link to clipboard?

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

That’s the raw extension (e.g. .jpeg) or the kind shown by the Finder & DEVONthink for this document type?

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 would prefer the kind shown by the Finder & DEVONthink , but it also goes the raw extension.

yes sure, tell Application, is with in it first. All in all, thanks, I’ll have to take a closer look and try it out.

:rofl: Wait for Christmas—the revenge of the bracket-haters will be sweet! :wink:

Stephen

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

In that case the kind property of records should be what you’re looking for.

1 Like

Here’s what I’m seeing for ‘kind’
Screen Shot 2022-11-15 at 08.45.25

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"
1 Like

Or even:

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 --> ""

Or even

const recordName = "this is a test"
const match = recordName.match(/.*\.(.*)$/);
const e = match ? match[1] : '';

without jumping through loops with TIDs and only half the typing :wink:

Well… you can have a script do the typing for you. My Script Menu is full of snippets to do just that.

1 Like

Or even…

set recordName to "this is a test.file.jpg"
do shell script "echo " & (quoted form of recordName) & " | sed -E 's_^.*\\.(.*$)_\\1_'"
--> jpg

:wink:

The ^ in the RE is not necessary :wink:

Indeed. I was thinking one thing, got sidetracked, and came back to it. Guess I should have reread what I was doing :stuck_out_tongue: