Org, AWK, and Anki

İsmail Efe Top

2024-03-17

Disclaimer: This blog post requires you to know what org-mode, Anki, and AWK are.

I use org-mode a lot for taking notes in my classes. There are not many classes that introduce a lot of new terms. But this semester, we are taking a class called 'introduction to literature' and as you can imagine there are tons of new terms.

My memory is not that good and I need to do a lot of practice to memorize. So, a flash card software like Anki comes handy.

My problem is that I don't know how I can turn my org notes into Anki flash cards.

What I Want

When I have a class that introduce lots of terms, I usually put a 'terms' heading on the beginning of my file. When we are introduced to a new term, I put that there.

My org class notes look something like this:

The image of my org class note, written in org-mode.

I need this system to also work for Anki. So, after a bit of thought, I decided I want something that can turn lines containing terms into Anki flash cards.

Let's search for solutions…

First Solution: Search Google

I found two projects that try to connect org-mode and Anki. These were anki-editor and org-anki. But after looking into them a bit more, I found that they have their own way of working and wouldn't be great for my basic use-case.

But if they interest you, I found a great blog post talking about them.

Second Solution: Make Your Own

Because I don't need anything complex, I think I can do something on my own. I know that Anki supports basic csv files. So, let's go with that.

Because I only need a term and a meaning, a csv file with two columns should be sufficient. First column should be the name of the term and the second should be what that term means. So, the resulting file should look something like this:

term_name;term_meaning
term_name;term_meaning
term_name;term_meaning
term_name;term_meaning

To turn my above org class note into a csv file that looks like that, I need to do a few things.

In plain-text, my org class note looks like this:

The image of my org class note, written in org-mode and turned into a plain text file.

Now that we have everything we need, let's get to work.

I normally would use python for this but I thought AWK would work better. I would strongly recommend that you watch this video to learn more. Let's start writing an AWK script to turn org files into csv files. We will start with…

In the end, our command should look something like this.

awk 'BEGIN { FS=": " } /^[[:space:]]*[-+]/ && index($0, ": ") { sub(/[-+]/, ""); sub(/^[[:space:]]+/, ""); printf "%s;", $1; print $2 }'

When I feed my class file into this command, it spits out this:

Subject;What a text is about, usually short and general
Theme;What the text tells us about the subject. Goes more into the subject
End-stopped line;A metrical line containing a complete phrase or sentence, or a poetic line ending with punctuation
Run-on line (enjambment);When the end of the line is not marked by punctuation, and the sentence or clause carries on over into the next line
Personification;Talking about a non-human as a person
The poetic persona/speaker;The word writer isn't used in poems, instead poetic persona or speaker is used
Simile;Likening something to something else. For example, like a thunderbolt he falls
Sonnet;A fourteen-line poem
Quatrain;A stanza of four lines
Couplet;Two lines of poetry at the end of a sonnet, that have the same length and rhyme pattern

When I give this file to Anki, it creates all the needed flash cards.

Conclusion

I am really happy with the outcome. I learned a lot about AWK and I now have a easy way to turn my org notes into Anki flash cards.

My AWK script could definitely use some polish. So, if you want to give me any tips, I will gladly take them.



Edit: u/cottasteel wrote my AWK command in elisp. It works great! Here is the code snippet:

(defun anki/export-notes-to-csv (file)
  (interactive "FExport notes to: ")
  (let ((regex (rx bol (in "+-") " " (group (1+ nonl)) ": " (group (1+ nonl))))
        (buf (find-file-noselect file))
        (output ""))
    (save-excursion
      (goto-char (point-min))
      (while (re-search-forward regex nil t)
        (setq output (concat output (format "%s;%s\n" (match-string 1)
                                            (match-string 2)))))
      (with-current-buffer buf
        (erase-buffer)
        (insert output)
        (save-buffer))
      (kill-buffer buf)
      (message "Export done."))))
Home Mail Me RSS Source
🔥⁠🐓