# Emacs teacher helpers This is a collection of scripts to aid teachers with the daily tasks of running a lecture. It relies on a descriptive filesystem hierarchy and plain-text files to ease extensive scripting and enable synchronization with Git (or any other VCS). Despite using plain-text formats, some data is machine readable to be consumed by the scripts. We rely on the [org-mode](https://orgmode.org) format as it provides both simple to use human friendly markup and reasonably strict machine-walkable structure. The functionality is composed of multiple small standalone scripts, some of which are usable even without org-mode and can therefore be easily adapted to other workflows as well. ## The data format The central data storage is an org-mode document with a heading for each student optionally nested, that is either ``` * Harry Potter * Tom Riddle ``` or ``` * Gryffindor ** Harry Potter * Slytherin ** Tom Riddle ``` The contents of these student records are mostly free form; you can store your own notes and opinions there. I also find it very handy to make the student's name a link to their photo, so I can connect my written notes with memories of how the student performs in the lecture. Each student heading must have certain properties attached, let me show an example ``` * Ronald Weasley :PROPERTIES: :baseFilename: Weasley :emailAddress: r.weasley@hogwarts.edu :emailName: Ronald Weasley :emailVocative: Ron :END: ``` `emailName` and `emailAddress` are used together by the tools to construct the recipient of messages as `name
`. While the name is equal to the heading title most of the time, it is handy when your students don't use their official names even in formal communication (such as Asian names transcribed to Latin and altered to fit Slavic language needs). `emailVocative` is an arbitrary variable passed to your email templates. It is meant to by used for templating `Dear ` and will probably be generalized in later versions to allow further customization of the templates. Whenever we need to guess a filename of an attachment related to this student, we append the appropriate extension to the student's `baseFilename`. That is _Ron's_ exam scan is supposed be in the exam's folder named `Weasley.pdf`. That's just the default though; all attachments will be explicitly linked to and can therefore be customized. There is one special subheading of the student record called `Exams`. This is where the scripts link to exam scans and also where they look for scans to attach to emails. It may look like (with properties collapsed as rendered by Emacs) ``` * Ronald Weasley :PROPERTIES:... ** Exams *** [[file:hw1/Weasley.pdf][Introductory home assignment]] *** [[file:exam1/Weasley.pdf][Midterm written exam]] ``` ## Available scripts ### Scan processing The script `renamedir.sh dir` walks over all PDF files in the specified directory and processes them one by one. The document will be shown twice. After the first round, you are asked for the new document name. This way you can only focus your eyes on the upper right corner to recognize the student's signature, immediately close the viewer and write it down. After the second round, you can decide to only keep the first page of the document and discard the rest. This rarely makes sense for manual scanning but comes in handy with unconditionally 2-sided scans (such as ADFs in the next paragraph). If your scanner is equipped with an automatic document feeder, it will produce a single PDF with all the pages. This is handled by `split.sh count file dir`. `count` is the number of pages of the original document (that is twice the amount of physical pages), `file` is the scanner output and `dir` is where processed scans will go. The script produces multiple documents each with the front and pack side of the scanned page. Then you can proceed with `renamedir.sh`. That is why it offers to keep the first page only. ## Attachment linking If you load the `linkAttachments.el` file (`M-: (load "linkAttachments.el")`) the function `eth/linkAttachments` becomes available. When called, it interactively asks for arguments and then walks through all student records and tries to find their exam scan (using the `baseFilename` property). When found, it creates a new heading for it under the `Exams` heading. ## Sending attachments via email The script `composeMails.py` is specific for the [aerc](https://aerc-mail.org) MUA, but is can be easily adapted for others. It processes all provided records and prepares an email for each of them feeding it with the recipient address, message body based on expanded template and the attachment. It keeps the messages open in `aerc`, so you can review and possibly hand edit them before sending. The script doesn't take care of its data source; you are supposed to pass the data on stdin. The usual workflow therefore is creating the message template (usually in the exam's directory) and a helper script such as ```sh #!/bin/sh set -eu -o pipefail emacs --batch --load ../../tools/getAttachmentMails.el --file ../students.org --eval '(princ (eth/getAttachmentMails "Exam 1"))' | ../../tools/composeMails.py -s 'Exam 1 results' -r 'e36d49bd-01cd-43b1-a884-b31bec66dd64@hogwarts.edu' -t mail.txt "$@" ``` When you run it, it'll just output debug information to quickly catch mistakes (still not such a big deal as the script never actually sends mail). If you pass `--really`, it proceeds with actually creating the messages in `aerc`.