How to build the add project tag (from Preferences)

Items marked as done can be moved to the Archive project, and with a Preferences option enabled the project in which they resided can be added in a @project tag when doing this.

I would like to move entries to projects different from Archive (e.g. a “Maybe Later” project) and have the same feature to add the project tag.

How do I go about creating a script that does that?

Thank you!!

Peter

Here’s TaskPaper’s code for implementing “Archive Done”:

archiveDone = (editor) ->
  outline = editor.outline
  selection = editor.selection
  startItem = selection.startItem
  endItem = selection.endItem
  archive = outline.evaluateItemPath("//@text = Archive:")[0]
  doneItems = Item.getCommonAncestors(outline.evaluateItemPath("//@done except //@text = Archive://@done"))
  removeExtraTags = Birch.preferences.get('BRemoveExtraTagsWhenArchivingDone')
  addProjectTag = Birch.preferences.get('BIncludeProjectWhenArchivingDone')

  outline.groupUndoAndChanges ->
    unless archive
      outline.root.appendChildren(archive = outline.createItem('Archive:'))
    for each in doneItems
      if removeExtraTags
        for eachName in each.attributeNames
          if eachName.indexOf('data-') is 0 and eachName isnt 'data-type' and eachName isnt 'data-done'
            each.removeAttribute(eachName)
      if addProjectTag
        if projects = (eachProject.bodyContentString for eachProject in outline.evaluateItemPath('ancestor::@type=project', each)).join(' / ')
          each.setAttribute('data-project', projects)
      if (each is startItem or each.contains(startItem)) or (each is endItem or each.contains(endItem))
        if previousItem = editor.getPreviousDisplayedItem(startItem)
          selection = startItem: previousItem, startOffset: -1
        else
          selection = start: 0
    archive.insertChildrenBefore(doneItems, archive.firstChild)
  editor.moveSelectionToItems(selection)

Note that the code is Coffee Script, but that’s translated into JavaScript during compile process. So syntax will be different when converting to JavaScript, but all the same API should be present. Anyway I hope that gets you started.

Here is the script translated into Javascript (automatically, so code is a bit messy, but functional) and wrapped in script that will run from Script Editor app:

var TaskPaper = Application('TaskPaper')

function TaskPaperContext(editor, options) {
  let outline = editor.outline;
  let selection = editor.selection;
  let startItem = selection.startItem;
  let endItem = selection.endItem;
  let archive = outline.evaluateItemPath("//@text = Archive:")[0];
  let doneItems = Item.getCommonAncestors(outline.evaluateItemPath("//@done except //@text = Archive://@done"));
  let removeExtraTags = Birch.preferences.get('BRemoveExtraTagsWhenArchivingDone');
  let addProjectTag = Birch.preferences.get('BIncludeProjectWhenArchivingDone');
  
  outline.groupUndoAndChanges(() => {
    var each, eachName, eachProject, i, j, len, len1, previousItem, projects, ref;
    if (!archive) {
      outline.root.appendChildren(archive = outline.createItem('Archive:'));
    }
	
    for (i = 0, len = doneItems.length; i < len; i++) {
      each = doneItems[i];
      if (removeExtraTags) {
        ref = each.attributeNames;
        for (j = 0, len1 = ref.length; j < len1; j++) {
          eachName = ref[j];
          if (eachName.indexOf('data-') === 0 && eachName !== 'data-type' && eachName !== 'data-done') {
            each.removeAttribute(eachName);
          }
        }
      }
	  
      if (addProjectTag) {
        if (projects = ((function() {
          var k, len2, ref1, results;
          ref1 = outline.evaluateItemPath('ancestor::@type=project', each);
          results = [];
          for (k = 0, len2 = ref1.length; k < len2; k++) {
            eachProject = ref1[k];
            results.push(eachProject.bodyContentString);
          }
          return results;
        })()).join(' / ')) {
          each.setAttribute('data-project', projects);
        }
      }
	  
      if ((each === startItem || each.contains(startItem)) || (each === endItem || each.contains(endItem))) {
        if (previousItem = editor.getPreviousDisplayedItem(startItem)) {
          selection = {
            startItem: previousItem,
            startOffset: -1
          };
        } else {
          selection = {
            start: 0
          };
        }
      }
    }
    return archive.insertChildrenBefore(doneItems, archive.firstChild);
  });
  
  return editor.moveSelectionToItems(selection);
}

var text = TaskPaper.documents[0].evaluate({
	script: TaskPaperContext.toString()
});

TaskPaper.includeStandardAdditions = true
TaskPaper.setTheClipboardTo(text)