Building a personal note-taking tool

Remind Me

If I have an important meeting or need to remember an anniversary, I already have several very capable calendar apps linked to my Gmail account that will send a reminder. Despite this, I am a terrible procrastinator and often put off or forget tasks on my mental to-do list.

The obvious answer would be a physical – or digital – to-do list, but I wanted to know if I could make it just a bit more useful for someone with my scattergun approach to time management.

Gina Trapani's excellent Todo.txt method [2] ticked all my boxes by using an open, plain-text file format and being completely app agnostic. For the unfamiliar, Todo.txt is just a way of formatting a text-based to-do list so that it is both human readable and easy to process with a computer.

An example Todo.txt file would be:

Buy some milk @shopping
(A) Call Grandma
Write Linux article
Tidy spare room

@shopping is just a tag to help you list all similar items using the basic Todo.txt shell script or one of the many Todo.txt-compatible apps. The optional (A) marks that task as high priority. You could also have tasks categorized as (B), (C), etc.

I can keep a Todo.txt file in a folder called Organizing under my Notes folder, sync it between all my devices, and always have easy access to my list of tasks. But how could I use it to help me remember to actually do those tasks? I thought what might help would be to get a random nudge throughout the day. I sometimes find that if I set an alarm for something, if I know when it is coming – paradoxically – it is easier to ignore. If a friend were to randomly interrupt me with a reminder, that might be harder to dodge.

A simple python code could read my to-do list every day and add a timed task using the Linux at command to give me that encouraging nudge when I least expected it.

This script (see Listing 1) requires Python v3 or later and the todotxio module, which is easily installed using the Python package manager, pip.

sudo pip3 install todotxtio

Listing 1


001 #!/usr/bin/python3
002 # nudgebot
003 # stuart houghton 2021
004 #
005 # read a todo.txt file and assemble a list of timed reminder notifications
006 #
007 import todotxtio
008 import sys, getopt, os
009 from random import randint
011 # look for parameters
012 todo_file = "null"
013 argv = sys.argv[1:]
015 try:
016     opts, args = getopt.getopt(argv, "f:")
018 except:
019     print("Error")
021 for opt, arg in opts:
022     if opt in ['-f']:
023         todo_file = arg
025 if (todo_file == "null"):
026     print ("No todo list specified")
027     quit()
029 # define the flavour text list
030 # this keeps each reminder slightly different, to make them more impactful
032 flavour_text=[
033     "Do not forget to",
034     "You had better not forget to",
035     "Whatever happens, remember to",
036     "ATTENTION!",
037     "You really should",
038     "You had better",
039     "If you know whats good for you,",
040     "Dig deep and",
041     "Do the right thing, i.e.",
042     "Do this:"
043 ]
044 flavour_text_list_length=len(flavour_text)-1
046 # define the notification tone list
047 # these are standard notification tones used by the pushover notification service
049 push_tones=[
050     "pushover",
051     "bike",
052     "bugle",
053     "cashregister",
054     "classical",
055     "cosmic",
056     "falling",
057     "gamelan",
058     "incoming",
059     "intermission",
060     "magic",
061     "mechanical",
062     "pianobar",
063     "siren",
064     "spacealarm",
065     "tugboat",
066     "alien",
067     "climb",
068     "persistent",
069     "echo",
070     "updown"
071 ]
072 push_tones_length=len(push_tones)-1
074 # let's read that file
075 print("Reading ", todo_file, "...")
077 list_of_todos = todotxtio.from_file(todo_file)
079 # ok, now do the priority A stuff - between 2 and 4 nudges per day
080 to_nudge_A =,
081     priority=['A'],
082     contexts=['nudge','blitz'],
083     completed=False
084 )
086 nudge_list_length_A=len(to_nudge_A)
088 print("=====Priority A=====")
090 for item in range(nudge_list_length_A):
091     item_text=to_nudge_A[item].text
092     item_duedate=to_nudge_A[item].text
093     #nudge a random number of times
094     rand_nudges=randint(2,4)
095     for nudgenum in range(rand_nudges):
096         print(rand_nudges)
097         rand_mins=randint(0,480)
098         rand_flavour=randint(0,flavour_text_list_length)
099         flavour_intro=flavour_text[rand_flavour]
100         send_text=flavour_intro+" "+item_text
101         rand_tone_index=randint(0,push_tones_length)
102         push_tone=push_tones[rand_tone_index]
103         command_string = f"echo \"/home/stu/bin/pushover \'{send_text}\' \'{push_tone}\'\" | at now + \'{rand_mins}\' minute"
104         print(command_string)
105         os.system(command_string)
107 # and now do the priority B stuff - 1 nudge per day
108 to_nudge_B =,
109     priority=['B'],
110     contexts=['nudge'],
111     completed=False
112 )
114 nudge_list_length_B=len(to_nudge_B)
116 print("=====Priority B=====")
118 for item in range(nudge_list_length_B):
119     item_text=to_nudge_B[item].text
120     rand_mins=randint(0,480)
121     rand_flavour=randint(0,flavour_text_list_length)
122     flavour_intro=flavour_text[rand_flavour]
123     send_text=flavour_intro+" "+item_text
124     rand_tone_index=randint(0,push_tones_length)
125     push_tone=push_tones[rand_tone_index]
126     command_string = f"echo \"/home/stu/bin/pushover \'{send_text}\' \'{push_tone}\'\" | at now + \'{rand_mins}\' minute"
127     print(command_string)
128     os.system(command_string)

