Action

Case toggle

Posted by @ComplexPoint, Last update almost 6 years ago

Toggle (cycle) the case of selected text:

Mixed case -> Upper -> Lower -> Initial Caps

Steps

  • script

    (() => {
        'use strict';
    
        // main :: () -> IO String
        const main = () => {
            const
                e = editor,
                strReCased = (
                    expandSelnByWord(),
                    caseToggled(
                        e.getSelectedText()
                    )
                );
            return strReCased.length > 0 ? (
                e.setSelectedText(
                    strReCased
                ),
                strReCased
            ) : '';
        };
    
        // caseToggled :: String -> String
        const caseToggled = s => {
            const cs = chars(s);
            return !any(isUpper, cs) ? (
                toInitialCaps(s)
            ) : !any(isLower, cs) ? (
                toLower(s)
            ) : toUpper(s);
        };
    
        // GENERIC FUNCTIONS ------------------------------------
    
        // Tuple (,) :: a -> b -> (a, b)
        const Tuple = (a, b) => ({
            type: 'Tuple',
            '0': a,
            '1': b,
            length: 2
        });
    
        // any :: (a -> Bool) -> [a] -> Bool
        const any = (p, xs) => xs.some(p);
    
        // chars :: String -> [Char]
        const chars = s => s.split('');
    
        // concatMap :: (a -> [b]) -> [a] -> [b]
        const concatMap = (f, xs) => [].concat.apply([], xs.map(f));
    
        // isLower :: Char -> Bool
        const isLower = c =>
            /[a-z]/.test(c);
    
        // isUpper :: Char -> Bool
        const isUpper = c =>
            /[A-Z]/.test(c);
    
       // regexMatches :: String -> String -> [[String]]
        const regexMatches = (strRgx, strHay) => {
            const rgx = new RegExp(strRgx, 'g');
            let m = rgx.exec(strHay),
                xs = [];
            while (m)(xs.push(m), m = rgx.exec(strHay));
            return xs;
        };
    
       // splitAt :: Int -> [a] -> ([a],[a])
        const splitAt = (n, xs) => Tuple(xs.slice(0, n), xs.slice(n));
    
        // toLower :: String -> String
        const toLower = s => s.toLowerCase();
    
        // toInitialCaps :: String -> String
        const toInitialCaps = s => {
            const rgx = /([A-Za-z\u00C0-\u00FF])([A-Za-z\u00C0-\u00FF]*)(\b[^[A-Za-z\u00C0-\u00FF]]*|$)/g;
            return regexMatches(rgx, s)
            .map(ms => ms[1].toUpperCase() + ms[2].toLowerCase() + ms[3])
            .join('')
        };
    
        // toUpper :: String -> String
        const toUpper = s => s.toUpperCase();
    
    	// SELECTING WORD
    
        // expandSelnByWord :: () -> IO ()
        const expandSelnByWord = (blnMultiWord, blnLeft) => {
            const
                e = editor,
                tplSeln = e.getSelectedRange(),
                tplLine = e.getSelectedLineRange(),
                strLine = e.getTextInRange(...tplLine),
                intPosn = tplSeln[0],
                xy = splitAt(
                    intPosn - tplLine[0],
                    strLine
                ),
                [dl, dr] = concatMap(
                    x => x !== null ? (
                        [x[0].length]
                    ) : [0], //
                    [/\b[\S]*$/.exec(xy[0]), /^[\S]*\b/.exec(xy[1])]
                );
            return (tplSeln[1] === 0 || dl > 0 && dr > 0) ? (
                e.setSelectedRange(intPosn - dl, dl + dr),
                'extended'
            ) : blnMultiWord ? [
               // additionalWord(
               //     blnLeft, tplSeln, tplLine, strLine
               // )
            ] : 'No further';
        };
    
      
        // MAIN ---
        return main();
    })();
    

Options

  • After Success Default
    Notification Error
    Log Level Error
Items available in the Drafts Directory are uploaded by community members. Use appropriate caution reviewing downloaded items before use.