Randomize caps?

I want to make a macro that rAndOmizEs the capitalization of copied text. This is what I have so far (the red action is the one that I need help with to randomize the selection):

This may not be the most efficient way of handling this, but this seems to work for me, and it's certainly quick enough as long as you're not random-capping whole documents:

Randomize Caps.kmmacros (4.7 KB)

(Setting the clipboard to a variable already makes it plain text, which is why there's no remove styles filter)

2 Likes

and another approach, in an Execute JavaScript for Automation action, might be to use a function like:

// randomlyCapitalised :: String -> String
const randomlyCapitalized = s => {
    const headTails = randomRInt(0)(1);
    return [...s].map(c => c[
        `toLocale${headTails() ? 'Upper' : 'Lower'}Case`
    ]()).join('');
};

For example, returning a randomly capitalized version of any text in the clipboard:

Randomly capitalised version of clipboard text.kmmacros (19.9 KB)

Full JS source for sample macro
(() => {
    'use strict';

    ObjC.import('AppKit');

    // randomlyCapitalised :: String -> String
    const randomlyCapitalized = s => {
        const headTails = randomRInt(0)(1);
        return [...s].map(c => c[
            `toLocale${headTails() ? 'Upper' : 'Lower'}Case`
        ]()).join('');
    };

    // main :: IO ()
    const main = () =>
        either(msg => msg)(
            randomlyCapitalized
        )(clipTextLR());

    // ----------------------- JXA ------------------------

    // clipTextLR :: () -> Either String String
    const clipTextLR = () => {
        // ObjC.import('AppKit')
        const
            v = ObjC.unwrap($.NSPasteboard.generalPasteboard
                .stringForType($.NSPasteboardTypeString));
        return Boolean(v) && v.length > 0 ? (
            Right(v)
        ) : Left('No utf8-plain-text found in clipboard.');
    };

    // GENERIC FUNCTIONS ----------------------------------
    // https://github.com/RobTrew/prelude-jxa

    // Left :: a -> Either a b
    const Left = x => ({
        type: 'Either',
        Left: x
    });

    // Right :: b -> Either a b
    const Right = x => ({
        type: 'Either',
        Right: x
    });

    // either :: (a -> c) -> (b -> c) -> Either a b -> c
    const either = fl =>
        // Application of the function fl to the
        // contents of any Left value in e, or
        // the application of fr to its Right value.
        fr => e => 'Either' === e.type ? (
            undefined !== e.Left ? (
                fl(e.Left)
            ) : fr(e.Right)
        ) : undefined;

    // randomRInt :: Int -> Int -> IO () -> Int
    const randomRInt = low =>
        high => () => low + Math.floor(
            (Math.random() * ((high - low) + 1))
        );

    // MAIN ---
    return main();
})();

2 Likes