← All articlesSept 15, 2019 11 Min Read

How I manage my LaTeX lecture notes

Over the past few years, I’ve been de­vel­op­ing an ef­fi­cient way to struc­ture and or­ga­nize my LaTeX lec­ture notes. In this blog post, I’ll ex­plain my cur­rent so­lu­tion. I’ve talked about tak­ing notes and draw­ing fig­ures be­fore, which makes this the third post in a se­ries ex­plain­ing my note tak­ing setup.

File structure

Let’s first talk about the file struc­ture of my lec­ture notes. Cur­rent­ly, it’s or­ga­nized as fol­lows:

  • university
    • bachelor-1
    • bachelor-2
    • bachelor-3
      • semester-1
      • semester-2
        • preamble.tex
        • complex-analysis
        • object-oriented-programming
    • current-course -> complex-analysis

As you can see, fair­ly self-​explanatory, but two things are worth ex­pand­ing upon: pre­am­ble.tex and current-​course.

Shared preamble

All cours­es in the same se­mes­ter share a com­mon pre­am­ble. It con­tains fre­quent­ly used pack­ages, macros and en­vi­ron­ments; you can find the lat­est ver­sion on Github. Each se­mes­ter, I re­view this pre­am­ble and re­move stuff I don’t use any more.

Shar­ing this pre­am­ble be­tween mul­ti­ple cours­es min­i­mizes con­text switch­ing. For ex­am­ple, I never have to think whether or not I’ve al­ready added a theorem en­vi­ron­ment in the pre­am­ble of a par­tic­u­lar course. Once I’ve added it to the shared pre­am­ble, I know it’s ac­ces­si­ble in all my notes, at any time.

Keeping track of the current course

The sec­ond thing that’s worth talk­ing about is current-​course, which is lo­cat­ed at the root of the file struc­ture:

  • university
    • current-course -> complex-analysis

While it func­tions like a di­rec­to­ry, current-​course is ac­tu­al­ly a sym­bol­ic link that points to a course di­rec­to­ry, in this case complex-​analysis. It rep­re­sents the cur­rent course I’m work­ing on: be it tak­ing notes dur­ing a lec­ture or writ­ing an as­sign­ment. Which course is ac­tive au­to­mat­i­cal­ly changes based on my sched­ule — more on that later — but I can also change it man­u­al­ly when nec­es­sary. Press­ing Alt+S opens the fol­low­ing di­a­log:

Se­lect­ing an item up­dates the des­ti­na­tion of the sym­bol­ic link, which in turn means I now have a whole bunch of key­board short­cuts at my dis­pos­al. For ex­am­ple, press­ing Alt+O opens my com­piled LaTeX notes by sim­ply ex­e­cut­ing zathura current-course/master.pdf. Like­wise, Alt+R opens the course di­rec­to­ry in a file brows­er, Alt+J in a ter­mi­nal, Alt+M opens the LaTeX source code in Vim, etc. These short­cuts are all glob­al, which means that I can use them in any con­text, when­ev­er I want. To con­fig­ure them, I’m using the Sim­ple X HotKey Dae­mon, or ‘sxhkd’ for short.

Be­sides these few sim­ple short­cuts, I’d like to share some more in­ter­est­ing ones as well, but be­fore I can ex­plain them, I first need to talk about the struc­ture of a course.

Course structure

Gen­er­al­ly, the struc­ture of a course looks as fol­lows:

  • complex-analysis
    • info.yaml
    • master.tex
    • lec_01.tex
    • lec_02.tex
    • lec_13.tex
    • figures
      • argument-principle.pdf
      • argument-principle.pdf_tex
      • argument-principle.svg
    • UltiSnips
      • tex.snippets

In what fol­lows, I’ll go over each of the files and di­rec­to­ries ex­plain­ing their func­tion.

1. Course properties: info.yaml

The first item that’s on the list is a file that con­tains in­for­ma­tion about the course: info.yaml. It’s a sim­ple yaml file whose con­tent is struc­tured as fol­lows:

title: 'Complex Analysis'
url: 'https://university.com/toledo?course_id=827278'
short: 'CA'

To re­trieve a prop­er­ty of this file, I use the com­mand line util­i­ty yq. For ex­am­ple, to get the url of the cur­rent course, I can sim­ply ex­e­cute:

$ yq read current-course/info.yaml url

Now it’s quite easy to cre­ate a short­cut that opens the url in my brows­er:

$ firefox "$(yq read current-course/info.yaml url)"

The title at­tribute is used for gen­er­at­ing the course se­lec­tion di­a­log I’ve dis­cussed be­fore, and the short for­mat is used as an in­di­ca­tor in my sta­tus bar to show which course is ac­tive.

2. Bundling up lecture notes: master.tex

Sec­ond­ly, each course has a mas­ter.tex file which bun­dles up in­di­vid­ual lec­ture notes. I can press Alt+M to open it up in Vim:


\title{Complex Analysis}

    % start lectures
    % end lectures

The file starts with the in­clu­sion of the shared pre­am­ble and after that, the pre­am­ble of the course fol­lows which con­sists of some course-​related macros. The meat of the doc­u­ment is lo­cat­ed in the lec_12.tex and lec_13.tex files.

