[request withdrawn] Small adaptation of script for "due report" of items with due dates?


#1

@complexpoint
I use your script to create a due report for Marked 2 on a daily basis, it is extremely useful. Would it be possible to adapt the script, such that it not only lists items with @due() dates attached, but also items with @waitingfor() dates?

I presume this asks for “expanding” the filter command to include ‘//@due’ AND ‘//@waitingfor’, and then adapting the groupBy and/or orderBy commands to have the @waitingfor items included in the list (they may be ‘mixed’ up’ with the @due items).

The current script is included below.

Best wishes,
Paul

// DUE REPORT script for TaskPaper 3 ver 0.04 b

// Modified for date display
// (removed red color, despite May Day, restored hyphen before day)
// and insertion of comma after project 
// 2016-05-01

var strClip = (function () {
    'use strict';

    function fnTP3Context(editor, options) {

        // concatMap ::  [a] -> (a -> [b]) -> [b]
        function concatMap(xs, f) {
            return [].concat.apply([], xs.map(f));
        }

        function itemProject(item) {
            var p = item.parent;

            while (p) {
                if (p.getAttribute('data-type') === 'project') {
                    return p.bodyContentString;
                };
                p = p.parent;
            }
            return '';
        }

        function timePart(item, strTimeTag) {
            var strDate = item.getAttribute('data-' + strTimeTag);

            return strDate ? strDate.slice(10, 16)
                .trim() : '';
        }

        function otherTags(lstAttribNames, attribs, strGroup) {
            return concatMap(
                    lstAttribNames,
                    function (k) {
                        var strTag = k.indexOf(
                                'data-'
                            ) === 0 ? k.slice(5) :
                            '',
                            strValue = attribs[k];

                        // Non-grouping tag attributes included
                        return (
                            strTag && ['type', strGroup]
                            .indexOf(strTag) === -1
                        ) ? [
                            '@' + strTag + (strValue ? '(' + strValue + ')' : '')
                        ] : [];
                    }
                )
                .join(' ');
        }

        var outline = editor.outline;


        // READING OF SORT SPEC
        var lstOrder = options.orderBy.split(/\s+/),
            strSortBy = lstOrder[0].trim(),
            blnZA = (lstOrder.length > 1) && (lstOrder[1].trim()
                .substr(0, 4)
                .toLowerCase() === 'desc'),
            strSortAttrib = 'data-' + strSortBy;


        // READING OF GROUPING SPEC
        var lstGroup = options.groupBy.split(/\./),
            strGroup = lstGroup[0],
            strGroupAttrib = 'data-' + strGroup,
            strGroupFn = lstGroup.length > 1 ? lstGroup[1] : undefined;


        // FILTERED BY ...
        var lstFiltered = outline.evaluateItemPath(options.filter),

            // GROUPED BY ...
            dctGroups = lstFiltered.reduce(
                function (groups, dctItem) {
                    var v = dctItem.getAttribute(strGroupAttrib),
                        vGroup = strGroupFn ? eval(
                            '"' + v.toString() + '".' + strGroupFn
                        ) : v,
                        dctGroup = groups[vGroup] || {};

                    dctGroup[dctItem.id] = dctItem;
                    groups[vGroup] = dctGroup;

                    return groups;
                }, {}
            ),

            // GROUPS ORDERED BY
            lstGroups = Object.keys(dctGroups)
            .sort(blnZA ?
                function (a, b) {
                    return a === b ? 0 : (a < b ? 1 : -1);
                } : function (a, b) {
                    return a === b ? 0 : (a > b ? 1 : -1);
                });

        return "### <font color='silver'>" + strGroup.charAt(0)
            .toUpperCase() + strGroup.slice(1) + "</font>\n\n" +
            lstGroups.map(function (k) {
                var dctGroup = dctGroups[k];

                // return "#### <font color=grey>" + k.substr(0, 7) + // delta
                return "#### <font color=red>" + k.substr(0, 10) +
                    // '</font>&nbsp;<font color=red>' + k.slice(8) + // delta
                    // (deleted)
                    '</font>\n' + Object.keys(dctGroup)
                    .map(function (id) {
                        var item = dctGroup[id];

                        var strTime = timePart(item, strGroup),
                            strProject = itemProject(item),
                            attribs = item.attributes,

                            strPrefixes = (strTime ?
                                '<font color=blue><b>' +
                                strTime +
                                '</font></b>\t' :
                                '') + (strProject ?
                                '<font color=blue>' +
                                //strProject + // delta
                                strProject + ':' +
                                '</font>&nbsp;' : '');

                        return strPrefixes +
                            // body text
                            item.bodyContentString
                            // Any remaining (non-grouping) tags
                            + ' <font color=gray>' + otherTags(
                                item.attributeNames,
                                attribs,
                                strGroup
                            ) + '</font>';
                    })
                    .sort()
                    .join('\n');
            })
            .join('\n\n');
    }

    var ds = Application("TaskPaper")
        .documents,
        varResult = ds.length ? ds[0].evaluate({
            script: fnTP3Context.toString(),
            withOptions: {
                filter: '//@due',
                groupBy: 'due.substr(0, 10)',
                orderBy: 'due'
            }
        }) : false;

    return varResult;
})();


var a = Application.currentApplication(),
    sa = (a.includeStandardAdditions = true, a);

sa.setTheClipboardTo(strClip);

strClip

#2

@Paul Thanks for sharing. I just edited your post to wrap the script in a github style code block.


#3

@complexpoint

UPDATE: adaptation of script is no longer needed. I now indicate waiting items as follows in TP document:

“- WAITING blablablah @due(2017-01-12)”

This allows for a clear visibility of these items alongside of the regular @due() items.

Paul