Navigation Menu

Writing for Large Classes With Docstrip

Jan 5, 2023

Last year, I did all of my course document preparation using docstrip, a standard component of LaTeX. It was revolutionary; docstrip allowed me to prepare all of my course documents in one large LaTeX project while maintaining a consistency of style across many formats including slides, quizzes, tests, and even posts to our learning management system.

What does docstrip do? It produces LaTeX files by selecting chunks of code from an input file using specially formatted comments. This sounds quite boring, but it is very helpful for writing materials for courses with multiple sections. To get a sense for why docstrip is helpful, suppose that you want to write multiple versions of a quiz. This is done as follows.

\begin{question} 
	Calculate the following integral:
		%<*version-a>
			\[
				\int x \sin(x) dx
			\]
		%</version-a>

		%<*version-b>
			\[
				\int x \cos(x) dx
			\]
		%</version-b>
\end{question}

With this code1 stored in a file called course.dtx,
one then asks LaTeX to compile two documents using a batch file.

\file{quiz-version-a.tex}{\from{course.dtx}{version-a}}
\file{quiz-version-b.tex}{\from{course.dtx}{version-b}}

This will generate two new LaTeX files: quiz-version-a.tex and quiz-version-b.tex. The file quiz-version-a.tex will contain:

\begin{question} 
	Calculate the following integral:
	\[
			\int x \sin(x) dx
	\]
\end{question}

The ability to pick out chunks of code from a main project file is powerful. One can write problems and their solutions in the same document or make special versions of slides for distribution to students2. Docstrip makes it easy to prepare multiple related documents in a flexible manner.

The specially formatted comments that tell docstrip which code to include are called guards. In the example above, the guards each contain a single option. However, guards can contain boolean expressions of the options. When preparing quizzes, one often wants to prepare a special version for TAs which contains the questions from all versions of the quiz. Adding an option all and appropriately modifying the guards to contain boolean ORs gives the following.

\begin{question} 
	Calculate the following integral:
		%<*version-a|all>
			%<all>Version A:	
			\[
				\int x \sin(x) dx
			\]
		%</version-a|all>

		%<*version-b|all>
			%<all>Version B:	
			\[
				\int x \cos(x) dx
			\]
		%</version-b|all>
\end{question}

One then modifies the batch file to be the following:

\file{quiz-version-a.tex}{\from{course.dtx}{version-a}}
\file{quiz-version-b.tex}{\from{course.dtx}{version-b}}
\file{quiz-all-versions.tex}{\from{course.dtx}{all}}

Now, one can easily make each quiz and a master copy in the same format. With the ability to handle boolean expressions of options, the sky is the limit.

Of course, there is more to docstrip then I’ve presented here. I first learned about docstrip from Matthew Leingang. His article Using docstrip for Multiple Document Variants is a great place to start learning this stuff. The documentation for docstrip is also great, although somewhat technical.

Bibliography

Leingang, M. (2020). Using DocStrip for multiple document variants. In TUGboat (Vol. 41, Issue 3, pp. 281–285). TeX Users Group. https://doi.org/10.47397/tb/41-3/tb129leingang-docstrip


  1. The example in this note is available on GitHub here: https://github.com/pgadey/quiz-example↩︎

  2. It is possible to these things in an ad hoc manner without using docstrip. The exam class has a special environment solution which whose contents can be included or excluded at compile time by using \printanswers or \noprintanswers. Alternatively, one can pass the option answers to the document class via \document[answers]{exam}. The beamer class has functionality for preparing handout versions by passing the option handout to the document class via \documentclass[handout]{beamer} but the format is quite restricted. Docstrip can handle both of these use cases in an uniform way. ↩︎

Related tags:

Navigation Menu

Thanks for reading! If you have any comments or questions about the content, please let me know. Anyone can contact me by email.