Over the past couple years in school, I've placed tremendous value in a few things:
- Comprehensive, single-document summaries of courses I've taken;
- Beautifully type-set reports;
- Writing the bare-minimum of LaTeX to get by.
I've made this guide in the hopes it may be helpful to other students pursuing CS and/or math education.
Consequently, I like this method so much, this is how I take notes, write reports, and compose pretty much any document these days. If you want to see this in action in a more complicated project, I've made a custom template for composing nice-looking recipes using Pandoc YAML/Markdown here.
Before we get started, get yourself a copy of:
- A full LaTeX distribution with xelatex (
texlive-full
on Fedora Linux, other packages on other operating systems) - Pandoc 2.11 or higher (https://pandoc.org)
- The
pandox-xnos
filter suite - An editor that understands Markdown syntax with pandoc extensions (VS Code and vim both have good plugins)
- A nice pandoc template like this one
This document-creation strategy is highly-template based.
I'm lazy, so I haven't scripted anything, but replace anything like ${var}
with a real value for your notes/report.
- YAML Meta-data (metadata.yml)
- Markdown body (body.md)
- Makefile
- A CSL file for references (optional; I use ieee.csl, Pandoc defaults to Chicago style)
If you're not familiar with Pandoc, you can provide a bunch of document information, invocation arguments, etc. via a well-formed YAML file. With recent versions of Pandoc, you can even define CSL-json references, instead of using gross tools like bibtex.
metadata.yml
---
# Document meta-data. See pandoc.org for a full list of options.
lang: en-CA
title: '${title}'
subtitle: '${subtitle}'
date: '${date-string}' # For reports, try \today.
author: # Yup, this is a list
- Keefer Rourke
- Second Author
- And so on...
# You can omit this to use the template's default class
documentclass: scrartcl
# This is a list of what you would literally pass as geometry options to the `\documentclass{}`
geometry:
- top=0.5in
- bottom=0.5in
- left=0.5in
- right=0.5in
urlcolor: blue
fontsize: 11pt
# Section numbers, table of contents, list of figures, list of tables.
numbersections: false
toc: true
toc-own-page: false
lof: false
lot: false
# If you're using a custom template, here's a good place to put extra options specific to that tpl.
# More literal LaTeX! Whatever packages you want to include, and other configurations
# that belong in a document preamble.
header-includes:
- \usepackage{enumitem}
- \usepackage{amsfonts}
- \usepackage{lipsum}
- \usepackage{forest}
- \setlist[itemize,1]{label=$\bullet$}
- \setlist[itemize,2]{label=$\circ$}
# CSL-style references go under this block, as a list.
references:
- id: example
type: webpage
title: Example
author:
- given: First
family: Last
- literal: Some Entity
URL: https://example.com
...
# ^ This end of document delimiter is very important!
The beauty of Pandoc is that you can write vanilla Markdown, but also take advantage of syntax extensions, like GitHub pipe-tables, fenced-code blocks, and custom extensions written by the community.
All items can also take additional parameters in {}
curly blocks, which direct Pandoc how to render them in a PDF, HTML, or other compilation target.
Furthermore (and this is particularly useful if you need to layout a weird figure or typeset math), you can intermix LaTeX commands with Markdown syntax fluidly.
Here's an example:
body.md
# Inline LaTeX
This is markdown, but now here's some lorem ipsum text generated by LaTeX: \lipsum[1]
## Math
Inline math is supported $\sum_{n=1}^{\infty} \frac{1}{n}$.
### Display Math
And display math (centered on a new line below). $$\sum_{n=1}^{\infty} \frac{1}{n}$$
Of course you can also start multi-line math environments like `\begin{align*}` if you want:
\begin{align*}
I &= \int f(x) dx \\
&= \int \frac{1}{x} dx \\
&= ...
\end{align*}
### Figures
{width=100% #fig:id}
Using the `fignos` extension, you can back-link to any figure, like +@fig:id.
Citations are also easy, and you can put them anywhere text goes.
They'll be formatted automatically according to the CSL file you're using [@example].
# Code snippets
Need to render some code with line numbers?
<!-- You can use backticks, but I'm writing this in a back-tick fenced block right now...
And tildes work fine too! -->
~~~{.c .numberLines}
#include <stdio.h>
~~~
Have some commentary half way through a snippet? Restart the numbering!
~~~{.c .numberLines .startFrom=42}
int main(int argc, char* argv) {
if (argc < 1) return 1;
printf("Hello %s!\n", argv[1]);
return 0;
}
~~~
# Embedded LaTeX
Need to include some fancy LaTeX stuff, like a tree diagram? Annotating a block with `{=latex}` will render the fenced code in-place, exactly as the written LaTeX, with no attempt to further process it by Pandoc.
~~~{=latex}
\begin{center}
\begin{forest}
for tree={
grow=south,
minimum size=2em, l sep=10mm, s sep=10mm,
edge=->
}
[ A
[ B ]
[ C [ D ]
[ E ]
]
\end{forest}
\end{center}
~~~
# References
By defaut, CSL-references will get appended to the document, but this isn't always desirable.
Control where they go by inserting a div with the `#refs` ID.
::: {#refs}
<!-- The bibliography will go here now, so I can write additional content after it. -->
:::
Awesome!
Makefile
A simple Makefile pulls it all together and lets you easily integrate your favourite editor with a hot PDF compilation pipeline.
SHELL = /bin/bash
.SUFFIXES:
.SUFFIXES: .md .yml .jpg .png .svg .pdf
# Inputs and outputs
DOCNAME = 'notes.pdf'
SRCFILES = body.md metadata.yml
# Omit or use the string 'default' for the default Pandoc LaTeX template.
# Any other string resolves to the template installed to $HOME/.pandoc/templates/$TEMPLATE.tex.
TEMPLATE = 'default'
.PHONY: pdf clean
pdf:
@pandoc -o $(DOCNAME) $(SRCFILES) --template $(TEMPLATE) \
--filter pandoc-fignos \
--filter pandoc-tablenos \
--filter pandoc-eqnos \
--pdf-engine=xelatex \
--columns=3 \
--citeproc \
--csl=ieee.csl
clean:
-@rm $(DOCNAME)
Not all markdown files I edit are meant for Pandoc, so I register a custom file type for pandoc-markdown.
If pandoc syntax highlighting gets in the way of what I'm doing (e.g. I never want pandoc features in a README file), then I call setf markdown
to switch to plasticboy
's markdown highlighter instead.
Excerpts from my vimrc
call plug#begin(g:vim_home.'/plugged')
Plug 'plasticboy/vim-markdown' " Better markdown support
Plug 'vim-pandoc/vim-pandoc' " Pandoc integration
Plug 'vim-pandoc/vim-pandoc-syntax' " Extended markdown syntax
call plug#end()
augroup pandoc_syntax
au! BufNewFile,BufFilePre,BufRead *.md set filetype=md.pandoc
augroup END
au FileType markdown set cc=100 tw=0
au FileType md.pandoc set cc=100 tw=100 spell formatoptions-=t
au BufRead README set cc=72 tw=72 filetype=markdown
au BufRead README.md set cc=72 tw=72 filetype=markdown
I don't extensively use VS Code, but I've found this plugin is ok: