Skip to content

Instantly share code, notes, and snippets.

@extratone
Created June 11, 2025 03:08
Show Gist options
  • Save extratone/caefebb1fa16a9096c85f16e829dd1ed to your computer and use it in GitHub Desktop.
Save extratone/caefebb1fa16a9096c85f16e829dd1ed to your computer and use it in GitHub Desktop.
Action script for FlohGro's Drafts action for creating DEVONThink bookmarks for URLs in the current Draft.
// created by @FlohGro
const content = draft.content;
// regel to match markdown urls "[]()”
let regex = /\[([^\[]+)\]\(([^\[]+)\)/g;
// prompt to select the url to open
var pSelUrl = Prompt.create();
// flag to indische if any url was found.
var foundUrlCounter = 0;
// if only one url is in the note - open it directly - first url will be stored in this variable
var firstURL = [];
var urlsWithDescription = [];
var links = new Map();
var urlToStore;
// DEVONthink URL scheme
if (device.model == "Mac") {
var baseUrl = "x-devonthink://createbookmark";
} else {
var baseUrl = "x-devonthink://x-callback-url/createbookmark";
}
let foundUrl = findAndStoreUrls();
if (foundUrl) {
urlToStore = getUrlToStore();
} else {
let message = "no markdown url '[..](..)' found in draft";
context.cancel(message);
app.displayInfoMessage(message);
}
if (foundUrl) {
if (urlToStore) {
storeURL(urlToStore);
} else {
let message = "no url to open selected";
context.cancel(message);
app.displayInfoMessage(message);
}
}
// functions
// stores the found urls in the prompt as buttons
function findAndStoreUrls() {
var matches = [...content.matchAll(regex)];
if (matches) {
for (match of matches) {
foundUrlCounter++;
let description = match[1];
let url = match[2];
// add "http://" if the url is no callback url and just witten as domain.
if (!url.match(/:\/\//)) {
url = "http://" + url;
}
links.set(description, url);
if (foundUrlCounter == 1) {
firstURL = [description, url];
}
}
}
if (foundUrlCounter == 0) {
return false;
} else {
return true;
}
}
function getUrlToStore() {
if (foundUrlCounter == 1) {
return firstURL;
} else if (foundUrlCounter > 0) {
pSelUrl.title = "select URL:";
for (currentDescription of links.keys()) {
let currentUrl = links.get(currentDescription);
pSelUrl.addButton(currentDescription, [currentDescription, currentUrl]);
}
pSelUrl.addButton("Add all URLs");
var didSelect = pSelUrl.show();
if (didSelect) {
return pSelUrl.buttonPressed;
}
}
}
function storeURL(descUrl) {
if (descUrl == "Add all URLs") {
for (currentDescription of links.keys()) {
let currentUrl = links.get(currentDescription);
let cb = CallbackURL.create();
cb.baseURL = baseUrl;
cb.addParameter("title", currentDescription);
cb.addParameter("location", currentUrl);
if (device.model == "Mac") {
cb.waitForResponse = false;
cb.open();
} else {
var success = cb.open();
if (success) {
app.displaySuccessMessage('bookmarked "' + currentDescription + '" in DEVONthink');
} else {
app.displayErrorMessage('bookmarking "' + currentDescription + '" in DEVONthink failed!');
context.fail();
}
}
}
} else {
let description = descUrl[0];
let url = descUrl[1];
//alert(description + ": " + url);
var cb = CallbackURL.create();
cb.baseURL = baseUrl;
cb.addParameter("title", description);
cb.addParameter("location", url);
if (device.model == "Mac") {
cb.waitForResponse = false;
cb.open();
} else {
var success = cb.open();
if (success) {
app.displaySuccessMessage('bookmarked "' + description + '" in DEVONthink');
} else {
app.displayErrorMessage('bookmarking "' + description + '" in DEVONthink failed!');
context.fail();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment