ex horto conclvso

A summarizer for due todo.txt tasks

This shell script processes $HOME/todo.txt to generate daily itemized lists of tasks grouped by context. It focuses on tasks due today, tomorrow, or overdue and can be used to email a summary every morning. It ignores tasks marked as done (x ).

Usage

  1. Ensure the script is executable.

    chmod +x todotxt-reminder.sh
    
  2. Execute the script to generate the filtered task lists.

    ./todotxt-reminder.sh
    
  3. Add the script to a cron job for automated daily execution and send the output to your email.

    # Add the following line to run the script daily at 7 AM and email the output:
    0 7 * * * /path/todotxt-reminder.sh | mail -s "Task List" email@example.com
    

Example

Given a todo.txt file with the following content:

(A) Discuss project focus with James due:2022-07-01 @James
(B) Decide shipping Canary Islands due:2022-06-28 +CustomerX @James
(B) Ensure automated export running due:2022-06-27 +CustomerZ @John
(C) Confirm DE availability due:2022-06-28 +CustomerZ @John
(C) Review summer recruitment plan due:2022-06-29 @Saskia

The script will output (if run on June 27):

@James
(B) Decide shipping Canary Islands due:2022-06-28 +CustomerX

@John
(B) Ensure automated export running due:2022-06-27 +CustomerZ
(C) Confirm DE availability due:2022-06-28 +CustomerZ

Requirements


#!/bin/bash

set -euo pipefail

TODO_FILE="$HOME/todo.txt"
TODAY=$(date +%Y-%m-%d)
TOMORROW=$(date -d tomorrow +%Y-%m-%d)

extract_tasks() {
    awk -v today="$TODAY" \
        -v tmrw="$TOMORROW" \
        '
        /^x / { next }

        /due: ?[0-9]{4}-[0-9]{2}-[0-9]{2}/ {
            
            match($0, /due: ?([0-9]{4}-[0-9]{2}-[0-9]{2})/, arr)
            due_date = arr[1]

            is_past = (due_date < today)
            is_today = (due_date == today)
            is_tmrw = (due_date == tmrw)

            if (is_past || is_today || is_tmrw) {
                if (match($0, /@[^[:space:]]+/, ctx_arr)) {
                    context = ctx_arr[0]
                    line = $0
                    gsub(context, "", line)
                    gsub(/^[[:space:]]+|[[:space:]]+$/, "", line)
                    print context "|" line
                }
            }
        }
        ' "$TODO_FILE"
}

generate_list() {
    local current_ctx=""
    local line_ctx
    local line_content

    extract_tasks | sort | while IFS="|" read -r line_ctx line_content
    do
        if [[ "$line_ctx" != "$current_ctx" ]]; then
            echo
            echo "$line_ctx"
            current_ctx="$line_ctx"
        fi
        
        echo "$line_content"
    done
}

generate_list

Rubriek:
Peri Technōn