Manga collections with orgmode, orgtable and orgplot

Saturday, July 15, 2023



I’ve talked about my move to orgmode (and thus emacs) before. I’m still heavily using orgmode while trying to understand emacs and use it better, even though I do believe it is a very complex software to get used to. That being said, I decided to manage my manga collection with it in an orgmode file. Before that, I was using a simple spreadsheet.

I know tools exists to help a lot any book / comics / manga collection and can even alert me when there is a new volume of a collection I’m buying. But for some reason, I prefer the manual way of managing it in a simple file that I can read in any devices. It is also very simple to export in any format like pdf (when I share it with friends) or in html / gemtext. The org file and exported versions are shared via syncthing to my other devices including my phone, making it easy to know what I need to buy when I’m in a store (I did buy some volumes twice before, that’s why I started saving my collection status in a spreadsheet in the first place).

Also, while I’m talking specifically about my manga collection in this case, the same idea could be used for any collections (book or otherwise).

The file

Within my org directory structure, I have a single file that contains everything. Let’s look at it.

The org file structure

The org file structure is simple:

#+title: Manga
#+html_head: <link rel="stylesheet" href="../../templates/org2.css">
#+FILETAGS: :perso:manga:
#+STARTUP: overview

* Summary
* Details
** Ongoing series
** Finished series with missing volumes
** Complete series
* Wishlist / Ideas

The heading section should be easy to understand. Let’s talk about each section, keeping the summary section for the end.

The Details section

The first subsection is ongoing series which contains manga named that are still being published (usually with different publishing cycles). Such manga are kept in a table looking like this:

#+name: manga-ongoing
| Name  | Purchased | Available | Missing | Comments                   |
| Name1 |         5 |         6 |       1 | Avail <date>. Pre-ordered. |
| Name2 |        13 |        13 |       0 | Avail <date>               |
| TOTAL |        18 |        19 |       1 | 2                          |

Each line represent a manga collection and the comments column allow me to write when the next volume will be available and if I already pre-ordered it. I don’t add them in the Available column if they are not published (in France) yet. The TOTAL values are automatically calculated as well as the value of the missing column (explained later in this post). The number in the TOTAL row and Comments column is the number of collections in this table. In this example 2: Name1 and Name2.

The second subsection is Finished series with missing volumes which contains manga that are entirely available already, but I don’t have all of them yet. I use the same table format as for the previous section:

#+name: manga-finished-incomplete
| Name  | Purchased | Available | Missing | Comments |
| Name3 |         0 |         4 |       4 |          |
| Name4 |        14 |        26 |      12 |          |
| TOTAL |        14 |        30 |      16 |        2 |

No need for more explanation than the previous similar one. In this case, the Comments section is usually empty, but I keep that row to have the total number of manga in this section too.

The 3rd and last subsection Completed series. The table here is even simpler:

#+name: manga-finished-complete
| Name  | Achetés | Comments |
| Name5 |      22 |          |
| Name6 |      21 |          |
| Name7 |      74 |          |
| TOTAL |    1056 |       42 |

No missing volumes here as if they are in this section, I have them all :). The comments section is again helpful to get the number of manga in this section.

The summary section

The summary section contains aggregated values of the different tables to give me an overview of my collections. Both in a table format and in graphs.

First it shows me an overview in terms of owned vs missing volumes:

Figure 1: Manga volumes summary

Figure 1: Manga volumes summary

And also in a table automatically filled also (see below):

#+name: manga-summary
| Total owned    | 1411 |
| Missing volume |  158 |

(Up to date number is 1470 :P).

And second overview is about collections:

Figure 2: Manga volumes summary

Figure 2: Manga volumes summary

Also as an automatically filled table:

#+name: manga-summary-series
| Total series    | 68 |
| Finished series | 52 |
| Complete series | 42 |
| On going series | 16 |

To be fully honest, I create graphs just because I wanted to play with orgplot, not because it was really necessary :).

The wishlist section

The last section of the file is the wishlist. Just a unordered list of manga names I may one day decide to purchase. Or not.

The org table functions

Let’s talk about the fun part here: using orgmode TBLFM to write formula in order to calculate table values. Again, let’s keep the summary section for the end.

Ongoing series / Finished collections with missing volumes

The table are the same for this 2 sections, and the formula will be too. The TBLFM line must be placed below the the TOTAL row. In the case of this two tables, the formula is:

#+TBLFM: @>$3=vsum(@2..@-1)::@>$2=vsum(@2..@-1)::$4=$3-$2::@>$5=@#-2

The :: separates different formula, it means we have the following:

  • @>$3=vsum(@2..@-1): @>$3: Calculate the value for the last row of the 3rd column with vsum(@2..@-1), which means the sum of the values of the current column from row 2 (@2)to one row below the end (@-1) to avoid the TOTAL row.
  • @>$2=vsum(@2..@-1): Similar as above, but for the 2nd column last row (@>$2).
  • $4=$3-$2: The forth column is simply the value of the current row 3rd column minus the value in the 2nd column. It calculates not only the total but also the value for each rows.
  • @>$5=@#-2: This one fills the last row of the 5th column (@>$5) with the number of lines of the table (@#) minus 2 (the header and the TOTAL column) to have the number of collections in this table.

