Compile .qmd lecture slides to Beamer PDF via convert_qmd3.py + pdflatex. Use when compiling one or all slides, or when user says 'compile', 'build PDF', 'render slides'.
Compile one or all .qmd lecture files using the custom Python converter pipeline.
.qmd → convert_qmd3.py → .tex (intermediate) → pdflatex (2 passes) → .pdf
Before compiling, run these checks:
# Quick brace check
python3 -c "
with open('FILENAME.qmd') as f:
lines = f.readlines()
total = 0
for i, l in enumerate(lines, 1):
s = l.rstrip()
d = s.count('{') - s.count('}')
total += d
if abs(d) > 1:
print(f' L{i}: {d:+d} | {s[:100]}')
print(f'Net: {total}')
"
# Check for unclosed \textcolor or \textbf
grep -n 'textcolor{[^}]*}{[^}]*$' FILENAME.qmd
# Check for ## before raw \begin{frame}
grep -B1 -n 'begin{frame}\[fragile\]' FILENAME.qmd
# Count pgfplots (warn if >3)
grep -c 'begin{axis}' FILENAME.qmd
\textcolor{X}{\textbf{text:} rest → add } at end\textbf{\textcolor{X}{text → add }} at end## Title before \begin{frame}[fragile] → remove the ## Title\newcommand{\source} in YAML header-includes → remove (converter defines it)cd Lectures/slides
python3 convert_qmd3.py FILENAME.qmd --output-dir pdf_out
cd Lectures/slides
for f in *.qmd; do
echo "=== $f ==="
python3 convert_qmd3.py "$f" --output-dir pdf_out
done
.tex in output dir for \begin{axis} blocksReport for each file:
After successful compilation, verify that all syllabus-required citations appear:
# For each lecture topic, check that required author surnames appear in the .qmd
# Lecture 01 (Foundations): Fearon, Blattman, Miguel
# Lecture 02 (Greed/Grievance): Collier, Hoeffler, Esteban, Ray, Dincecco, Tilly
# Lecture 03 (Economic Shocks): Miguel, Dube, Vargas, Hsiang, Berman, Couttenier, McGuirk, Burke
grep -c "AUTHOR_SURNAME" FILENAME.qmd
If any required citation is missing → flag as FAIL and list missing citations. This is a strict rule: every syllabus-listed paper for the lecture topic MUST appear.
After successful compilation, estimate total lecture time:
# Count raw PDF pages
PAGES=$(pdfinfo pdf_out/FILENAME.pdf | grep Pages | awk '{print $2}')
# Count pause overlays (each adds ~1 extra PDF page)
PAUSES=$(grep -c '\\pause' FILENAME.qmd)
# Count content slides (## headings = unique content slides)
CONTENT_SLIDES=$(grep -c '^## ' FILENAME.qmd)
# Count figure/table-only slides (~0.5 weight)
# These are slides where content between ## headings is only \includegraphics, \begin{tabular}, or TikZ
FIG_TABLE=$(grep -c 'includegraphics\|begin{tabular}\|begin{tikzpicture}\|begin{axis}' FILENAME.qmd)
# Count interactive slides with time estimates
# Match patterns like "(8 min)", "<!-- time: 10min -->", "(5 minutes)"
grep -oP '(\d+)\s*min' FILENAME.qmd | awk '{sum+=$1} END {print sum+0}'
Time estimation formula:
Report format:
Estimated lecture time: ~82 min / 90 min target
Content slides: 28 × 2 min = 56 min
Figure/table slides: 6 × 1.5 min = 9 min
Interactive (explicit): 3 slides = 17 min
Assessment: Good fit for 90-min slot
If estimated time exceeds 100 min: warn "Lecture may run over — consider cutting ~N slides" If estimated time is below 60 min: warn "Lecture may be thin — consider adding depth or exercises"
The converter preamble provides:
\source{}, \takeaway{}rules/converter_rules.md for full list of known issues--output-dir to avoid permission errors on existing PDFs