BagerBach

How I Import Literature Notes into Obsidian

1 September 2021 | 10 min read | Read more about Productivity


Importing highlights and notes into Obsidian for processing can be a very painful process without automation. So I automated it.

More precisely, I have automated the fetching and formatting of annotations, highlights, and notes taken on various platforms. Even better, I have made it possible to fetch new notes taken on an item and add them to your existing notes for that item.

Before I read things on the internet, I have a workflow that accumulates all of them in my Inbox. It's how I curate what I should read. So when I have the chance to read something, I'll find something in my Inbox and start reading.

While I read, I take notes. I usually do so using Hypothes.is — depending on the resource. I also use Readwise, which grabs the notes I take from various sources. Here's a breakdown.

  • Books I read on my iPad, from which I send the notes to Readwise.
  • Articles I read on their respective webpages. On the page, I use Hypothes.is to write notes. These are synchronized to Readwise.
  • Tweets I send directly to Readwise.
  • YouTube videos I use a template in Obsidian along with the Media Extended plugin to write notes with timestamps.
  • Podcast episodes I either use Airr or write notes while listening to it on my computer. Airr is synchronized to Readwise.

This is fine, but it only covers the initial annotation workflow. So let's talk about how I import the notes into Obsidian with EzImport.

Importing into Obsidian

EzImport is a script I've created for QuickAdd. It will grab highlights for any resource and create a note (or update it) with those highlights.

There are multiple good importers for Obsidian that import notes from Readwise:

In fact, the official Readwise plugin came very close to replacing this workflow for me. However, there are too many customizable features that I enjoy now, which it does not support. Most importantly, however, is that I don't enjoy how the synchronization process works with any of those plugins. My notes feel much too fragile with them.

With EzImport, only two things can happen.

  1. The note does not exist, in which case it creates a new notes and pulls in the highlights.
  2. The note does exist, in which case it checks if I have added new highlights since I last fetched them to the note. If I did, it updates the update time and appends the highlights to the bottom of the note. If I did not, it doesn't do anything at all.

I can also entirely control the format of my note from within Obsidian. Likewise, I can control how the highlights are formatted through JavaScript code.

Alright. Enough about what it is, here's how you can get it.

First, you'll need to install QuickAdd inside of Obsidian. Just go to community plugins and grab it from there. And while you're at it, you should grab MetaEdit as well. MetaEdit is what enables the updating process for the notes. You don't need to set MetaEdit up.

Now, place the EzImport script in your vault — you can download it here. It doesn't matter where you put it, really. Now you'll want to create a macro which activates the script. You do so by opening the Macro settings for QuickAdd through 'Manage Macros' in the main settings. There, you add the script to the macro.

You can also follow along in my video instructions on how to use QuickAdd.

Now that we've installed the script, we need to set it up. The macro will look somewhat like this (depending on what name you chose):

You'll want to click the configure ⚙ button for the script. In there, you'll be met with something like this:

Except, of course, mine already has a blurred API key and some settings. Here's what the settings mean. The first setting is your Readwise API key. You can get that here. It's used to grab the highlights.

Enabling "Ignore empty properties" will prevent QuickAdd from asking you about a value if Readwise doesn't have it. I recommend enabling it.