As you can see, only the last two lec­tures are in­clud­ed. I do this be­cause in­clud­ing too many lec­tures slows down the com­pi­la­tion of my doc­u­ment. In­clud­ing both the cur­rent and the pre­vi­ous lec­ture strikes the right bal­ance: it makes it easy to have a glance at the ma­te­r­i­al cov­ered in the pre­vi­ous lec­ture, mak­ing tran­si­tion­ing be­tween them smooth, while still re­tain­ing fast com­pi­la­tion. To in­clude the notes of all the lec­tures — for ex­am­ple to make the final pdf — I can press Alt+V and se­lect one of the fol­low­ing op­tions:

Se­lect­ing an item or typ­ing a range (e.g. 3-8) up­dates the con­tents of mas­ter.tex and re­com­piles my notes.

To list all lec­ture notes, I can press Alt+L. It shows the title, date and week of each lec­ture, which are all parsed from the LaTeX files.

Se­lect­ing a lec­ture opens it up in Vim. It is worth not­ing that I al­ways call Vim with the flags --servername uni and --remote-silent so that every time I open a file using one of my short­cuts, the same Vim win­dow is used. More about that in :help re­mote.

3. Creating a lecture note

To cre­ate a lec­ture, I can press Ctrl+N. In the case above, this would make a file lec_14.tex in the di­rec­to­ry complex-​analysis and mas­ter.tex would be up­dat­ed to only in­clude the two most re­cent lec­tures. The newly cre­at­ed file has the fol­low­ing con­tents:

\lecture{14}{di 29 jul 16:00}{Title of the lecture}

which, when com­piled, looks like this:

Compiled lecture

The code re­spon­si­ble for this is lo­cat­ed in the shared pre­am­ble, and goes as fol­lows:

        \def\@lecture{Lecture #1}%
        \def\@lecture{Lecture #1: #3}%

First, the \lecture macro stores the third ar­gu­ment in a vari­able called \@lecture. De­pend­ing on whether or not it is empty, it be­comes ‘Lec­ture n: The Title’ or sim­ply ‘Lec­ture n’. Then it prints the lec­ture title and it adds the date in the mar­gin. I’ve cho­sen to save the lec­ture title in a vari­able to make it pos­si­ble to use it in fancy head­ers. You can see them at the top and bot­tom in the screen­shot above. The con­fig­u­ra­tion goes as fol­lows:


\fancyhead[RO,LE]{\@lecture} % Right odd,  Left even
\fancyhead[RE,LO]{}          % Right even, Left odd

\fancyfoot[RO,LE]{\thepage}  % Right odd,  Left even
\fancyfoot[RE,LO]{}          % Right even, Left odd
\fancyfoot[C]{\leftmark}     % Center


4. Figures

As ex­plained in my pre­vi­ous blog post, I draw my fig­ures using Inkscape and the fig­ures di­rec­to­ry is where they are stored. To edit one, I can press Alt+F which uses my inkscape-figure script to list them:

The code re­spon­si­ble for this is sim­ply the fol­low­ing:

inkscape-figures edit ~/university/current_course/figures

5. Course dependent snippets

The final item present in all of my course di­rec­to­ries is a di­rec­to­ry called Ul­tiSnips. It con­tains course spe­cif­ic snip­pets, as ex­plained in my first blog post. If I add the fol­low­ing line to my ~/.vimrc,

set rtp+=~/university/current-course

Ul­tiSnips also loads snip­pets lo­cat­ed at current-course/UltiSnips. This way, my snip­pet setup is split up in two parts. On the one hand, a sin­gle file con­tain­ing com­mon­ly used snip­pets lo­cat­ed at ~/.vim/UltiSnips, and on the other hand the files lo­cat­ed in each course di­rec­to­ry con­tain­ing snip­pets that are spe­cif­ic to that course.

Automatically changing the active course

As men­tioned ear­li­er, the ac­tive course changes au­to­mat­i­cal­ly based on my sched­ule. The script that’s in con­trol for that also shows some rel­e­vant in­for­ma­tion to my sta­tus bar, for which I’m using poly­bar. It turned out to be quite use­ful, es­pe­cial­ly know­ing what room the next lec­ture is in.

To give you an idea of what it looks like, here are some ex­am­ples of what I might see dur­ing my day:

Electrodynamics in 1:22h in A350 10:44
ED Ends in 10 minutes. Next: Complex Analysis in C611 13:50
CA Ends in 1 minute. Next: Statistics in A348 after a 30 minute break 15:29
Stat Ends in 59 minutes! 16:01

You can find my script on Github. The main out­put is lo­cat­ed in the mid­dle of my sta­tus bar. Shown on the left there’s a short in­di­ca­tor for the ac­tive course. My real sta­tus bar also in­cludes plen­ty of other in­for­ma­tion that I’ve omit­ted here for brevi­ty.


In this blog post, I’ve dis­cussed a num­ber of things, all of which some­how con­tribute to my lec­ture man­age­ment: shared pre­am­ble, current-​course sym­link, info.yaml, bundling up and cre­at­ing lec­tures, my fig­ure and snip­pet setup, and my sta­tus bar. Al­to­geth­er they allow for a smooth and ef­fi­cient note-​taking ex­pe­ri­ence.

Liked this blog post? Con­sid­er buy­ing me a cof­fee!

Written by Gilles Castel, who lives in Belgium studying mathematics at the university of Leuven.