on performSmartRule(theRecords)
tell application id "DNtp"
set theSelection to the selection
repeat with theRecord in theSelection
set recordURL to reference URL of theRecord
-- The UUID is the alphanumeric portion of the reference URL
-- The rererence URL is the entire item link
set recordName to name of theRecord
-- Get the name of the record
set the comment of theRecord to recordURL
-- Set the comment of the record to the item link
set agendaNote to "agenda://x-callback-url/append-to-note?identifier=D5F1A1A4-D77D-4AE2-95CC-708AA6F1A006&text=" & "[" & (my urlencode(recordName)) & "](" & recordURL & ")"
-- The recordName is passed to the URLEncode handler
open location agendaNote
end repeat
end tell
on urlencode(str)
local str
try
return (do shell script "/bin/echo " & quoted form of str & ¬
" | perl -MURI::Escape -lne 'print uri_escape($_)'")
on error eMsg number eNum
error "Can't urlEncode: " & eMsg number eNum
end try
end urlencode
end performSmartRule
Note: I would get in the habit of adding comments to your code, especially as you’re thinking through something. Actually, a pen and pad of paper is a fantastic set of tools for scripting.
May I add that URI::Encode is not necessarily available? At least on my Big Sur installation, it does not exist.
If the whole thing doesn’t have to work in a smart rule, I could try to provide a JavaScript version. It provides a built-in method to encode URIs.
Do you mean MURI::Escape? Or am I overlooking a reference to URI::Encode in Jim’s script?
@bangersandmash from what you’ve posted I can’t see any obvious reason - would you post the whole script you are using - or is it exactly cut&paste from what Jim posted?
perl -MURI::Escape
tells the Perl interpreter to load the M odule (hence -M) URI::Escape. So: No, I mean URI::Escape. If you’re still on Catalina, give it a try:
ja, but you wrote URI::Encode, so I was confused (and see my next post, maybe you were too but thanks for the -M info - it’s little things like that which make it clear I’ve not got a clue )
Yeah, I tried that, had the same problem and posted the solution a couple of posts up. You might have missed that, because I went a little OT, which is why I’m pointing you to the solution again.
Thanks everyone, for your help. I can’t explain how, or why, but this is what finally worked (urlencode has to go first, for some reason):
on urlencode(str)
local str
try
return (do shell script "/bin/echo " & quoted form of str & ¬
" | perl -MURI::Escape -lne 'print uri_escape($_)'")
on error eMsg number eNum
error "Can't urlEncode: " & eMsg number eNum
end try
end urlencode
on performSmartRule(theRecords)
tell application id "DNtp"
set theSelection to the selection
repeat with theRecord in theSelection
set recordURL to reference URL of theRecord
-- The UUID is the alphanumeric portion of the reference URL
-- The rererence URL is the entire item link
set recordName to name of theRecord
-- Get the name of the record
set the comment of theRecord to recordURL
-- Set the comment of the record to the item link
set agendaNote to "agenda://x-callback-url/append-to-note?identifier=8DE495E1-6F45-41E0-9D34-30960408B0F4&text=" & "[" & (my urlencode(recordName)) & "](" & recordURL & ")"
-- The recordName is passed to the URLEncode handler
open location agendaNote
end repeat
end tell
end performSmartRule
Here’s a JavaScript version of the script (note: I used the “Title” to find the appropriate note in Agenda, so whoever prefers to use the “Identifier” has to change this).
It is a simple script, that CAN NOT be used in a smart rule (but from the context of this thread, I didn’t see the need for a smart rule anyway). Tested it with one DT record only.
(() => {
let app=Application("DEVONthink 3");
app.includeStandardAdditions = true;
let sel = app.selection();
sel.forEach(rec => {
let URL = rec.referenceURL();
let nameEncoded = encodeURIComponent(rec.name());
/* Change "title=Example%20Note" to "Identifier=xxx" if needed */
rec.comment = referenceURL();
let agendaNote = `agenda://x-callback-url/append-to-note?title=Example%20Note&text=[${nameEncoded}](${URL})`
app.openLocation(agendaNote);
});
})();
Today, URLs can contain Unicode characters. Which the code you linked to doesn’t handle. For example, encodeCharacter("个") returns “63”. The correct value is “%E4%B8%AA”, i.e. three encoded characters, not one.
And it’s a more work to encode a complete string then a single character.
A better alternative (if you insist on using AppleScript, that is )would be the stringByAddingPercentEncodingWithAllowedCharacters method of the NSString class (or a similar method), which you can access through the ASObjC bridge. Still more than a single line of code, I guess, but at least you should get the correct result.
FWIW, if you can use the satimage addition, it has an escapeURL command which returns the url encoding for any characters you feed it.
set x to "悪㎯个"
escapeURL x
--> "%E6%82%AA%E3%8E%AF%E4%B8%AA"
Of course, you can feed it just a single character as well.
set x to "个"
escapeURL x
--> "%E4%B8%AA"
As an aside, if you only have a character or two to encode, you can get the url encoding using the Character Viewer (aka Emoji & Symbols). From within the viewer, search for the character.
Right-click on the resulting character and you should see a Copy character info command. Click on it and then paste into an empty textedit window. You should see a result like this below.
个
CJK UNIFIED IDEOGRAPH-4E2A
Unicode: U+4E2A, UTF-8: E4 B8 AA
Take the hex numbers in the UTF-8 section, insert % and remove the spaces. You now have the url encoding for the character.
It works in both directions. If you search for E4 B8 AA then it will display the following:
Character
E4 B8 AA
Character code
个
Unfortunately, other than by using satimage’s escapeURL command, I don’t know how to programmatically get the UTF-8 code so it’s not as versatile as it might be (or maybe it’s just me that’s not).