Change the welcome text


#1

I think it would be a good idea, and beneficiary to all the users of Taskpaper to create a welcome text file within the application to support to change or modify the “Welcome text” of TaskPaper to the user’s liking.

As I was going through some of the search posts, I figure it would be a good idea for me to include certain of those by default. I then modified the welcome text within the app to my liking, but thought that for others it was what some have already accused Taskpaper to be, “too geeky.”

If this is implemented, some people can share their default searches and doing so, educate the beginner user of the many ways power users are using the app. Like Doug said in one of his posts, [quote=“doug, post:7, topic:1628”]
but i found Matt Gemmell’s examples from his blogpost hugely useful
[/quote]

These are examples in a default text Matt Gemmell shared :wink:


#2

Perhaps, as a stop-gap – a script or macro to easily back-up, edit or revert:

/Applications/TaskPaper.app/Contents/Resources/Welcome.txt

?


#3

My idea of changing the default “welcome text” was to change it to something that I can use all the time and change every blue moon.

When you proposed having a script or macro to do it, I thought… well, if I could have a folder with several of these “default texts” for certain jobs and I could pick and choose those when I am editing a document, that would be mind blowing awesome :smile: Something like those snippets that someone uses for coding, but for searches, tags, etc.


#4

So perhaps a script which supplements the usual ⌘N with something like ⌘⌥ N for ‘New document based on template’, and simply throws up a list of templates in a folder somewhere ?

(Rather than fiddling with the resources in the .app package, which are refreshed with every update)


#5

Although my original request was to have Taskpaper read a document in the application support folder and use that for new documents when the “Show Welcome Text” option was selected – if such document wasn’t available, then just read the welcomed text included in the .app package – I do like your idea better.


#6

Here is a very rough first sketch – if you would like to test it and suggest adjustments, we could put a version into the script wiki, and perhaps make Keyboard Maestro and LaunchBar etc versions ?

// CHOOSE A TEMPLATE FOR A NEW TASKPAPER 3 DOCUMENT

// 1. CREATE A FOLDER CONTAINING TWO OR MORE MODEL TASKPAPER DOCUMENTS
// 2. SUPPLY THE PATH OF THE FOLDER TO THE OPTIONS AT THE BOTTOM OF THIS SCRIPT
// 3. RUN SCRIPT (E.G. FROM A KEYBOARD MAESTRO OR FASTSCRIPTS SHORTCUT

(function (dctOptions) {
    'use strict';

    // expandTilde :: String -> FilePath
    function expandTilde(strPath) {
        return strPath.charCodeAt(0) === 126 ? ObjC.unwrap(
            $(strPath)
            .stringByExpandingTildeInPath
        ) : strPath;
    }

    // pathExistsAndisFolder :: String -> (Bool, Int)
    function pathExistsAndisFolder(strPath) {
        var ref = Ref();

        return $.NSFileManager.defaultManager
            .fileExistsAtPathIsDirectory(
                strPath, ref) ? {
                'exists': true,
                'isFolder': ref[0] === 1
            } : {
                'exists': false
            };
    }

    // listDirectory :: FilePath -> [FilePath]
    function listDirectory(strPath, fm) {
        var fm = fm || $.NSFileManager.defaultManager;

        return ObjC.unwrap(
                fm.contentsOfDirectoryAtPathError(strPath, null))
            .map(ObjC.unwrap);
    }

    // fileType :: FilePath -> UTI String
    function fileType(strPath) {
        var error = $();

        return ObjC.unwrap(
            $.NSWorkspace.sharedWorkspace
            .typeOfFileError(strPath, error)
        );
    }
    
    // readFile :: FilePath -> IO String
    function readFile(strPath) {
        var ref = Ref();
        
        return ObjC.unwrap(
            $.NSString.stringWithContentsOfFileEncodingError(
                strPath, $.NSUTF8StringEncoding, ref
            )
        );
    }

    ObjC.import('AppKit');
    var strPath = expandTilde(dctOptions.templateFolder);

    if (pathExistsAndisFolder(strPath)
        .isFolder) {
        var lstMenu = listDirectory(strPath)
            .filter(function (x) {
                return fileType(
                    strPath + '/' + x
                ) === "com.hogbaysoftware.taskpaper.document";
            });

        if (lstMenu.length > 0) {
            var a = Application.currentApplication(),
                sa = (a.includeStandardAdditions = true, a),


            varResult = sa.chooseFromList(lstMenu, {
                withTitle: dctOptions.withTitle || "",
                withPrompt: dctOptions.withPrompt || "Choose template:",
                defaultItems: dctOptions.defaultItems ||
                    lstMenu[0],
                okButtonName: dctOptions.okButtonName || "OK",
                cancelButtonName: dctOptions.cancelButtonName ||
                    "Cancel",
                multipleSelectionsAllowed: dctOptions.multipleSelectionsAllowed ||
                    false,
                emptySelectionAllowed: dctOptions.emptySelectionAllowed ||
                    false
            }),
            
            strTemplatePath = (varResult ? strPath + '/' + varResult[0] : undefined);
            
            if (strTemplatePath) {
                var tp3 = Application("com.hogbaysoftware.TaskPaper3"),
                    strText = readFile(strTemplatePath);
                
                tp3.documents.push(
                    tp3.Document({textContents: strText})
                );
                tp3.activate();
            }
        }
    } else return "Folder not found:\n\t" + strPath;

})({
    templateFolder: '~/TaskPaper Templates',
    withTitle: 'New from Template'
});

#7

Thank you. I added that to the wiki, and I think that we had enough scripts of this kind to create a new category.


#8

