Since getting going with emacs I’ve gone down the org-mode rabbit hole a little bit. In particular the very nice org-journal package. It basically does what it says on the tin: maintains a journal with a selection of org files. This has been very nice for me. I have often thought about journalling but never really got up a head of steam. Somehow having an entry a keybinding away while I’m doing something with my text editor makes it a lot more palletable.
Having said all this, I am not completely converted to the church of emacs. Thus, I thoght it would be nice to write a little editor agnostic script which would emulate some of org-journal’s features but allow you to use whatever editor you like with markdown.
WHAT’S THE TIME?
First things first, I wrote this little function that would give you a formatted version of your local time. This will be important as a lot of this comes down to dates and times really. It uses python’s time module:
def whats_the_time(format): return time.strftime(format, time.localtime(time.time()))
This function takes a string using python date format codes and spits out the corresponding time. For example,
'%A %d %B, %Y' would give you Wednesday 12 December, 2022.
WHAT TO CALL THE FILES?
My plan is to have three options for
journal_frequency: daily, monthly, and yearly. Depending on the value of this variable, each journal file the script creates will represent a day, month, or year. This function gives you a different filename depending on the
journal_frequency that is set:
def make_filename(): if journal_frequency == 'daily': return whats_the_time('%Y%m%d')+'.md' elif journal_frequency == 'monthly': return whats_the_time('%Y%m')+'.md' elif journal_frequency == 'yearly': return whats_the_time('%Y')+'.md'
DO WE NEED A NEW FILE?
As I could see it, the next problem was determining whether a new journal file was needed. This would only happen if it was the first entry for a day, month, or year. Otherwise, you would simply want to add to the existing file. I came up with this little function using the os module to check if the file that would be created already exists:
def new_file_required(): if os.path.exists(os.path.join(journal_dir,make_filename())): return False else: return True
MAKING FILES AND PUTTING THINGS IN THEM
Now we have that admin out the way, we’re on the home straight. This function creates a file and adds a little title heading at the top using the
title_string variable. This will be called when we do need a new file:
def create_file(): path = os.path.join(journal_dir,make_filename()) with open(path, 'w') as f: f.write('# ' + whats_the_time(title_string))
This guy adds a subheading wtih the current time as default using the
entry_string variable. If you had
journal_frequency set to monthly or yearly though you would likely want to edit this to include bits fo the date. This is called evry time you run the script.
def write_date(): path = os.path.join(journal_dir,make_filename()) with open(path, 'a') as f: f.write('\n'*2+'### '+ whats_the_time(entry_string))
OPENING A TEXT EDITOR
Final order of business: how to open the appropriate journal file with the user’s chosen editor. For this we can use the subprocess module and Popen. By default I have this set to get your EDITOR environemnt variable and use that (come to think of it that probs won’t work with tui programs) but it could be set to anything.
def open_editor(): cmd = [ editor, os.path.join(journal_dir, make_filename()) ] process = subprocess.Popen(cmd, stdout=subprocess.PIPE)
Now it’s just a matter of sticking all the functions together:
def main(): if new_file_required(): create_file() write_date() open_editor() else: write_date() open_editor() main()
As simple as it is, it works reasonalby well as it stands. I would though like to add the ability to customise the file format you want to use so you could have org, plain text, markdown, or whatever. I’ve got the script set to just run with a keybinding at the moment so it fulfils the immediacy I was enjoying with org-journal. You can find the script here atm. BYEBYE xxx