The notifications are done using a free web service called Pushover [3], which sends a push notification to an Android or iOS app. The API for Pushover is very simple, and the Pushover site has example code for using curl to send notifications that you can put in a Bash script. I called mine pushover. You could, of course, send an email instead or use something like the notify-send notification app [4] to direct a pop-up notification to your desktop.

I then add a crontab file so a daily cron job can run this script (Listing 2).

Listing 2

crontab File

01 # Edit this file to introduce tasks to be run by cron.
02 #
03 # Each task to run has to be defined through a single line
04 # indicating with different fields when the task will be run
05 # and what command to run for the task
06 #
07 # To define the time you can provide concrete values for
08 # minute (m), hour (h), day of month (dom), month (mon),
09 # and day of week (dow) or use '*' in these fields (for 'any').
10 #
11 # Notice that tasks will be started based on the cron's system
12 # daemon's notion of time and timezones.
13 #
14 # Output of the crontab jobs (including errors) is sent through
15 # email to the user the crontab file belongs to (unless redirected).
16 #
17 # For example, you can run a backup of all your user accounts
18 # at 5 a.m every week with:
19 # 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
20 #
21 # For more information see the manual pages of crontab(5) and cron(8)
22 #
23 # m h  dom mon dow   command
24 0 8 * * *       /home/stu/bin/ -f /notes-location/Notes/organising/todo.txt

With the script running on my Pi, I just need to tag a to-do item with @nudge and make it either priority (A) or (B), and I will get one or more automated, random reminders during the day until I complete the task.


My note-taking solution suits my purposes well. It doesn't have some of the extra features of commercial apps, but it does what I need it to do, and it isn't cluttered up with unnecessary features. Markdown is a portable and sensible note format that is supported by a variety of tools (see the box entitled "Apps,") and the clever Todo.txt format makes it easy to keep a list of tasks and generate reminders. The simple concepts discussed in this article are easy to adapt to your own needs if you decide to experiment with building your own note-taking tool.


The advantage of using Markdown is that you can use any text editor, from something as simple as Notepad on Windows to a Swiss Army chainsaw such as Emacs. That said, there are some apps which are better suited to taking and managing notes. Similarly, although you could edit a Todo.txt file in anything, a number of apps can make the editing process much more user-friendly.


On my phone I use Markor, which is fast and fairly no-frills but supports searching and embedded images. Other options would be iA Writer or JotterPad. Markor has a built-on Todo.txt mode, but it is a little basic. I prefer an excellent free app called Mindstream, which looks good and makes adding new tasks a breeze.


I run Linux on my laptop (naturally), and there are of course hundreds of text editors available for it. For my note-taking needs, however, I use Typora, which looks nice and just works, and ThiefMD. Most of this article was written in ThiefMD, which also supports Fountain, a superset of Markdown geared towards screenwriting. Sleek is a great-looking and very easy to use Todo.txt editor available in most Linux repositories.

Other Platforms

My sysadmin work requires me to manage Windows systems, so being able to view and edit my notes from there is handy too. Syncthing has Windows and iOS ports, and Markdown editors are available for both platforms. I would recommend iA Writer on iOS and Ghostwriter for Windows. Sleek has Mac and Windows ports, and SwiftoDo is a very capable equivalent for iOS.

Buy this article as PDF

Express-Checkout as PDF
Price $2.95
(incl. VAT)

Buy Linux Magazine

Get it on Google Play

US / Canada

Get it on Google Play

UK / Australia

Related content

comments powered by Disqus
Subscribe to our Linux Newsletters
Find Linux and Open Source Jobs
Subscribe to our ADMIN Newsletters

Support Our Work

Linux Magazine content is made possible with support from readers like you. Please consider contributing when you’ve found an article to be beneficial.

Learn More