Rupert Bedford

Creating a macOS droplet in JavaScript

Having tried quite a few apps, I've settled on writing notes in Markdown using Visual Studio Code. It works well but adding images can be a little fiddly. I thought it would be interesting to create a droplet to automate it.

It's as simple as dropping the image on the droplet. The droplet moves the image to the correct folder, renames it, and copies the image tag to the clipboard. Then you can paste the image tag into the Markdown file.

I couldn't find many examples on the Internet, so I thought I'd share my efforts here.

On macOS, droplets can be created using the built-in Script Editor. You can choose between the quirky AppleScript language or JavaScript. I was able to piece the script together using a few examples from Stack Overflow and the documentation in the Library window (โ‡งโŒ˜L).

  1. Open Script Editor.app.
  2. Create a new script and use the dropdown to switch the language from AppleScript to JavaScript ๐Ÿ˜Œ.
  3. Save the script as an application (with the .app extension).
var app = Application.currentApplication();
app.includeStandardAdditions = true;

var finder = Application("Finder");

function openDocuments(droppedItems) { // 1
  for (var droppedItem of droppedItems) {
    var filename = getFilename(droppedItem); // 2

    var response = app.displayDialog("Move", {
      defaultAnswer: filename,
      buttons: ["Cancel", "Continue"]
    }); // 3

    if (response.buttonReturned === "Cancel") {
      break;
    }

    filename = response.textReturned;

    var item = finder.move(droppedItem, {
        to: Path("/Users/rupert/Documents/Notes/")
    });
    item.name = filename; // 4

    app.setTheClipboardTo("![](" + filename + ")"); // 5
  }
}

function getFilename(path) {
  var parts = path.toString().split("/");
  var filename = parts[parts.length - 1];
  filename = filename.toLowerCase();
  filename = filename.replace(/[_\s]/g, "-");
  filename = filename.replace(/[^a-z0-9-\.]/g, "");
  filename = filename.replace(/-{2,}/g, "-");
  filename = filename.replace(/\.{2,}/g, ".");
  return filename;
}

Here's a breakdown of what each bit is doing:

  1. openDocuments is called with the list of paths dropped on the droplet application.
  2. getFilename takes each path and returns a normalised filename with spaces etc. removed.
  3. Shows a dialog box so the filename can be customised if necessary.
  4. Moves the file into the notes folder with its new name.
  5. Copies the image syntax (![]($filename)) to the clipboard so it can be pasted into the Markdown file.