List all JSONs Macro (v11.0.3)

I'm starting to work with JSON variables, and I realized I needed a utility that shows all my JSON variables. After I wrote this, I asked some AI to tell me if this was possible, and all it came up with was some JXA code, which I couldn't understand, so maybe this simpler solution will help those of us who are trying to learn to use JSON variables.

If anyone asks, I could probably modify this macro to let you choose between names only, or names plus values. Right now it's the latter.

If anyone has a different or better solution, please provide it.

List all JSONs Macro (v11.0.3)

List all JSONs.kmmacros (6.1 KB)

Some of the Keyboard Maestro variable values which you may not consciously have intended as JSON strings will nevertheless be parseable as well-formed JSON

( any numbers, any strings in double quotes, any of the unquoted special words true, false and null are, for example parseable as JSON).

For a lightly Markdown-formatted listing of any Keyboard Maestro variables which turn out to be parseable as JSON strings, you could write something like:

MD listing of KM variables with JSON-parseable values.kmmacros (2.8 KB)


Expand disclosure triangle to view JS source
const main = () => {
    const
        kmvars = Application("Keyboard Maestro Engine").variables,
        listing = zipWith(
            name => value => validJSON(value)
                ? [`#### ${name}:\n\`\`\`json\n${value}\n\`\`\``]
                : []
        )(
            kmvars.name()
        )(
            kmvars.value()
        )
            .flat()
            .join("\n\n");

    return `## KM variables with values parseable as JSON:\n\n${listing}`;
};


// --------------------- GENERIC ---------------------

// validJSON :: String -> Bool
const validJSON = s => {
    try {
        return (
            JSON.parse(s),
            true
        );
    } catch (e) {
        return false;
    }
};


// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
const zipWith = f =>
    // A list constructed by zipping with a
    // custom function, rather than with the
    // default tuple constructor.
    xs => ys => Array.from(
        { length: Math.min(xs.length, ys.length) },
        (_, i) => f(xs[i])(ys[i])
    );


return main();

I could add this option to my Variable Inspector Prompt, if you wanted it. It already supports the option to see all variables, and when I display the value of a variable, I check to see if it's JSON and if it is, I display it that way.

It would be simple enough to add a button to filter on JSON variables.

By the way, the way I determine if something is JSON is I first check to see if it starts with "[" or "{", then do a JSON.parse (in javascript) on it, and if it doesn't fail, then then its JSON.

If this is something you would find useful, let me know and I'll implement it.

2 Likes

Useful for testing for one particular subset of JSON strings (representations of dictionary Objects, and Arrays), but not quite the same as the JSON standard itself, which – unlike the plist standard – includes, for example, JS notation for stand-alone String, Number, Boolean, and null objects.

(String values have to begin and end with a double-quote character)


JavaScript Object Notation – www.json.org

There's exceptions to everything. My goals are always to cover the most obvious needs, and respond to others as needed.

Of course, with that said, I'm spending an inordinate amount of time tweaking something I'm working on to handle certain things probably nobody needs, (and I know you totally understand this need), so I guess I'm just strange. ;p

Indeed :slight_smile:

Perhaps that sheds light on why vehicles go off the road, and code fails ?

Worth working with (rather than against) all the effort that goes into things like:

  • The definition of JSON
  • The engineering of the Keyboard Maestro %JSONValue% token.

if we don't want macro evaluation to go off the rails unexpectedly.

For example, if we bind values to a Keyboard Maestro variable with a name like local_JSON,

the value returned by an expression like %JSONValue%local_JSON% depends on whether the value of local_JSON is a valid JSON string or not. If not, the return value is just an empty string.

local_JSON %JSONValue%local_JSON%
[1,2,3] [1,2,3]
{"alpha":1} {"alpha":1}
"hello" hello
42 42
true true
false false
True
False
unquoted string
'single quoted'
Null
null null

I don't mean this to sound, well, the way it will sound, but... I don't want to spend any mental energy on this. Or another way of saying that is: I just don't care. :joy:

1 Like

Caveat emptor then :slight_smile:

1 Like

In fact we can define the listing directly in terms of %JSONValue% or %JSONValuePretty% tokens, since these return only empty strings for any Keyboard Maestro variable whose values are not parseable as JSON:

MD listing of KM Variables returning non-empty %JSONValue%.kmmacros (4.8 KB)

1 Like

I wish I knew about the double "%" mark technique that you used there. I might have done it your way if I had known about that method.

Now that's confusing, because among my 1000 variables I have variables containing quoted strings, numbers and similar things which are NOT being reported by my macro. Did you try running my macro and did you get any false positives?

Here are some actual "variable contents," one per line, which do not get reported by my macro:

true
"aa"
111

Did you try running my macro and did you get any false positives?

No false positives, the test which you are using errs on the other side, I think :slight_smile:

( false negatives – the keys of the json container is relevant to JSON values which have keys – dictionary objects and arrays – but misses other JSON values which are atomic, and not containers. %JSONValue% provides a more general test)

I'm a "roll your own macro" kind of guy. I'm learning how to use JSONs right now, which means I need to learn from the school of hard knocks.

1 Like

Note, incidentally, that it's useful to be able to check whether KM variable strings are valid as atomic JSON values.

If you are constructing your own JSON containers, you will find that the macro below works with JSON values like "aa", true, and 111 – for which %JSONValue% returns non-empty strings – but fails if you switch any of the atomics to non-JSON strings, e.g.

JSON Non-JSON
"aa" aa
true True
111 111 05

Building JSON containers from atomic JSON values.kmmacros (3.9 KB)

1 Like

I am exactly the same way.