MACRO Template: Copy Quiver Note to Clipboard as JavaScript

MACRO Template: Copy Quiver Note to Clipboard as JavaScript

Copy Quiver Note to Clipboard as JavaScript.kmmacros (18.7 KB)

###NOTES:

This is a first draft. It works as it is, but I expect it to go through many changes.

I'm posting this so other people can take the idea, and go wherever they want with it. It's just a working template - use it as is, or let your imagination run wild (or both).

##PURPOSE:

This is a macro which takes a Quiver note formatted like this:



and translate it into JavaScript with comments, like this:

// Does word-wrapping on a string.
// PARAMETERS:
// str: The input string.
// width: The width to wrap at, or 0 for no wrapping.
// cut: Cut in the middle of a long word, if needed.
// RESULTS:
// Returns an array of strings.
// UPDATED: 2016/06/16 09:23 PDT
function wordWrap(str, width, cut) {
    if (!str || width <= 0) {
        return [str];
    }
    cut = cut || false;

    var regex = '.{1,' + width + '}(\\s|$)' +
        (cut ? '|.{' + width + '}|.+$' : '|\\S+?(\\s|$)');
    return str.match(RegExp(regex, 'g'));
}

The main item of interest is the JS code that does the translation. Currently, this is the logic:

  1. It expects there to be Markdown code, followed by the JavaScript code block.
  2. It has Regexes for markdown lines that should be skipped. In this example, the "##" (h2) line is removed, as is the "## PURPOSE" line. Use as you see fit.
  3. It removes the leading "#" characters.
  4. It optionally word-wraps the comments, using a VERY COOL word wrapping function I found.
  5. It adds leading "//" characters
  6. It removes blank lines between the last comment and the JavaScript code.

###Things it does not handle:

  • There is a function called "removeSpecialMarkings", but it isn't coded yet. It's intended to be code that removes Markdown code like bold, etc.

###Here's the source for JavaScript routine:

(function() {
    'use strict';

    function readFile(strPath) {
        var error = $(),
            str = ObjC.unwrap(
                $.NSString.stringWithContentsOfFileEncodingError(
                    $(strPath)
                    .stringByStandardizingPath,
                    $.NSUTF8StringEncoding,
                    error
                )
            );
        if (error && error.code) {
            throw Error('Error ' + error.code + ' reading file "' + strPath + '"');
        }
        return str;
    }

    function shouldSkip(line) {
        return [
            /^## /,
            /^#* PURPOSE/,
            /^### AUTOMATION/
        ].some(function(regexp) {
            return regexp.test(line);
        });
    }

    function wordWrap(str, width, cut) {
        if (!str || width <= 0) {
            return [str];
        }
        cut = cut || false;

        var regex = '.{1,' + width + '}(\\s|$)' +
            (cut ? '|.{' + width + '}|.+$' : '|\\S+?(\\s|$)');
        return str.match(RegExp(regex, 'g'));
    }

    function commentAndWordWrap(str, width) {
        var lines = wordWrap(str, width, false);
        var result = "";
        lines.forEach(function(line) {
            result = (result + (result === "" ? "" : "\n") + "// " + line)
                .trimRight();
        });
        return result;
    }

    // tbd
    function removeSpecialMarkings(str) {
        return str;
    }

    var _kme = Application("Keyboard Maestro Engine");
    var _filePath = _kme.getvariable("cnjsFileName");
    if (_filePath == "") {
        throw "No file name";
    }
    var _inputLines = readFile(_filePath).split("\n");

    var _wrapWidth = 75;
    var _result = [];
    var _inJS = false;
    for (var i = 0; i < _inputLines.length; i++) {
        var line = _inputLines[i].trimRight();
        if (_inJS) {
            if (line.match(/^```/)) {
                break;
            }
            _result.push(line);
        } else if (line.match(/^```/)) {
            _inJS = true;
            if (_result.length > 0 && _result[_result.length - 1] == "//") {
                _result.pop();
            }
        } else if (!shouldSkip(line)) {
            _result.push(
                commentAndWordWrap(
                    line.replace(/(#* ?)/, ""), _wrapWidth));
        }
    }
    return _result.join("\n");
})()
1 Like

Interesting idea. I'm sure it will help some.

My style and approach are so different, that it is not of immediate use to me -- maybe later.

  • I always embed header comments directly in the code (regardless of language)
  • So all I really need is to copy the code, and put into the proper code editor.
  • Currently, for JXA, that would the the Script Editor, but may change.

I'm not asking you to change anything in your macro/script.
Just discussing alternate approaches.

BTW, did you know that Quiver stores its notes in a JSON file?
I know how you like to pry under the hood, so thought that might be of interest.

Oh, one more thing. some time ago I requested that Quiver support scripting (that would be AppleScript and JXA). The owner/developer liked the idea, and is working on it.

Considering this is the first thing I zeroed in on in your reply, then yes, this is interesting. Thanks - I kind of knew this, but I didn't really think it through.

I get that. For some reason, I liked the idea of having the comments in Markdown. Not sure why - maybe it's just a shiny new toy (no maybe about it). It's quite possible I'll change my mind.

What I really miss is Microsoft's "Intellisense" comments. You put a specially formatted set of comments (3 slashes instead of two, and some keywords), and the IDE reads them real-time and they get integrated right into the popup help. Very cool. And they can be mined to produce documentation - you can even generate an entire help website with full linkage and everything. But I digress (clearly).

Oh man, you have got to get Atom set up for this. So much better. Took me a while to figure out all the packages and stuff, and I'm still learning, but right now I'm loving it. I've even got local Git repositories going (piece of cake, as it turns out), and I LOVE version control.

And... as soon as I get the chance, I'm going to learn how to write packages myself, so I can finally get the keys to do exactly what I want.

As for Quiver supporting Automation, that would be cool.