The remaining options are for file name formatting. You can use whatever format syntax you want here. Mine starts with the folder I want to place the created note in. For books, this is inputs/books. Them, I provide my desired file name. All of my input sources have some symbol in front of them to prevent conflicts with other (evergreen) notes. And for convenience — if a note has { in front of it, I always know that it's a book.

The {{VALUE:safeTitle}} is very important. safeTitle is the title of the resource you're importing from, but without illegal file name characters. That means, without commas, question marks, and so on. To increase searchability, I put the actual title of the resource as an alias. You'll see how that works later.

So go ahead and enter your desired file names with their desired locations. Once you're done, we're ready to set up the final part!

Books, articles, tweets, and podcast episodes

These all have similar setups, which is why I'm grouping them together.

At this point, we need something to start the process. To start the script and to guide the creation (or updating) of a note.

Enter, QuickAdd Captures.

A capture can do exactly those things! So it's time to create on. In the QuickAdd main menu, create a new Capture Choice. You're free to choose the name. I used 📕 Add Book.

We'll want to set it up with a few settings. It'll look like this when we're done.

The very first thing is the way we start the EzImport script. We do that in the file name field. This is also how we get the file name. For books, it'll look like what's shown in the image above.

Here's the rundown. If you want to create a new note which contains highlights from a…

  • Book, use {{MACRO:EzImport::book}}
  • Article, use {{MACRO:EzImport::article}}
  • Tweet / Thread, use {{MACRO:EzImport::tweet}}
  • Podcast episode, use {{MACRO:EzImport::podcastEpisode}}

OK. That's most of it out of the way. The remaining settings you can (almost) decide for yourself, but here are my recommendations:

  • Create the file if it doesn't exist (mandatory).
  • Create file with given template — and then specify a template. You can use mine entirely or for inspiration — they're optimized for this workflow. You can find them below.
  • Write to bottom of file — otherwise, when you add new highlights, they'll be added to the top of the file.
  • Open — kind of self-explanatory; it opens the file.
  • Capture format of {{VALUE:highlights}} — mandatory if you want to synchronize your highlights. This inserts your highlights when you activate the Capture Choice.

Templates

These templates can just be copied into your Obsidian templates folder. Both Templater and the core Templates plugin will work.

Books

---
image: 
tags: in/books state/process
aliases:
  - "{{VALUE:title}}"
cssclass: 
lastHighlightAt: {{VALUE:lastHighlightAt}}
---

# {{VALUE:title}}

## Metadata
Tags:: {{VALUE:tags}}
Type:: [[{]]
Author:: {{VALUE:author}}
Reference::
Rating:: {{VALUE:10,9,8,7,6,5,4,3,2,1,0}}
Reviewed Date:: [[{{DATE:gggg-MM-DD - ddd MMM D}}]]
Finished Year:: [[{{DATE:gggg}}]]

# Thoughts

# Actions Taken / Changes

# Summary of Key Points

# Highlights & Notes

Tweets

---
tags: in/tweet state/process
aliases:
  - "{{VALUE:title}}"
cssclass: null
lastHighlightAt: {{VALUE:lastHighlightAt}}
---

Title:: {{VALUE:title}}
Type:: [[!]]
Tags:: 
Account:: {{VALUE:author}}
Rating:: {{VALUE:10,9,8,7,6,5,4,3,2,1,0}}
Link:: {{VALUE:source}}
Reviewed Date:: [[{{DATE:gggg-MM-DD - ddd MMM D}}]]

---

Articles

---
tags: in/article state/process
aliases:
  - "{{VALUE:title}}"
cssclass: null
lastHighlightAt: {{VALUE:lastHighlightAt}}
---

# {{VALUE:title}}

## Metadata
Title:: {{VALUE:title}}
Type:: [[(]]
Tags:: {{VALUE:tags}}
Author:: {{VALUE:author}}
Link:: {{VALUE:source}}
Rating:: {{VALUE:10,9,8,7,6,5,4,3,2,1,0}}
Reference::  
Reviewed Date:: [[{{DATE:gggg-MM-DD - ddd MMM D}}]]

---

Podcast episodes

---
tags: in/podcast state/process
aliases:
  - "{{VALUE:title}}"
cssclass: null
lastHighlightAt: {{VALUE:lastHighlightAt}}
---

Type:: [[%]]
Tags:: 
Podcast:: {{VALUE:author}}
Title:: {{VALUE:title}}
URL:: {{VALUE:source}}
Host:: 
Guest:: 
Reviewed Date:: [[{{DATE:gggg-MM-DD - ddd MMM D}}]]
Reference:: 

---

Youtube videos

---
tags: in/video state/process
aliases:
  - "{{VALUE}}"
cssclass: null
---

Title:: {{VALUE}}
Type:: [[+]]
Tags:: 
URL:: https://www.youtube.com/watch?v={{VALUE:📺 YouTube Video ID}}
Channel:: 
Reference:: 
Publish Date:: 
Reviewed Date:: [[{{DATE:gggg-MM-DD - ddd MMM D}}]]

---

<center><iframe width="560" height="315" src="https://www.youtube.com/embed/{{VALUE:📺 YouTube Video ID}}" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></center>

---

- 

My workflow for videos is slightly different. You'll need to create a Template Choice for QuickAdd with the above template. It should look like this:

You specify the tempalte path, define the file name, and optionally select a folder to place it in.

{{VALUE}} will make QuickAdd ask you what the video title is, which I usually just copy from the video page.

You'll also be asked for a video ID. You get this from the video link. Let's take https://www.youtube.com/watch?v=gYK3VDQsZJo as an example. Here, the gYK3VDQsZJo is the ID. So just paste that in. This is the end result:

Making your own templates

I won't force you to use my templates, so here is a small guide to creating your own. As I mentioned, the file name should be created with {{VALUE:safeTitle}}. But there are more variables that you can access and use in your templates.

  • {{VALUE:safeTitle}} is the resource title without illegal file name characters
  • {{VALUE:fileName}} is the final file name
  • {{VALUE:title}} is the title of the resource
  • {{VALUE:author}} is the author's name in wikilinks, i.e., [[Adam Smith]]
  • {{VALUE:source}} is the source URL of the resource
  • {{VALUE:tags}} are the tags from the resource
  • {{VALUE:cover}} is the cover image URL for the resource
  • {{VALUE:lastHighlightAt}} is the date and time at which the latest highlight was added
  • {{VALUE:updated}} is the date and time at which the resource was updated in Readwise
  • {{VALUE:numHighlights}} is the amount of highlights for the resource

You can use any of these in your template. I strongly encourage you to have a YAML field with lastHighlightAt to enable updating of your note.

Bonus: Unprocessed Note Inbox

For me, both reading and processing a note can't happen during the same session. Sometimes I rack up a ton of unprocessed notes, and they're all just sitting in the back of my mind, waiting for me to get back to them.

My solution? An Unprocessed Note Inbox. If you use my templates (or the #state/process tag), you can use this Dataview query!

I actually use both Dataview and Admonition for this, since I may want to minimize it sometimes.

````ad-tip
title:## 📥 Inbox
collapse: open
```dataview
TABLE Type
FROM #state/process and !"inputs/literature_notes" and !"bins"
```
````

And this is what it looks like:

So let me just explain the query. It creates a table with both a File column and a Type column. To populate this table, it looks for all files tagged #state/process that are not in the inputs/literature_notes folder nor the bins folder.

Any questions, requests, or otherwise? Feel free to reach out (Twitter).

Sign up for my newsletter below 👇 to get updates and be the first to hear when I release new posts like this.

Join the newsletter