Customizing Athens Research

I’ve long been intrigued by the hype around Roam Research. As an early adopter of this type of tool, I started using it back when accounts were free, but I couldn’t get on board with sticking all my important data in someone else’s cloud.

Getting banned from the Roam subreddit for a brief comment listing the reasons I don’t use Roam reminded me of Athens Research, which is heavily inspired by Roam, but importantly is open source and can be run as a local app. My first Athens trial didn’t last very long. My eyesight isn’t the best, so I can’t read small fonts for very long, and for whatever reason, the Athens founder doesn’t view this as a priority. It’s been more than eight months since that issue was first opened and it doesn’t look like anything’s been done with it. Fonts are not merely a matter of preference, they’re a matter of accessibility, as I wrote in a comment there. Ctrl-+ isn’t a solution because it makes the app unusable.

Athens is open source so I forked the repo and started digging through the code. It’s a pretty easy codebase to read. I installed the dependencies listed on this page. I built the app using lein dev. I ran the app using yarn run electron .. Much to my surprise, it actually worked. It’s not often that apps like this build and run so easily. On to customizing for my own usage.

Changing the font size

This was my main issue. The default font size for the main text on the daily note is too small for me. A little digging around led me to src/cljs/athens/views/blocks/content.cljs, and the definition of block-content-el:

(defn block-content-el
  "Actual string contents. Two elements, one for reading and one for writing.
  The CSS class is-editing is used for many things, such as block selection.
  Opacity is 0 when block is selected, so that the block is entirely blue, rather than darkened like normal editing.
  is-editing can be used for shift up/down, so it is used in both editing and selection."
  [block state]
  (let [{:block/keys [uid original-uid header]} block
        editing? (rf/subscribe [:editing/is-editing uid])
        selected-items (rf/subscribe [::select-subs/items])]
    (fn [_block _state]
      (let [font-size (case header
                        1 "2.1em"
                        2 "1.7em"
                        3 "1.3em"
                        "1em")]

The bottom line sets the main text (non-header) font size at 1em. I changed it to 1.25em and after a rebuild and restarting the app (changes didn’t always come through after an automatic rebuild), I had a usable Athens Research. The single issue holding me back was now solved.

After I’d gone through the trouble to do this, why stop there? I’m already maintaining my own fork. I’ve invested a couple of hours in the codebase. Might as well keep going.

Changing the font family

The default IBM Plex Sans font is acceptable, but I’ve come to prefer Source Code Pro in Obsidian and Emacs, so it would be nice to use that in Athens too. I downloaded all the Google Fonts ttf files for Source Code Pro and copied them into resources/public/css/fonts.

In src/cljs/athens/style.cljs, I changed

(def base-styles
  {:background-color (color :background-color)
   :font-family      "IBM Plex Sans, Sans-Serif"

to

(def base-styles
  {:background-color (color :background-color)
   :font-family      "Source Code Pro, IBM Plex Sans, Sans-Serif"

After a rebuild and reload, I had a nicely-sized Source Code Pro font.

Changing the text width

The width of text on the daily page was set a bit too small, and it annoyed the heck out of me. Text width is hard to get right. A little bit too narrow or too wide is very noticeable to me. In src/cljs/athens/views/pages/node_page.cljs there is a definition of page-style:

(def page-style
  {:margin "2rem auto"
   :padding "1rem 2rem 10rem 2rem"
   :flex-basis "100%"
   :max-width "55rem"})

The text width is determined by the 55rem in the last line. I changed it to 60rem and it felt right. At this point, I was comfortably adding information to my daily page, but when I’d stop to read what I was writing, I didn’t like that the headings were (i) so big, and (ii) used the Source Code Pro font. I think it’s important to distinguish headings from the main text by using a different font/emphasis rather than a dramatic difference in font size. (As always, this is simply my preference.)

You can go further down in the base-styles definition described above and change things as needed. To change the font family for all headers back to the default IBM Plex Sans, I went here

[:h1 :h2 :h3 :h4 :h5 :h6 {:margin      "0em 0"
                          :line-height "1.3"
                          :color       (color :header-text-color)}]

and added a line

[:h1 :h2 :h3 :h4 :h5 :h6 {:margin      "0em 0"
                          :line-height "1.3"
                          :font-family "IBM Plex Sans, Sans-Serif"
                          :color       (color :header-text-color)}]

Then to make a change specific to first-level headers, I changed

                      [:h1 {:font-size      "3.125em"
                            :font-weight    600
                            :letter-spacing "-0.03em"}]

to

                      [:h1 {:font-size      "2.125em"
                            :font-weight    600
                            :letter-spacing "-0.03em"}]

Now I have acceptable headers.

I’m sure there are styling issues that will bother me in the future. Even though I’m a longtime Emacs user, I’m not the type of person that enjoys tinkering with configuration files - customization has never been a reason for me to use Emacs. There are just a lot of better things to do with my time. Having said that, I don’t regret the time I spent modifying Athens at all. Doing this had added another high-value tool to my toolbox.