summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/mi-solns
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /macros/latex/contrib/mi-solns
Initial commit
Diffstat (limited to 'macros/latex/contrib/mi-solns')
-rw-r--r--macros/latex/contrib/mi-solns/README.md14
-rw-r--r--macros/latex/contrib/mi-solns/docs/mi-solns.pdfbin0 -> 276191 bytes
-rw-r--r--macros/latex/contrib/mi-solns/docs/mi-solnsman.pdfbin0 -> 223143 bytes
-rw-r--r--macros/latex/contrib/mi-solns/docs/mi-solnsman.tex406
-rw-r--r--macros/latex/contrib/mi-solns/examples/create-db.tex92
-rw-r--r--macros/latex/contrib/mi-solns/examples/mi-solns-eq.tex159
-rw-r--r--macros/latex/contrib/mi-solns/examples/mi-solns-eqe.tex202
-rw-r--r--macros/latex/contrib/mi-solns/examples/use-db.tex23
-rw-r--r--macros/latex/contrib/mi-solns/mi-solns.dtx411
-rw-r--r--macros/latex/contrib/mi-solns/mi-solns.ins59
10 files changed, 1366 insertions, 0 deletions
diff --git a/macros/latex/contrib/mi-solns/README.md b/macros/latex/contrib/mi-solns/README.md
new file mode 100644
index 0000000000..3148e4ca1b
--- /dev/null
+++ b/macros/latex/contrib/mi-solns/README.md
@@ -0,0 +1,14 @@
+The mi-solns Package
+Author: D. P. Story
+Dated: 2018/12/18
+
+This package is designed to mark a solution environment of an exercise or
+quiz and insert it into the same or a different document. Solutions are
+ones created by either the exerquiz or eqexam package.
+
+All PDF creators are supported.
+
+D. P. Story
+www.acrotex.net
+dpstory@uakron.edu
+dpstory@acrotex.net
diff --git a/macros/latex/contrib/mi-solns/docs/mi-solns.pdf b/macros/latex/contrib/mi-solns/docs/mi-solns.pdf
new file mode 100644
index 0000000000..3d0e0f6e31
--- /dev/null
+++ b/macros/latex/contrib/mi-solns/docs/mi-solns.pdf
Binary files differ
diff --git a/macros/latex/contrib/mi-solns/docs/mi-solnsman.pdf b/macros/latex/contrib/mi-solns/docs/mi-solnsman.pdf
new file mode 100644
index 0000000000..5f21c1545e
--- /dev/null
+++ b/macros/latex/contrib/mi-solns/docs/mi-solnsman.pdf
Binary files differ
diff --git a/macros/latex/contrib/mi-solns/docs/mi-solnsman.tex b/macros/latex/contrib/mi-solns/docs/mi-solnsman.tex
new file mode 100644
index 0000000000..a7a7ca588b
--- /dev/null
+++ b/macros/latex/contrib/mi-solns/docs/mi-solnsman.tex
@@ -0,0 +1,406 @@
+\documentclass{article}
+\usepackage[fleqn]{amsmath}
+\usepackage[
+ web={centertitlepage,designv,forcolorpaper,tight*,latextoc,pro},
+ exerquiz={nosolutions},eforms,aebxmp
+]{aeb_pro}
+\let\protected\relax
+\usepackage{mi-solns}
+%\usepackage{eq-save}
+%\usepackage[ImplMulti]{dljslib}
+%\usepackage{graphicx,array,fancyvrb}
+\usepackage{aeb_mlink}
+%\usepackage{myriadpro}
+%\usepackage{calibri}
+
+\usepackage[altbullet]{lucidbry}
+
+\def\hardspace{{\fontfamily{cmtt}\selectfont\symbol{32}}}
+\newif\ifmiswitch \miswitchfalse
+
+\usepackage{acroman}
+
+\usepackage[active]{srcltx}
+
+\urlstyle{tt}
+
+
+
+\def\STRUT{\rule{0pt}{14pt}}
+%\useBeginQuizButton[\CA{Begin}]
+%\useEndQuizButton[\CA{End}]
+\def\SOL{\textsf{SOL}}
+\def\QSL{\textsf{QSL}}
+
+\makeatletter
+\def\eExmpl{\eq@fititin{\mbox{\exrtnlabelformatwp}}}
+\newcount\hesheCnt \hesheCnt=-1
+\def\heshe{\@ifstar{\heshei}{\global\advance\hesheCnt\@ne\heshei}}
+\def\heshei{\ifodd\hesheCnt she\else he\fi}
+\def\HeShe{\@ifstar{\HeShei}{\global\advance\hesheCnt\@ne\HeShei}}
+\def\HeShei{\ifodd\hesheCnt She\else He\fi}
+\def\hisher{\@ifstar{\hisheri}{\global\advance\hesheCnt\@ne\hisheri}}
+\def\hisheri{\ifodd\hesheCnt her\else his\fi}
+\def\himher{\@ifstar{\himheri}{\global\advance\hesheCnt\@ne\himheri}}
+\def\himheri{\ifodd\hesheCnt her\else him\fi}
+\makeatother
+
+\DeclareDocInfo
+{
+ university={\AcroTeX.Net},
+ title={The \textsf{mi-solns} Package},
+ author={D. P. Story},
+ email={dpstory@acrotex.net},
+ subject=Documentation for the mi-solns package,
+ talksite={\url{www.acrotex.net}},
+ version={0.6, 2018/12/29},
+ Keywords={LaTeX, AeB, exercises, quizzes, mark and insert solutions},
+ copyrightStatus=True,
+ copyrightNotice={Copyright (C) \the\year, D. P. Story},
+ copyrightInfoURL={http://www.acrotex.net}
+}
+
+\universityLayout{fontsize=Large}
+\titleLayout{fontsize=LARGE}
+\authorLayout{fontsize=Large}
+\tocLayout{fontsize=Large,color=aeb}
+\sectionLayout{indent=-62.5pt,fontsize=large,color=aeb}
+\subsectionLayout{indent=-31.25pt,color=aeb}
+\subsubsectionLayout{indent=0pt,color=aeb}
+\subsubDefaultDing{\texorpdfstring{$\bullet$}{\textrm\textbullet}}
+
+\chngDocObjectTo{\newDO}{doc}
+\begin{docassembly}
+var titleOfManual="The mi-solns Package";
+var manualfilename="Manual_BG_Print_mi-solns.pdf";
+var manualtemplate="Manual_BG_Brown.pdf"; // Blue, Green, Brown
+var _pathToBlank="C:/Users/Public/Documents/ManualBGs/"+manualtemplate;
+var doc;
+var buildIt=false;
+if ( buildIt ) {
+ console.println("Creating new " + manualfilename + " file.");
+ doc = \appopenDoc({cPath: _pathToBlank, bHidden: true});
+ var _path=this.path;
+ var pos=_path.lastIndexOf("/");
+ _path=_path.substring(0,pos)+"/"+manualfilename;
+ \docSaveAs\newDO ({ cPath: _path });
+ doc.closeDoc();
+ doc = \appopenDoc({cPath: manualfilename, oDoc:this, bHidden: true});
+ f=doc.getField("ManualTitle");
+ f.value=titleOfManual;
+ doc.flattenPages();
+ \docSaveAs\newDO({ cPath: manualfilename });
+ doc.closeDoc();
+} else {
+ console.println("Using the current "+manualfilename+" file.");
+}
+var _path=this.path;
+var pos=_path.lastIndexOf("/");
+_path=_path.substring(0,pos)+"/"+manualfilename;
+\addWatermarkFromFile({
+ bOnTop:false,
+ bOnPrint:false,
+ cDIPath:_path
+});
+\executeSave();
+\end{docassembly}
+
+
+\begin{document}
+
+\maketitle
+
+\selectColors{linkColor=black}
+\tableofcontents
+\selectColors{linkColor=webgreen}
+
+
+\section{Introduction}
+
+The name of the package is \pkg{mi-solns}, where `m' is for `mark' and `i' is
+for `insert'. So the \pkg{mi-solns} package can mark and insert solutions
+(created by the \pkg{exerquiz} and \pkg{eqexam} packages).
+
+The \pkg{exerquiz}
+(\href{https://www.ctan.org/pkg/acrotex}{ctan.org/pkg/acrotex}) and
+\pkg{eqexam} (\href{https://www.ctan.org/pkg/eqexam}{ctan.org/pkg/eqexam})
+packages are capable of creating questions and solutions to exercises and
+quizzes. The purpose of this package is to present commands for marking, and
+for inserting any marked solution---for whatever reason---into the body of
+the document.\footnote{A solution may be inserted into anohter solution, but
+may not be inserted into itself.} To accomplish this goal, recent versions
+of \pkg{exerquiz} and \pkg{eqexam} are required (dated 2018/12/13 or later);
+also required is the \pkg{shellesc} package
+(\href{https://ctan.org/pkg/shellesc}{ctan.org/pkg/shellesc}).
+
+While the document is being compiled, the solution files (\SOL{} and \QSL) are
+being written to, so we cannot input them or read them. What we do is to make
+a copy of the solution files from within the operating system, and input the
+copy back into the body of the document when required. Consequently, it is
+necessary to activate the feature of executing an OS script from within the
+compiling operation. To activate the feature, the document needs to be
+compiled with the \texttt{-{}-shell-escape} switch (for
+\app{latex}, \app{pdflatex}, \app{lualatex}, or \app{xelatex}, depending on
+your workflow).
+
+\paragraph*{Description of workflow.} The procedure is simple and short: (1)
+mark a solution for insertion (\cs{mrkForIns\darg{\ameta{name}}}), just above
+the \env{solution} environment; and (2) insert the solution with
+\cs{insExSoln\darg{\ameta{name}}}, \cs{insSqSoln\darg{\ameta{name}}}, or
+\cs{insQzSoln\darg{\ameta{name}}}, depending on whether the solution came
+from an \env{exercise}, \env{shortquiz}, or \env{quiz} environment.
+
+\paragraph*{Demo files.} There are four demonstration files.
+\begin{itemize}
+ \item \texttt{mi-solns-eq.tex} uses \pkg{exerquiz} to test the features
+ of \pkg{mi-solns}.
+ \item \texttt{mi-solns-eqe.tex} uses \pkg{eqexam} to test the features
+ of \pkg{mi-solns}.
+ \item \texttt{create-db.tex} part of a novel idea, it is an application for changing
+ the output file names. Compiling this file creates \texttt{poems.lst}, which is a very small database
+ of poetic quotations.
+ \item \texttt{use-db.tex} is the companion file to
+ \texttt{create-db.tex}. Once \texttt{poems.lst} is created, compile
+ \texttt{use-db.tex}, which will input \texttt{poems.lst} and
+ display the quotations.
+\end{itemize}
+
+\section{Copying the \texorpdfstring{\SOL\space and \QSL}{SOL and QSL} files}
+
+Assuming you have determined how to compile using the
+\texttt{-{}-shell-escape} switch, when you compile a \pkg{mi-solns} document,
+the files \cs{jobname.sol} and \cs{jobname.qsl} are copied at the end of the
+document. The destination filenames are \cs{jobname-cpy.sol} and
+\cs{jobname-cpy.qsl} by default, but these names can be changed through the
+commands \cs{declSOLOut} and \cs{declQSLOut}.
+\bVerb\takeMeasure{\string\declSOLOut\darg{\ameta{sol-out}}}%
+\setlength\aebscratch{\bxSize}%
+\def\1{\makebox[0pt][l]{\hspace{\aebscratch}\enspace\makebox[0pt][l]{\normalfont(\cs{declSOLIn\darg{\string\jobname.sol}})}}}%
+\def\2{\makebox[0pt][l]{\hspace{\aebscratch}\enspace\makebox[0pt][l]{\normalfont(\cs{declSOLOut\darg{\string\jobname-cpy.sol}})}}}%
+\def\3{\makebox[0pt][l]{\hspace{\aebscratch}\enspace\makebox[0pt][l]{\normalfont(\cs{declQSLIn\darg{\string\jobname.qsl}})}}}%
+\def\4{\makebox[0pt][l]{\hspace{\aebscratch}\enspace\makebox[0pt][l]{\normalfont(\cs{declQSLOut\darg{\string\jobname-cpy.qsl}})}}}%
+\begin{dCmd}[commandchars=!(),commentchar=\%]{\bxSize}
+%!1\declSOLIn{!ameta(sol-in)}
+!2\declSOLOut{!ameta(sol-out)}
+%!3\declQSLIn{!ameta(qsl-in)}
+!4\declQSLOut{!ameta(qsl-out)}
+\end{dCmd}
+\eVerb At the end of the document, the following OS operations occur:
+\begin{itemize}
+ \item Copy \cs{jobname.sol} to \ameta{sol-out} (\cs{jobname.sol} to \cs{jobname-cpy.sol})
+ \item Copy \cs{jobname.qsl} to \ameta{qsl-out} (\cs{jobname.qsl} to \cs{jobname-cpy.qsl})
+\end{itemize}
+Freely change the names of the output files according to your own whims.
+
+\paragraph*{The copy commands.} The following two commands expand the run-time scripts for
+copying one file to another.
+\bVerb\takeMeasure{\string\newcommand\darg{\string\copyfileCmdEx}\darg{copy \string\jobname.sol \string\misolout}}%
+\setlength\aebscratch{\bxSize}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\newcommand{\copyfileCmdEx}{copy \jobname.sol \misolout}
+\newcommand{\copyfileCmdQz}{copy \jobname.qsl \miqslout}
+\end{dCmd}
+\eVerb where \cs{misolout} and \cs{miqslout} expand to the names assigned by
+the declarations \cs{declSOLOut} and \cs{declQSLOut}, respectively. These are
+the definitions for \app{Windows} OS, it might be necessary to redefine these
+commands corresponding to the OS in which you reside.
+
+\paragraph*{Turn copying on and off.} The SOL and QSL files are automatically copied, by default;
+however, this operation can be turned off.
+\bVerb\takeMeasure{\string\copySolnsOn\qquad\string\copySolnsOff}%
+\setlength\aebscratch{\bxSize}%
+\def\1{\makebox[0pt][l]{\hspace{\aebscratch}\enspace\makebox[0pt][l]{\sffamily(preamble only)}}}%
+\def\2{\makebox[0pt][l]{\hspace{\aebscratch}\enspace\makebox[0pt][l]{\sffamily(anywhere)}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+!1\copySolnsOn!qquad\copySolnsOff
+!2\readSolnsOn!qquad\readSolnsOff
+\end{dCmd}
+\eVerb \cs{copySolnsOn} is the default, it causes the solutions to be copied
+at the end of the document; \cs{copySolnsOff} turns off the copying. Why
+would you do this? Well, if you have completed composing your solutions and
+you are concentrating on the other content of the document, there is no need
+to repeatedly copy the solution files. Perhaps turn it on for the final
+\emph{two compiles}. Yes, you read correctly, two compiles. Since the
+solution files are copied at the end of the document, the refreshed
+\ameta{sol-out} and \ameta{qsl-out} files do not get read until the next
+compile.
+
+\cs{readSolnsOn} is initially expanded by the package, so it is the default. If you expand \cs{readSolnsOff}, the commands
+\cs{insExSoln}, \cs{insSqSoln}, and \cs{insQzSoln} do not input their target file; instead
+\cs{miReadOffMsg} is typeset. The default definition of this command is,
+\begin{Verbatim}[xleftmargin=\parindent]
+\newcommand\miReadOffMsg{(\textbf{?? read is off ??})}
+\end{Verbatim}
+This command may be redefined as desired.
+
+\section{Marking a solution}
+
+The first step is to mark a solution you wish to insert elsewhere in the document.
+\bVerb\takeMeasure{\string\mrkForIns\darg{\ameta{name}}}%
+\setlength\aebscratch{\bxSize}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\mrkForIns{!ameta(name)}
+\end{dCmd}
+\eVerb The placement is just above the targeted \env{solution} environment.
+\begin{Verbatim}[xleftmargin=\parindent,commandchars=!()]
+!textbf(\mrkForIns{!ameta(name)})
+\begin{solution}[!ameta(options)]
+!quad!ameta(solution)
+\end{solution}
+\end{Verbatim}
+Here, \ameta{name} is a word consisting of only ASCII characters. As the \ameta{sol-out} file is read in,
+a simple string comparison is performed. If \pkg{mi-solns} is not displaying the solution you want to insert,
+this could be the problem; simplify the word(s) used for the \ameta{name} argument.
+
+%\insExSoln[\ignoreques]{dps}
+
+Below is a simple example we'll work with throughout the rest of this documentation.
+
+\begin{exercise}\label{ex:First}
+\begin{cq}An intelligent question.\end{cq}
+\mrkForIns{myIQ}
+\begin{solution}
+A brilliant answer to the intelligent question.
+\ifmiswitch(D. P. Story)\fi
+\end{solution}
+\end{exercise}
+The verbatim listing is,
+\begin{Verbatim}[xleftmargin=\parindent,commandchars={!@^}]
+\newif\ifmiswitch \miswitchfalse %!sffamily@ used in Example 4^
+...
+\begin{exercise}
+\begin{cq}An intelligent question.\end{cq}
+!textbf@\mrkForIns{myIQ}^
+\begin{solution}
+A brilliant answer to the intelligent question.
+\ifmiswitch(D. P. Story)\fi
+\end{solution}
+\end{exercise}
+\end{Verbatim}
+Continue to the next section for information on how to insert the solution
+into the document.
+
+\section{Inserting a solution}
+
+The second step is to insert the solution into the document. There are three
+commands for inserting marked content back in the document.
+\bVerb\takeMeasure{\string\insExSoln[\ameta{inserts}]\darg{\ameta{name}}}%
+\setlength\aebscratch{\bxSize}%
+\setlength\aebscratch{\bxSize}%
+\def\1{\makebox[0pt][l]{\hspace{\aebscratch}\enspace\makebox[0pt][l]{\sffamily(for \env{exercise} env.)}}}%
+\def\2{\makebox[0pt][l]{\hspace{\aebscratch}\enspace\makebox[0pt][l]{\sffamily(for \env{shortquiz} env.)}}}%
+\def\3{\makebox[0pt][l]{\hspace{\aebscratch}\enspace\makebox[0pt][l]{\sffamily(for \env{quiz} env.)}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+!1\insExSoln[!ameta(inserts)]{!ameta(name)}
+!2\insSqSoln[!ameta(inserts)]{!ameta(name)}
+!3\insQzSoln[!ameta(inserts)]{!ameta(name)}
+\end{dCmd}
+\eVerb where, \ameta{name} must match up with the \ameta{name} argument of a
+\cs{mrkForIns} command somewhere in the document. For solution content to
+appear correctly, the choice of the insertion command must match the
+environment that has been marked. If you marked a solution to an exercise,
+then use \cs{insExSoln} to insert that solution. This is possible error
+point, if the \ameta{name} does not match up with the correct insertion
+command.
+
+The \ameta{inserts} optional parameter can be most anything that does not
+disrupt the expansion of the \cs{ins??Soln} commands. \emph{It is placed
+within a group.}\marginpar{\small\raggedleft\slshape\ameta{inserts} placed in
+a group} This may be an interesting, useful, and significant feature,
+depending on your imagination to use it. One command designed for the
+\ameta{inserts} option for an exercise is \cs{ignoreques}. This is
+discussed in \textbf{Example~2} below.
+
+\paragraph*{Example~1.} Insert the solution to \textsc{\hyperref[ex:First]{Exercise~\ref*{ex:First}}}: \insExSoln{myIQ}
+\begin{Verbatim}[xleftmargin=\parindent,commandchars=!()]
+(!sffamily(Insert the solution to !ameta(link removed):)) !textbf(\insExSoln{myIQ})
+\end{Verbatim}
+The above is the verbatim listing. It's just that simple! However, the
+question to the problem also appears! Continue this problem with
+\textbf{Example~2}.\eExmpl
+
+\paragraph*{Example~2.} \textsc{\hyperref[ex:First]{Exercise~\ref*{ex:First}}} has its question
+enclosed in the \env{cq} environment. This environment passes
+the question along with the solution. If we don't want to include the
+question, pass a special command \cs{ignoreques} in the optional
+\ameta{inserts} argument. The expansion of
+\verb~``\insExSoln[\ignoreques]{myIQ}''~ is
+``\insExSoln[\ignoreques]{myIQ}''\eExmpl
+
+\def\myFmt{\declCQPre{\emph{\textcolor{blue}{\cqQStr}:}\space}%
+\declCQPost{\par\medskip\noindent\emph{\textcolor{blue}{\cqSStr}:}\space\ignorespaces}}
+
+\paragraph*{Example~3.} Again referring to \textsc{\hyperref[ex:First]{Exercise~\ref*{ex:First}}}, the
+\env{cq} environment (defined in \pkg{exerquiz} and \pkg{eqexam}) has certain
+formatting controls. We can pass some formatting commands through the
+\ameta{inserts} argument without affecting other \env{cq} environments in the
+document. For example,
+\par\medskip\noindent
+\insExSoln[\myFmt]{myIQ}
+\begin{Verbatim}[xleftmargin=\parindent,commandchars=!(),fontsize=\small]
+\newcommand\myFmt{\declCQPre{\emph{\textcolor{blue}{\cqQStr}:}\space}%
+ \declCQPost{\par\medskip\noindent
+ \emph{\textcolor{blue}{\cqSStr}:}\space\ignorespaces}}
+\end{Verbatim}
+Verbatim listing:
+{\let\leftmargini\parindent
+\begin{quote}
+\textsf{For example,}\texttt{\cs{par}\string\medskip\string\noindent\textbf{\string\insExSoln[\string\myFmt]\darg{myIQ}}}
+\end{quote}}\noindent
+Be sure not to introduce any spurious spaces.\eExmpl
+
+\paragraph*{Example~4.} (\textbf{Conditional content}) The \ameta{solution} can have conditional content, which
+may be controlled locally by passing the state of a Boolean switch through the \ameta{inserts} argument.
+\begin{Verbatim}[xleftmargin=\parindent,commandchars=!(),fontsize=\small]
+\newif\ifmiswitch \miswitchfalse
+...
+(!normalfont!sffamily(This code results in ))``!textbf(\insExSoln[\ignoreques\miswitchtrue]{myIQ})''
+\end{Verbatim}
+This code results in ``\insExSoln[\ignoreques\miswitchtrue]{myIQ}''\eExmpl
+
+\paragraph*{Example~5.} (\textbf{Changing \ameta{sol-out}}) There is a file \texttt{poems.lst} produced by
+the demo file \texttt{create-db.tex}; here, we insert one of the verses by
+changing the \ameta{sol-out} file.\medskip \bVerb
+\begin{minipage}[t]{2in+20pt}
+\begin{flushleft}\setlength{\baselineskip}{0pt}\setlength{\leftmargini}{15pt}
+\textbf{The Lama} by \textbf{Ogden Nash}
+\insExSoln[\declSOLOut{poems.lst}]{The Lama}
+\end{flushleft}
+\end{minipage}\hfill
+\begin{minipage}[t]{\linewidth-2in-20pt}
+Verbatim listing of the poem:\\[3pt]
+{\ttfamily\small\string\insExSoln[\textbf{\string\declSOLOut\darg{poems.lst}}]\darg{The Lama}}
+\end{minipage}\medskip
+\eVerb Refer to demo files \texttt{create-db.tex} and \texttt{use-db.tex}.\eExmpl
+
+\section{Building the solution sets}
+
+We can extract the solution to a problem only if the solution file is fully
+built. Generally, the solution sets are fully built when the solutions appear
+at the end of the file, but that is not the only situation. The following
+list summarizes the options for which the solution files are created in their
+entirety.
+\begin{itemize}
+ \item For the \pkg{exerquiz} package, any option other than \texttt{solutionsafter}.
+ This includes the following options: \texttt{nosolutions}, \texttt{noquizsolutions},
+ \texttt{vspacewithsolns}, and no solution-related option at all
+ (\verb~\usepackage{exerquiz}~). Hidden solutions are not displayed.
+ \item For the \pkg{eqexam} package, any option other than
+ \texttt{solutionsafter} and \texttt{answerkey}. This includes the
+ following options: \texttt{nosolutions},
+ \texttt{vspacewithsolns}, and no solution-related option at all
+ (\verb~\usepackage{eqexam}~). Hidden solutions are not displayed.
+\end{itemize}
+You can insert solutions even when the \texttt{answerkey} or
+\texttt{solutionsafter} option is in effect. First compile with
+\texttt{vspaceiwithsolns},\footnote{This creates fully built \ameta{sol-out}
+and \ameta{qsl-out} files.} for example, then place \cs{copySolnsOff} in the
+preamble and compile again with the \texttt{answerkey} or
+\texttt{solutionsafter} option. The insertions will then appear on the next
+compile.
+
+\section{My retirement}
+
+Now, I simply must get back to it. \dps
+
+\end{document}
diff --git a/macros/latex/contrib/mi-solns/examples/create-db.tex b/macros/latex/contrib/mi-solns/examples/create-db.tex
new file mode 100644
index 0000000000..2a55c1e8e8
--- /dev/null
+++ b/macros/latex/contrib/mi-solns/examples/create-db.tex
@@ -0,0 +1,92 @@
+\documentclass{article}
+\usepackage[designiv,forcolorpaper]{web}
+\usepackage{exerquiz}
+
+\usepackage{mi-solns}
+\declSOLOut{poems.lst}
+
+%\copySolnsOff
+
+% This formatting is optional, the purpose of this file is to create
+% the poems.lst file, which is to be input by another file.
+\renewcommand\exlabel{Poet}
+\renewcommand\exlabelformat{{\scshape\exlabel:}}
+\renewcommand\exsllabelformat{\protect\textbf{\exlabelsol\ \currentpoet}}
+\renewcommand\exsllabelformatwp
+ {\protect\textbf{\currentpoet: \currenttitle}}
+\renewcommand\exsectitle{List of \exlabel s and their Poems}
+\partsformat{}
+\def\currentPoet#1{\def\currentpoet{#1}}
+\def\currentTitle#1{\def\currenttitle{#1}}
+\partsitemsep{6pt}
+
+\begin{document}
+
+\currentPoet{Ogden Nash}
+\begin{exercise*}
+\textbf{Ogden Nash}
+\begin{parts}
+\item \currentTitle{First Limerick}\textbf{First Limerick}
+\insExSoln{First Limerick}
+\mrkForIns{First Limerick}
+\begin{solution}[]
+\begin{quote}\obeylines
+An old person of Troy
+Is so prudish and coy
+That it doesn't know yet
+If it's a girl or a boy.
+\end{quote}
+\end{solution}
+
+\item \currentTitle{The Lama}\textbf{The Lama}
+\insExSoln{The Lama}
+\mrkForIns{The Lama}
+\begin{solution}[]
+\begin{quote}\obeylines
+The one-l lama,
+He's a priest,
+The two-l llama,
+He's a beast.
+And I will bet
+A silk pajama
+There isn't any
+Three-l lllama\footnote{\raggedright The author here is referring to a three-alarm fire, called a ``three-alarmer''.}
+\end{quote}
+\end{solution}
+\end{parts}
+\end{exercise*}
+
+\currentPoet{Edward R. Sill}
+\begin{exercise*}
+\textbf{Edward R. Sill}
+\begin{parts}
+\item \currentTitle{Opportunity}\textbf{Opportunity}
+\insExSoln{Opportunity}
+\mrkForIns{Opportunity}
+\begin{solution}[]
+\begin{quote}\obeylines
+This I beheld, or dreamed it in a dream:---
+There spread a cloud of dust along a plain;
+And underneath the cloud, or in it, raged
+A furious battle, and men yelled, and swords
+Shocked upon swords and shields. A prince's banner
+Wavered then staggered backward, hemmed by foes.\vspace{\baselineskip}
+
+A craven hung along the battle's edge,
+And thought, ``Had I a sword of keener steal---
+That blue blade that the king's son bears---but this
+Blunt thing!''---he snapped and flung it from his hand.
+And lowering crept away and left the field.\vspace{\baselineskip}
+
+Then came the king's son, wounded, sore bestead,
+And weaponless, and saw the broken sword,
+Hilt-buried in the dry and trodden sand,
+And ran and snatched it, and with battle-shout,
+Lifted afresh he hewed his enemy down,
+And saved a great cause that heroic day.
+\end{quote}
+\end{solution}
+\end{parts}
+\end{exercise*}
+
+\end{document}
diff --git a/macros/latex/contrib/mi-solns/examples/mi-solns-eq.tex b/macros/latex/contrib/mi-solns/examples/mi-solns-eq.tex
new file mode 100644
index 0000000000..d6cc6b31ab
--- /dev/null
+++ b/macros/latex/contrib/mi-solns/examples/mi-solns-eq.tex
@@ -0,0 +1,159 @@
+\documentclass{article}
+\usepackage[designiv,forcolorpaper]{web}
+\usepackage{exerquiz}
+\usepackage{mi-solns}
+
+\def\cs#1{\texttt{\char`\\#1}}
+\let\pkg\textsf
+\let\env\texttt
+
+%\copySolnsOff
+%\readSolnsOff
+
+\noSolnOpt
+
+\declCQSolStr{\textit{Solution}}\declCQQuesStr{\textit{Question}}
+
+\begin{document}
+
+\section{Introduction}
+
+\noindent
+\textbf{The Problem.} For a document that uses \pkg{exerquiz} or \pkg{eqexam}, can a solution
+that is marked in some way be reproduced in another part of the
+document?\medskip
+
+\noindent\textbf{The Solution.} We require copies of \cs{jobname.sol} and
+\cs{jobname.qsl} be made; these are named \cs{jobname-cpy.sol} and
+\cs{jobname-cpy.qsl} (default names), and they are created at the end of each
+compile. This file is closed when you compile again and hence can be input.
+The switch for the compiler must be \texttt{--shell-escape} for those using
+MiK\TeX. When a copy of a solution is needed, one of these two files are
+input with the appropriate redefinitions. The solution has been formalized
+into a new package \pkg{ci-solns}.
+
+\section{Exercises}
+
+Below are two extracted solutions from the exercises in this section.
+\begin{itemize}
+
+ \item The solution to Exercise~2 is\\[6pt]\textsl{\insExSoln{dps}} True this!
+
+ \item The question of Exercise~2 is enclosed in the \env{cq} environment.
+ The question to the solution is typeset automatically, as above. The solution to
+ Exercise~2 again, this time without the question, we pass the special command
+ \cs{ignoreterminex}: \textsl{\insExSoln[\ignoreterminex]{dps}}
+
+ \item J\"{u}rgen's solution is \textsl{\insExSoln{j-mon}}
+
+\end{itemize}
+
+\begin{exercise}\label{ex:one}
+Solve this tricky one
+\begin{solution}
+1) That was a tricky one, can't do it.
+\end{solution}
+\end{exercise}
+
+\begin{exercise}\label{ex:two}\begin{cq}
+Solve this tricky one.\end{cq}
+
+\mrkForIns{dps}
+\begin{solution}
+\ifwithinsoldoc
+2) That was a tricky one, can't do it. \else whatever!\fi
+
+Pass some verbatim content as a test: \verb~$&%$^^%&~.
+\end{solution}
+\end{exercise}
+
+\begin{exercise}\label{ex:three}
+Solve this tricky one
+\begin{solution}
+3) That was a tricky one, can't do it.
+\end{solution}
+\end{exercise}
+
+\begin{exercise*}
+\begin{parts}
+ \item This is the part (a) question.
+\begin{solution}
+This is the part (a) solution.
+\end{solution}
+
+ \item (J\"{u}rgen's little q) This is the part (b) question.
+\mrkForIns{j-mon}
+\begin{solution}
+This is the part (b) solution.
+\end{solution}
+
+ \item This is the part (b) question.
+\begin{solution}
+This is the part (b) solution.
+\end{solution}
+
+\end{parts}
+\end{exercise*}
+
+\newpage
+
+\section{Quizzes}
+
+In this section are two quizzes, generated by the \env{shortquiz} and \env{quiz} environments.
+
+\begin{itemize}
+
+\item Alex's solution is \textsl{\insSqSoln{aps}} Check for spurious spaces.
+
+\item Topi's solution is \textsl{\insQzSoln{topi}} Check for spurious spaces.
+\end{itemize}
+
+\begin{shortquiz}
+Solve each
+\begin{questions}
+\item \begin{answers}*{4}
+\Ans0 False &\Ans1 True
+\end{answers}
+\begin{solution}
+The answer is True
+\end{solution}
+
+\mrkForIns{aps}
+\item (Alex's question) $\cos(\pi) = \RespBoxMath{-1}*{1}{.0001}{[2,4]}\cgBdry\kern1bp\CorrAnsButton{-1}$
+\begin{solution}
+Of course, everyone knows that $\cos(\pi) = -1 $.
+\end{solution}
+\end{questions}
+\end{shortquiz}
+
+\useBeginQuizButton
+\useEndQuizButton
+
+\begin{quiz*}{mathquiz} Answer each of the following. Passing
+is 100\%.
+
+\begin{questions}
+
+\mrkForIns{topi}
+\item (Topi's question) If $\lim_{x\to a} f(x) = f(a)$, then we say that $f$ is\dots
+\begin{answers}*{3}
+\Ans0 differentiable &\Ans1 continuous &\Ans0 integrable
+\end{answers}
+
+\begin{solution}
+A function $f$ is said to be continuous at $x=a$ if $x\in\mbox{Dom}(f)$,
+$\lim_{x\to a} f(x) $ exists and $\lim_{x\to a} f(x) = f(a)$.
+\end{solution}
+
+\item $\cos(\pi) = \RespBoxMath{-1}*{1}{.0001}{[2,4]}\cgBdry\kern1bp\CorrAnsButton{-1}$
+\begin{solution}
+Of course, everyone knows that $\cos(\pi) = -1 $.
+\end{solution}
+
+\end{questions}
+\end{quiz*}\quad\ScoreField\currQuiz\olBdry\eqButton\currQuiz
+
+\noindent
+Answers: \AnswerField\currQuiz
+
+\end{document}
diff --git a/macros/latex/contrib/mi-solns/examples/mi-solns-eqe.tex b/macros/latex/contrib/mi-solns/examples/mi-solns-eqe.tex
new file mode 100644
index 0000000000..a17be61f01
--- /dev/null
+++ b/macros/latex/contrib/mi-solns/examples/mi-solns-eqe.tex
@@ -0,0 +1,202 @@
+%
+% This is a modified version of selectversion_tst.tex, which is distributed with eqexam
+%
+\documentclass{article}
+\usepackage[fleqn]{amsmath}
+\usepackage[pointsonleft,nototals,forcolorpaper,
+% Select exactly one of the next three options
+% nosolutions,
+% answerkey,
+ vspacewithsolns,
+ obeylocalversions
+]{eqexam}
+
+\usepackage{mi-solns}
+
+\university
+{%
+ NORTHWEST FLORIDA STATE COLLEGE\\
+ Department of Mathematics
+}
+\email{storyd@nwfsc.edu}
+
+\examNum{1}\numVersions{5}\forVersion{e}
+\subject[CA]{College Algebra}
+\longTitleText
+ {Test~{\nExam} A}
+ {Test~{\nExam} B}
+ {Test~{\nExam} C}
+ {Test~{\nExam} D}
+ {Test~{\nExam} E}
+\endlongTitleText
+\shortTitleText
+ {T\nExam-A}
+ {T\nExam-B}
+ {T\nExam-C}
+ {T\nExam-D}
+ {T\nExam-E}
+\endshortTitleText
+\title[\sExam]{\Exam}
+\author{Dr.\ D. P. Story}
+\date{\thisterm, \the\year}
+\duedate{09/30/09}
+\keywords{MAC 1105, Exam \nExam, {\thisterm} semester, \theduedate, at NWFSC}
+
+\newcommand{\cs}[1]{\texttt{\char`\\#1}}
+\solAtEndFormatting{\eqequesitemsep{3pt}}
+\turnContAnnotOn
+
+%\copySolnsOff
+
+\begin{document}
+
+\maketitle
+
+\medskip\noindent
+This is a modified version of \texttt{selectversion\_tst.tex}, which is
+distributed with \textsf{eqexam}, see that file for more details on producing
+a document with multiple versions.
+
+\ifanswerkey When \texttt{answerkey} option is taken, the SOL file is not
+written to include the solutions to the problem, as a result, the solutions
+not available; however, by saying \cs{SolutionsAtEnd} you can locally turn on
+writing the solutions and off writing with \cs{SolutionsAfter}.\fi
+\par\medskip\noindent
+dps: \textsl{\insExSoln[\ignoreterminex]{dps}}\medskip\par\noindent
+kaf: \textsl{\insExSoln[\ignoreterminex]{kaf}}
+
+\begin{exam}[Part 1]{P1}
+
+\writeToSolnFile{\par\medskip
+ This comment is written to the solution file, but it should appear
+ when a solution is input using \protect\cs{insExSoln}, at least I hope so.\par\medskip}
+
+\selectVersion{}{3}
+\begin{problem}\relax
+\verb!\selectVersion{}{3}! \begin{cq}This problem is version \vA{A}\vB{B}\vC{C} of 3.\end{cq}
+
+\mrkForIns{dps}
+\begin{solution}
+The first problem, version \vA{A}\vB{B}\vC{C} of 3.
+\end{solution}
+\end{problem}
+
+\begin{problem*}[2ea]
+Multi-part question.
+ \begin{parts}
+\selectVersion{}{4}
+ \item \verb!\selectVersion{}{4}! This is problem, version \vA{A}\vB{B}\vC{C}\vD{D} of 4.
+\begin{solution}
+This is version \vA{A}\vB{B}\vC{C}\vD{D}
+
+The answer is:
+\begin{verA}
+This is version A
+\end{verA}
+\begin{verB}
+This is version B
+\end{verB}
+\begin{verC}
+This is version C
+\end{verC}
+\begin{verD}
+This is version D
+\end{verD}
+\end{solution}
+
+\selectVersion{}{3}
+ \item \verb!\selectVersion{}{3}! This is a problem, version \vA{A}\vB{B}\vC{C} of 3.
+\begin{verA}
+This is A
+\end{verA}
+\begin{verB}
+This is version B
+\end{verB}
+\begin{verE}
+This is version E
+\end{verE}
+
+\mrkForIns{kaf}
+\begin{solution}
+This is version \vA{A}\vB{B}\vC{C}\vD{D}
+
+The answer is:
+\begin{verA}
+This is version A
+\end{verA}
+\begin{verB}
+This is version B
+\end{verB}
+\begin{verC}
+This is version C
+\end{verC}
+\begin{verD}
+This is version D
+\end{verD}
+\end{solution}
+
+\pushProblem % this closes the group
+\begin{eqComments}
+We insert a new page command so we can see the shortened titles on the next page
+to verify that the new system of title management is working correctly.
+\end{eqComments}
+\emitMessageNearBottom*[.75\textheight]{%
+ \vfill\hfill\textbf{Problem~{\eqeCurrProb} continues on next page}}
+\popProblem % this begins a group
+
+\selectVersion{}{5}
+ \item \verb!\selectVersion{}{5}! This is a problem, version \vA{A}\vB{B}\vC{C}\vD{D}\vE{E} of 5.
+\begin{verB}
+This is version B
+\end{verB}
+\begin{verE}
+This is version E
+\end{verE}
+\begin{solution}
+This is version \vA{A}\vB{B}\vC{C}\vD{D}\vE{E}
+
+The answer is:
+\begin{verB}
+This is version B
+\end{verB}
+\begin{verE}
+This is version E
+\end{verE}
+\end{solution}
+
+\selectVersion{}{4}
+ \item \verb!\selectVersion{}{4}! This is a problem, version \vA{A}\vB{B}\vC{C}\vD{D} of 4.
+\begin{verA}
+This is A
+\end{verA}
+\begin{verB}
+This is version B
+\end{verB}
+\begin{verE}
+This is version E
+\end{verE}
+\begin{solution}
+This is version \vA{A}\vB{B}\vC{C}\vD{D}\vE{E}.
+
+The answer is:
+\begin{verA}
+This is version A
+\end{verA}
+\begin{verB}
+This is version B
+\end{verB}
+\begin{verC}
+This is version C
+\end{verC}
+\begin{verD}
+This is version D
+\end{verD}
+\begin{verE}
+This is version E
+\end{verE}
+\end{solution}
+\end{parts}
+\end{problem*}
+
+\end{exam}
+\end{document}
diff --git a/macros/latex/contrib/mi-solns/examples/use-db.tex b/macros/latex/contrib/mi-solns/examples/use-db.tex
new file mode 100644
index 0000000000..c743f72138
--- /dev/null
+++ b/macros/latex/contrib/mi-solns/examples/use-db.tex
@@ -0,0 +1,23 @@
+\documentclass{article}
+\usepackage[forcolorpaper]{web}
+
+\usepackage{exerquiz}
+
+\usepackage{mi-solns}
+
+\copySolnsOff
+
+
+\begin{document}
+
+%\noindent\textbf{Ogden Nash: First Limerick}
+%\insExSoln[\declSOLOut{poems.lst}]{First Limerick}\medskip
+
+\noindent\textbf{Ogden Nash: The Lama}
+\insExSoln[\declSOLOut{poems.lst}]{The Lama}\medskip
+
+\noindent\textbf{Edward R. Sill: Opportunity}
+\insExSoln[\declSOLOut{poems.lst}]{Opportunity}\medskip
+
+
+\end{document}
diff --git a/macros/latex/contrib/mi-solns/mi-solns.dtx b/macros/latex/contrib/mi-solns/mi-solns.dtx
new file mode 100644
index 0000000000..4181d68a5e
--- /dev/null
+++ b/macros/latex/contrib/mi-solns/mi-solns.dtx
@@ -0,0 +1,411 @@
+% \iffalse
+%<*copyright>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% mi-solns package %%
+%% Copyright (C) 2018 D. P. Story %%
+%% dpstory@uakron.edu %%
+%% %%
+%% This program can redistributed and/or modified under %%
+%% the terms of the LaTeX Project Public License %%
+%% Distributed from CTAN archives in directory %%
+%% macros/latex/base/lppl.txt; either version 1.2 of the %%
+%% License, or (at your option) any later version. %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%</copyright>
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{mi-solns}
+%<package> [2018/12/28 v0.6 extract solutions from exerquiz (dps)]
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[colorlinks,hyperindex=false]{hyperref}
+\OnlyDescription % comment out for implementation details
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\InputIfFileExists{aebdocfmt.def}{\PackageInfo{web}{Inputting aebdocfmt.def}}
+ {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
+ \PackageInfo{web}{aebdocfmt.def cannot be found}}
+\makeatletter
+ \let\@latex@warning\@gobble
+\makeatother
+\begin{document}
+\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}}
+\def\meta#1{\textsl{\texttt{#1}}}
+\def\darg#1{{\ttfamily\char123\relax#1\char125\relax}}
+\def\CMD#1{\textbackslash#1}
+\let\pkg\textsf
+\let\app\textsf
+\let\opt\texttt
+\let\env\texttt
+ \GetFileInfo{mi-solns.sty}
+ \title{\textsf{mi-solns}: Extract solutions from exercises and quizzes}
+ \author{D. P. Story\\
+ Email: \texttt{dpstory@uakron.edu}}
+ \date{processed \today}
+ \maketitle
+ \tableofcontents
+ \DocInput{mi-solns.dtx}
+\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here. Execute
+ \begin{quote}\texttt{makeindex -s gind.ist -o\\\null\quad mi-solns.ind mi-solns.idx}\end{quote} on the command line and recompile
+ \texttt{mi-solns.dtx}.}
+\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here. Execute
+ \begin{quote}\texttt{makeindex -s gglo.ist -o\\\null\quad mi-solns.gls mi-solns.glo}\end{quote} on the command line and recompile
+ \texttt{mi-solns.dtx}.}
+\makeatletter
+ \let\@latex@warning\@gobble
+\makeatother
+\end{document}
+%</driver>
+% \fi
+%
+% \MakeShortVerb{|}
+% \DoNotIndex{\w,\x,\y,\z}
+% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{web}{Inputting aebdonotindex.def}}
+% {\PackageInfo{web}{cannot find aebdonotindex.def}}
+%
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+% \section{Introduction}
+% The \pkg{exerquiz} package is capable of creating questions and solutions to exercises and quizzes.
+% The purpose of this package is to develop commands for extracting any desired solution, for whatever
+% reason, and typesetting it anywhere in the body of the document. To accomplish this goal, the
+% recent version of \pkg{exerquiz} is required (dated 2018/12/13 or later) and the \pkg{shellesc} package.
+%
+% While the document is being compiled, the solution files (SOL and QSL) are being written to, so we cannot
+% input them or read them. What we do is to make a copy of the solution files from within the operating system,
+% and input that back into the body of the document when required. Consequently, it is necessary to activate
+% the feature of executing an OS script from within the compiling operation. To activate the feature, the document
+% needs to be compiled with the \texttt{--shell-escape} switch (for \app{latex}, \app{pdflatex}, \app{lualatex}, and \app{xelatex}).
+%
+% The basic idea is to mark a solution that is to be reproduced elsewhere, \cs{mrkForIns\darg{\ameta{name}}}, just above
+% the \env{solution} environment. Then elsewhere in the document, input the solution using the command \cs{insExSoln\darg{\ameta{name}}},
+% \cs{insSqSoln\darg{\ameta{name}}}, or \cs{insQzSoln\darg{\ameta{name}}}, depending on whether the solution came from
+% the \env{exercise}, \env{shortquiz}, or \env{quiz} environment.
+% \changes{v0.6}{2018/12/28}{Change package name from \string\pkg{ci-solns} to \string\pkg{mi-solns}; change internal commands
+% to reflect this renaming}
+% \section{Preliminaries}
+% \begin{macrocode}
+\RequirePackage{shellesc}
+\ProcessOptions\relax
+% \end{macrocode}
+% We require either \pkg{exerquiz} or \pkg{eqexam} with a minimal publish date, \cs{mi@reqChk} performs the
+% check, but delays it until \cs{AtBeginDocument}.
+% \begin{macrocode}
+\def\mi@reqChk{\begingroup\mifoundfalse
+ \@ifpackageloaded{exerquiz}{\mifoundtrue\def\reqDate{2018/12/13}
+ \@ifpackagelater{exerquiz}{\reqDate}
+ {}{\PackageWarning{mi-solns}{exerquiz dated \reqDate\space
+ or later\MessageBreak required}}%
+ }{}%
+ \@ifpackageloaded{eqexam}{\mifoundtrue
+ \def\reqDate{2018/12/13}\@ifpackagelater{eqexam}{\reqDate}
+ {\mi@solutionsonlyfix}{\PackageWarning{mi-solns}
+ {eqexam dated \reqDate\space or\MessageBreak
+ later required}}%
+ }{}%
+ \ifmifound\else
+ \PackageWarning{mi-solns}{For this package to be
+ effective\MessageBreak you need either exerquiz
+ or eqexam, as appropriate}\fi
+\endgroup}
+\AtBeginDocument{\mi@reqChk}
+% \end{macrocode}
+% Beginning with \pkg{exerquiz/eqexam} dated 2018/12/13, we can change the name of the
+% SOL file (from its default of \cs{jobname.sol}. If the \opt{solutionsonly} option of
+% \pkg{eqexam} is being applied, we made some changes so that option works with
+% \pkg{mi-solns}.
+% \begin{macrocode}
+\def\mi@solutionsonlyfix{\ifsolutionsonly
+ \edef\eqExSolFileName{\misolout}\expandafter
+ \global\copySolnsOff\global\notamiopfalse\fi}
+% \end{macrocode}
+% \section{Core commands for this package}
+% \begin{macro}{\copyfileCmdEx}
+% \begin{macro}{\copyfileCmdQz}
+% The commands to copy SOL and QSL files, may be redefined as needed in the operating system.
+% \begin{macrocode}
+\def\declSOLIn#1{\def\misolin{#1}}\def\declSOLOut#1{\def\misolout{#1}}
+\def\misolin{\jobname.sol}\def\misolout{\jobname-cpy.sol}
+\def\declQSLIn#1{\def\miqslin{#1}}\def\declQSLOut#1{\def\miqslout{#1}}
+\def\miqslin{\jobname.qsl}\def\miqslout{\jobname-cpy.qsl}
+\newcommand*{\copyfileCmdEx}{copy \misolin\space\misolout}
+\newcommand*{\copyfileCmdQz}{copy \miqslin\space\miqslout}
+\def\mi@copysolns{%
+ \ShellEscape{\copyfileCmdEx}\ShellEscape{\copyfileCmdQz}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\copySolnsOn}
+% Making a copy of the solution files is the default.
+% \begin{macro}{\copySolnsOff}
+% After there are no more changes to the solution files, you can say
+% \cs{copySolnsOff}, and each compile will not rebuild `\texttt{cpy-}' solution
+% files.
+% \begin{macrocode}
+\def\copySolnsOn{\let\mi@copySolns\mi@copysolns}
+\def\copySolnsOff{\let\mi@copySolns\relax}
+\@onlypreamble\copySolnsOn
+\@onlypreamble\copySolnsOff
+\copySolnsOn
+% \end{macrocode}
+% \textbf{Copy the solution files.} At the end of the document, we make a copy of the solution files, provided
+% \cs{copySolnsOn} is in effect.
+% \begin{macrocode}
+\AtEndDocument{\mi@copySolns}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \textbf{Some utility commands}
+% Below, we define a few useful commands.\medskip\par
+% \noindent\DescribeMacro\ignoreterminex If \cs{eqterminex} has a special definition,
+% perhaps created from the \env{cq} environment, you can pass \cs{ignoreterminex} through
+% the optional argument of \cs{insExSoln} and the question to the problem does not appear.
+% We also declare \DescribeMacro\ignoreques\cs{ignoreques} as an alias for \cs{ignoreterminex}.\medskip
+%
+% \noindent We define two switches: \DescribeMacro\ifmifound\cs{ifmifound} is set to true when
+% a \ameta{name} we are searching for is found; otherwise it remains false. A value of false causes
+% a warning to be issued. \DescribeMacro\ifnotamiop\cs{ifnotamiop} (not a MI operation) is used to control what is displayed
+% when one of the \cs{ins...} commands are used. See comments just below.
+% \begin{macrocode}
+\newif\ifmifound \mifoundfalse
+\newif\ifnotamiop \notamioptrue
+\newif\ifmi@OKtoRead \mi@OKtoReadtrue
+\def\readSolnsOn{\mi@OKtoReadtrue}
+\def\readSolnsOff{\mi@OKtoReadfalse}
+\newcommand*{\miReadOffMsg}{(\textbf{?? read is off ??})}
+% \end{macrocode}
+% The document author can can write to the solution files using
+% \DescribeMacro\writeToExSolns\cs{writeToExSolns}, \DescribeMacro\writeToSolnFile\cs{writeToSolnFile},
+% or \DescribeMacro\writeToQzSolns. The macros are originally defined in \pkg{exerquiz} and
+% \pkg{eqexam}, but we redefine them here so their argument is enclosed in
+% \cs{ifnotamiop}.
+% \begin{macrocode}
+\newcommand\mi@wrt@fix[1]{\protect\ifnotamiop^^J%
+ #1^^J\protect\fi}
+\renewcommand\writeToExSolns[1]{\writeT@ExSolns{\mi@wrt@fix{#1}}}
+\renewcommand\writeToQzSolns[1]{\writeT@QzSolns{\mi@wrt@fix{#1}}}
+\@ifpackageloaded{eqexam}
+ {\renewcommand\writeToSolnFile[1]{\writeT@SolnFile{\mi@wrt@fix{#1}}}}
+ {\let\writeToSolnFile\writeToExSolns}
+\def\ignoreterminex{\let\eqterminex\relax\let\decleqterminex\@gobble}
+\let\ignoreques\ignoreterminex
+% \end{macrocode}
+% Some gobbling macros.
+% \begin{macrocode}
+\long\def\gobbleiiterminex#1\eqterminex{}
+\long\def\gobbleiiendinput#1\endinput{\endinput}
+\long\def\gobbleiiendgroup#1\endgroup{}
+\long\def\mi@griii#1#2#3{}
+% \end{macrocode}
+% \cs{eqgriii} is eventually \cs{let} to\DescribeMacro{\mi@griii}\cs{mi@griii}, while \cs{eqgrii} is
+% \cs{let} to \cs{@gobbletwo}. In the data structure of
+% the solution file of an \pkg{eqexam} document. In such a document, \cs{eqgriii} and \cs{eqgrii} appears at the top
+% and bottom of the file; for example,
+% \begin{flushleft}\ttfamily\small\let\s\string\let\b\darg\let\t\quad
+% \t\s\eqgriii\s\noindent\s\begin\b{eqequestions}\\
+% \t\dots\\
+% \t\s\eqgrii\s\end\b{eqequestions}
+% \end{flushleft}
+% We don't want the \env{eqequestions} environment input as part of the insertion, so we must gobble
+% them up using \cs{eqgriii} (\cs{let} to \cs{mi@griii}) and \cs{eqgrii} (\cs{let} to \cs{@gobbletwo}).
+% These are formatting (a list env), which we don't want in the body of our document. We are
+% just trying to input the \ameta{solution} part of the data structure; everything else needs to be
+% ignored.
+% \begin{macrocode}
+% \end{macrocode}
+% The next three commands do some internal
+% work. They are each called by \cs{insExSoln}, \cs{insSqSoln}, and \cs{insQzSoln}, respectively\medskip
+%
+% \subsection{Internal macros that expand within a solutions file}
+% There are three macros that are defined and are executed as a solution file is input.
+%
+% \subsubsection{For exercises}
+% Exercises are the more difficult case because they are used not only by \pkg{exerquiz},
+% but also \pkg{eqexam}; in the latter, there are may more `control' commands that are written
+% to the solution file (SOL) to format how the solutions appear at the end of the document.
+%
+% Below is a representation of a solution to an exercise. The \cs{insExSoln} command, \cs{let}s
+% \cs{eqMrkSoln} to \cs{eqMrkSolnCpyEx}\par\medskip\noindent
+% \textbf{A representative data structure for an exercise (\pkg{exerquiz})}\vadjust{\kern-6pt}
+% \begin{flushleft}\ttfamily\small\let\s\string\let\b\darg\let\t\quad
+% \t\s\eqMrkSoln\b{\ameta{name}}\s\eqEXt\b{}\b{}\s\solnItemMngt\\
+% \t\s\exerSolnHeader\b{\ameta{argi}}\b{\ameta{argii}}{\b{argiii}}\s\eqterminex\\
+% \t\t\t\ameta{solution}\\
+% \t\s\ReturnTo\b{\ameta{argi}}\b{\ameta{argii}}\s\endeqEXt\s\par\b{\s\medskip}\%
+% \end{flushleft}
+% If a solution to an exercise (or quiz) is \emph{not marked} by \cs{mrkForIns{\ameta{name}}}, then
+% \cs{eqMrkSoln\darg{\ameta{name}}} \emph{does not appear} in the structure.\par\medskip\noindent
+% \textbf{A representative data structure for an problem (\pkg{eforms})}\vadjust{\kern-6pt}
+% \begin{flushleft}\ttfamily\small\let\s\string\let\b\darg\let\t\quad
+% \t\s\decleqterminex\b{\s\cqFmtPasteQues\b{cq-1.cut}}\%\\
+% \t\s\eqMrkSoln\b{\ameta{name}}\s\eqEXt\b{}\b{}\s\solnItemMngt\\
+% \t\s\exerSolnHeader\b{\ameta{argi}}\b{\ameta{argii}}\b{\ameta{argiii}}\s\selectVersion\b{}\b{3}\s\eqterminex\\
+% \t\t\t\ameta{solution}\\
+% \t\s\ReturnTo\b{\ameta{argi}}\b{\ameta{argii}}\s\endeqEXt\s\par\b{\b{}}\%
+% \end{flushleft}
+% When \cs{selectVersion} \emph{does not appear} prior to the \env{solution} environment, then the \cs{declareterminex}
+% and \cs{selectVersion} (and args) \emph{do not appear} in the structure.\par\medskip\noindent
+% \textbf{In general.} When \cs{eqMrkSoln} is expanded, it tests whether
+% \ameta{name} matches \cs{eqMrkCpyArg}. Referencing the above data structures, \cs{insExSoln} pretty
+% much sets \cs{eqEXt}, \cs{solnItemMngt}, \cs{exerSolnHeader}, \cs{ReturnTo} to gobble their argument and become noops.
+% \cs{endeqEXt} gobbles everything up down to \cs{endinput}.\medskip
+%
+% \noindent\DescribeMacro{\eqMrkSolnCpyEx}\hskip-\marginparsep\texttt{\darg{\ameta{name}}} Process
+% a marked solution for an exercise. We hunt for \ameta{name}.
+% \begin{macrocode}
+\def\eqMrkSolnCpyEx#1{\def\eqargi{#1}%
+ \ifx\eqargi\eqMrkCpyArg
+ \mifoundtrue
+ \let\par\par@SAVE
+ \ifmakeExSlLocal
+ \long\def\endeqEXt##1##2##3{##3\gobbleiiendinput}\else
+ \let\endeqEXt\gobbleiiendinput\fi
+ \let\eqEXt\@gobbletwo
+ \let\mi@next\relax
+ \else
+ \long\def\endeqEXt##1##2{}%
+ \let\mi@next\gobbleToEndEXt
+ \fi
+\mi@next}
+% \end{macrocode}
+% \subsubsection{For short-quizzes}
+% \textbf{A representative data structure for a short-quiz (\pkg{exerquiz})}\vadjust{\kern-6pt}
+% \begin{flushleft}\ttfamily\small\let\s\string\let\b\darg\let\t\quad
+% \t\s\eqMrkSoln\b{\ameta{name}}\s\eqSQt\b{}\s\quizSolnHeader\b{\ameta{argi}}\b{\ameta{argii}}\s\eqterminex\\
+% \t\t\t\ameta{solution}\\
+% \t\s\ReturnTo\b{\ameta{argi}}\b{\ameta{argii}}\s\endeqQt\s\fpAfterSolutionsSkip
+% \end{flushleft}
+% As commented above, \cs{eqMrkSoln} may not appear in the data structure.\medskip
+%
+% \noindent\DescribeMacro{\eqMrkSolnCpySQ}\hskip-\marginparsep\texttt{\darg{\ameta{name}}} Process
+% a marked solution for an short-quiz (\env{shortquiz} env). We hunt for \ameta{name}.
+% \begin{macrocode}
+\def\eqMrkSolnCpySQ#1{\def\eqargi{#1}%
+ \ifx\eqargi\eqMrkCpyArg
+ \mifoundtrue
+ \let\par\par@SAVE
+ \ifmakeQzSlLocal
+ \long\def\endeqSQt##1##2{##2\gobbleiiendinput}\else
+ \let\endeqSQt\gobbleiiendinput
+ \fi
+ \let\mi@next\gobbleiiterminex
+ \else
+ \long\def\endeqSQt##1{}%
+ \let\mi@next\gobbleToEndSQt
+ \fi
+\mi@next}
+% \end{macrocode}
+% \subsubsection{For quizzes}
+% \textbf{A representative data structure for a quiz (\pkg{exerquiz})}\vadjust{\kern-6pt}
+% \begin{flushleft}\ttfamily\small\let\s\string\let\b\darg\let\t\quad
+% \t\s\eqMrkSoln\b{\ameta{name}}\s\eqQt\b{}\s\quizSolnHeader\b{\ameta{argi}}\b{\ameta{argii}}\s\eqterminex\\
+% \t\t\t\ameta{solution}\\
+% \t\s\ReturnTo\b{\ameta{argi}}\b{\ameta{argii}}\s\endeqQt\s\fpAfterSolutionsSkip
+% \end{flushleft}
+% As commented above, \cs{eqMrkSoln} may not appear in the data structure.\medskip
+%
+% \noindent\DescribeMacro{\eqMrkSolnCpyQz}\hskip-\marginparsep\texttt{\darg{\ameta{name}}} Process
+% a marked solution for an quiz (\env{quiz} env). We hunt for \ameta{name}.
+% \begin{macrocode}
+\def\eqMrkSolnCpyQz#1{\def\eqargi{#1}%
+ \ifx\eqargi\eqMrkCpyArg
+ \mifoundtrue
+ \let\par\par@SAVE
+ \ifmakeQzSlLocal
+ \long\def\endeqQt##1##2{##2\gobbleiiendinput}\else
+ \let\endeqQt\gobbleiiendinput
+ \fi
+ \let\mi@next\gobbleiiterminex
+ \else
+ \long\def\endeqQt##1{}%
+ \let\mi@next\gobbleToEndSQt
+ \fi
+\mi@next}
+% \end{macrocode}
+
+% \section{User commands for inserting a solution}
+% The main commands are \cs{insExSoln}, \cs{insSqSoln}, and \cs{insQzSoln}.
+%
+% Preliminary to the definitions, we define a command that is common to all of them.
+% When inputting a solutions file, we cannot any vertical spaces that are not part of
+% the solution, not formatting, not list environments, and so on. The
+% \DescribeMacro\mi@nullify\cs{mi@nullify} is designed to cancel, nullify, or otherwise
+% neutralize anything that is unwanted. I've added \DescribeMacro\addToMINullify\cs{addToMINullify}
+% for any unforseen things we don't want to appear or to affect spacing.
+%
+% \begin{macrocode}
+\let\addToMINullify\relax
+\def\mi@nullify{\let\par@SAVE\par\let\par\relax
+ \let\eqgrii\@gobbletwo\let\eqgriii\mi@griii\let\solnItemMngt\relax
+ \def\exerSolnHeader##1##2##3{}\def\ReturnTo##1##2{\unskip}%
+ \let\eqTopOfSolnPage\relax\let\preExamSolnHead\relax
+ \let\eqTopOfQslPage\relax
+ \let\examSolnHeadFmt\@gobble\let\postExamSolnHead\relax
+ \let\btwnExamSkip\relax\def\quizSolnHeader##1##2{}\addToMINullify}
+% \end{macrocode}
+%
+% \subsection{For exercises}
+%
+% \begin{macro}{\insExSoln}\hskip-\marginparsep\texttt{[\ameta{inserts}]\darg{\ameta{name}}}
+% Used for displaying the solution to an exercise that has been marked by
+% \cs{mrkForIns\darg{\ameta{name}}}. The optional argument (\ameta{inserts}) is passed (inserted) into the top of the
+% \cs{insExSoln}. For exercises, there is a \env{cq} command that copies the question
+% to the solution. By default, the question \emph{is displayed}; however, by passing
+% \DescribeMacro{\ignoreterminex}\cs{ignoreterminex} the question \emph{is not displayed}.
+% \begin{macrocode}
+\newcommand{\insExSoln}[2][]{\begingroup\withinsoldoctrue#1\relax
+ \notamiopfalse\mi@nullify
+ \let\eqMrkSoln\eqMrkSolnCpyEx
+% \end{macrocode}
+% Setting \cs{useExtFilter} and \cs{filterFor\darg{@NOMATCH@}}; hopefully, no match is ever obtained, which
+% means the already existent function of \cs{useExtFilter} will skip over the entries.
+% When \cs{eqMrkSoln} does not appear in a data structure, the filter will care of the structure entry.
+% \begin{macrocode}
+ \useEXtFilter\filterFor{@NOMATCH@}\def\eqMrkCpyArg{#2}%
+ \ifmi@OKtoRead\InputIfFileExists{\misolout}{}{}\ifmifound\else
+ \textbf{??}\PackageWarning{mi-solns}{The name '#2' defined by
+ \string\mrkForIns\MessageBreak was not found}\fi\else
+ \miReadOffMsg\fi\endgroup}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{For quizzes}
+% The commands \cs{insSqSoln} and \cs{insQzSoln} are identical, except for
+% two parameters: \texttt{\#3} is the internal command (\cs{eqMrkSolnCpySQ}
+% or \cs{eqMrkSolnCpyQz}); while \texttt{\#4} is the normal filter
+% (\cs{useSQtFilter} or \cs{useQtFilter}).
+% \begin{macrocode}
+\newcommand\mi@insSQzSoln[4][]{\begingroup\withinqsldoctrue#1\relax
+ \notamiopfalse\mi@nullify
+ \let\eqMrkSoln#3\relax
+ #4\filterFor{@NOMATCH@}\def\eqMrkCpyArg{#2}%
+ \ifmi@OKtoRead\InputIfFileExists{\miqslout}{}{}\ifmifound\else
+ \textbf{??}\PackageWarning{mi-solns}
+ {The name '#2' defined by \string\mrkForIns\MessageBreak
+ was not found}\fi\else\miReadOffMsg\fi\endgroup}
+% \end{macrocode}
+% \begin{macro}{\insSqSoln}\hskip-\marginparsep\texttt{[\ameta{inserts}]\darg{\ameta{name}}}
+% Used for displaying the solution to an short-quiz that has been marked by
+% \cs{mrkForIns\darg{\ameta{name}}}. The optional argument (\ameta{inserts}) is passed (inserted) into the top of the
+% \cs{insSqSoln}.
+% \begin{macrocode}
+\newcommand{\insSqSoln}[2][]{%
+ \mi@insSQzSoln[#1]{#2}{\eqMrkSolnCpySQ}{\useSQtFilter}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\insQzSoln}\hskip-\marginparsep\texttt{[\ameta{inserts}]\darg{\ameta{name}}}
+% Used for displaying the solution to an quiz that has been marked by
+% \cs{mrkForIns\darg{\ameta{name}}}. The optional argument (\ameta{inserts}) is passed (inserted) into the top of the
+% \cs{insQzSoln}.
+% \begin{macrocode}
+\newcommand{\insQzSoln}[2][]{%
+ \mi@insSQzSoln[#1]{#2}{\eqMrkSolnCpyQz}{\useQtFilter}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macrocode}
+%</package>
+% \end{macrocode}
+% \Finale
+\endinput
diff --git a/macros/latex/contrib/mi-solns/mi-solns.ins b/macros/latex/contrib/mi-solns/mi-solns.ins
new file mode 100644
index 0000000000..8e01d7e65e
--- /dev/null
+++ b/macros/latex/contrib/mi-solns/mi-solns.ins
@@ -0,0 +1,59 @@
+%%
+%% This file will generate fast loadable files and documentation
+%% driver files from the doc files in this package when run through
+%% LaTeX or TeX.
+%%
+%% Copyright 1999-2006 D. P. Story
+%%
+%% This file is part of the `AcroTeX eDucation Bundle'.
+%% -------------------------------------------
+%%
+%% It may be distributed under the conditions of the LaTeX Project Public
+%% License, either version 1.2 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.2 or later is part of all distributions of LaTeX
+%% version 1999/12/01 or later.
+%%
+%% --------------- start of docstrip commands ------------------
+%%
+\def\filedate{2018/12/04}
+\def\batchfile{mi-solns.ins}
+
+\input docstrip
+\ifx\generate\undefined
+ \Msg{**********************************************}
+ \Msg{*}
+ \Msg{* This installation requires docstrip}
+ \Msg{* version 2.4 or later.}
+ \Msg{*}
+ \Msg{* An older version of docstrip has been input}
+ \Msg{*}
+ \Msg{**********************************************}
+ \errhelp{Move or rename old docstrip.tex and get a newer one.}
+ \errmessage{Old docstrip in input path}
+ \batchmode
+ \csname @@end\endcsname\end
+\fi
+
+\keepsilent
+\askforoverwritefalse
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\preamble
+\endpreamble
+
+\generate{%
+ \file{mi-solns.sty}{\from{mi-solns.dtx}{copyright,package}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files }
+\Msg{*}
+\Msg{* \space *.sty, *.cfg and *.def into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput