Skip to main content

solrub

Build the student, solution and rubric PDFs of a LaTeX assignment.

One .tex source carries all three copies. \sol marks what only the answer key shows and \rub what only the grading rubric shows; each copy is a pdflatex run defining a different subset of them.

pip install solrub

Use

solrub quiz1a              # quiz1a.pdf, quiz1a_sol.pdf, quiz1a_rub.pdf
solrub quiz1*              # every version at once
solrub quiz1/              # every document in a folder

All three copies are the default, minus any that would come out empty: a document with no \rub anywhere in it gets no rubric copy, since that copy would only duplicate the answer key. It says so when it skips one.

==> exam1a.tex
    exam1a.pdf  exam1a_sol.pdf
    no \rub in it, rub copy skipped

The check follows \input through the whole tree, because the content macros usually sit in the problem files rather than the document. Where the tree cannot be read to the end — a missing file, or an \input whose path is built from a macro — it builds the copy rather than guess. --rub forces one, --no-rub refuses it outright, and the same pair exists for --sol.

If your repo calls the macros something else, name them in solrub.toml:

[macros]
sol = 'answer'
rub = 'rubric'

Arguments are files, globs or directories, with the .tex suffix optional. Globs are expanded by the tool rather than left to the shell, so quiz1* works the same on Windows. Two filters keep a wide pattern honest: sibling builds (quiz1a.pdf, quiz1a_sol.pdf) collapse onto the .tex they came from, and a fragment with no \documentclass is skipped.

The pdflatex transcript is hidden, leaving one line per document:

==> quiz1a.tex
    quiz1a.pdf  quiz1a_sol.pdf  quiz1a_rub.pdf

A failure prints the error pdflatex reported and keeps that document's .log, but does not stop the rest of the batch; the failures are listed at the end and the exit status is non-zero. -v restores the full transcript.

Counting points

-p sums the points per problem, using sum-pts: pip install "solrub[pts]".

solrub -p quiz1a

The default expects a bracket at the front of a \prob{...} title, and reads both spellings:

\prob{[20 pts (8, 12)]: Bayes Net}
\prob{[16 points (4 pts each)]: Ecology System}

If that is not your convention, a [points] table in a solrub.toml at your repo root overrides it for every document underneath. The keys are sum-pts' own parameters, so its documentation is the reference:

[points]
prefix = ' *\\question'
points = '(marks|pts?)'

When the patterns do not fit, solrub says so and links to docs/points.md, which explains each key and the traps. Points are read from the source, so -p still reports on a document that failed to build.

In the document

Three macros divide the source. \sol and \rub are hidden by default and revealed by their own build; \stud is the reverse, student-only content such as the blank space left for the work, dropped from both keys.

\newcommand{\sol}[1]{}
\newcommand{\rub}[1]{}
\newcommand{\stud}[1]{#1}

\ifdefined\showsol
  \renewcommand{\sol}[1]{#1}
  \renewcommand{\stud}[1]{}
\fi

\ifdefined\showrub
  \renewcommand{\rub}[1]{#1}
  \renewcommand{\stud}[1]{}
\fi
\stud{\vfill}
\sol{The boundary is $x = 3$.}
\rub{6 pts: correct slope.  3 pts if the intercept is off.}

The flags solrub defines are \showsol and \showrub, deliberately not \sol and \rub. A document cannot both define a macro and ask whether it is defined: \newcommand{\sol} would make \ifdefined\sol true on every build, so the student copy would silently print the answers.

Requires

pdflatex on the PATH, and Python 3.9 or newer.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

solrub-0.4.0.tar.gz (11.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

solrub-0.4.0-py3-none-any.whl (10.1 kB view details)

Uploaded Python 3

File details

Details for the file solrub-0.4.0.tar.gz.

File metadata

  • Download URL: solrub-0.4.0.tar.gz
  • Upload date:
  • Size: 11.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.13

File hashes

Hashes for solrub-0.4.0.tar.gz
Algorithm Hash digest
SHA256 3a53d6ce1e6d43a6c875e9c30a8919a4cefed929e05f39f66f0faab1eaa5995a
MD5 c268f65cc8e3c7d978a381fc6044e7b9
BLAKE2b-256 01050d43ee0dc7146e9c47be16fd72e1dc40886416e74c8e4455c0294dbbba48

See more details on using hashes here.

File details

Details for the file solrub-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: solrub-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 10.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.13.13

File hashes

Hashes for solrub-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 84798ca557dd8540b8e1bb13a3c07c02be2b9f7cbd71cb82dc23b30aa346d87f
MD5 65482bff9463ccc02cf2e92ef8e891ad
BLAKE2b-256 4ea90f12d7b385144ba581a58ce2e43d07df61c8ba5324f9231ac1b7dd8bd75b

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.4.0 This release

2 files

0.3.1

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page