Completed collections

Very similar to the above, the formula i’m using on this simpler table is also simpler:

#+TBLFM: @>$2=vsum(@2..@-1)::@>$3=@#-2

Which means:

  • @>$2=vsum(@2..@-1): Calculate the sum of values within the 2nd column, minus the first and last row (vsum(@2..@-1)) and put this value in the last row of the 2nd column (@>$2)
  • @>$3=@#-2: Similar to above, calculate the number of lines minus header and TOTAL row to get the number of collections.

The summary section

Now this is fine to get all the values for each tables, but let’s use these values in the summary table. For the 1st summary table (owned / missing volumes), the formula is:

#+TBLFM: @1$2=remote(manga-ongoing, @>$2) + remote(manga-finished-incomplete, @>$2) + remote(manga-finished-complete, @>$2)::@2$2=(remote(manga-ongoing, @>$3) + remote(manga-finished-incomplete, @>$3) + remote(manga-finished-complete, @>$2) - @1$2)

A bit longer because using “external” values is more verbose (with remote(<tablename>)), but simply explained:

  • @1$2=remote(manga-ongoing, @>$2) + remote(manga-finished-incomplete, @>$2) + remote(manga-finished-complete, @>$2): Insert in the 2nd column of the first row (@1$2) the addition of the Purchased total of each tables. As they are stored each time in the last row of the second columns (@>$2), only the name of the table changes.
  • @2$2=(remote(manga-ongoing, @>$3) + remote(manga-finished-incomplete, @>$3) + remote(manga-finished-complete, @>$2) - @1$2): As the previous one, it is simple maths: total of available volumes in the ongoing and finished but incomplete collections + total of purchased volumes (giving me the total number of volumes available) minus the total of volumes I own which is calculated just before in the same table (@1$2).

For the second table, same idea:

#+TBLFM: @1$2=remote(manga-ongoing, @>$5) + remote(manga-finished-incomplete, @>$5) + remote(manga-finished-complete, @>$3)::@2$2=remote(manga-finished-complete, @>$3) + remote(manga-finished-incomplete, @>$5)::@3$2=remote(manga-finished-complete, @>$3)::@4$2=remote(manga-ongoing, @>$5)

Only simple maths taking values from external tables:

  • @1$2=remote(manga-ongoing, @>$5) + remote(manga-finished-incomplete, @>$5) + remote(manga-finished-complete, @>$3): Add the number of each number of series (in the TOTAL row of the comments column of each table) and set the first value of the second column (number of collections @1$2) as value.
  • @2$2=remote(manga-finished-complete, @>$3) + remote(manga-finished-incomplete, @>$5): 2nd value (finished collections) is the sum of the total of finished series, both incomplete and complete collections.
  • @3$2=remote(manga-finished-complete, @>$3): Simply reuse the value from the completed collections table for the “complete series”.
  • @4$2=remote(manga-ongoing, @>$5): Use the remote value from ongoing collections in the 4th row of the second column (@4$2) containing the number of ongoing collections.

The orgplot functions

To generate the graphs showed above, I use orgplot (that uses gnuplot for generating the graphs). To do so, we need a new line above the table with our plot definition, for example for the first table:

#+PLOT: title:"Manga Collection owned volumes" ind:1 deps!(2) set:"xrange [-0.5:1.5]" with:histograms type:2d file:"./manga-summary.png"

And with some colors:

  • #+PLOT:: starts a plot definition
  • title:"Manga Collection owned volumes": The title
  • ind:1: The number of the column to use for the x axis
  • deps!(2): which columns to graph, in my case only the 2nd one
  • set:"xrange [-0.5:1.5]": I find it nicer to have a bit of space before/after the first/last bar.
  • with:histograms: I prefer an bars than lines
  • type:2d: 2D graph
  • file:"./manga-summary.png": the image to be created.

For the second table, I use a very similar command that I don’t think I need to re-explain:

#+PLOT: title:"Manga Collection - series summary" ind:1 deps!(2) set:"xrange [-0.5:3.5]" with:histograms type:2d file:"./manga-summary-series.png"

Bonus: Recalculate when saving

To tell emacs to calculate values within tables automatically, I added in my emacs configuration:

(add-hook 'before-save-hook 'org-table-recalculate-buffer-tables)


This is not the most automated or simplest way to manage such a collection. Using a selfhosted app or specialized websites might be better. But I like the simplicity and it is sync-ed with my phone and other devices with ease and without relying on an external and/or mobile app (well it does require syncthing, but I used it already for other file sharing anyway).

I still manage my book collection in a spreadsheet because it is more complex than my manga collection (with reading dates) but I still plan to move that collection to orgmode some day too… A day I won’t be as lazy or when it will be higher in my todo list :).

Also, I’m not sharing the collection itself on this blog. I keep that for my gemini capsule. If you are curious about gemini or really want to see my manga collection, read here to learn a bit more about gemini.


If you find any issue or have any question about this article, feel free to reach out to me via email, mastodon, matrix or even IRC, see the About Me page for details.

See Also

New laptop part 6: Firefox extensions

New laptop part 6: Managing multi screens with i3wm and autorandr