When we last left off, I talked about the need to convert Markdown to HTML:
For the small price of adopting some kind of "compilation" stage in my notes, whereby they get compiled from Markdown to HTML, I could take notes that had all of the [features I wanted]...
Markdown generally looks okay as plain text, but elements like tables, links, or images don't work. Converting to HTML is how I pick up the power of these features.
The beauty of the Markdown ecosystem is that there are many common tools already available to render HTML from Markdown. I found many of them already installed on my system. Here are just a few examples:
- Text converter tools like pandoc
- IDE's like VS Code
- Plain text editors like Sublime Text
- Static site generators like Hugo
I'm going to talk about specific use cases below, but let me briefly introduce the two tools I selected. This is not a one-size-fits-all solution. Maybe it would work for most people, but the point of me writing this is to show how flexible modern tools are. A typical developer might quickly and easily roll their own solution that fits their own use cases better.
First, I've already adopted TextMate as the primary text editor on my system. TextMate is the lightest-weight piece of software besides vim that supports all of my daily tasks, including note-taking. It offers additional benefits by being hackable / pluggable through a bundle system. That is a huge benefit for note-taking as well.
Finally, TextMate is open-source.
You can download TextMate from here.
You can also contact MacroMates.
Before you submit a bug report please read the writing bug reports instructions.
To build TextMate, you need the following:
- boost — portable C++ source libraries
- Cap’n Proto — serialization library
- multimarkdown — marked-up plain text compiler
ninja — build system similar to
- ragel — state machine compiler
sparsehash — a cache friendly
# Homebrew brew install boost capnp google-sparsehash multimarkdown ninja ragel # MacPorts sudo port install boost capnproto multimarkdown ninja ragel sparsehash
After installing dependencies, make sure you have a full checkout (including submodules) and then run
./configure followed by
ninja, for example:
git clone --recursive…
The Markdown bundle for Textmate includes a "preview" feature that renders Markdown as HTML. But there were a couple things I wanted to add to that. The main one was indexed navigation across multiple days. For that purpose, a better approach was to actually build a full site out of my notes folder, and I used the Maven site plugin with the Fluido skin to do that. It looks incredible, as you will see.
On top of all of this, I wanted a single interface to these tools, so I created a cli that I use. For now, I call it Noted but the name isn't really so important.
Lightweight CLI for taking markdown notes in a journal-like (time-seried) fashion
Lightweight CLI for taking markdown notes in a journal-like (time-seried) fashion on macOS.
- Getting Started
- Typical usage
- Subcommand reference
- Configuration guide
- Recommended aliases
- Usage with a static site generator
- Change default editor
Noted can do the following and more:
- Automatically create a markdown file for you, named with today's date (in a customizable date format)
- Append note entries from the command line automatically, formatted with a Markdown template you can customize
- Timestamp all entries with a customizable timestamp format
- Quickly open the notes from any given date for you to view or edit
- Work with any text editor, with no interference between
notedand the editor
Getting started with Noted only requires that
noted is placed on your path.
A good standard way to do this is to symlink the…
Let me walk though a contrived example of my note-taking process, to show you how my tools support me throughout. Maybe I come in to work on Monday morning and I need to go through email and Slack messages. On my terminal, I type:
$ n 'Going through email and slack messages'
What is that "n?" As I mentioned, I use a lightweight cli called Noted which is nothing more than a simple shell script. The alias for
noted in my shell is
n, to cut down on keystrokes.
The basic gist of this command is to automate a few basic steps for me so I don't have to think about them. In detail, the cli does the following.
- It checks for a file named with today's date in a known directory (
~/Documents/notes). If it's October 26, then it looks for
2021-10-26.mdand if that doesn't exist, it creates it.
- It appends a Markdown template for the new entry into the file, stamped with the current system time and date.
- It appends the text
Going through email and slack messagesinto this template.
The result looks like this in Markdown:
-------- 07:43:32 Pacific # Going through email and Slack messages --------
nv (alias for
noted view) in the terminal, I can launch TextMate with today's notes file should I then need to edit or add to the entry. The TextMate Markdown bundle has a feature called "Preview" which renders the Markdown to HTML in a separate window. Just select Bundles > Markdown > Show Preview from the menus or type ^⌥⌘P (Control + Option + Command + P).
The above snippet looks like this when rendered to HTML:
The habit of simply recording tasks as they happen provides the first benefit of my system, which is that I can account for my time if I ever need to, because all entries are automatically time-stamped.
In my terminal, I'm going to type something like this, and notice that by leaving the ending quotation mark off the first line, I get a multi-line entry:
$ n 'HTTP Client Comparison quote> - [Spring WebFlux WebClient](https://spring.getdocs.org/en-US/spring-framework-docs/docs/spring-web-reactive/webflux-client/webflux-client.html) quote> - [OkHttp](https://square.github.io/okhttp/) quote> - [Jersey HTTP client](https://eclipse-ee4j.github.io/jersey.github.io/documentation/latest/client.html)'
nv which is my alias for
noted view and that opens my notes in TextMate again. They currently look like this when rendered:
For me, all of this happens automatically and reflexively. It doesn't even register on my consciousness.
At this point, I start to add a table to compare the options. Since tables are slightly more complex, I type this within TextMate. It starts out like this:
| | WebFlux | OKHttp | Jersey | |:-- | :-- | :-- | :-- | | Maintainer | Spring / VMWare | Square | Jakarta | | License | Apache 2.0 | Apache 2.0 | Eclipse / Gnu | | GitHub Stars | 44.8k | 41k | 541 |
Eventually, I collect more information into this table to help with my comparison.
Besides the ability to preview notes within TextMate itself, I have a markdown generator (Maven site plugin) wrapped around it, so I can also type
noted build (or alias
nb) to generate that quickly, and my notes now look like this so far:
Here another benefit of this system comes into view. Later I can do a straight copy/paste of this material into our wiki or a GitHub gist or page at work in order to share it with my team.
Let's assume that I have a weekly meeting to attend at this point. The
noted view command also takes an argument, which is the file name of any notes file. If today is 2021-10-26, and I want to review the notes from last week's meeting, I type:
$ nv 2021-10-19
And that just pops open the notes from 2021-10-19 in TextMate.
After the meeting, I might work on a bug and part of documenting repro steps is to get a screenshot of the bug. Once I repro, I can use ordinary Mac screen capturing to capture the screenshot. The great thing about this feature of macOS is that you can set where screen captures are saved. I've configured mine to save them into an
images directory within the same directory where all my markdown files are going.
With that capability, I simply take the screenshot, use the built-in Mac tools to highlight the issue I see, and quickly add the image into my notes with ordinary Markdown image syntax. That then renders like this:
A third benefit appears. Scientists often say that if it isn't written down it doesn't exist. By documenting all these things as I go in one central system, I now have a record I can always go back to and check. The above can be transferred into Jira or another bug-tracking system with copy/paste. But I can always come back to this in my local notes.
And that brings me to my fourth benefit. Regardless of being online or offline, or being on VPN or off-VPN, I have information that allows me to continue working.
By the way, the cli I wrote also has a grep command to search in the notes directory. I can always find anything and everything connected to a particular topic. I can issue the command
noted grep foo to find everything related to Project Foo, for example.
I have considered using a simple tagging system where each note entry related to a given topic just has some tags at the bottom such as "#promotion" or "#java" to help with finding things, but, in practice, I've never needed this. Just having all notes as text in a single directory is a superpower in and of itself. I can't count the number of times someone has asked me "Do you remember such and such, do you remember how we solved that?" and simply searching through my notes found the answer.
The ability to search through old notes is the most useful when confirming what was agreed upon in meetings. I am usually the secretary of meetings because of my note-taking habit, and what I like to do is take notes within my system during a meeting. I clean them up after the meeting and then send a copy to all participants. We all have transparency that way, and no one can say that there was an action item that wasn't there, or vice-versa.
I know that all of this requires a certain level of discipline in actually taking notes, but with this set of completely open-source, off-the-shelf tools, I find that taking notes seems no more of a trifle than pouring a cup of coffee.
It's also worth noting (ha ha) that on some days, I take more notes than others. On a day that's entirely dedicated to implementing a new feature in our codebase, for example, I take almost no notes at all in the note-taking system. I instead use IDE features (like IntelliJ tasks) or old-fashioned
TODO comments—basically I try and use the best tool for every job, rather than use a "single tool to rule them all."
The last thing I want to say is that not everyone needs notes for the same purposes. There are definitely other use cases not covered here. And for the ones that are, you would need to decide how you want to take notes and what the best tool for the job would be.
In the next installment of this series, I will address some of these other issues, and talk about how other tools can be used, or how the same tools can be used differently. Because I believe the major point in all of this is that we should all have the freedom to write and engineer our own process.