summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/mandi/mandistudent.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/mandi/mandistudent.dtx')
-rw-r--r--macros/latex/contrib/mandi/mandistudent.dtx1789
1 files changed, 1789 insertions, 0 deletions
diff --git a/macros/latex/contrib/mandi/mandistudent.dtx b/macros/latex/contrib/mandi/mandistudent.dtx
new file mode 100644
index 0000000000..278725234c
--- /dev/null
+++ b/macros/latex/contrib/mandi/mandistudent.dtx
@@ -0,0 +1,1789 @@
+% \iffalse meta-comment
+% !TEX program = lualatexmk
+%
+% Copyright (C) 2021 by Paul J. Heafner <heafnerj@gmail.com>
+% ---------------------------------------------------------------------------
+% This work may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License, either version 1.3 of this license or (at
+% your option) any later version. The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX version
+% 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Paul J. Heafner.
+%
+% This work consists of the files mandi.dtx
+% mandistudent.dtx
+% mandiexp.dtx
+% mandi.ins
+% mandi.pdf
+% README.md
+%
+% and includes the derived files mandi.sty
+% mandistudent.sty
+% mandiexp.sty
+% vdemo.py
+% ---------------------------------------------------------------------------
+%
+% \fi
+%
+% \iffalse
+%
+%<*internal>
+\iffalse
+%</internal>
+%
+%<*vdemo>
+from vpython import *
+
+scene.width = 400
+scene.height = 760
+# constants and data
+g = 9.8 # m/s^2
+mball = 0.03 # kg
+Lo = 0.26 # m
+ks = 1.8 # N/m
+deltat = 0.01 # s
+
+# objects (origin is at ceiling)
+ceiling = box(pos=vector(0,0,0), length=0.2, height=0.01,
+ width=0.2)
+ball = sphere(pos=vector(0,-0.3,0),radius=0.025,
+ color=color.orange)
+spring = helix(pos=ceiling.pos, axis=ball.pos-ceiling.pos,
+ color=color.cyan,thickness=0.003,coils=40,
+ radius=0.010)
+
+# initial values
+pball = mball * vector(0,0,0) # kg m/s
+Fgrav = mball * g * vector(0,-1,0) # N
+t = 0
+
+# improve the display
+scene.autoscale = False # turn off automatic camera zoom
+scene.center = vector(0,-Lo,0) # move camera down
+scene.waitfor('click') # wait for a mouse click
+
+# initial calculation loop
+# calculation loop
+while t < 10:
+ rate(100)
+ # we need the stretch
+ s = mag(ball.pos) - Lo
+ # we need the spring force
+ Fspring = ks * s * -norm(spring.axis)
+ Fnet = Fgrav + Fspring
+ pball = pball + Fnet * deltat
+ ball.pos = ball.pos + (pball / mball) * deltat
+ spring.axis = ball.pos - ceiling.pos
+ t = t + deltat
+%</vdemo>
+%
+%<*internal>
+\fi
+\def\nameofplainTeX{plain}
+\ifx\fmtname\nameofplainTeX\else
+ \expandafter\begingroup
+\fi
+%</internal>
+%
+%<*internal>
+\usedir{tex/latex/mandi}
+\ifx\fmtname\nameofplainTeX
+ \expandafter\endbatchfile
+\else
+ \expandafter\endgroup
+\fi
+%</internal>
+%
+%<*driver>
+\ProvidesFile{mandistudent.dtx}
+\DisableCrossrefs % index descriptions only
+\PageIndex % index refers to page numbers
+\CodelineNumbered % number source lines
+\RecordChanges % record changes
+\begin{document} % main document
+ \DocInput{\jobname.dtx} %
+ \PrintIndex %
+\end{document} % end main document
+%</driver>
+% \fi
+%
+% \CheckSum{706}
+%
+% \CharacterTable
+% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+% Digits \0\1\2\3\4\5\6\7\8\9
+% Exclamation \! Double quote \" Hash (number) \#
+% Dollar \$ Percent \% Ampersand \&
+% Acute accent \' Left paren \( Right paren \)
+% Asterisk \* Plus \+ Comma \,
+% Minus \- Point \. Solidus \/
+% Colon \: Semicolon \; Less than \<
+% Equals \= Greater than \> Question mark \?
+% Commercial at \@ Left bracket \[ Backslash \\
+% Right bracket \] Circumflex \^ Underscore \_
+% Grave accent \` Left brace \{ Vertical bar \|
+% Right brace \} Tilde \~}
+%
+% ^^A DO NOT TRY TO COMPILE THIS DTX FILE BY ITSELF. IT WILL FAIL.
+%
+% \section{The \mandistudent\ Package}\setplace{sec:mandistudentpkg}
+%
+% \mandi\ comes with an accessory package \mandistudent,
+% which provides a collection of commands physics students can
+% use for writing problem solutions. This package focuses on
+% the most frequently needed tools. These commands should always
+% be used in math mode. Note that \mandistudent\ requires, and
+% loads, \mandi\ but \mandi\ doesn't require, and doesn't load,
+% \mandistudent.
+%
+% Load \mandistudent\ as you would any package in your preamble.
+% There are no package options.
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{dispListing*}{sidebyside=false,listing only}
+ \usepackage{mandistudent}
+\end{dispListing*}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommand}{mandistudentversion}{}
+ Typesets the current version and build date.
+\end{docCommand}
+\begin{dispExample*}{sidebyside=false}
+ The version is \mandistudentversion\ and is a stable build.
+\end{dispExample*}
+%\iffalse
+%</example>
+%\fi
+%
+% \subsection{Traditional Vector Notation}
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}[%
+ doc parameter = \marg{symbol}\oarg{labels},%
+ ]%
+ {%
+ {%
+ doc name = vec,%
+ doc description = use this variant for boldface notation,%
+ },%
+ {%
+ doc name = vec*,%
+ doc description = use this variant for arrow notation,%
+ }%
+ }%
+ Powerful and intelligent command for symbolic vector notation. The
+ mandatory argument is the symbol for the vector quantity. The optional
+ label(s) consists of superscripts and/or subscripts and can be
+ mathematical or textual in nature. If textual, be sure to wrap them in
+ |\symup{...}| for proper typesetting. The starred variant gives arrow
+ notation whereas without the star you get boldface notation. Subscript
+ and superscript labels can be arbitrarily mixed, and order doesn't matter.
+ This command redefines the default \LaTeX\ |\vec| command.
+\end{docCommands}
+\begin{dispExample*}{lefthand ratio=0.6}
+ \( \vec{p} \) \\
+ \( \vec{p}_{2} \) \\
+ \( \vec{p}^{\symup{ball}} \) \\
+ \( \vec{p}_{\symup{final}} \) \\
+ \( \vec{p}^{\symup{ball}}_{\symup{final}} \) \\
+ \( \vec{p}^{\symup{final}}_{\symup{ball}} \) \\
+ \( \vec*{p} \)
+\end{dispExample*}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}[%
+ doc parameter = \marg{symbol}\oarg{labels},%
+ ]%
+ {%
+ {%
+ doc name = dirvec,%
+ doc description = use this variant for boldface notation,%
+ },%
+ {%
+ doc name = dirvec*,%
+ doc description = use this variant for arrow notation,%
+ }%
+ }%
+ Powerful and intelligent command for typesetting the direction of
+ a vector. The options are the same as those for \refCom{vec}.
+\end{docCommands}
+\begin{dispExample*}{lefthand ratio=0.65}
+ \( \dirvec{p} \) \\
+ \( \dirvec{p}_{2} \) \\
+ \( \dirvec{p}^{\symup{ball}} \) \\
+ \( \dirvec{p}_{\symup{final}} \) \\
+ \( \dirvec{p}^{\symup{ball}}_{\symup{final}} \) \\
+ \( \dirvec{p}^{\symup{final}}_{\symup{ball}} \) \\
+ \( \dirvec*{p} \)
+\end{dispExample*}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}
+ {%
+ {%
+ doc name = zerovec,%
+ doc description = use this variant for boldface notation,%
+ },%
+ {%
+ doc name = zerovec*,%
+ doc description = use this variant for arrow notation,%
+ },%
+ }%
+ Command for typesetting the zero vector. The starred variant gives
+ arrow notation. Without the star you get boldface notation.
+\end{docCommands}
+\begin{dispExample}
+ \( \zerovec \) \\
+ \( \zerovec* \)
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommand}{changein}{}%
+ Semantic alias for |\Delta|.
+\end{docCommand}
+\begin{dispExample}
+ \( \changein t \) \\
+ \( \changein \vec{p} \)
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}[%
+ doc new = 2021-02-21,%
+ doc parameter = \oarg{size}\marg{quantity},%
+ ]%
+ {%
+ {%
+ doc name = doublebars,%
+ doc description = double bars,%
+ },%
+ {%
+ doc name = doublebars*,%
+ doc description = double bars for fractions,%
+ },%
+ {%
+ doc name = singlebars,%
+ doc description = single bars,%
+ },%
+ {%
+ doc name = singlebars*,%
+ doc description = single bars for fractions,%
+ },%
+ {%
+ doc name = anglebrackets,%
+ doc description = angle brackets,%
+ },%
+ {%
+ doc name = anglebrackets*,%
+ doc description = angle brackets for fractions,%
+ },%
+ {%
+ doc name = parentheses,%
+ doc description = parentheses,%
+ },%
+ {%
+ doc name = parentheses*,%
+ doc description = parentheses for fractions,%
+ },%
+ {%
+ doc name = squarebrackets,%
+ doc description = square brackets,%
+ },%
+ {%
+ doc name = squarebrackets*,%
+ doc description = square brackets for fractions,%
+ },%
+ {%
+ doc name = curlybraces,%
+ doc description = curly braces,%
+ },%
+ {%
+ doc name = curlybraces*,%
+ doc description = curly braces for fractions,%
+ },%
+ }%
+ If no argument is given, a placeholder is provided.
+ Sizers like |\big|,|\Big|,|\bigg|, and |\Bigg| can
+ be optionally specified. Beginners are encouraged
+ not to use them. See the
+ \href{https://www.ctan.org/pkg/mathtools}{\pkg{mathtools}} package
+ documentation for details.
+\end{docCommands}
+\begin{dispExample}
+ \[ \doublebars{} \]
+ \[ \doublebars{\vec{a}} \]
+ \[ \doublebars*{\frac{\vec{a}}{3}} \]
+ \[ \doublebars[\Bigg]{\frac{\vec{a}}{3}} \]
+\end{dispExample}
+\begin{dispExample}
+ \[ \singlebars{} \]
+ \[ \singlebars{x} \]
+ \[ \singlebars*{\frac{x}{3}} \]
+ \[ \singlebars[\Bigg]{\frac{x}{3}} \]
+\end{dispExample}
+\begin{dispExample}
+ \[ \anglebrackets{} \]
+ \[ \anglebrackets{\vec{a}} \]
+ \[ \anglebrackets*{\frac{\vec{a}}{3}} \]
+ \[ \anglebrackets[\Bigg]{\frac{\vec{a}}{3}} \]
+\end{dispExample}
+\begin{dispExample}
+ \[ \parentheses{} \]
+ \[ \parentheses{x} \]
+ \[ \parentheses*{\frac{x}{3}} \]
+ \[ \parentheses[\Bigg]{\frac{x}{3}} \]
+\end{dispExample}
+\begin{dispExample}
+ \[ \squarebrackets{} \]
+ \[ \squarebrackets{x} \]
+ \[ \squarebrackets*{\frac{x}{3}} \]
+ \[ \squarebrackets[\Bigg]{\frac{x}{3}} \]
+\end{dispExample}
+\begin{dispExample}
+ \[ \curlybraces{} \]
+ \[ \curlybraces{x} \]
+ \[ \curlybraces*{\frac{x}{3}} \]
+ \[ \curlybraces[\Bigg]{\frac{x}{3}} \]
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}[%
+ doc new = 2021-02-21,%
+ doc parameter = \oarg{size}\marg{quantity},%
+ ]%
+ {%
+ {%
+ doc name = magnitude,%
+ doc description = alias for double bars,%
+ },%
+ {%
+ doc name = magnitude*,%
+ doc description = alias for double bars for fractions,%
+ },%
+ {%
+ doc name = norm,%
+ doc description = alias for double bars,%
+ },%
+ {%
+ doc name = norm*,%
+ doc description = alias for double bars for fractions,%
+ },%
+ {%
+ doc name = absolutevalue,%
+ doc description = alias for single bars,%
+ },%
+ {%
+ doc name = absolutevalue*,%
+ doc description = alias for single bars for fractions,%
+ },%
+ }%
+ Semantic aliases. Use \refCom{magnitude} or \refCom{magnitude*} to
+ typeset the magnitude of a vector.
+\end{docCommands}
+\begin{dispExample}
+ \[ \magnitude{\vec{p}} \]
+ \[ \magnitude{\vec*{p}} \]
+ \[ \magnitude*{\vec{p}_{\symup{final}}} \]
+ \[ \magnitude*{\vec*{p}_{\symup{final}}} \]
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}[%
+ doc new = 2021-04-06,%
+ ]%
+ {%
+ {%
+ doc name = parallelto,%
+ },%
+ {%
+ doc name = perpendicularto,%
+ },%
+ }%
+ Commands for geometric relationships, mainly
+ intended for subscripts.
+\end{docCommands}
+\begin{dispExample*}{lefthand ratio=0.6}
+ \( \vec{F}_{\parallelto} + \vec{F}_{\perpendicularto} \)
+\end{dispExample*}
+%\iffalse
+%</example>
+%\fi
+%
+% \subsection{Problems and Annotated Problem Solutions}
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docEnvironments}[%
+ doc new = 2021-02-03,%
+ doc parameter = \marg{title},%
+ doclang/environment content = problem,%
+ ]%
+ {%
+ {%
+ doc name = physicsproblem,%
+ doc description = use this variant for vertical lists,%
+ },%
+ {%
+ doc name = physicsproblem*,%
+ doc description = use this variant for in-line lists,%
+ },%
+ {%
+ doc name = parts,%
+ doc description = provides problem parts,%
+ },%
+ }%
+ Provides an environment for stating physics problems. Each problem will
+ begin on a new page. See the examples for how to handle single and
+ multiple part problems.
+\end{docEnvironments}
+\begin{docCommand}[doc new = 2012-02-03]{problempart}{}
+ Denotes a part of a problem within a \refEnv{parts}
+ environment.
+\end{docCommand}
+\begin{dispExample*}{sidebyside=false}
+ \begin{physicsproblem}{Problem 1}
+ This is a physics problem with no parts.
+ \end{physicsproblem}
+\end{dispExample*}
+\begin{dispExample*}{sidebyside=false}
+ \begin{physicsproblem}{Problem 2}
+ This is a physics problem with multiple parts.
+ The list is vertical.
+ \begin{parts}
+ \problempart This is the first part.
+ \problempart This is the second part.
+ \problempart This is the third part.
+ \end{parts}
+ \end{physicsproblem}
+\end{dispExample*}
+\begin{dispExample*}{sidebyside=false}
+ \begin{physicsproblem*}{Problem 3}
+ This is a physics problem with multiple parts.
+ The list is in-line.
+ \begin{parts}
+ \problempart This is the first part.
+ \problempart This is the second part.
+ \problempart This is the third part.
+ \end{parts}
+ \end{physicsproblem*}
+\end{dispExample*}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docEnvironments}[%
+ doc updated = 2021-02-26,%
+ doc parameter = {},%
+ doclang/environment content = solution steps,%
+ ]%
+ {%
+ {%
+ doc name = physicssolution,%
+ doc description = use this variant for numbered steps,%
+ },%
+ {%
+ doc name = physicssolution*,%
+ doc description = use this variant for unnumbered steps,%
+ },%
+ }%
+ This environment is only for mathematical solutions. The starred
+ variant omits numbering of steps. See the examples.
+\end{docEnvironments}
+\begin{dispExample}
+ \begin{physicssolution}
+ x &= y + z \\
+ z &= x - y \\
+ y &= x - z
+ \end{physicssolution}
+ \begin{physicssolution*}
+ x &= y + z \\
+ z &= x - y \\
+ y &= x - z
+ \end{physicssolution*}
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommand}[doc updated = 2012-02-26]{reason}{\marg{reason}}
+ Provides an annotation in a step-by-step solution.
+ Keep reasons short and to the point. Wrap mathematical
+ content in math mode.
+\end{docCommand}
+\begin{dispExample}
+ \begin{physicssolution}
+ x &= y + z \reason{This is a reason.} \\
+ z &= x - y \reason{This is a reason too.} \\
+ y &= x - z \reason{final answer}
+ \end{physicssolution}
+ \begin{physicssolution*}
+ x &= y + z \reason{This is a reason.} \\
+ z &= x - y \reason{This is a reason too.} \\
+ y &= x - z \reason{final answer}
+ \end{physicssolution*}
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+% When writing solutions, remember that the \refEnv{physicssolution}
+% environment is \emph{only} for mathematical content, not textual
+% content or explanations.
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{dispListing*}{sidebyside=false,listing only}
+ \begin{physicsproblem}{Combined Problem and Solution}
+ This is an interesting physics problem.
+ \begin{physicssolution}
+ The solution goes here.
+ \end{physicssolution}
+ \end{physicsproblem}
+\end{dispListing*}
+\begin{dispListing*}{sidebyside=false,listing only}
+ \begin{physicsproblem}{Combined Multipart Problem with Solutions}
+ This is a physics problem with multiple parts.
+ \begin{parts}
+ \problempart This is the first part.
+ \begin{physicssolution}
+ The solution goes here.
+ \end{physicssolution}
+ \problempart This is the second part.
+ \begin{physicssolution}
+ The solution goes here.
+ \end{physicssolution}
+ \problempart This is the third part.
+ \begin{physicssolution}
+ The solution goes here.
+ \end{physicssolution}
+ \end{parts}
+ \end{physicsproblem}
+\end{dispListing*}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommand}[doc new=2021-02-06]{hilite}{%
+ \oarg{color}\marg{target}\oarg{shape}
+ }%
+ Hilites the desired target, which can be an entire mathematical expression
+ or a part thereof. The default color is magenta and the default shape is a
+ rectangle.
+\end{docCommand}
+\begin{dispListing*}{sidebyside=false,listing only}
+ \begin{align*}
+ (\Delta s)^2 &= -(\Delta t)^2 + (\Delta x)^2 + (\Delta y)^2 +
+ (\Delta z)^2 \\
+ (\Delta s)^2 &= \hilite{-(\Delta t)^2 + (\Delta x)^2}[rounded rectangle] +
+ (\Delta y)^2 + (\Delta z)^2 \\
+ (\Delta s)^2 &= \hilite{-(\Delta t)^2 + (\Delta x)^2}[rectangle] +
+ (\Delta y)^2 + (\Delta z)^2 \\
+ (\Delta s)^2 &= \hilite{-(\Delta t)^2 + (\Delta x)^2}[ellipse] +
+ (\Delta y)^2 + (\Delta z)^2 \\
+ (\Delta s)^{\hilite{2}[circle]} &= \hilite[green]{-}[circle]
+ (\Delta t)^{\hilite[cyan]{2}[circle]}+
+ (\Delta x)^{\hilite[orange]{2}[circle]} +
+ (\Delta y)^{\hilite[blue!50]{2}[circle]} +
+ (\Delta z)^{\hilite[violet!45]{2}[circle]}
+ \end{align*}
+\end{dispListing*}
+ \begin{align*}
+ (\Delta s)^2 &= -(\Delta t)^2 + (\Delta x)^2 + (\Delta y)^2 +
+ (\Delta z)^2 \\
+ (\Delta s)^2 &= \hilite{-(\Delta t)^2 + (\Delta x)^2}[rounded rectangle] +
+ (\Delta y)^2 + (\Delta z)^2 \\
+ (\Delta s)^2 &= \hilite{-(\Delta t)^2 + (\Delta x)^2}[rectangle] +
+ (\Delta y)^2 + (\Delta z)^2 \\
+ (\Delta s)^2 &= \hilite{-(\Delta t)^2 + (\Delta x)^2}[ellipse] +
+ (\Delta y)^2 + (\Delta z)^2 \\
+ (\Delta s)^{\hilite{2}[circle]} &= \hilite[green]{-}[circle]
+ (\Delta t)^{\hilite[cyan]{2}[circle]}+
+ (\Delta x)^{\hilite[orange]{2}[circle]} +
+ (\Delta y)^{\hilite[blue!50]{2}[circle]} +
+ (\Delta z)^{\hilite[violet!45]{2}[circle]}
+ \end{align*}
+\begin{dispListing*}{sidebyside=false,listing only}
+ \begin{align*}
+ \Delta\vec{p} &= \vec{F}_{\sumup{net}}\Delta t \\
+ \hilite[orange]{\Delta\vec{p}}[circle] &= \vec{F}_{\symup{net}}\Delta t \\
+ \Delta\vec{p} &= \hilite[yellow!50]{\vec{F}_{\symup{net}}}
+ [rounded rectangle]\Delta t \\
+ \Delta\vec{p} &= \vec{F}_{\symup{net}}\hilite[olive!50]
+ {\Delta t}[rectangle] \\
+ \Delta\vec{p} &= \hilite[cyan!50]{\vec{F}_{\symup{net}}\Delta t}
+ [ellipse] \\
+ \hilite{\Delta\vec{p}}[rectangle] &= \vec{F}_{\symup{net}}\Delta t
+ \end{align*}
+\end{dispListing*}
+ \begin{align*}
+ \Delta\vec{p} &= \vec{F}_{\symup{net}}\Delta t \\
+ \hilite[orange]{\Delta\vec{p}}[circle] &= \vec{F}_{\symup{net}}
+ \Delta t \\
+ \Delta\vec{p} &= \hilite[yellow!50]{\vec{F}_{\symup{net}}}
+ [rounded rectangle]\Delta t \\
+ \Delta\vec{p} &= \vec{F}_{\symup{net}}\hilite[olive!50]{\Delta t}
+ [rectangle] \\
+ \Delta\vec{p} &= \hilite[cyan!50]{\vec{F}_{\symup{net}}\Delta t}
+ [ellipse] \\
+ \hilite{\Delta\vec{p}}[rectangle] &= \vec{F}_{\symup{net}}\Delta t
+ \end{align*}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommand}[doc updated = 2021-02-26]{image}{%
+ \oarg{options}\marg{caption}\marg{label}\marg{image}
+ }%
+ Simplified interface for importing an image. The images are treated
+ as floats, so they may not appear at the most logically intuitive
+ place.
+\end{docCommand}
+\begin{dispListing*}{sidebyside=false,listing only,verbatim ignore percent}
+ \image[scale=0.20]{example-image-1x1}
+ {Image shown 20 percent actual size.}{reffig1}
+\end{dispListing*}
+\image[scale=0.20]{example-image-1x1}
+ {Image shown 20 percent actual size.}{reffig1}
+\begin{dispExample*}{sidebyside=false}
+ Figure \ref{reffig1} is nice.
+ It's captioned \nameref{reffig1} and is on page \pageref{reffig1}.
+\end{dispExample*}
+\begin{dispListing*}{sidebyside=false,listing only,verbatim ignore percent}
+ \image[scale=0.20,angle=45]{example-image-1x1}
+ {Image shown 20 percent actual size and rotated.}{reffig1}
+\end{dispListing*}
+\image[scale=0.20,angle=45]{example-image-1x1}
+{Image shown 20 percent actual size and rotated.}{reffig2}
+\begin{dispExample*}{sidebyside=false}
+ Figure \ref{reffig2} is nice.
+ It's captioned \nameref{reffig2} and is on page \pageref{reffig2}.
+\end{dispExample*}
+%\iffalse
+%</example>
+%\fi
+%
+% \subsection{Coordinate-Free and Index Notation}
+%
+% Beyond the current level of introductory physics, we need intelligent
+% commands for typesetting vector and tensor symbols and components
+% suitable for both coordinate-free and index notations.
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}[%
+ doc parameter = \oarg{delimiter}\marg{\ensuremath{c_1,\dots,c_n}},%
+ ]%
+ {%
+ {%
+ doc name = colvec,%
+ },%
+ {%
+ doc name = rowvec,%
+ },%
+ }%
+ Typesets column vectors and row vectors as numeric or symbolic components.
+ There can be more than three components. The delimiter used in the list of
+ components can be specified; the default is a comma. Units are not
+ supported, so these are mainly for symbolic work.
+\end{docCommands}
+\begin{dispExample}
+ \[ \colvec{1,2,3} \]
+ \[ \rowvec{1,2,3} \]
+ \[ \colvec{x^0,x^1,x^2,x^3} \]
+ \[ \rowvec{x_0,x_1,x_2,x_3} \]
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}[%
+ doc parameter = \marg{symbol},%
+ ]%
+ {%
+ {%
+ doc name = veccomp,%
+ doc description = use this variant for coordinate-free vector notation,%
+ },%
+ {%
+ doc name = veccomp*,%
+ doc description = use this variant for index vector notation,%
+ },%
+ {%
+ doc name = tencomp,%
+ doc description = use this variant for coordinate-free tensor notation,%
+ },%
+ {%
+ doc name = tencomp*,%
+ doc description = use this variant for index tensor notation,%
+ },%
+ }%
+ Conforms to ISO 80000-2 notation.
+\end{docCommands}
+\begin{dispExample}
+ \( \veccomp{r} \) \\
+ \( \veccomp*{r} \) \\
+ \( \tencomp{r} \) \\
+ \( \tencomp*{r} \)
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}[%
+ doc parameter = \marg{index}\marg{index},%
+ ]%
+ {%
+ {%
+ doc name = valence,%
+ },%
+ {%
+ doc name = valence*,%
+ },%
+ }%
+ Typesets tensor valence. The starred variant typesets it horizontally.
+\end{docCommands}
+\begin{dispExample}
+ A vector is a \( \valence{1}{0} \) tensor. \\
+ A vector is a \( \valence*{1}{0} \) tensor.
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}[%
+ doc parameter = \marg{slot,slot},%
+ ]%
+ {%
+ {%
+ doc name = contraction,%
+ },%
+ {%
+ doc name = contraction*,%
+ },%
+ }%
+ Typesets tensor contraction in coordinate-free notation. There
+ is no standard on this so we assert one here.
+\end{docCommands}
+\begin{dispExample}
+ \( \contraction{1,2} \) \\
+ \( \contraction*{1,2} \)
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}%
+ {%
+ {%
+ doc name = slot,%
+ doc parameter = \oarg{vector},%
+ },%
+ {%
+ doc name = slot*,%
+ doc parameter = \oarg{vector},%
+ },%
+ }%
+ An intelligent slot command for coordinate-free vector
+ and tensor notation. The starred variants suppress the
+ underscore.
+\end{docCommands}
+\begin{dispExample}
+ \( (\slot) \) \\
+ \( (\slot[\vec{a}]) \) \\
+ \( (\slot*) \) \\
+ \( (\slot*[\vec{a}]) \)
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommand}[doc new=2021-04-06]{diff}{}%
+ Intelligent differential (exterior derivative)
+ operator.
+\end{docCommand}
+\begin{dispExample}
+ \[
+ \int x\,dx
+ \]
+ \[
+ \int x\,\diff{x}
+ \]
+ \[
+ \int x\,\diff*{x}
+ \]
+\end{dispExample}
+%\iffalse
+%</example>
+%\fi
+%
+% \subsection{\GlowScript\ and \VPython\ Program Listings}
+%
+% \href{https://\gsurl}{\GlowScript}\footnote{\href{https://\gsurl}{https://\gsurl}}
+% and
+% \href{https://\vpurl}{VPython}\footnote{\href{https://\vpurl}{https://\vpurl}}
+% are programming environments (both use \href{https://www.python.org}{Python})
+% frequently used in introductory physics to introduce students
+% for modeling physical systems. \mandi\ makes including code listings
+% very simple for students.
+%
+% \subsection{The \texttt{\small glowscriptblock} Environment}
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docEnvironment}[%
+ doc updated = 2021-02-26,doclang/environment content=GlowScript code%
+ ]%
+ {glowscriptblock}{\oarg{options}(\meta{link})\marg{caption}}
+ Code placed here is nicely formatted and optionally linked to its source on
+ \href{https://\gsurl}{\GlowScriptorg}. Clicking anywhere in the code window
+ will open the link in the default browser. A caption is mandatory, and a
+ label is internally generated. The listing always begins on a new page. A
+ URL shortening utility is recommended to keep the URL from getting unruly.
+ For convenience, |https://| is automatically prepended to the URL and can
+ thus be omitted. The program must exist in a public, not private, folder.
+\end{docEnvironment}
+\begin{dispListing*}{sidebyside=false}
+\begin{glowscriptblock}(tinyurl.com/y3lnqyn3){A \texttt{GlowScript} Program}
+GlowScript 3.0 vpython
+
+scene.width = 400
+scene.height = 760
+# constants and data
+g = 9.8 # m/s^2
+mball = 0.03 # kg
+Lo = 0.26 # m
+ks = 1.8 # N/m
+deltat = 0.01 # s
+
+# objects (origin is at ceiling)
+ceiling = box(pos=vector(0,0,0), length=0.2, height=0.01,
+ width=0.2)
+ball = sphere(pos=vector(0,-0.3,0),radius=0.025,
+ color=color.orange)
+spring = helix(pos=ceiling.pos, axis=ball.pos-ceiling.pos,
+ color=color.cyan,thickness=0.003,coils=40,
+ radius=0.010)
+
+# initial values
+pball = mball * vector(0,0,0) # kg m/s
+Fgrav = mball * g * vector(0,-1,0) # N
+t = 0
+
+# improve the display
+scene.autoscale = False # turn off automatic camera zoom
+scene.center = vector(0,-Lo,0) # move camera down
+scene.waitfor('click') # wait for a mouse click
+
+# initial calculation loop
+# calculation loop
+while t < 10:
+ rate(100)
+ # we need the stretch
+ s = mag(ball.pos) - Lo
+ # we need the spring force
+ Fspring = ks * s * -norm(spring.axis)
+ Fnet = Fgrav + Fspring
+ pball = pball + Fnet * deltat
+ ball.pos = ball.pos + (pball / mball) * deltat
+ spring.axis = ball.pos - ceiling.pos
+ t = t + deltat
+\end{glowscriptblock}
+\end{dispListing*}
+\begin{glowscriptblock}(tinyurl.com/y3lnqyn3){A \texttt{GlowScript} Program}
+GlowScript 3.0 vpython
+
+scene.width = 400
+scene.height = 760
+# constants and data
+g = 9.8 # m/s^2
+mball = 0.03 # kg
+Lo = 0.26 # m
+ks = 1.8 # N/m
+deltat = 0.01 # s
+
+# objects (origin is at ceiling)
+ceiling = box(pos=vector(0,0,0), length=0.2, height=0.01,
+ width=0.2)
+ball = sphere(pos=vector(0,-0.3,0),radius=0.025,
+ color=color.orange)
+spring = helix(pos=ceiling.pos, axis=ball.pos-ceiling.pos,
+ color=color.cyan,thickness=0.003,coils=40,
+ radius=0.010)
+
+# initial values
+pball = mball * vector(0,0,0) # kg m/s
+Fgrav = mball * g * vector(0,-1,0) # N
+t = 0
+
+# improve the display
+scene.autoscale = False # turn off automatic camera zoom
+scene.center = vector(0,-Lo,0) # move camera down
+scene.waitfor('click') # wait for a mouse click
+
+# initial calculation loop
+# calculation loop
+while t < 10:
+ rate(100)
+ # we need the stretch
+ s = mag(ball.pos) - Lo
+ # we need the spring force
+ Fspring = ks * s * -norm(spring.axis)
+ Fnet = Fgrav + Fspring
+ pball = pball + Fnet * deltat
+ ball.pos = ball.pos + (pball / mball) * deltat
+ spring.axis = ball.pos - ceiling.pos
+ t = t + deltat
+\end{glowscriptblock}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{dispExample*}{sidebyside=false}
+ \GlowScript\ program \ref{gs:1} is nice.
+ It's called \nameref{gs:1} and is on page \pageref{gs:1}.
+\end{dispExample*}
+%
+%\iffalse
+%</example>
+%\fi
+%
+% \subsection{The \texttt{\small vpythonfile} Command}
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommand}[doc updated = 2021-02-26]{vpythonfile}
+ {\oarg{options}\marg{file}\marg{caption}}
+ Command to load and typeset a \VPython\ program. The file is read from
+ \marg{file}. Clicking anywhere in the code window can optionally open
+ a link, passed as an option, in the default browser. A caption is mandatory,
+ and a label is internally generated. The listing always begins on a new page.
+ A URL shortening utility is recommended to keep the URL from getting unruly.
+ For convenience, |https://| is automatically prepended to the URL and can
+ thus be omitted.
+\end{docCommand}
+\begin{dispListing*}{sidebyside=false}
+\vpythonfile[hyperurl interior = https://vpython.org]{vdemo.py}
+ {A \VPython\ Program}
+\end{dispListing*}
+\vpythonfile[hyperurl interior = https://vpython.org]{vdemo.py}
+ {A \VPython\ Program}
+%\iffalse
+%</example>
+%\fi
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{dispExample*}{sidebyside=false}
+ \VPython\ program \ref{vp:1} is nice.
+ It's called \nameref{vp:1} and is on page \pageref{vp:1}.
+\end{dispExample*}
+%
+%\iffalse
+%</example>
+%\fi
+%
+% \subsection{The \texttt{\small glowscriptinline} and
+% \texttt{\small vpythoninline} Commands}
+%
+%\iffalse
+%<*example>
+%\fi
+\begin{docCommands}[%
+ doc updated = 2021-02-26,%
+ ]%
+ {%
+ {%
+ doc name = glowscriptinline,%
+ doc parameter = \marg{GlowScript code},%
+ },%
+ {%
+ doc name = vpythoninline,%
+ doc parameter = \marg{VPython code},%
+ },%
+ }%
+ Typesets a small, in-line snippet of code. The snippet should be
+ less than one line long.
+\end{docCommands}
+\begin{dispExample*}{sidebyside=false}
+ \GlowScript\ programs begin with \glowscriptinline{GlowScript 3.0 VPython}
+ and \VPython\ programs begin with \vpythoninline{from vpython import *}.
+\end{dispExample*}
+%\iffalse
+%</example>
+%\fi
+%
+% \StopEventually{}
+%
+% \newgeometry{left=0.50in,right=0.50in,top=1.00in,bottom=1.00in}
+% \subsection{\mandistudent\ Source Code}
+%
+% \iffalse
+%<*package>
+% \fi
+% Definine the package version and date for global use, exploiting the fact
+% that in a \pkg{.sty} file there is now no need for |\makeatletter| and
+% |\makeatother|. This simplifies defining internal commands, with |@|
+% in the name, that are not for the user to know about.
+%
+% \begin{macrocode}
+\def\mandistudent@version{\mandi@version}
+\def\mandistudent@date{\mandi@date}
+\NeedsTeXFormat{LaTeX2e}[2020-02-02]
+\DeclareRelease{v3.0.0}{2021-08-21}{mandistudent.sty}
+\DeclareCurrentRelease{v\mandi@version}{\mandi@date}
+\ProvidesPackage{mandistudent}
+ [\mandistudent@date\space v\mandistudent@version\space Macros for introductory physics]
+% \end{macrocode}
+%
+% Define a convenient package version command.
+%
+% \begin{macrocode}
+\newcommand*{\mandistudentversion}{v\mandistudent@version\space dated \mandistudent@date}
+% \end{macrocode}
+%
+% Load third party packages, documenting why each one is needed.
+%
+% \begin{macrocode}
+\RequirePackage{amsmath} % AMS goodness (don't load amssymb or amsfonts)
+\RequirePackage[inline]{enumitem} % needed for physicsproblem environment
+\RequirePackage{eso-pic} % needed for \hilite
+\RequirePackage[g]{esvect} % needed for nice vector arrow, style g
+\RequirePackage{pgfopts} % needed for key-value interface
+\RequirePackage{iftex} % needed for requiring LuaLaTeX
+\RequirePackage{makebox} % needed for consistent \dirvect; \makebox
+\RequirePackage{mandi}
+\RequirePackage{mathtools} % needed for paired delimiters; extends amsmath
+\RequirePackage{nicematrix} % needed for column and row vectors
+\RequirePackage[most]{tcolorbox} % needed for program listings
+\RequirePackage{tensor} % needed for index notation
+\RequirePackage{tikz} % needed for \hilite
+\usetikzlibrary{shapes,fit,tikzmark} % needed for \hilite
+\RequirePackage{unicode-math} % needed for Unicode support
+\RequirePackage{hyperref} % load last
+\RequireLuaTeX % require this engine
+% \end{macrocode}
+%
+% Set up the fonts to be consistent with ISO 80000-2 notation.
+% The \href{https://www.ctan.org/pkg/unicode-math}{\pkg{unicode-math}} package
+% loads the \href{https://www.ctan.org/pkg/fontspec}{\pkg{fontspec}} and
+% \href{https://www.ctan.org/pkg/xparse}{\pkg{xparse}}
+% packages. Note that \pkg{xparse} is now part of the \LaTeX\ kernel.
+% Because \pkg{unicode-math} is required, all documents using \mandi\ must
+% be compiled with an engine that supports Unicode. We recommend \lualatex.
+%
+% \begin{macrocode}
+\unimathsetup{math-style=ISO}
+\unimathsetup{warnings-off={mathtools-colon,mathtools-overbracket}}
+%
+% Use normal math letters from Latin Modern Math for familiarity with
+% textbooks.
+%
+% \begin{macrocode}
+\setmathfont[Scale=MatchLowercase]
+ {Latin Modern Math} % default math font; better J
+% \end{macrocode}
+%
+% Borrow from GeX Gyre DejaVu Math for vectors and tensors to get single-storey g.
+%
+% \begin{macrocode}
+\setmathfont[Scale=MatchLowercase,range={sfit/{latin},bfsfit/{latin}}]
+ {TeX Gyre DejaVu Math} % single-storey lowercase g
+% \end{macrocode}
+%
+% Borrow from GeX Gyre DejaVu Math to get single-storey g.
+%
+% \begin{macrocode}
+\setmathfont[Scale=MatchLowercase,range={sfup/{latin},bfsfup/{latin}}]
+ {TeX Gyre DejaVu Math} % single-storey lowercase g
+% \end{macrocode}
+% Borrow |mathscr| and |mathbfscr| from XITS Math.\newline
+% See \url{https://tex.stackexchange.com/a/120073/218142}.
+%
+% \begin{macrocode}
+\setmathfont[Scale=MatchLowercase,range={\mathscr,\mathbfscr}]{XITS Math}
+% \end{macrocode}
+%
+% Get original and bold |mathcal| fonts.\newline
+% See \url{https://tex.stackexchange.com/a/21742/218142}.
+%
+% \begin{macrocode}
+\setmathfont[Scale=MatchLowercase,range={\mathcal,\mathbfcal},StylisticSet=1]{XITS Math}
+% \end{macrocode}
+%
+% Borrow Greek sfup and sfit letters from STIX Two Math.
+% Since this isn't officially supported in \pkg{unicode-math}
+% we have to manually set this up.
+%
+% \begin{macrocode}
+\setmathfont[Scale=MatchLowercase,range={"E17C-"E1F6}]{STIX Two Math}
+\newfontfamily{\symsfgreek}{STIX Two Math}
+% I don't understand why \text{...} is necessary.
+\newcommand{\symsfupalpha} {\text{\symsfgreek{^^^^e196}}}
+\newcommand{\symsfupbeta} {\text{\symsfgreek{^^^^e197}}}
+\newcommand{\symsfupgamma} {\text{\symsfgreek{^^^^e198}}}
+\newcommand{\symsfupdelta} {\text{\symsfgreek{^^^^e199}}}
+\newcommand{\symsfupepsilon} {\text{\symsfgreek{^^^^e1af}}}
+\newcommand{\symsfupvarepsilon} {\text{\symsfgreek{^^^^e19a}}}
+\newcommand{\symsfupzeta} {\text{\symsfgreek{^^^^e19b}}}
+\newcommand{\symsfupeta} {\text{\symsfgreek{^^^^e19c}}}
+\newcommand{\symsfuptheta} {\text{\symsfgreek{^^^^e19d}}}
+\newcommand{\symsfupvartheta} {\text{\symsfgreek{^^^^e1b0}}}
+\newcommand{\symsfupiota} {\text{\symsfgreek{^^^^e19e}}}
+\newcommand{\symsfupkappa} {\text{\symsfgreek{^^^^e19f}}}
+\newcommand{\symsfuplambda} {\text{\symsfgreek{^^^^e1a0}}}
+\newcommand{\symsfupmu} {\text{\symsfgreek{^^^^e1a1}}}
+\newcommand{\symsfupnu} {\text{\symsfgreek{^^^^e1a2}}}
+\newcommand{\symsfupxi} {\text{\symsfgreek{^^^^e1a3}}}
+\newcommand{\symsfupomicron} {\text{\symsfgreek{^^^^e1a4}}}
+\newcommand{\symsfuppi} {\text{\symsfgreek{^^^^e1a5}}}
+\newcommand{\symsfupvarpi} {\text{\symsfgreek{^^^^e1b3}}}
+\newcommand{\symsfuprho} {\text{\symsfgreek{^^^^e1a6}}}
+\newcommand{\symsfupvarrho} {\text{\symsfgreek{^^^^e1b2}}}
+\newcommand{\symsfupsigma} {\text{\symsfgreek{^^^^e1a8}}}
+\newcommand{\symsfupvarsigma} {\text{\symsfgreek{^^^^e1a7}}}
+\newcommand{\symsfuptau} {\text{\symsfgreek{^^^^e1a9}}}
+\newcommand{\symsfupupsilon} {\text{\symsfgreek{^^^^e1aa}}}
+\newcommand{\symsfupphi} {\text{\symsfgreek{^^^^e1b1}}}
+\newcommand{\symsfupvarphi} {\text{\symsfgreek{^^^^e1ab}}}
+\newcommand{\symsfupchi} {\text{\symsfgreek{^^^^e1ac}}}
+\newcommand{\symsfuppsi} {\text{\symsfgreek{^^^^e1ad}}}
+\newcommand{\symsfupomega} {\text{\symsfgreek{^^^^e1ae}}}
+\newcommand{\symsfupDelta} {\text{\symsfgreek{^^^^e180}}}
+\newcommand{\symsfupGamma} {\text{\symsfgreek{^^^^e17f}}}
+\newcommand{\symsfupTheta} {\text{\symsfgreek{^^^^e18e}}}
+\newcommand{\symsfupLambda} {\text{\symsfgreek{^^^^e187}}}
+\newcommand{\symsfupXi} {\text{\symsfgreek{^^^^e18a}}}
+\newcommand{\symsfupPi} {\text{\symsfgreek{^^^^e18c}}}
+\newcommand{\symsfupSigma} {\text{\symsfgreek{^^^^e18f}}}
+\newcommand{\symsfupUpsilon} {\text{\symsfgreek{^^^^e191}}}
+\newcommand{\symsfupPhi} {\text{\symsfgreek{^^^^e192}}}
+\newcommand{\symsfupPsi} {\text{\symsfgreek{^^^^e194}}}
+\newcommand{\symsfupOmega} {\text{\symsfgreek{^^^^e195}}}
+\newcommand{\symsfitalpha} {\text{\symsfgreek{^^^^e1d8}}}
+\newcommand{\symsfitbeta} {\text{\symsfgreek{^^^^e1d9}}}
+\newcommand{\symsfitgamma} {\text{\symsfgreek{^^^^e1da}}}
+\newcommand{\symsfitdelta} {\text{\symsfgreek{^^^^e1db}}}
+\newcommand{\symsfitepsilon} {\text{\symsfgreek{^^^^e1f1}}}
+\newcommand{\symsfitvarepsilon} {\text{\symsfgreek{^^^^e1dc}}}
+\newcommand{\symsfitzeta} {\text{\symsfgreek{^^^^e1dd}}}
+\newcommand{\symsfiteta} {\text{\symsfgreek{^^^^e1de}}}
+\newcommand{\symsfittheta} {\text{\symsfgreek{^^^^e1df}}}
+\newcommand{\symsfitvartheta} {\text{\symsfgreek{^^^^e1f2}}}
+\newcommand{\symsfitiota} {\text{\symsfgreek{^^^^e1e0}}}
+\newcommand{\symsfitkappa} {\text{\symsfgreek{^^^^e1e1}}}
+\newcommand{\symsfitlambda} {\text{\symsfgreek{^^^^e1e2}}}
+\newcommand{\symsfitmu} {\text{\symsfgreek{^^^^e1e3}}}
+\newcommand{\symsfitnu} {\text{\symsfgreek{^^^^e1e4}}}
+\newcommand{\symsfitxi} {\text{\symsfgreek{^^^^e1e5}}}
+\newcommand{\symsfitomicron} {\text{\symsfgreek{^^^^e1e6}}}
+\newcommand{\symsfitpi} {\text{\symsfgreek{^^^^e1e7}}}
+\newcommand{\symsfitvarpi} {\text{\symsfgreek{^^^^e1f5}}}
+\newcommand{\symsfitrho} {\text{\symsfgreek{^^^^e1e8}}}
+\newcommand{\symsfitvarrho} {\text{\symsfgreek{^^^^e1f4}}}
+\newcommand{\symsfitsigma} {\text{\symsfgreek{^^^^e1ea}}}
+\newcommand{\symsfitvarsigma} {\text{\symsfgreek{^^^^e1e9}}}
+\newcommand{\symsfittau} {\text{\symsfgreek{^^^^e1eb}}}
+\newcommand{\symsfitupsilon} {\text{\symsfgreek{^^^^e1ec}}}
+\newcommand{\symsfitphi} {\text{\symsfgreek{^^^^e1f3}}}
+\newcommand{\symsfitvarphi} {\text{\symsfgreek{^^^^e1ed}}}
+\newcommand{\symsfitchi} {\text{\symsfgreek{^^^^e1ee}}}
+\newcommand{\symsfitpsi} {\text{\symsfgreek{^^^^e1ef}}}
+\newcommand{\symsfitomega} {\text{\symsfgreek{^^^^e1f0}}}
+\newcommand{\symsfitDelta} {\text{\symsfgreek{^^^^e1c2}}}
+\newcommand{\symsfitGamma} {\text{\symsfgreek{^^^^e1c1}}}
+\newcommand{\symsfitTheta} {\text{\symsfgreek{^^^^e1d0}}}
+\newcommand{\symsfitLambda} {\text{\symsfgreek{^^^^e1c9}}}
+\newcommand{\symsfitXi} {\text{\symsfgreek{^^^^e1cc}}}
+\newcommand{\symsfitPi} {\text{\symsfgreek{^^^^e1ce}}}
+\newcommand{\symsfitSigma} {\text{\symsfgreek{^^^^e1d1}}}
+\newcommand{\symsfitUpsilon} {\text{\symsfgreek{^^^^e1d3}}}
+\newcommand{\symsfitPhi} {\text{\symsfgreek{^^^^e1d4}}}
+\newcommand{\symsfitPsi} {\text{\symsfgreek{^^^^e1d6}}}
+\newcommand{\symsfitOmega} {\text{\symsfgreek{^^^^e1d7}}}
+% \end{macrocode}
+%
+% Tweak the \href{https://www.ctan.org/pkg/esvect}{\pkg{esvect}} package
+% fonts to get the correct font size. Code provided by |@egreg|.\newline
+% See \url{https://tex.stackexchange.com/a/566676}.
+%
+% \begin{macrocode}
+\DeclareFontFamily{U}{esvect}{}
+\DeclareFontShape{U}{esvect}{m}{n}{%
+ <-5.5> vect5
+ <5.5-6.5> vect6
+ <6.5-7.5> vect7
+ <7.5-8.5> vect8
+ <8.5-9.5> vect9
+ <9.5-> vect10
+}{}%
+% \end{macrocode}
+%
+% Write a banner to the console showing the options in use.
+%
+% \begin{macrocode}
+\typeout{}%
+\typeout{mandistudent: You are using mandistudent \mandistudentversion.}%
+\typeout{mandistudent: This package requires LuaLaTeX.}%
+\typeout{mandistudent: This package changes the default math font(s).}%
+\typeout{mandistudent: This package redefines the \protect\vec\space command.}%
+\typeout{}%
+% \end{macrocode}
+%
+% A better, intelligent coordinate-free \refCom{vec} command. Note the use of
+% the |e{_^}| type of optional argument. This accounts for much of the
+% flexibility and power of this command. Also note the use of the \TeX\
+% primitives |\sb{}| and |\sp{}|. Why doesn't it work when I put spaces
+% around |#3| or |#4|? Because outside of |\ExplSyntaxOn...\ExplSyntaxOff|,
+% the |_| character has a different catcode and is treated as a mathematical
+% entity.\newline
+% See \url{https://tex.stackexchange.com/q/554706/218142}.\newline
+% See also \url{https://tex.stackexchange.com/a/531037/218142}.
+%
+% \begin{macrocode}
+\RenewDocumentCommand{\vec}{ s m e{_^} }{%
+ % Note the \, used to make superscript look better.
+ \IfBooleanTF {#1}
+ {\vv{#2}% % * gives an arrow
+ % Use \sp{} primitive for superscript.
+ % Adjust superscript for the arrow.
+ \sp{\IfValueT{#4}{\,#4}\vphantom{\smash[t]{\big|}}}
+ }%
+ {\symbfit{#2} % no * gives us bold
+ % Use \sp{} primitive for superscript.
+ % No superscript adjustment needed.
+ \sp{\IfValueT{#4}{#4}\vphantom{\smash[t]{\big|}}}
+ }%
+ % Use \sb{} primitive for subscript.
+ \sb{\IfValueT{#3}{#3}\vphantom{\smash[b]{|}}}
+}%
+% \end{macrocode}
+%
+% A command for the direction of a vector.
+% We use a slight tweak to get uniform hats that
+% requires the \href{https://www.ctan.org/pkg/makebox}{\pkg{makebox}}
+% package.\newline
+% See \url{https://tex.stackexchange.com/a/391204/218142}.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\dirvec}{ s m e{_^} }{%
+ \widehat{\makebox*{\(w\)}{\ensuremath{%
+ \IfBooleanTF {#1}
+ {%
+ #2
+ }%
+ {%
+ \symbfit{#2}
+ }%
+ }%
+ }%
+ }%
+ \sb{\IfValueT{#3}{#3}\vphantom{\smash[b]{|}}}
+ \sp{\IfValueT{#4}{\,#4}\vphantom{\smash[t]{\big|}}}
+}%
+% \end{macrocode}
+%
+% The zero vector.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\zerovec}{ s }{%
+ \IfBooleanTF {#1}
+ {\vv{0}}%
+ {\symbfup{0}}%
+}%
+% \end{macrocode}
+%
+% Notation for column and row vectors.
+% Orginal code provided by |@egreg|.\newline
+% See \url{https://tex.stackexchange.com/a/39054/218142}.
+%
+% \begin{macrocode}
+\ExplSyntaxOn
+\NewDocumentCommand{\colvec}{ O{,} m }{%
+ \vector_main:nnnn { p } { \\ } { #1 } { #2 }
+}%
+\NewDocumentCommand{\rowvec}{ O{,} m }{%
+ \vector_main:nnnn { p } { & } { #1 } { #2 }
+}%
+\seq_new:N \l__vector_arg_seq
+\cs_new_protected:Npn \vector_main:nnnn #1 #2 #3 #4 {%
+ \seq_set_split:Nnn \l__vector_arg_seq { #3 } { #4 }
+ \begin{#1NiceMatrix}[r]
+ \seq_use:Nnnn \l__vector_arg_seq { #2 } { #2 } { #2 }
+ \end{#1NiceMatrix}
+}%
+\ExplSyntaxOff
+% \end{macrocode}
+%
+% Students always need this symbol.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\changein}{}{\Delta}
+% \end{macrocode}
+%
+% Intelligent delimiters provided via the
+% \href{https://www.ctan.org/pkg/mathtools}{\pkg{mathtools}} package.
+% Use the starred variants for fractions. You can supply optional sizes.
+% Note that default placeholders are used when the argument is empty.
+%
+% \begin{macrocode}
+\DeclarePairedDelimiterX{\doublebars}[1]{\lVert}{\rVert}{\ifblank{#1}{\:\cdot\:}{#1}}
+\DeclarePairedDelimiterX{\singlebars}[1]{\lvert}{\rvert}{\ifblank{#1}{\:\cdot\:}{#1}}
+\DeclarePairedDelimiterX{\anglebrackets}[1]{\langle}{\rangle}{\ifblank{#1}{\:\cdot\:}{#1}}
+\DeclarePairedDelimiterX{\parentheses}[1]{(}{)}{\ifblank{#1}{\:\cdot\:}{#1}}
+\DeclarePairedDelimiterX{\squarebrackets}[1]{\lbrack}{\rbrack}{\ifblank{#1}{\:\cdot\:}{#1}}
+\DeclarePairedDelimiterX{\curlybraces}[1]{\lbrace}{\rbrace}{\ifblank{#1}{\:\cdot\:}{#1}}
+% \end{macrocode}
+%
+% Some semantic aliases. Because of the way \refCom{vec} and
+% \refCom{dirvec} are defined, I reluctantly decided not to
+% implement a |\magvec| command. It would require accounting
+% for too mamy options. So \refCom{magnitude} is the new
+% solution.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\magnitude}{}{\doublebars}
+\NewDocumentCommand{\norm}{}{\doublebars}
+\NewDocumentCommand{\absolutevalue}{}{\singlebars}
+% \end{macrocode}
+%
+% Commands for two important geometric relationships. These are meant
+% mainly to be subscripts.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\parallelto}{}
+ {\mkern3mu\vphantom{\perp}\vrule depth 0pt\mkern2mu\vrule depth 0pt\mkern3mu}
+\NewDocumentCommand{\perpendicularto}{}{\perp}
+% \end{macrocode}
+%
+% An environment for problem statements. The starred variant gives
+% in-line lists.
+%
+% \begin{macrocode}
+\NewDocumentEnvironment{physicsproblem}{ m }{%
+ \newpage%
+ \section*{#1}%
+ \newlist{parts}{enumerate}{2}%
+ \setlist[parts]{label=\bfseries(\alph*)}}%
+ {}%
+\NewDocumentEnvironment{physicsproblem*}{ m }{%
+ \newpage%
+ \section*{#1}%
+ \newlist{parts}{enumerate*}{2}%
+ \setlist[parts]{label=\bfseries(\alph*)}}%
+ {}%
+\NewDocumentCommand{\problempart}{}{\item}%
+% \end{macrocode}
+%
+% An environment for problem solutions.
+%
+% \begin{macrocode}
+\NewDocumentEnvironment{physicssolution}{ +b }{%
+ % Make equation numbering consecutive through the document.
+ \begin{align}
+ #1
+ \end{align}
+}{}%
+\NewDocumentEnvironment{physicssolution*}{ +b }{%
+ % Make equation numbering consecutive through the document.
+ \begin{align*}
+ #1
+ \end{align*}
+}{}%
+% \end{macrocode}
+%
+% See \url{https://tex.stackexchange.com/q/570223/218142}.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\reason}{ O{4cm} m }
+ {&&\begin{minipage}{#1}\raggedright\small #2\end{minipage}}
+% \end{macrocode}
+%
+% Command for highlighting parts of, or entire, mathematical expressions.\newline
+% Original code by anonymous user |@abcdefg|, modified by me.\newline
+% See \url{https://texample.net/tikz/examples/beamer-arrows/}.\newline
+% See also \url{https://tex.stackexchange.com/a/406084/218142}.\newline
+% See also \url{https://tex.stackexchange.com/a/570858/218142}.\newline
+% See also \url{https://tex.stackexchange.com/a/570789/218142}.\newline
+% See also \url{https://tex.stackexchange.com/a/79659/218142}.\newline
+% See also \url{https://tex.stackexchange.com/q/375032/218142}.\newline
+% See also \url{https://tex.stackexchange.com/a/571744/218142}%
+%
+% \begin{macrocode}
+\newcounter{tikzhighlightnode}
+\NewDocumentCommand{\hilite}{ O{magenta!60} m O{rectangle} }{%
+ \stepcounter{tikzhighlightnode}%
+ \tikzmarknode{highlighted-node-\number\value{tikzhighlightnode}}{#2}%
+ \edef\temp{%
+ \noexpand\AddToShipoutPictureBG{%
+ \noexpand\begin{tikzpicture}[overlay,remember picture]%
+ \noexpand\iftikzmarkoncurrentpage{highlighted-node-\number\value{tikzhighlightnode}}%
+ \noexpand\node[inner sep=1.0pt,fill=#1,#3,fit=(highlighted-node-\number\value{tikzhighlightnode})]{};%
+ \noexpand\fi
+ \noexpand\end{tikzpicture}%
+ }%
+ }%
+ \temp%
+}%
+% \end{macrocode}
+%
+% A simplified command for importing images.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\image}{ O{scale=1} m m m }{%
+ \begin{figure}[ht!]
+ \begin{center}%
+ \includegraphics[#1]{#2}%
+ \end{center}%
+ \caption{#3}%
+ \label{#4}%
+ \end{figure}%
+}%
+% \end{macrocode}
+%
+% Intelligent commands for typesetting vector and tensor symbols and
+% components suitable for use with both coordinate-free and index
+% notations. Use starred form for index notation, unstarred form for
+% coordinate-free.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\veccomp}{ s m }{%
+ % Consider renaming this to \vectorsym.
+ \IfBooleanTF{#1}
+ {%
+ \symnormal{#2}%
+ }%
+ {%
+ \symbfit{#2}%
+ }%
+}%
+\NewDocumentCommand{\tencomp}{ s m }{%
+ % Consider renaming this to \tensororsym.
+ \IfBooleanTF{#1}
+ {%
+ \symsfit{#2}%
+ }%
+ {%
+ \symbfsfit{#2}
+ }%
+}%
+% \end{macrocode}
+%
+% Command to typeset tensor valence.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\valence}{ s m m }{%
+ \IfBooleanTF{#1}
+ {(#2,#3)}
+ {\binom{#2}{#3}}
+}%
+% \end{macrocode}
+%
+% Intelligent notation for contraction on pairs of slots.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\contraction}{ s m }{%
+ \IfBooleanTF{#1}
+ {\mathsf{C}}%
+ {\symbb{C}}%
+ _{#2}
+}%
+% \end{macrocode}
+%
+% Intelligent slot command for coordinate-free tensor notation.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\slot}{ s d[] }{%
+ % d[] must be used because of the way consecutive optional
+ % arguments are handled. See xparse docs for details.
+ \IfBooleanTF{#1}
+ {%
+ \IfValueTF{#2}
+ {% Insert a vector, but don't show the slot.
+ \smash{\makebox[1.5em]{\ensuremath{#2}}}
+ }%
+ {% No vector, no slot.
+ \smash{\makebox[1.5em]{\ensuremath{}}}
+ }%
+ }%
+ {%
+ \IfValueTF{#2}
+ {% Insert a vector and show the slot.
+ \underline{\smash{\makebox[1.5em]{\ensuremath{#2}}}}
+ }%
+ {% No vector; just show the slot.
+ \underline{\smash{\makebox[1.5em]{\ensuremath{}}}}
+ }%
+ }%
+}%
+% \end{macrocode}
+%
+% Intelligent differential (exterior derivative) operator.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\diff}{ s }{%
+ \mathop{}\!
+ \IfBooleanTF{#1}
+ {\symbfsfup{d}}%
+ {\symsfup{d}}%
+}%
+% \end{macrocode}
+%
+% Here is a clever way to color digits in program listsings thanks to
+% Ulrike Fischer.\newline
+% See \url{https://tex.stackexchange.com/a/570717/218142}.
+%
+% \begin{macrocode}
+\directlua{%
+ luaotfload.add_colorscheme("colordigits",
+ {["8000FF"] = {"one","two","three","four","five","six","seven","eight","nine","zero"}})
+}%
+\newfontfamily\colordigits{DejaVuSansMono}[RawFeature={color=colordigits}]
+% \end{macrocode}
+%
+% Set up a color scheme and a new code environment for listings. The new colors
+% are more restful on the eye. All listing commands now use
+% \href{https://www.ctan.org/pkg/tcolorbox}{\pkg{tcolorbox}}.\newline
+% See \url{https://tex.stackexchange.com/a/529421/218142}.
+%
+% \begin{macrocode}
+\newfontfamily{\gsfontfamily}{DejaVuSansMono} % new font for listings
+\definecolor{gsbggray} {rgb}{0.90,0.90,0.90} % background gray
+\definecolor{gsgray} {rgb}{0.30,0.30,0.30} % gray
+\definecolor{gsgreen} {rgb}{0.00,0.60,0.00} % green
+\definecolor{gsorange} {rgb}{0.80,0.45,0.12} % orange
+\definecolor{gspeach} {rgb}{1.00,0.90,0.71} % peach
+\definecolor{gspearl} {rgb}{0.94,0.92,0.84} % pearl
+\definecolor{gsplum} {rgb}{0.74,0.46,0.70} % plum
+\lstdefinestyle{vpython}{% % style for listings
+ backgroundcolor=\color{gsbggray},% % background color
+ basicstyle=\colordigits\footnotesize,% % default style
+ breakatwhitespace=true% % break at whitespace
+ breaklines=true,% % break long lines
+ captionpos=b,% % position caption
+ classoffset=1,% % STILL DON'T UNDERSTAND THIS
+ commentstyle=\color{gsgray},% % font for comments
+ deletekeywords={print},% % delete keywords from the given language
+ emph={self,cls,@classmethod,@property},% % words to emphasize
+ emphstyle=\color{gsorange}\itshape,% % font for emphasis
+ escapeinside={(*@}{@*)},% % add LaTeX within your code
+ frame=tb,% % frame style
+ framerule=2.0pt,% % frame thickness
+ framexleftmargin=5pt,% % extra frame left margin
+ %identifierstyle=\sffamily,% % style for identifiers
+ keywordstyle=\gsfontfamily\color{gsplum},% % color for keywords
+ language=Python,% % select language
+ linewidth=\linewidth,% % width of listings
+ morekeywords={% % VPython/GlowScript specific keywords
+ __future__,abs,acos,align,ambient,angle,append,append_to_caption,%
+ append_to_title,arange,arrow,asin,astuple,atan,atan2,attach_arrow,%
+ attach_trail,autoscale,axis,background,billboard,bind,black,blue,border,%
+ bounding_box,box,bumpaxis,bumpmap,bumpmaps,camera,canvas,caption,capture,%
+ ceil,center,clear,clear_trail,click,clone,CoffeeScript,coils,color,combin,%
+ comp,compound,cone,convex,cos,cross,curve,cyan,cylinder,data,degrees,del,%
+ delete,depth,descender,diff_angle,digits,division,dot,draw_complete,%
+ ellipsoid,emissive,end_face_color,equals,explog,extrusion,faces,factorial,%
+ False,floor,follow,font,format,forward,fov,frame,gcurve,gdisplay,gdots,%
+ get_library,get_selected,ghbars,global,GlowScript,graph,graphs,green,gvbars,%
+ hat,headlength,headwidth,height,helix,hsv_to_rgb,index,interval,keydown,%
+ keyup,label,length,lights,line,linecolor,linewidth,logx,logy,lower_left,%
+ lower_right,mag,mag2,magenta,make_trail,marker_color,markers,material,%
+ max,min,mouse,mousedown,mousemove,mouseup,newball,norm,normal,objects,%
+ offset,one,opacity,orange,origin,path,pause,pi,pixel_to_world,pixels,plot,%
+ points,pos,pow,pps,print,print_function,print_options,proj,purple,pyramid,%
+ quad,radians,radius,random,rate,ray,read_local_file,readonly,red,redraw,%
+ retain,rgb_to_hsv,ring,rotate,round,scene,scroll,shaftwidth,shape,shapes,%
+ shininess,show_end_face,show_start_face,sign,sin,size,size_units,sleep,%
+ smooth,space,sphere,sqrt,start,start_face_color,stop,tan,text,textpos,%
+ texture,textures,thickness,title,trail_color,trail_object,trail_radius,%
+ trail_type,triangle,trigger,True,twist,unbind,up,upper_left,upper_right,%
+ userpan,userspin,userzoom,vec,vector,vertex,vertical_spacing,visible,%
+ visual,vpython,VPython,waitfor,white,width,world,xtitle,yellow,yoffset,%
+ ytitle%
+ },%
+ morekeywords={print,None,TypeError},% % additional keywords
+ morestring=[b]{"""},% % treat triple quotes as strings
+ numbers=left,% % where to put line numbers
+ numbersep=10pt,% % how far line numbers are from code
+ numberstyle=\bfseries\tiny,% % set to 'none' for no line numbers
+ showstringspaces=false,% % show spaces in strings
+ showtabs=false,% % show tabs within strings
+ stringstyle=\gsfontfamily\color{gsgreen},% % color for strings
+ upquote=true,% % how to typeset quotes
+}%
+% \end{macrocode}
+%
+% Introduce a new, more intelligent \refEnv{glowscriptblock} environment.
+%
+% \begin{macrocode}
+\NewTCBListing[auto counter,list inside=gsprogs]{glowscriptblock}
+ { O{} D(){glowscript.org} m }{%
+ breakable,%
+ center,%
+ code = \newpage,%
+ %derivpeach,%
+ enhanced,%
+ hyperurl interior = https://#2,%
+ label = {gs:\thetcbcounter},%
+ left = 8mm,%
+ list entry = \thetcbcounter~~~~~#3,%
+ listing only,%
+ listing style = vpython,%
+ nameref = {#3},%
+ title = \texttt{GlowScript} Program \thetcbcounter: #3,%
+ width = 0.9\textwidth,%
+ {#1},
+}%
+% \end{macrocode}
+%
+% A new command for generating a list of \GlowScript\ programs.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\listofglowscriptprograms}{}{\tcblistof[\section*]{gsprogs}
+ {List of \texttt{GlowScript} Programs}}%
+% \end{macrocode}
+%
+% Introduce a new, more intelligent \refCom{vpythonfile} command.
+%
+% \begin{macrocode}
+\NewTCBInputListing[auto counter,list inside=vpprogs]{\vpythonfile}
+ { O{} m m }{%
+ breakable,%
+ center,%
+ code = \newpage,%
+ %derivgray,%
+ enhanced,%
+ hyperurl interior = https://,%
+ label = {vp:\thetcbcounter},%
+ left = 8mm,%
+ list entry = \thetcbcounter~~~~~#3,%
+ listing file = {#2},%
+ listing only,%
+ listing style = vpython,%
+ nameref = {#3},%
+ title = \texttt{VPython} Program \thetcbcounter: #3,%
+ width = 0.9\textwidth,%
+ {#1},%
+}%
+% \end{macrocode}
+%
+% A new command for generating a list of \VPython\ programs.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\listofvpythonprograms}{}{\tcblistof[\section*]{vpprogs}
+ {List of \texttt{VPython} Programs}}%
+% \end{macrocode}
+%
+% Introduce a new \refCom{glowscriptinline} command.
+%
+% \begin{macrocode}
+\DeclareTotalTCBox{\glowscriptinline}{ m }{%
+ bottom = 0pt,%
+ bottomrule = 0.0mm,%
+ boxsep = 1.0mm,%
+ colback = gsbggray,%
+ colframe = gsbggray,%
+ left = 0pt,%
+ leftrule = 0.0mm,%
+ nobeforeafter,%
+ right = 0pt,%
+ rightrule = 0.0mm,%
+ sharp corners,%
+ tcbox raise base,%
+ top = 0pt,%
+ toprule = 0.0mm,%
+}{\lstinline[style = vpython]{#1}}%
+% \end{macrocode}
+%
+% Define \refCom{vpythoninline}, a semantic alias for \VPython\
+% in-line listings.
+%
+% \begin{macrocode}
+\NewDocumentCommand{\vpythoninline}{}{\glowscriptinline}%
+% \end{macrocode}
+%
+% \restoregeometry
+%
+% \iffalse
+%</package>
+% \fi
+%
+% \Finale