Script: displaying the active task in the OS X menu bar


#1

Inspired by Brett Terpstra’s Doing, and his link to Verify & Repair’s post on combining Doing with Textbar, here is a script for TP3 which:

  1. Can be used with TextBar to display the task that is active in TP3 on the OS X menu
  2. Can show a full or partial outline path for that task (its parent, and N further ancestors, where N can be adjusted)

USE:

  • install the script below in TextBar
  • tag the TP3 line you are working on with @now
  • the task and any parental/ancestral context that you want will appear on the menu bar
    (moving the @now tag to another line will result in the menu bar display being updated)

SCRIPT:

(to be copied and pasted into a text field in TextBar - can be tested first in something like CodeRunner.app, or in the terminal)

osascript -l JavaScript <<JXA_END 2>/dev/null
(function (intMaxParts) {
	'use strict';
	// ver 0.3 Requires TaskPaper 3 Preview version 166
	// (FIRST LINE TAGGED WITH @NOW and optionally a path to it)
	// Increase the value of intMaxParts (argument at end of script)
	// to lengthen the path displayed
	var intMax = intMaxParts || 99,
		strQuery = '//@now[0]/ancestor-or-self::*[-' + intMax + ':]',
		rgxBullet = /^- /,
		strArrow = " -&gt; ",
		strTextColor = '#00FF00'; // orange: '#FFA361'. For green: '#00FF00'

	// ConcatMap A FUNCTION OVER A LIST
	var strStep = function (xs, f) {
		return [].concat.apply([], xs.map(f));
	// LIST: LINES ANCESTRAL TO FIRST @NOW-TAGGED LINE IN FRONT TP3 DOC
	}(function () {
		var ds = Application("TaskPaper").documents,
			d = ds.length ? ds[0] : null;

		return d ? d.evaluate({
			script: (function (editor, options) {
				return editor.itemBuffer.outline.evaluateItemPath(
					options.query
				).map(function (x) {
					return x.body.string;
				});
			}).toString(),
			withOptions: {
				query: strQuery
			}
		}) : [];
	}(),
	// MAPPED FUNCTION: INCLUDE ITEM STRING IF NOT EMPTY,
	// AND NOT ABOVE intMaxParts FROM RIGHT.
	// ALSO PRUNE ANY LEADING BULLET
	function (x) {
		return x ? [x.replace(rgxBullet, '')] : [];
	})
	// CONCATENATE WITH ARROWS, DROPPING FINAL @NOW
	.join(strArrow).replace(/\s*\@now\s*$/, "");
	
	
	return strStep ? '<html><font style=color:' + strTextColor + ';font-family:"Menlo">' +
		strStep + '</font></html>' : '❓';
	
})(2); // MAX NUMBER OF PATH SEGMENTS TO INCLUDE
JXA_END

