3: PGML (PG Markup Language)
- Page ID
- 488660
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\( \newcommand{\dsum}{\displaystyle\sum\limits} \)
\( \newcommand{\dint}{\displaystyle\int\limits} \)
\( \newcommand{\dlim}{\displaystyle\lim\limits} \)
\( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)
( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\id}{\mathrm{id}}\)
\( \newcommand{\Span}{\mathrm{span}}\)
\( \newcommand{\kernel}{\mathrm{null}\,}\)
\( \newcommand{\range}{\mathrm{range}\,}\)
\( \newcommand{\RealPart}{\mathrm{Re}}\)
\( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)
\( \newcommand{\Argument}{\mathrm{Arg}}\)
\( \newcommand{\norm}[1]{\| #1 \|}\)
\( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)
\( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)
\( \newcommand{\vectorA}[1]{\vec{#1}} % arrow\)
\( \newcommand{\vectorAt}[1]{\vec{\text{#1}}} % arrow\)
\( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\( \newcommand{\vectorC}[1]{\textbf{#1}} \)
\( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)
\( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)
\( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)
\( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)
\(\newcommand{\longvect}{\overrightarrow}\)
\( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)
\(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)PGML (PG Markup Language) is the recommended way to write the student-facing text of a WeBWorK problem. It is designed to replace older authoring patterns that required long blocks of text and manual escaping.
Start here (task first)
- I need one blank that grades correctly -> Answer blanks and answers (Core).
- I need a multi-step lab workflow prompt -> Lists and workflows (Core).
- I need a small dataset table students read from -> Tables and structured data (Core).
- My prompt is too long and hard to scan -> Layout controls (Optional).
- I need to insert computed or helper-generated output -> Command substitution and inserts (Optional).
This chapter is the core of the book: most science-friendly question writing can be done by combining a small PG setup with a clear PGML prompt.
What PGML gives you
- Readable prompts that look similar to the rendered output.
- Math in TeX or calculator notation, with consistent delimiters.
- Answer blanks that can be tied directly to answers.
- Simple structure tools (headings, lists, tables) that fit science prompts.
PGML quick patterns
| Task | Use | Page |
|---|---|---|
| One blank that grades correctly | Answer blanks attached to answers | Answer blanks and answers |
| Multi-step lab workflow | Numbered lists | Lists and workflows |
| Small dataset table | DataTable | Tables and structured data |
| Long prompt cleanup | Headings and light emphasis | Layout controls |
| Computed or helper output | Command substitution | Command substitution and inserts |
| PGML basics and notation | Minimal PGML patterns | Introduction to PGML (Optional) |
The subsections in this chapter cover the small set of PGML features you will use constantly: math notation, answer blanks, lists for workflows, tables for data, and a small "escape hatch" for advanced insertion when PGML alone is not enough.
Core pages: Answer blanks and answers (Answer blanks) and Lists and workflows (Lists). Optional pages: Layout controls (Layout) and Command substitution and inserts (Command substitution). Use Introduction to PGML as a quick primer if you want notation examples.
If you are unsure which PGML pattern to use, start with the simplest option that clearly communicates the task. Most grading issues in life science questions come from misaligned structure rather than missing features. When in doubt, clarity beats cleverness.
- 3.1: Introduction to PGML
- Defines PGML and summarizes the small set of math-notation patterns you will use constantly. After finishing, you can choose TeX versus calculator notation and use the correct delimiters reliably. Use it when onboarding a new author or standardizing prompt style in a course team.
- 3.2: Answer blanks and answers
- Explains answer blanks and the recommended habit of attaching answers directly to blanks. After finishing, you can keep grading rules next to the prompt text and reduce mismatches in multi-part items. Use it when building biology-style prompts where several short answers must stay aligned with the story, and use Chapter 7 when blank binding failures show up as a generic ADAPT error.
- 3.3: Lists and workflows
- Shows how to write numbered and bulleted lists in PGML and how to keep multi-step instructions readable. After finishing, you can express lab-style workflows with explicit units and reporting requirements inside each step. Use it when a prompt has procedural steps or a short grading checklist.
- 3.4: Tables and Structured Data
- Frames tables as the default way to present measurements and observations in science prompts and introduces the DataTable/LayoutTable split. After finishing, you can decide when a table is real data versus a layout trick and pick the helper that fits. Use it when a question depends on reading a small dataset and computing from it.
- 3.5: Layout controls
- Collects light-weight structure and layout tools like headings, emphasis, horizontal rules, and limited justification syntax. After finishing, you can improve scanability without creating fragile formatting that breaks across renderers. Use it as a finishing pass for longer prompts once the grading logic is correct.
- 3.6: Command substitution and inserts
- Explains command substitution as a controlled escape hatch for inserting computed or helper-generated content. After finishing, you can decide when to use a small substitution and how to keep it readable and testable. Use it sparingly for advanced insertion patterns, and keep textbook content self-contained without page links.


