Script to increase and decrease date tag values

Continuing the discussion from Help with moving @start date AppleScript to JavaScript:

It’s set to increase @due date value by one day. But you can change the options to target another tag. You can change the offset value to offset + or - and change to unit to any supported in the time format:

http://guide.taskpaper.com/formatting_dates.html

var TaskPaper = Application('TaskPaper')

function TPContextGetCurrentPath(editor, options) {
  var selection = editor.selection;
  var selectedItems = selection.selectedItems;

  editor.outline.groupUndoAndChanges(function() {
    selectedItems.forEach(function(each) {
      var attributeName = 'data-' + options.tag;
      var dueDate = each.getAttribute(attributeName);
      if (dueDate) {
        each.setAttribute(attributeName, DateTime.format(dueDate + options.offset));
      } else {
        each.setAttribute(attributeName, DateTime.format('today'));
      }
    });
  });
  
  editor.moveSelectionToItems(selection);
}

var path = TaskPaper.documents[0].evaluate({
  script: TPContextGetCurrentPath.toString(),
  withOptions: {
    tag: 'due',
    offset: '+1d'
  }
});
3 Likes

Thanks Jesse—I now have my four macros for @start and @due working again!

1 Like

As a footnote, for anyone using KeyBoard Maestro to attach keystrokes (or other triggers) to scripts like this, here is an example of how you can wrap a script like Jesse’s in a form that gets its variables (i.e. which tag type ? how many days or weeks of adjustment ?) from Keyboard Maestro (if KM is installed), or otherwise gets them from literal default strings in the text:

AdjustTaskPaper 3 date.kmmacros.zip (10.4 KB)

JavaScript source, for running either in a Keyboard Maestro Execute JavaScript for Automation action, or from Script Editor or any other launcher:

(If Keyboard Maestro is not found, or its engine does not contain the incTag and incOffset variables, then the defaults at the bottom of the script are used)

// Nudge Taskpaper dates in selection
// Adjust dates in given tag type by given offset

// Keyboard Maestro version
// Rob Trew

(function () {
    'use strict';

    // TASKPAPER CONTEXT  *************************************************

    function TaskPaperContext(editor, options) {
        var selection = editor.selection,
            selectedItems = selection.selectedItems,

            strAttrib = 'data-' + options.tag,
            strOffset = options.offset,
            
            // if there is no unit after the number, add a default 'd'
            strDelta = isNaN(strOffset) ? strOffset : strOffset + 'd';

        editor.outline.groupUndoAndChanges(function () {
            selectedItems.forEach(function (item) {

                var strDate = item.getAttribute(strAttrib);

                item.setAttribute(
                    strAttrib,
                    DateTime.format(
                        strDate ? strDate + strDelta :
                        'today'
                    )
                );
            });
        });

        editor.moveSelectionToItems(selection);
    }

    // JAVASCRIPT FOR AUTOMATION CONTEXT  *********************************

    // (for checking whether Keyboard Maestro is installed)
    
    // appIsInstalled :: String -> Bool
    function appIsInstalled(strBundleId) {
        ObjC.import('AppKit');

        return ObjC.unwrap(
            $.NSWorkspace.sharedWorkspace
            .URLForApplicationWithBundleIdentifier(
                strBundleId
            )
            .fileSystemRepresentation
        ) !== undefined;
    }

    // ****** MAIN ********************************************************

    // 1. If Keyboard Maestro is installed, 
    //    look for *incTag* and *incOffset* variables in the KM Engine

    var strKMEid = "com.stairways.keyboardmaestro.engine",
        kmVars = appIsInstalled(strKMEid) ? Application(strKMEid)
        .variables : {},
        varTag = kmVars.incTag,
        varOffset = kmVars.incOffset;


    // 2. Run the TaskPaper 3 script, 
    //    using manual defaults for tag and offset if there are no KM values

    var ds = Application('com.hogbaysoftware.TaskPaper3')
        .documents();

    if (ds.length) {
        return ds[0].evaluate({
            script: TaskPaperContext.toString(),
            withOptions: {
                // Keyboard Maestro 'incTag' variable
                //   OR a literal string default
                tag: (varTag && varTag.value()) || 'due',

                // Keyboard Maestro 'incOffset' variable
                // OR a literal string default
                offset: (varOffset && varOffset.value()) || '+1d'
            }
        });
    }

})();
4 Likes

For anyone running into errors with @complexpoint’s excellent KM macro while running current versions of TP and mac OS, change the part of line 72 of the JXA in the KM macro that reads

com.hogbaysoftware.TaskPaper3

to

TaskPaper.

That got me up and running. (I’m currently using TaskPaper 3.7.7 (319) and macOS Mojave (10.14b6).)

PS: @complexpoint rocks! Virtually anytime I feel the need to create a TaskPaper script, I find that @complexpoint has already made one. Thanks so much! :slight_smile:

1 Like

I updated Jesse’s script slightly to account for @today items—adding a @start(...) and removing the @today tag.

var TaskPaper = Application('TaskPaper')

function TPContextGetCurrentPath(editor, options) {
  var selection = editor.selection;
  var selectedItems = selection.selectedItems;

  editor.outline.groupUndoAndChanges(function() {
    selectedItems.forEach(function(each) {
     
      var attributeName = 'data-' + options.tag;
      var startDate = each.getAttribute(attributeName);
	 
   	  if (startDate) {
        each.setAttribute(attributeName, DateTime.format(startDate + options.offset));
      } else {
        each.setAttribute(attributeName, DateTime.format('today ' + options.offset));
		if (each.hasAttribute('data-today')) each.removeAttribute('data-today')
      }	    
    });
  });
  
  editor.moveSelectionToItems(selection);
}

var path = TaskPaper.documents[0].evaluate({
  script: TPContextGetCurrentPath.toString(),
  withOptions: {
    tag: 'start',
    offset: '+1d'
  }
});