INSTALLATION

  • Install TextBar
  • Adjust the intMaxParts integer argument at the end of the script (the default 2 gives the @now line and its parent – 1 gives just the @now lineInfinity gives the whole path, other numbers give an ancestral path up to a maximum number of path segments long.

Adding the script to TextBar

  1. Click the plus icon to create a new item
  2. Paste in all of the code script and hit return (only the first line will show)
  3. Set the refresh interval to something like 10 seconds
  4. Check the activation box


Script: move a @now or @next tag on to the next item
Theme: Dark Theme based on Atom One Dark Syntax
Stylesheet: Atom One Dark
#2

A PS:

If you want to display the current task in a different color, you can send text wrapped in HTML tags to TextBar.

For example (in OS X dark menu-bar mode):

from:

<html><font style=color:#FFA361;font-family:"Menlo">Choose which to work on first -&gt; Reports -&gt; Apply query</font></html>

Note that for use between HTML tags the line:

  strArrow = " -> ",

Would need to be edited to:

  strArrow = " -&gt; ",

#3

Wasn’t familiar with TextBar. Great little app. I need to delve into it a little more and this use case is a great one indeed!


#4

Just changed the code above for compatibility with TP3 Preview ver. 166

( Quit TextBar to install the latest version of TP3, and then restart both)


#5

nice little gem from left field. now my brain is spinning about what else I can do with it. gee thanks :wink:


#6

Thank you very much @complexpoint!
This is perfect, but
Q:
how to change font for system and color for white?


#7

The part of the script to focus on is:

return strStep ? '<html><font style=color:' + strTextColor + ';font-family:"Menlo">' +
		strStep + '</font></html>' : '❓';
  • The quoted name of the font-family can be edited directly, and
  • the value of strTextColor is a hexadecimal string preceded by a hash

See, higher up:

strTextColor = '#00FF00'; // orange: '#FFA361'. For green: '#00FF00'

For hex strings yielding other colors, a web search will quickly lead to rgb -> hex converters, and lists of colors with their hexadecimal strings.

Good luck !


#8

hi, complexpoint,

can you give a mothed of apply bitbar app?
after all, it is free to me.

thank a lot.


#9

I’m not personally a user of BitBar, so I haven’t tested this, but glancing at their notes, it seems that all that is required is an (execute-enabled) bash script with a .sh extension, which returns a text.

If you save the following as an .sh file, you should be able to fine-tune it to generate the text you want.

This rough draft lists the first task which has a @now tag (any ancestral path delimited with arrows up to a maximum segment length).

To generate a different text, you can adjust the itemPath expression that is bound to the variable name strQuery, near the top of the script.

#!/bin/bash

osascript -l JavaScript <<JXA_END 2>/dev/null
(function (intMaxParts) {
    'use strict';
    // ver 0.3 Requires TaskPaper 3 Preview version 166
    // (FIRST LINE TAGGED WITH @NOW and optionally a path to it)
    // Increase the value of intMaxParts (argument at end of script)
    // to lengthen the path displayed
    var intMax = intMaxParts || 99,
    
        // EDIT THE TASKPAPER 3 QUERY (itemPath) THAT YOU NEED
        strQuery = '//@now[0]/ancestor-or-self::*[-' + intMax + ':]',
        
        rgxBullet = /^- /,
        strArrow = " -> "; 

    // ConcatMap A FUNCTION OVER A LIST
    var strStep = function (xs, f) {
        return [].concat.apply([], xs.map(f));
    // LIST: LINES ANCESTRAL TO FIRST @NOW-TAGGED LINE IN FRONT TP3 DOC
    }(function () {
        var ds = Application("TaskPaper").documents,
            d = ds.length ? ds[0] : null;

        return d ? d.evaluate({
            script: (function (editor, options) {
                return editor.itemBuffer.outline.evaluateItemPath(
                    options.query
                ).map(function (x) {
                    return x.body.string;
                });
            }).toString(),
            withOptions: {
                query: strQuery
            }
        }) : [];
    }(),
    // MAPPED FUNCTION: INCLUDE ITEM STRING IF NOT EMPTY,
    // AND NOT ABOVE intMaxParts FROM RIGHT.
    // ALSO PRUNE ANY LEADING BULLET
    function (x) {
        return x ? [x.replace(rgxBullet, '')] : [];
    })
    // CONCATENATE WITH ARROWS, DROPPING FINAL @NOW
    .join(strArrow).replace(/\s*\@now\s*$/, "");
    
    
    return strStep ? strStep : '❓';
    
})(2); // MAX NUMBER OF PATH SEGMENTS TO INCLUDE
JXA_END

#10

hi,complexpoint,

thank you for your reply so quickly.

and it is works.

the textbar app is very good app,but it is not support to retina.

have a good day (night?),and thanks a lot.


#11

You did well to get that working so quickly.

Textbar may be worth experimenting with too - you can use HTML for simple formatting.


#12

This is awesome. For anyone like me who might have other tags you want to strip, just add \s*@TAGTOREMOVE to the following line:

// CONCATENATE WITH ARROWS, DROPPING FINAL @NOW .join(strArrow).replace(/\s*\@now\s*@today\s*$/, "");

(You’ll notice I have it set to remove the @today tag)

Thanks for this, @complexpoint!


#13

This is very cool! But I can’t get it to work for some reason. The script seems to produce the right result when run in terminal, but all I see in Textbar is “.” where the task should be. Any ideas? Thanks!


#14

@dgg I’m experiencing the same thing. Any ideas @complexpoint ? Perhaps this isn’t compatible with the latest version of Taskpaper? Very cool idea though.