Case INsensitivity with tags (request)

I would like an option in Preferences to make all tags lowercase or in some fashion treat them as case INsensitive.

I would like @Scott and @scott to be one tag or to be automatically corrected to @scott all lower case.

As not everyone might like this change for some reason, make it an option turned on by default.

The design of TaskPaper lends itself to getting this kind of customisation immediately with a script (rather than waiting for the possibility of a single-user option).

Here is a draft of a script which make all tags in the document lowercase.

See TaskPaper Guide: Using Scripts

Expand disclosure triangle to view JS Source
(() => {
    "use strict";

    // Normalize all tags in document to lower case

    // Rob Trew 2022
    // Draft 0.1

    const TaskPaperContext = editor => {
        const outline = editor.outline;

        const tpMain = () =>
            outline.groupUndoAndChanges(
                () => outline.items.forEach(x => {
                    x.attributeNames
                        .filter(isUpper)
                        .forEach(k => {
                            x.setAttribute(
                                toLower(k),
                                x.getAttribute(k)
                            );
                            x.removeAttribute(k);
                        });
                })
            );

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

        // isUpper :: String -> Bool
        const isUpper = s =>
            // True if s contains an upper case character.
            (/[A-Z]/u).test(s);


        // toLower :: String -> String
        const toLower = s =>
            // Lower-case version of string.
            s.toLocaleLowerCase();

        // TASKPAPER MAIN
        return tpMain();
    };

    // ---------------------- MAIN -----------------------

    // main :: IO String
    const main = () => {
        const ds = Application("TaskPaper").documents;

        return 0 < ds.length ? (
            ds.at(0).evaluate({
                script: `${TaskPaperContext}`
            })
        ) : "No documents open in TaskPaper";
    };

    return main();
})();

As always, make sure that you copy the whole of the script above, right down to the end, which should be:

  return main();
})();
2 Likes

That’s very helpful, thanks! I have never run a script but I will give it a try.

1 Like

Let us know if you meet any puzzlements or frustrations.

FastScripts and Keyboard Maestro are helpful – they let you attach a custom keystroke to a script.

(The evaluation version of FastScripts is free up to a certain number of scripts, I think)

That worked well, thanks! My introduction into Scripts!

A small thing of note, that is NOT a concern for me, but to let you know. I sometimes include tags inline, like:

  • Talk to @Scott about the project deadlines

When your script acts on a tag, i.e. finds Mixed or CAPS, it moves the tag to the end, so that one becomes

  • Talk to about the project deadlines @scott

It would be nice to put the Scripts in a menu in TaskPaper. I don’t use Command Palette that much, maybe I should. @jessegrosjean what is “Lower Case” in the command palette do? I named my script something similar and saw it

Task Paper help points me to the Script Editor help which says I can put a script into the menu by putting it into a certain script folder, but Task Paper needs it in its own folder. So does not seem like I can add my script to a system script menu in Task Paper, am i reading it wrong?

1 Like

That command converts the selection to lowercase text.

I think both are true… if you want a script to show up in TaskPaper’s “Commands” menu then you need to put that script into TaskPaper’s special script folder. On the other hand there’s a separate special folder that will show scripts in a “System” scripts menu. If you wanted the script to show up in both places then you could create a copy of the script file and put in both locations.

1 Like

Put your script into: ~/Library/Scripts/

Open Script Editor and then open the Script Editor preferences.
In General, check Show Script menu in menu bar.

If you do the above properly, your script should appear in that menu, and the menu should be available whenever the Mac menu bar is visible.

Here is a variant which aims to retain the position of each adjusted tag:

Expand disclosure triangle to view JS Source
(() => {
    "use strict";

    // Normalize all tags in document to lower case

    // Rob Trew 2022
    // Draft 0.2

    // Aims to preserve position of updated tags.

    const TaskPaperContext = editor => {
        const outline = editor.outline;

        const tpMain = () =>
            outline.groupUndoAndChanges(
                () => outline.items.forEach(x => {
                    const ks = x.attributeNames.filter(isUpper);

                    if (0 < ks.length) {
                        x.bodyString = ks.reduce(
                            (a, k) => {
                                const tag = `@${k.slice(5)}`;

                                return a.replace(
                                    tag,
                                    toLower(tag)
                                );
                            },
                            x.bodyString
                        );
                    }
                })
            );

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

        // isUpper :: String -> Bool
        const isUpper = s =>
            // True if s contains an upper case character.
            (/[A-Z]/u).test(s);


        // toLower :: String -> String
        const toLower = s =>
            // Lower-case version of string.
            s.toLocaleLowerCase();


        // TASKPAPER MAIN
        return tpMain();
    };

    // ---------------------- MAIN -----------------------

    // main :: IO String
    const main = () => {
        const ds = Application("TaskPaper").documents;

        return 0 < ds.length ? (
            ds.at(0).evaluate({
                script: `${TaskPaperContext}`
            })
        ) : "No documents open in TaskPaper";
    };

    return main();
})();

Thanks @complexpoint , i probably can’t test right away, but if I do i will post back here!

1 Like