Adding the prefixes might look like this:
Insert quoted or bracketet text.kmmacros (13.0 KB)
(() => {
"use strict";
// Lines of quoted strings only.
// quotedTokens :: String -> [String]
const quotedTokens = source => {
// A list of the quoted tokens in the source.
const quoteChars = "“”‘’„‟()";
return groupBy(
on(eq)(
c => quoteChars.includes(c)
)
)(` ${source}`)
.reduce(
([s, xs], cs, i) => 0 !== i % 4 ? (
[`${s}${cs.join("")}`, xs]
) : Boolean(s) ? (
["", xs.concat(s)]
) : [s, xs],
["", []]
)[1];
};
const main = () => {
const
prefixes = "abcdefghijklmnopqrstuvwxyz0123456789";
const
tokens = quotedTokens(
Application("Keyboard Maestro Engine")
.getvariable("quotedSource")
);
return prefixes.length >= tokens.length ? (
zipWith(
prefix => token => `${prefix} - ${token}`
)(
prefixes.split("")
)(
tokens
).join("\n")
) : "Not enough prefixes defined for token list";
};
// --------------------- GENERIC ---------------------
// Tuple (,) :: a -> b -> (a, b)
const Tuple = a =>
// A pair of values, possibly of
// different types.
b => ({
type: "Tuple",
"0": a,
"1": b,
length: 2,
*[Symbol.iterator]() {
for (const k in this) {
if (!isNaN(k)) {
yield this[k];
}
}
}
});
// eq (==) :: Eq a => a -> a -> Bool
const eq = a =>
// True when a and b are equivalent in the terms
// defined below for their shared data type.
b => a === b;
// groupBy :: (a -> a -> Bool) -> [a] -> [[a]]
const groupBy = eqOp =>
// A list of lists, each containing only elements
// equal under the given equality operator,
// such that the concatenation of these lists is xs.
xs => 0 < xs.length ? (() => {
const [h, ...t] = xs;
const [groups, g] = t.reduce(
([gs, a], x) => eqOp(x)(a[0]) ? (
Tuple(gs)([...a, x])
) : Tuple([...gs, a])([x]),
Tuple([])([h])
);
return [...groups, g];
})() : [];
// on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
const on = f =>
// e.g. groupBy(on(eq)(length))
g => a => b => f(g(a))(g(b));
// 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 => xs.map(
(x, i) => f(x)(ys[i])
).slice(
0, Math.min(xs.length, ys.length)
);
// MAIN ---
return main();
})();