I like the script approach for now too. Maybe someday I would make a template document in the application support folder, but I think I’d rather live with the current “copy paste” favorite searches approach for a while. I think in the end it might make more sense to add some “built in” searches (that can be edited in preferences or something) so that you can use saved searches without embedding them in your doc. Then you could just used in document saved searches for very specific cases.


#9

A Keyboard Maestro ( ⌘⌥N ) version here:


#10

Hey guys, the KM script above works great however it creates a new file instead of appending the template to an existing file (it’s listed on the TP wiki as “A script to append templates in a folder to document”).

Has anyone tried to modify it to make it append to an existing file instead of creating a new file?
Another idea would be to have it add the contents of the template to the open document (perhaps to wherever the text cursor is).

My goal would be to have template for projects / searches that I could add to larger taskpaper files instead of having templates for entire files.


#11

Thanks – I hadn’t seen that labelling of the script: amended now.

Would it work for you to add a button to Copy the text of the selected template into the clipboard ?


#12

I guess that’d be quite useful because I could just add another action to the KM macro to make it immediately paste the clipboard to wherever my cursor is at. :slight_smile:


#13

For a similar macro which copies the contents of the template to clipboard (rather than creating a new document with it), you can use a lightly modified version of the code in the Keyboard Maestro Execute JavaScript for Automation action:

( Or, of course, use something like Typinator )

JavaScript for Automation source:

// CHOOSE A TEMPLATE AND COPY ITS TEXT TO CLIPBOARD

// 1. CREATE A FOLDER CONTAINING TWO OR MORE MODEL TASKPAPER DOCUMENTS
// 2. SPECIFY THE PATH OF THE FOLDER IN THE templatePath VARIABLE
// 3. RUN MACRO ( requires TaskPaper 3 https://www.taskpaper.com/ )

(function (dctOptions) {
    'use strict';

    // expandTilde :: String -> FilePath
    function expandTilde(strPath) {
        return strPath.charCodeAt(0) === 126 ? ObjC.unwrap(
            $(strPath)
            .stringByExpandingTildeInPath
        ) : strPath;
    }

    // pathExistsAndisFolder :: String -> (Bool, Int)
    function pathExistsAndisFolder(strPath) {
        var ref = Ref();

        return $.NSFileManager.defaultManager
            .fileExistsAtPathIsDirectory(
                strPath, ref) ? {
                'exists': true,
                'isFolder': ref[0] === 1
            } : {
                'exists': false
            };
    }

    // listDirectory :: FilePath -> [FilePath]
    function listDirectory(strPath, fm) {
        var fm = fm || $.NSFileManager.defaultManager;

        return ObjC.unwrap(
                fm.contentsOfDirectoryAtPathError(strPath, null))
            .map(ObjC.unwrap);
    }

    // fileType :: FilePath -> UTC String
    function fileType(strPath) {
        var error = $();

        return ObjC.unwrap(
            $.NSWorkspace.sharedWorkspace
            .typeOfFileError(strPath, error)
        );
    }

    // readFile :: FilePath -> IO String
    function readFile(strPath) {
        var ref = Ref();

        return ObjC.unwrap(
            $.NSString.stringWithContentsOfFileEncodingError(
                strPath, $.NSUTF8StringEncoding, ref
            )
        );
    }

    // MAIN 

    ObjC.import('AppKit');
    var strFolder = dctOptions.templateFolder,
        strPath = strFolder ? expandTilde(strFolder) : undefined;

    if (strPath && pathExistsAndisFolder(strPath)
        .isFolder) {
        var lstMenu = listDirectory(strPath)
            .filter(function (x) {
                return fileType(
                    strPath + '/' + x
                ) === "com.hogbaysoftware.taskpaper.document";
            });

        if (lstMenu.length > 0) {
            var ui = Application("com.apple.systemuiserver"),
                sa = (ui.includeStandardAdditions = true, ui);

            sa.activate();

            var varResult = sa.chooseFromList(lstMenu, {
                    withTitle: dctOptions.withTitle || "",
                    withPrompt: dctOptions.withPrompt ||
                        "Templates in folder:\n\n" + strFolder +
                        "\n\nChoose:",
                    defaultItems: dctOptions.defaultItems ||
                        lstMenu[0],
                    okButtonName: dctOptions.okButtonName ||
                        "Copy file contents",
                    cancelButtonName: dctOptions.cancelButtonName ||
                        "Cancel",
                    multipleSelectionsAllowed: dctOptions.multipleSelectionsAllowed ||
                        false,
                    emptySelectionAllowed: dctOptions.emptySelectionAllowed ||
                        false
                }),

                strFile = (varResult ? varResult[0] : undefined);

            if (strFile) {
                var tp3 = Application("com.hogbaysoftware.TaskPaper3"),
                    strTemplatePath = strPath + '/' + strFile,
                    strText = readFile(strTemplatePath);

                sa.setTheClipboardTo(
                    strText
                );

                tp3.activate();

                return strText;
            }
        }
    } else return "Folder not found:\n\t" + strPath;

})({
    templateFolder: Application("com.stairways.keyboardmaestro.engine")
        .variables['templatePath'].value(), // e.g. '~/TaskPaper Templates',
    withTitle: 'Copy template contents to clipboard'
});

#14

Thanks @complexpoint! This works great!

While this is not a huge problem, I’d just like to point out that the script doesn’t deal that well with special characters such as ç, ã, ó, etc.
For example, if a template contains the word “documentação” (portuguese for documentation), the script will copy it as “documenta√ß√£o”.
This is not a deal breaker however I believe other users might welcome a fix for this issue as well.


#15

Obrigado !

( good catch – I’ve updated the readFile() function in the two scripts above to be a bit less parochially Anglo Saxon )

Should work OK now, I think.


#16

@complexpoint Yeap! That fixed it!

Obrigado! :stuck_out_tongue_winking_eye: