texlive[51388] Master/texmf-dist: exframe (16jun19)
commits+karl at tug.org
commits+karl at tug.org
Mon Jun 17 00:04:42 CEST 2019
Revision: 51388
http://tug.org/svn/texlive?view=revision&revision=51388
Author: karl
Date: 2019-06-17 00:04:41 +0200 (Mon, 17 Jun 2019)
Log Message:
-----------
exframe (16jun19)
Modified Paths:
--------------
trunk/Master/texmf-dist/doc/latex/exframe/README.txt
trunk/Master/texmf-dist/doc/latex/exframe/exframe.pdf
trunk/Master/texmf-dist/doc/latex/exframe/exfsamp.tex
trunk/Master/texmf-dist/doc/latex/exframe/exfserm.tex
trunk/Master/texmf-dist/source/latex/exframe/exframe.dtx
trunk/Master/texmf-dist/tex/latex/exframe/exframe.sty
Modified: trunk/Master/texmf-dist/doc/latex/exframe/README.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/exframe/README.txt 2019-06-16 22:04:20 UTC (rev 51387)
+++ trunk/Master/texmf-dist/doc/latex/exframe/README.txt 2019-06-16 22:04:41 UTC (rev 51388)
@@ -1,4 +1,4 @@
-exframe v3.2
+exframe v3.3
Copyright 2011-2019 Niklas Beisert
exframe is a LaTeX2e package which provides a general purpose
Modified: trunk/Master/texmf-dist/doc/latex/exframe/exframe.pdf
===================================================================
(Binary files differ)
Modified: trunk/Master/texmf-dist/doc/latex/exframe/exfsamp.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/exframe/exfsamp.tex 2019-06-16 22:04:20 UTC (rev 51387)
+++ trunk/Master/texmf-dist/doc/latex/exframe/exfsamp.tex 2019-06-16 22:04:41 UTC (rev 51388)
@@ -17,7 +17,7 @@
%% version 2005/12/01 or later.
%%
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
-\ProvidesFile{exfsamp.tex}[2019/05/01 v3.2 standalone sample for exframe]
+\ProvidesFile{exfsamp.tex}[2019/06/15 v3.3 standalone sample for exframe]
\documentclass[12pt]{article}
\usepackage{geometry}
@@ -41,10 +41,15 @@
\exerciseconfig{countersubproblem}{\roman{subproblem})}
\exerciseconfig{countersubproblemmax}{vii)}
+\exerciseconfig{insertsubprobleminfo}{%
+ \switchpoints{}{\addprobleminfo*{%
+ \hspace{-\getexerciseconfig{skipsubprobleminfo}}*}}%
+ {}{}{\getsubproblempoints{}}}
+
\exerciseconfig{termsheet}{\"Ubungsblatt}
\exerciseconfig{termsheets}{\"Ubungsbl\"atter}
-\exercisestyle{pointsat=margin}
+\exercisestyle{problempointsat=margin}
\reversemarginpar
\exerciseconfig{composepointsmargin}[1]{#1p.}
\exerciseconfig{composepointspairmargin}[2]{
Modified: trunk/Master/texmf-dist/doc/latex/exframe/exfserm.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/exframe/exfserm.tex 2019-06-16 22:04:20 UTC (rev 51387)
+++ trunk/Master/texmf-dist/doc/latex/exframe/exfserm.tex 2019-06-16 22:04:41 UTC (rev 51388)
@@ -17,7 +17,7 @@
%% version 2005/12/01 or later.
%%
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
-\ProvidesFile{exfserm.tex}[2019/05/01 v3.2 multipart sample for exframe]
+\ProvidesFile{exfserm.tex}[2019/06/15 v3.3 multipart sample for exframe]
\input{childdoc.def}
\childdocmain{exfserm}
Modified: trunk/Master/texmf-dist/source/latex/exframe/exframe.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/exframe/exframe.dtx 2019-06-16 22:04:20 UTC (rev 51387)
+++ trunk/Master/texmf-dist/source/latex/exframe/exframe.dtx 2019-06-16 22:04:41 UTC (rev 51388)
@@ -20,11 +20,11 @@
% exfserpe.tex, exfserpf.tex, exfsermk.sh, exfsermk.mak.
%
%<package|samplesingle|samplemultimain>\NeedsTeXFormat{LaTeX2e}[1996/12/01]
-%<package>\ProvidesPackage{exframe}[2019/05/01 v3.2 Framework for Exercise Problems]
-%<samplesingle>\ProvidesFile{exfsamp.tex}[2019/05/01 v3.2 standalone sample for exframe]
-%<samplemultimain>\ProvidesFile{exfserm.tex}[2019/05/01 v3.2 multipart sample for exframe]
+%<package>\ProvidesPackage{exframe}[2019/06/15 v3.3 Framework for Exercise Problems]
+%<samplesingle>\ProvidesFile{exfsamp.tex}[2019/06/15 v3.3 standalone sample for exframe]
+%<samplemultimain>\ProvidesFile{exfserm.tex}[2019/06/15 v3.3 multipart sample for exframe]
%<*driver>
-\def\thedate#1{2019/05/01}\def\theversion#1{v3.2}
+\def\thedate#1{2019/06/15}\def\theversion#1{v3.3}
\ProvidesFile{exframe.dtx}[\thedate{} \theversion{} exframe reference manual file]
\PassOptionsToClass{10pt,a4paper}{article}
\documentclass{ltxdoc}
@@ -218,7 +218,7 @@
\end{tabular}
\end{center}
%
-A |subproblem| block must be contained within a |problem| block
+A |subproblem| environment must be contained within a |problem| environment
(however, a |problem| block need not contain |subproblem| blocks).
\DescribeEnv{solution}
@@ -232,13 +232,14 @@
\end{tabular}
\end{center}
%
-A |solution| block should be at the end of a |subproblem| or |problem| block
+A |solution| environment should be
+at the end of a |subproblem| or |problem| environment
(it is not mandatory to provide a |solution|).
-It can be contained within the corresponding block or it can follow it.
+It can be contained within the corresponding environment or it can follow it.
Depending on the choice of solution display, see \secref{sec:solutions},
the output may have a slightly different layout.
In terms of logic, it is preferred
-to define a solution \emph{within} the corresponding block;
+to define a solution \emph{within} the corresponding environment;
this may also have some technical advantages and produce
a slightly better result in terms of layout.
@@ -259,10 +260,11 @@
A header will be added to the sheet according to the specified layout.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\subsection{Solution Display}
+\subsection{Solution and Problem Display}
\label{sec:solutions}
-There are several options to control the output of solutions.
+There are several options to control the output of solutions
+and of problems.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\DescribeMacro{solutions}
@@ -327,15 +329,11 @@
Note that typically solutions are defined at the end of a (sub)problem
and therefore the choice |here| is similar to (|sub|)|problem|.
The latter form, however, makes sure that a solution
-does not inherit the margin of the parent block.
-The alternate mode |here*| does not intermediately store
-the solution block content in a token buffer;
-this might resolve some tokenisation issues
-in special circumstances.
+does not inherit the margin of the parent environment.
The alternate modes |problem*| and |subproblem*|
-positions the solution \emph{after} the (sub)problem block
+positions the solution \emph{after} the (sub)problem environment
such that it does not inherit any layout,
-but also no definitions made in the parent block.
+but also no definitions made in the parent environment.
In |manual| mode, all solutions are collected (with appropriate headers)
until they are output by the directive |\insertsolutions|.
If no solutions are stored in the buffer
@@ -352,7 +350,8 @@
\end{center}
%
The optional argument describes the filename as \textit{filename}|.sol|;
-no argument defaults to the main tex filename as |\jobname.sol|.
+no argument defaults to the main tex filename as |\jobname.sol|;
+the extension |.sol| can be customised by the configuration |extsolutions|.
This mode overrides the |solutionbelow| behaviour described above;
all subsequent solutions are written to the file.
The file is closed by |\closesolutions| and the display of solutions
@@ -372,6 +371,94 @@
This command outputs a sectional title
and reads the file via |\input{|\textit{filename}|.sol}|.
+\medskip
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\DescribeMacro{solutionbuf}
+\DescribeMacro{problembuf}
+The package offers similar functionality to control the display of problems.
+In order to have any control over the content of |problem| environments,
+the latter needs to be read into an internal buffer.
+Reading of solutions and problems to internal buffers is activated
+or deactivated by:
+%
+\begin{center}
+\begin{tabular}{l}
+|\exercisesetup{solutionbuf|[|=true|\textbar|false|]|}|\\
+|\exercisesetup{problembuf|[|=true|\textbar|false|]|}|
+\end{tabular}
+\end{center}
+%
+By default, |solution| environments are read to an internal buffer,
+while the content of |problem| environments is processed directly
+by the \TeX\ engine.
+Therefore, the following options to control the display
+of |problem| environments require the statement |\exercisesetup{problembuf}|.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\DescribeMacro{problemmanual}
+\DescribeMacro{\insertproblems}
+The immediate display of |problem| environments is controlled by:
+%
+\begin{center}
+|\exercisestyle{problemmanual|[|=true|\textbar|false|]|}|
+\end{center}
+%
+In the default automatic mode, problems are displayed directly
+where they are declared.
+In manual mode, problems are collected to an internal buffer,
+and only displayed by issuing |\insertproblems|.
+
+Note that |solution| environments should be
+declared within the corresponding |problem| environment in order to
+preserve their appropriate association.
+The |solution| environment is then processed at the place
+where the |problem| environment is displayed,
+and it may (or may not) be deferred further.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\DescribeMacro{\writeproblems}
+\DescribeMacro{\readproblems}
+Problems can be written out to an external file for later usage.
+The functionality is analogous to solutions
+and uses the macros:
+%
+\begin{center}
+\begin{tabular}{l}
+|\writeproblems[|\textit{filename}|]|\\
+|\readproblems[|\textit{filename}|]|
+\end{tabular}
+\end{center}
+%
+The optional argument describes the filename as \textit{filename}|.prb|;
+no argument defaults to the main tex filename as |\jobname.prb|;
+the extension |.prb| can be customised by the configuration |extproblems|.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\DescribeMacro{disable}
+\DescribeMacro{insertproblemselect}
+The display of a particular |problem|
+can be suppressed altogether by an optional argument:
+%
+\begin{center}
+|\begin{problem}[disable]|
+\end{center}
+%
+
+This option can be exploited to automatically
+suppress certain classes of problems as follows:
+A hook function |insertproblemselect| declared by:
+%
+\begin{center}
+|\exerciseconfig{insertproblemselect}[1]{|\textit{code}|}|
+\end{center}
+%
+can call
+|\setproblemdata{disable}| whenever a problem is to be suppressed.
+In order to decide, the optional argument of the |problem| environment
+is passed on to the hook function as the single argument.
+Note that the argument needs to be processed manually.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\subsection{Metadata}
\label{sec:metadata}
@@ -477,8 +564,10 @@
for sheets and problems:
%
\begin{center}
-|\begin{sheet}[|\textit{opts}|]|
+\begin{tabular}{l}
+|\begin{sheet}[|\textit{opts}|]|\\
|\begin{problem}[|\textit{opts}|]|
+\end{tabular}
\end{center}
%
The argument \textit{opt}
@@ -523,22 +612,26 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\DescribeMacro{\defsheetdata}
+\DescribeMacro{\setsheetdata}
\DescribeMacro{\getsheetdata}
\DescribeMacro{\sheetdataempty}
\DescribeMacro{\defproblemdata}
+\DescribeMacro{\setproblemdata}
\DescribeMacro{\getproblemdata}
\DescribeMacro{\problemdataempty}
Metadata for sheets can be used in the same way as the global metadata.
-The following directives are analogous to |\defexecisesdata|,
-|\getproblemdata| and |\problemdataempty|:
+The following directives are analogous to |\defexercisedata|,
+|\exercisedata|, |\getexercisedata| and |\exercisedataempty|:
%
\begin{center}
\begin{tabular}{l}
|\defsheetdata{|\textit{key}|}|\\
+|\setsheetdata{|\textit{data}|}|\\
|\getsheetdata{|\textit{key}|}|\\
|\sheetdataempty{|\textit{key}|}|%
|{|\textit{empty code}|}{|\textit{filled code}|}|\\[1ex]
|\defproblemdata{|\textit{key}|}|\\
+|\setproblemdata{|\textit{data}|}|\\
|\getproblemdata{|\textit{key}|}|\\
|\problemdataempty{|\textit{key}|}|%
|{|\textit{empty code}|}{|\textit{filled code}|}|
@@ -631,12 +724,15 @@
\item |comment|:
some comment on the problem.
\item |optional|
-(enabled by default):
+(display enabled by default):
whether addressing the problem is mandatory or optional;
by default the text will be displayed after the title
in italic shape.
\end{itemize}
%
+By default, only the |optional| items are displayed,
+all other types of items are hidden;
+controlling the display for each type of item is described below.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\DescribeMacro{extdata}
@@ -740,16 +836,19 @@
[\textit{regular}][|+|\textit{bonus}] where 0 components are omitted.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\DescribeMacro{pointsat}
-\DescribeMacro{subpointsat}
+\DescribeMacro{problempointsat}
+\DescribeMacro{subproblempointsat}
+\DescribeMacro{solutionpointsat}
The location where points of problems and subproblems
shall be displayed can be adjusted individually by:
%
\begin{center}
\begin{tabular}{l}
-|\problemstyle{points=start|\textbar|start*|\textbar|margin|%
+|\exercisestyle{problempointsat=start|\textbar|start*|\textbar|margin|%
\textbar|end|\textbar|manual|\textbar|off}|\\
-|\problemstyle{subpoints=start|\textbar|start*|\textbar|margin|%
+|\exercisestyle{subproblempointsat=start|\textbar|start*|\textbar|margin|%
+ \textbar|end|\textbar|manual|\textbar|off}|\\
+|\exercisestyle{solutionpointsat=start|\textbar|start*|\textbar|margin|%
\textbar|end|\textbar|manual|\textbar|off}|
\end{tabular}
\end{center}
@@ -785,7 +884,10 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\DescribeMacro{\getsheetpoints}
\DescribeMacro{\getproblempoints}
+\DescribeMacro{\getsubproblempoints}
+\DescribeMacro{\getsolutionpoints}
\DescribeMacro{\extractpoints}
+\DescribeMacro{\switchpoints}
The package allows to read the point totals
for other sheets and problems:
%
@@ -792,17 +894,36 @@
\begin{center}
\begin{tabular}{l}
|\getsheetpoints{|\textit{tag}|}|\\
-|\getproblempoints{|\textit{tag}|}|
+|\getproblempoints{|\textit{tag}|}|\\
+|\getsubproblempoints{}|\\
+|\getsolutionpoints{}|
\end{tabular}
\end{center}
%
Here \textit{tag} is the tag assigned to the corresponding sheet or problem,
see \secref{sec:labels}.
+An empty argument \textit{tag} refers to the current
+sheet, (sub)problem or solution.
If bonus points are used, the points will be returned
in the format [\textit{regular}][|+|\textit{bonus}];
the components \textit{regular} and \textit{bonus}
can be extracted from the returned expression
by |\extractpoints| and |\extractpoints*|, respectively.
+A convenient case switch of the returned value can be performed by:
+%
+\begin{center}
+|\switchpoints{|\textit{reg}|}{|\textit{bonus}|}{|\textit{both}|}{|%
+\textit{none}|}{|\textit{val}|}|
+\end{center}
+%
+Here \textit{val} is the value returned from the points register,
+\textit{reg} is displayed for purely regular points,
+\textit{bonus} is displayed for purely bonus points,
+\textit{both} is displayed for mixed points,
+\textit{none} is displayed for no points.
+In each of the four expressions,
+|#1| will be replaced by the regular points
+and |#2| by the bonus points.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\DescribeMacro{\awardpoints}
@@ -1103,24 +1224,30 @@
%
\begin{itemize}
\item |solutionbelow=|\textit{pos}
-(can take values |here|, |here*|, |subproblem|, |subproblem*|,
+(can take values |here|, |subproblem|, |subproblem*|,
|problem|, |problem*|, |sheet| and |manual|;
initially set to |subproblem|) --
-positions the solutions below the indicated blocks;
+positions the solutions below the indicated environments;
see \secref{sec:solutions} for details.
-\item |pointsat=|\textit{pos}
+\item |problempointsat=|\textit{pos}
(can take values |start|, |start*|, |margin|, |end| and |manual|;
initially set to |start|) --
displays points in problems at the indicated location;
see \secref{sec:points} for details.
-\item |subpointsat=|\textit{pos}
+\item |subproblempointsat=|\textit{pos}
(can take values |start|, |start*|, |margin|, |end| and |manual|;
initially set to |end|) --
displays points in subproblems at the indicated location;
see \secref{sec:points} for details.
+\item |solutionpointsat=|\textit{pos}
+(can take values |start|, |start*|, |margin|, |end| and |manual|;
+initially set to |end|) --
+displays points in solutions at the indicated location;
+see \secref{sec:points} for details.
+
\item |problemby={|\textit{counter}|}| --
number problems with the prefix \textit{counter},
i.e.\ reset the problem counter whenever \textit{counter} increases
@@ -1340,6 +1467,21 @@
(|prob:\problemtag|; can be adjusted)
to problems according to their tag |\problemtag|.
+\item |solutionbuf|[|=true|\textbar|false|]
+(no value implies |true|, initially set to |true|) --
+enable/disable buffering for |solution| environments
+in order to control their display;
+disabling buffering can be helpful
+in debugging faulty |solution| environments;
+it might also resolve some tokenisation issues in special circumstances;
+note that the display of solutions cannot be suppressed
+with |\exercisesetup{solutions=false}| when buffering if disabled.
+
+\item |problembuf|[|=true|\textbar|false|]
+(no value implies |true|, initially set to |false|) --
+enable/disable buffering for |problem| environments
+in order to control their display.
+
\end{itemize}
%
@@ -1533,12 +1675,16 @@
%
\begin{itemize}
\item
+Add a section on useful combinations of customisation settings
+to achieve specific goals. Please send suggestions.
+\item
Option to hide problem text while maintaining access to embedded solutions
-(for a version containing only solutions)
-or to postpone problems (for collecting them in an exercises section):
-this is difficult to implement because the problem block
-cannot simply be discarded, but must be scanned very carefully
-for the embedded solution.
+(for a version containing only solutions):
+this is difficult to implement because the problem environment
+cannot simply be discarded, but would have to be scanned very carefully
+for the embedded solution;
+instead process problems to some document and save solutions to file,
+then read solutions from different document.
\item
Define structures for multiple-choice questions.
\end{itemize}
@@ -1547,6 +1693,37 @@
\subsection{Revision History}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\paragraph{v3.3:} 2019/06/15
+
+\begin{itemize}
+\item
+control display of |problem| environments via
+package option |problembuf|:
+manual display, write to file, disable individual problems
+\item
+|solutionbelow| mode |here*| superseded by
+package option |solutionbuf|
+\item
+display total points within solution: |solutionpointsat|
+(thanks to Till Bargheer for suggestion)
+\item
+read points for current sheet, (sub)problem and solution
+(thanks to Johannes Hahn for suggestion)
+\item
+case switch for bonus points
+(thanks to Johannes Hahn for suggestion)
+\item
+option to |disable| particular problems,
+control by hook function
+(thanks to Manuel Benz for suggestion)
+\item
+provided interface |\showfracpoints| and |\exerciseconfig{frac}|
+for fractional points display
+\item
+filename extensions configurable
+\end{itemize}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\paragraph{v3.2:} 2019/05/01
\begin{itemize}
@@ -1555,7 +1732,7 @@
|points=|[\textit{regular}][|+|\textit{bonus}]
\item
|solutionbelow| mode |here*| added
-for direct processing of the solution block
+for direct processing of the solution environment
\item
multipart sample added
\end{itemize}
@@ -1569,10 +1746,11 @@
package \href{http://ctan.org/pkg/calc}{\textsf{calc}}
(thanks to Johannes Hahn for bug report)
\item
-fix style |fracpoints| in combination with some [|sub|]|pointsat| choices
+fix style |fracpoints| in combination
+with some [|sub|]|problempointsat| choices
(thanks to Johannes Hahn for bug report)
\item
-fix spacing for [|sub|]|pointsat=margin|
+fix spacing for [|sub|]|problempointsat=margin|
(thanks to Johannes Hahn for bug report)
\end{itemize}
@@ -1750,6 +1928,16 @@
\exerciseconfig{countersubproblemmax}{vii)}
% \end{macrocode}
+% Automatically display an asterisk for all
+% subproblems with bonus points only;
+% remove space to separate items:
+% \begin{macrocode}
+\exerciseconfig{insertsubprobleminfo}{%
+ \switchpoints{}{\addprobleminfo*{%
+ \hspace{-\getexerciseconfig{skipsubprobleminfo}}*}}%
+ {}{}{\getsubproblempoints{}}}
+% \end{macrocode}
+
% Redefine the terms to be used for sheet(s);
% here, a German version:
% \begin{macrocode}
@@ -1761,7 +1949,7 @@
% change margin display to use the left margin;
% use the abbreviated form `$n$p.':
% \begin{macrocode}
-\exercisestyle{pointsat=margin}
+\exercisestyle{problempointsat=margin}
\reversemarginpar
\exerciseconfig{composepointsmargin}[1]{#1p.}
\exerciseconfig{composepointspairmargin}[2]{
@@ -1854,7 +2042,7 @@
\end{equation}
% \end{macrocode}
-% Provide a solution for the subproblem (within the subproblem block):
+% Provide a solution for the subproblem (within the subproblem environment):
% \begin{macrocode}
\begin{solution}
The result is
@@ -2220,7 +2408,7 @@
% Number figures within sheet to provide a stable numbering
% upon insertion/deletion of new figures or partial compilation.
% Do not warn about unused figures when preparing without solutions
-% (figures for solutions should be declared outside |solution| blocks):
+% (figures for solutions should be declared outside |solution| environments):
% \begin{macrocode}
\mpostsetup{checksum}
\if\draftver y\mpostsetup{now,nowall}\fi
@@ -2620,7 +2808,7 @@
% Problem body without a figure;
% this time the |solution| environments are
-% included in the |subproblem| blocks:
+% included in the |subproblem| environments:
% \begin{macrocode}
\lorem
@@ -2674,7 +2862,7 @@
% allows to compile each problem individually.
%
% To that end, prepare a file |exfserp|\textit{nn}|.tex|
-% containing the problem block |\begin{problem}| \ldots |\end{problem}|.
+% containing the |problem| environment.
% This file should start with:
% \begin{macrocode}
%%\providecommand{\printsol}{n}
@@ -2995,7 +3183,7 @@
% The package loads the package
% \textsf{verbatim} and \textsf{xkeyval}
% if not yet present.
-% \textsf{verbatim} is used for solution block reading
+% \textsf{verbatim} is used for solution environment reading
% and \textsf{xkeyval} is used for extended options processing:
% \begin{macrocode}
\RequirePackage{verbatim}
@@ -3061,7 +3249,6 @@
{\def\exf at tmp{#2}\ifx#1\exf at tmp#3\fi}
% \end{macrocode}
-
% \macro{\exf at href}
% Display text with hyperreference passed by macro |#1|
% (in case \textsf{hyperref} is loaded
@@ -3167,6 +3354,15 @@
% \begin{macrocode}
\define at boolkey{exf at setup}[exf@]{warntext}[true]{}
% \end{macrocode}
+% Activate buffering of solutions:
+% \begin{macrocode}
+\define at boolkey{exf at setup}[exf@]{solutionbuf}[true]{}
+\exf at solutionbuftrue
+% \end{macrocode}
+% Activate buffering of problems:
+% \begin{macrocode}
+\define at boolkey{exf at setup}[exf@]{problembuf}[true]{}
+% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Processing.}
@@ -3298,6 +3494,10 @@
% \begin{macrocode}
\exerciseconfig{styletitlesolutions}{\normalsize}
% \end{macrocode}
+% Style for problem block title:
+% \begin{macrocode}
+\exerciseconfig{styletitleproblems}{\Large}
+% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Spacing.}
@@ -3364,21 +3564,38 @@
\exerciseconfig{skipsolutionitemsub}{0pt}
% \end{macrocode}
-% Spaces related to blocks of solutions;
+% Spaces related to solution blocks;
% space above and below a solution block:
% \begin{macrocode}
\exerciseconfig{skipsolutionsabove}{1.5ex plus 0.5ex minus 1ex}
\exerciseconfig{skipsolutionsbelow}{1.5ex plus 0.5ex minus 1ex}
% \end{macrocode}
-% Space following problem titles in a solution block:
+% Space above problem titles in a solution block:
% \begin{macrocode}
-\exerciseconfig{skipsolutionsproblem}{1.0ex plus 0ex minus 0.5ex}
+\exerciseconfig{skipsolutionsproblemabove}{1.0ex plus 0ex minus 0.5ex}
% \end{macrocode}
+% Space following problem titles in a solution block
+% (with legacy definition):
+% \begin{macrocode}
+\exerciseconfig{skipsolutionsproblemtitle}{1.0ex plus 0ex minus 0.5ex}
+\exerciseconfig{skipsolutionsproblem}{\exf at config@skipsolutionsproblemtitle}
+% \end{macrocode}
% Space following title of a solution block:
% \begin{macrocode}
\exerciseconfig{skipsolutionstitle}{1.0ex plus 0ex minus 0.5ex}
% \end{macrocode}
+% Spaces related to problem blocks;
+% space above and below a problem block:
+% \begin{macrocode}
+\exerciseconfig{skipproblemsabove}{1.5ex plus 0.5ex minus 1ex}
+\exerciseconfig{skipproblemsbelow}{1.5ex plus 0.5ex minus 1ex}
+% \end{macrocode}
+% Space following title of a problem block:
+% \begin{macrocode}
+\exerciseconfig{skipproblemstitle}{1.0ex plus 0ex minus 0.5ex}
+% \end{macrocode}
+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Hook Code.}
%
@@ -3410,6 +3627,14 @@
% \begin{macrocode}
\exerciseconfig{insertsolutionsafter}{}
% \end{macrocode}
+% Code to insert before a problem block is displayed:
+% \begin{macrocode}
+\exerciseconfig{insertproblemsbefore}{}
+% \end{macrocode}
+% Code to insert after a problem block is displayed:
+% \begin{macrocode}
+\exerciseconfig{insertproblemsafter}{}
+% \end{macrocode}
% Code to insert before a problem is displayed:
% \begin{macrocode}
\exerciseconfig{insertproblembefore}{}
@@ -3428,6 +3653,10 @@
% \begin{macrocode}
\exerciseconfig{insertprobleminfo}{}
% \end{macrocode}
+% Code to determine the display of problems:
+% \begin{macrocode}
+\exerciseconfig{insertproblemselect}[1]{}
+% \end{macrocode}
% Analogous definitions for subproblems:
% \begin{macrocode}
\exerciseconfig{insertsubproblembefore}{}
@@ -3546,11 +3775,21 @@
\exerciseconfig{composetitlesolutions}%
{\getexerciseconfig{termsolutions}}
% \end{macrocode}
+% Compose title for problem block:
+% \begin{macrocode}
+\exerciseconfig{composetitleproblems}%
+ {\getexerciseconfig{termproblems}}
+% \end{macrocode}
% Compose table of contents line for solution block:
% \begin{macrocode}
\exerciseconfig{composetocsolutions}%
{\getexerciseconfig{composetitlesolutions}}
% \end{macrocode}
+% Compose table of contents line for problem block:
+% \begin{macrocode}
+\exerciseconfig{composetocproblems}%
+ {\getexerciseconfig{composetitleproblems}}
+% \end{macrocode}
% Compose sectional title for solution following a single problem;
% arguments are problem number and raw title:
% \begin{macrocode}
@@ -3557,7 +3796,7 @@
\exerciseconfig{composetitlesolutionsproblemsingle}[2]%
{\getexerciseconfig{termsolution}}
% \end{macrocode}
-% Compose sectional title for solution of one problem within a block;
+% Compose sectional title for solution of one problem within a solution block;
% arguments are problem number and raw title:
% \begin{macrocode}
\exerciseconfig{composetitlesolutionsproblemmulti}[2]%
@@ -3647,6 +3886,21 @@
(\getexerciseconfig{composepointspair}{#1}{#2}*%
\exerciseifnotempty{#3}{; #3})\fi}
% \end{macrocode}
+% Compose pairs of points for designated situations:
+% \begin{macrocode}
+\exerciseconfig{composepointspairbodyproblem}[2]{%
+ \getexerciseconfig{composepointspairbody}{#1}{#2}}
+\exerciseconfig{composepointspairbodysubproblem}[2]{%
+ \getexerciseconfig{composepointspairbody}{#1}{#2}}
+\exerciseconfig{composepointspairbodysolution}[2]{%
+ \getexerciseconfig{composepointspairbody}{#1}{#2}}
+\exerciseconfig{composepointspairstartproblem}[2]{%
+ \getexerciseconfig{composepointspairstart}{#1}{#2}}
+\exerciseconfig{composepointspairstartsubproblem}[2]{%
+ \getexerciseconfig{composepointspairstart}{#1}{#2}}
+\exerciseconfig{composepointspairstartsolution}[2]{%
+ \getexerciseconfig{composepointspairstart}{#1}{#2}}
+% \end{macrocode}
% Display points in the margin:
% \begin{macrocode}
@@ -3682,7 +3936,8 @@
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Further Definitions.}
%
-% \macro{label...}
+% \macro{labelsheet}
+% \macro{labelproblem}
% Templates for automatic generation of labels from tags:
% \begin{macrocode}
\exerciseconfig{labelsheet}[1]{sheet:#1}
@@ -3696,10 +3951,19 @@
% \begin{macrocode}
\exerciseconfig{toclevelsheet}{}
\exerciseconfig{toclevelproblem}{}
+\exerciseconfig{toclevelproblems}{}
\exerciseconfig{toclevelsolution}{}
\exerciseconfig{toclevelsolutions}{}
% \end{macrocode}
+% \macro{extsolutions}
+% \macro{extproblems}
+% Filename extension for solution and problem blocks:
+% \begin{macrocode}
+\exerciseconfig{extsolutions}{.sol}
+\exerciseconfig{extproblems}{.prb}
+% \end{macrocode}
+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \subsection{Styles}
% \label{sec:imp-styles}
@@ -3741,13 +4005,20 @@
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Default Exercise Styles.}
%
+% \macro{problemmanual}
+% Delay display of problems:
+% \begin{macrocode}
+\define at boolkey{exf at style}[exf@]{problemmanual}[true]{}
+\exf at problemmanualfalse
+% \end{macrocode}
+%
% \macro{solutionbelow}
% Choose location for solutions:
% \begin{macrocode}
\def\exf at solutionbelow{subproblem}
\define at choicekey{exf at style}{solutionbelow}%
- {here,here*,subproblem,subproblem*,problem,problem*,sheet,manual}%
- {\ifexf at infile\else\def\exf at solutionbelow{#1}\fi}
+ {here,subproblem,subproblem*,problem,problem*,sheet,manual}%
+ {\ifexf at solfile@open\else\gdef\exf at solutionbelow{#1}\fi}
% \end{macrocode}
%
% \macro{sheetequation}
@@ -3761,16 +4032,26 @@
\exf at style@solutionequationtrue
% \end{macrocode}
%
-% \macro{pointsat}
-% \macro{subpointsat}
-% Choose where points of problems and subproblems are displayed:
+% \macro{problempointsat}
+% \macro{subproblempointsat}
+% \macro{solutionpointsat}
+% Choose where points of (sub)problems and solutions are displayed:
% \begin{macrocode}
\def\exf at pointsat{start}
+\define at choicekey{exf at style}{problempointsat}%
+ {start,start*,margin,end,manual,off}{\def\exf at pointsat{#1}}
\define at choicekey{exf at style}{pointsat}%
{start,start*,margin,end,manual,off}{\def\exf at pointsat{#1}}
\def\exf at subpointsat{end}
+\define at choicekey{exf at style}{subproblempointsat}%
+ {start,start*,margin,end,manual,off}{\def\exf at subpointsat{#1}}
\define at choicekey{exf at style}{subpointsat}%
{start,start*,margin,end,manual,off}{\def\exf at subpointsat{#1}}
+\def\exf at solpointsat{off}
+\define at choicekey{exf at style}{solutionpointsat}%
+ {start,start*,margin,end,manual,off}{\def\exf at solpointsat{#1}}
+\define at choicekey{exf at style}{solpointsat}%
+ {start,start*,margin,end,manual,off}{\def\exf at solpointsat{#1}}
% \end{macrocode}
%
% \macro{problemby}
@@ -3800,7 +4081,7 @@
% Use vulgar fractions to display binary fractional points:
% \begin{macrocode}
\defexercisestyle{fracpoints}%
- {\exerciseconfig{composepointsnum}[1]{\protect\exf at nicefrac{##1}}}
+ {\exerciseconfig{composepointsnum}[1]{\protect\showfracpoints{##1}}}
% \end{macrocode}
%
% \macro{twoside}
@@ -3843,7 +4124,8 @@
% \begin{macrocode}
\defexercisestyle{solutionsep}{%
\exerciseconfig{insertsolutionsbefore}{\hrule\nopagebreak[3]\vspace{0.5ex}}%
- \exerciseconfig{insertsolutionsafter}{\nopagebreak[3]\vspace{1.0ex}\hrule}}
+ \exerciseconfig{insertsolutionsafter}%
+ {\removelastskip\nopagebreak[3]\vspace{1.0ex}\hrule}}
% \end{macrocode}
% \macro{plainheader}
% Declare a simple sheet header with some configurable options;
@@ -3967,8 +4249,13 @@
\define at key{exf at sheet}{#1}%
{\exf at csdo\def{exf at data@sheet@#1}{##1}}}
% \end{macrocode}
+% \macro{\setsheetdata}
+% Set sheet metadata:
+% \begin{macrocode}
+\newcommand{\setsheetdata}[1]{\setkeys{exf at sheet}{#1}}
+% \end{macrocode}
% \macro{\getsheetdata}
-% Read global metadata:
+% Read sheet metadata:
% \begin{macrocode}
\newcommand{\getsheetdata}[1]{\csname exf at data@sheet@#1\endcsname}
% \end{macrocode}
@@ -4005,7 +4292,7 @@
% \paragraph{Problem Metadata.}
%
% \macro{\defproblemdata}
-% Declare sheet metadata field
+% Declare problem metadata field
% by defining a key \textit{key} in category |exf at problem|
% that stores the chosen value in |\exf at data@problem@|\textit{key}:
% \begin{macrocode}
@@ -4014,8 +4301,13 @@
\define at key{exf at problem}{#1}%
{\exf at csdo\def{exf at data@problem@#1}{##1}}}
% \end{macrocode}
+% \macro{\setproblemdata}
+% Set problem metadata:
+% \begin{macrocode}
+\newcommand{\setproblemdata}[1]{\setkeys{exf at problem,exf at scanproblem}{#1}}
+% \end{macrocode}
% \macro{\getproblemdata}
-% Read global metadata:
+% Read problem metadata:
% \begin{macrocode}
\newcommand{\getproblemdata}[1]{\csname exf at data@problem@#1\endcsname}
% \end{macrocode}
@@ -4035,10 +4327,10 @@
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \paragraph{Problem Block Code.}
+% \paragraph{Problem Environment Code.}
%
% \macro{\exf at addmargin}
-% Define a length for block margin:
+% Define a length for environment margin:
% \begin{macrocode}
\newlength\exf at addmargin
% \end{macrocode}
@@ -4080,7 +4372,7 @@
{\exf at prepend@def\exf at intro{#1\hspace{\exf at intro@skip}}}
% \end{macrocode}
% \macro{\exf at open@block}
-% Open block, set margin, compose opening line:
+% Open environment, set margin, compose opening line:
% \begin{macrocode}
\newcommand{\exf at open@block}[1]{%
\advance\leftskip\exf at addmargin%
@@ -4093,7 +4385,7 @@
\fi}%
% \end{macrocode}
% \macro{\exf at close@block}
-% Close block, undo margin:
+% Close environment, undo margin:
% \begin{macrocode}
\newcommand{\exf at close@block}{%
\advance\leftskip-\exf at addmargin%
@@ -4287,21 +4579,23 @@
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{File Output.}
%
-% \macro{\ifexf at infile}
-% Conditional whether an output file is presently in use:
+% \macro{\ifexf at solfile@open}
+% Conditional whether output files are presently in use:
% \begin{macrocode}
-\newif\ifexf at infile\exf at infilefalse
+\newif\ifexf at solfile@open\exf at solfile@openfalse
+\newif\ifexf at probfile@open\exf at probfile@openfalse
% \end{macrocode}
-% \macro{\exf at out}
-% Reserve file handle:
+% \macro{\exf at solfile}
+% Reserve file handles:
% \begin{macrocode}
-\newwrite\exf at out
+\newwrite\exf at solfile
+\newwrite\exf at probfile
% \end{macrocode}
% \macro{\exf at writeline}
% Write a line to the file:
% \begin{macrocode}
-\newcommand{\exf at writeline}[1]{\immediate\write\exf at out{#1}}
+\newcommand{\exf at writeline}[2]{\immediate\write#1{#2}}
% \end{macrocode}
% \macro{\exf at linesep}
@@ -4320,82 +4614,120 @@
l.\the\inputlineno}
% \end{macrocode}
-% \macro{\exf at startfile}
-% Open a new file |#1.sol| (do nothing if already open);
+% \macro{\exf at start@solfile}
+% Open a new solution file |#1.sol| (do nothing if already open);
% indicate source, switch to manual solution display mode:
% \begin{macrocode}
-\newcommand{\exf at startfile}[1]{%
- \ifexf at infile\else%
- \global\exf at infiletrue%
- \gdef\exf at solutionbelow{manual}%
+\newcommand{\exf at start@solfile}[1]{%
+ \ifexf at solfile@open\else%
+ \exercisestyle{solutionbelow=manual}%
+ \global\exf at solfile@opentrue%
\edef\exf at tmp{#1}%
- \immediate\openout\exf at out\exf at tmp.sol%
- \exf at writeline{\@percentchar%
+ \immediate\openout\exf at solfile\exf at tmp\exf at config@extsolutions\relax%
+ \exf at writeline\exf at solfile{\@percentchar%
generated from file `\jobname' by exframe.sty}%
- \ifexf at lineno\exf at writeline{\exf at lineno}\fi%
- \exf at writeline{}%
+ \ifexf at lineno\exf at writeline\exf at solfile{\exf at lineno}\fi%
+ \exf at writeline\exf at solfile{}%
\fi}
% \end{macrocode}
-% \macro{\exf at closefile}
-% Close file (if open);
+% \macro{\exf at close@solfile}
+% Close solution file (if open);
% indicate position, close and reset variables:
% \begin{macrocode}
-\newcommand{\exf at closefile}{%
- \ifexf at infile%
- \ifexf at lineno%
- \exf at writeline{\exf at linesep}\exf at writeline{\exf at lineno}\fi%
- \exf at writeline{\@backslashchar endinput}%
- \immediate\closeout\exf at out%
- \global\exf at infilefalse%
+\newcommand{\exf at close@solfile}{%
+ \ifexf at solfile@open%
+ \ifexf at lineno\exf at writeline\exf at solfile{\exf at linesep}%
+ \exf at writeline\exf at solfile{\exf at lineno}\fi%
+ \exf at writeline\exf at solfile{\@backslashchar endinput}%
+ \immediate\closeout\exf at solfile%
+ \global\exf at solfile@openfalse%
\fi}
% \end{macrocode}
-% Make sure to properly close file at the end:
+% \macro{\exf at start@probfile}
+% Open a new problem file |#1.prb| (do nothing if already open);
+% indicate source, switch to manual problem display mode:
% \begin{macrocode}
-\AtEndDocument{\exf at closefile}
+\newcommand{\exf at start@probfile}[1]{%
+ \ifexf at probfile@open\else%
+ \global\exf at probfile@opentrue%
+ \edef\exf at tmp{#1}%
+ \immediate\openout\exf at probfile\exf at tmp\exf at config@extproblems\relax%
+ \exf at writeline\exf at probfile{\@percentchar%
+ generated from file `\jobname' by exframe.sty}%
+ \ifexf at lineno\exf at writeline\exf at probfile{\exf at lineno}\fi%
+ \exf at writeline\exf at probfile{}%
+ \fi}
% \end{macrocode}
+% \macro{\exf at close@probfile}
+% Close problem file (if open);
+% indicate position, close and reset variables:
+% \begin{macrocode}
+\newcommand{\exf at close@probfile}{%
+ \ifexf at probfile@open%
+ \ifexf at lineno\exf at writeline\exf at probfile{\exf at linesep}%
+ \exf at writeline\exf at probfile{\exf at lineno}\fi%
+ \exf at writeline\exf at probfile{\@backslashchar endinput}%
+ \immediate\closeout\exf at probfile%
+ \global\exf at probfile@openfalse%
+ \fi}
+% \end{macrocode}
+
+% Make sure to properly close files at the end:
+% \begin{macrocode}
+\AtEndDocument{\exf at close@solfile\exf at close@probfile}
+% \end{macrocode}
+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \paragraph{Solution Buffer.}
+% \paragraph{Buffers.}
%
-% \macro{\exf at buf}
-% \macro{\ifexf at bufclean}
-% Declare a token buffer for storing the solutions
-% and a conditional indicating whether the buffer has been used:
+% \macro{\exf at solbuf}
+% \macro{\exf at probbuf}
+% \macro{\ifexf at solbuf@clean}
+% \macro{\ifexf at probbuf@clean}
+% Declare token buffers for storing problems and solutions
+% and conditionals indicating whether the buffers have been used:
% \begin{macrocode}
-\newtoks\exf at buf
-\newif\ifexf at bufclean\exf at bufcleantrue
+\newtoks\exf at solbuf
+\newtoks\exf at probbuf
+\newif\ifexf at solbuf@clean\exf at solbuf@cleantrue
+\newif\ifexf at probbuf@clean\exf at probbuf@cleantrue
% \end{macrocode}
-
-% \macro{\exf at clearbuf}
-% Clear solution buffer and mark clean:
+% \macro{\exf at clear@solbuf}
+% \macro{\exf at clear@probbuf}
+% Clear a buffer and mark clean:
% \begin{macrocode}
-\def\exf at clearbuf{\global\exf at bufcleantrue\global\exf at buf={}}
+\def\exf at clear@solbuf{\global\exf at solbuf@cleantrue\global\exf at solbuf={}}
+\def\exf at clear@probbuf{\global\exf at probbuf@cleantrue\global\exf at probbuf={}}
% \end{macrocode}
+
% \macro{\exf at append@buf}
% Append tokens to buffer:
% \begin{macrocode}
-\def\exf at append@buf#1{\global\exf at buf=\expandafter{\the\exf at buf#1}}
+\def\exf at append@buf#1#2{\global#1=\expandafter{\the#1#2}}
% \end{macrocode}
-% \macro{\exf at addbufline}
+% \macro{\exf at addline}
% Add a protected expanded line to the buffer:
% \begin{macrocode}
-\def\exf at addbufline#1{{\protected at edef\exf at tmp{#1}%
- \exf at exptwo\exf at append@buf{\exf at tmp^^J}}}
+\def\exf at addline#1#2{{\protected at edef\exf at tmp{#2}%
+ \exf at exparg{\exf at append@buf#1}{\exf at tmp^^J}}}
% \end{macrocode}
-
-% \macro{\exf at sourcebuf}
-% Source the solution buffer into the document:
+% \macro{\exf at source@buf}
+% Source a buffer into the document:
% \begin{macrocode}
-\def\exf at sourcebuf{\exf at exptwo\scantokens{\the\exf at buf}}
+\def\exf at source@buf#1{\exf at exptwo\scantokens{\the#1}}
% \end{macrocode}
-% \macro{\exf at writebuf}
+% \macro{\exf at write@buf}
% Write the buffer into the solution file:
% \begin{macrocode}
-\def\exf at writebuf{\exf at writeline{\the\exf at buf}}
+\def\exf at write@buf#1#2{\exf at writeline#1{\the#2}}
% \end{macrocode}
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \paragraph{Verbatim Processing.}
+%
% \macro{\exf at verbatim}
% Start reading the buffer from the environment body:
% \begin{macrocode}
@@ -4404,7 +4736,8 @@
\@bsphack%
\let\do\@makeother\dospecials%
\catcode`\^^M\active%
- \def\verbatim at processline{\exf at exptwo\exf at append@buf{\the\verbatim at line^^J}}%
+ \def\verbatim at processline{\exf at exptwo\exf at verbatim@process%
+ {\the\verbatim at line^^J}}%
\verbatim at start}
% \end{macrocode}
@@ -4415,8 +4748,8 @@
% \end{macrocode}
% \macro{\exf at scanblock}
-% Scan an optional argument from a verbatim block;
-% allow for an empty block and an empty first line;
+% Scan an optional argument from a verbatim environment;
+% allow for an empty environment and an empty first line;
% argument |#1| is macro to be called eventually:
% \begin{macrocode}
\def\exf at scanblock#1{%
@@ -4429,12 +4762,12 @@
% \begin{macrocode}
\long\def\exf at scanblock@par#1\par{\exf at scanblock@sel{#1}[]}
% \end{macrocode}
-% Check for optional argument (|[|) and for block ending (|\end|):
+% Check for optional argument (|[|) and for environment ending (|\end|):
% \begin{macrocode}
\def\exf at scanblock@sel#1{\@ifnextchar[{\exf at scanblock@opt{#1}}%
{\@ifnextchar\end{\exf at scanblock@end{#1}}{\exf at scanblock@noopt{#1}}}}
% \end{macrocode}
-% Handle empty block, hopefully environment matches (otherwise?!):
+% Handle empty environment, hopefully environment matches (otherwise?!):
% \begin{macrocode}
\def\exf at scanblock@end#1\end#2{%
\def\exf at tmp{#2}\ifx\exf at tmp\@currenvir%
@@ -4520,6 +4853,20 @@
\expandafter#1\exf at tmp}
% \end{macrocode}
+% \macro{\switchpoints}
+% Extract main (plain) and bonus (starred) part from points,
+% and execute one of three:
+% \begin{macrocode}
+\newcommand{\switchpoints}[5]{\edef\exf at tmp{#5}%
+ \exf at exptwo\exf at scanpoints\exf at tmp\exf at tmp++&%
+ \expandafter\exf at switchpoints\exf at tmp{#1}{#2}{#3}{#4}}
+\newcommand{\exf at switchpoints}[6]{%
+ \ifdim#2pt=0pt\ifdim#1pt=0pt\def\exf at tmp##1##2{#6}%
+ \else\def\exf at tmp##1##2{#3}\fi%
+ \else\ifdim#1pt=0pt\def\exf at tmp##1##2{#4}%
+ \else\def\exf at tmp##1##2{#5}\fi\fi\exf at tmp{#1}{#2}}
+% \end{macrocode}
+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Tools.}
%
@@ -4571,12 +4918,12 @@
\def\exf at splitdecimal#1.#2.#3&{\def\exf at splitint{#1}\def\exf at splitdec{#2}}
% \end{macrocode}
-% \macro{\exf at nicefrac}
+% \macro{\showfracpoints}
% Display a float number as a fraction
% with denominators 2, 4 or 8 when possible;
% first split number, complete missing zeros and handle cases:
% \begin{macrocode}
-\newcommand{\exf at nicefrac}[1]{%
+\newcommand{\showfracpoints}[1]{%
\edef\exf at tmp{#1}%
\expandafter\exf at splitsign\exf at tmp--&%
\expandafter\exf at splitdecimal\exf at splitnum..&%
@@ -4584,22 +4931,22 @@
\if&\exf at splitdec&\def\exf at splitdec{0}\fi%
\def\exf at tmp{\exf at splitint.\exf at splitdec}%
\ifnum\exf at splitdec=0\def\exf at tmp{\exf at splitint}\fi%
- \ifnum\exf at splitdec=5\def\exf at tmp{\exf at intfrac{\exf at splitint}{1}{2}}\fi%
- \ifnum\exf at splitdec=25\def\exf at tmp{\exf at intfrac{\exf at splitint}{1}{4}}\fi%
- \ifnum\exf at splitdec=75\def\exf at tmp{\exf at intfrac{\exf at splitint}{3}{4}}\fi%
- \ifnum\exf at splitdec=125\def\exf at tmp{\exf at intfrac{\exf at splitint}{1}{8}}\fi%
- \ifnum\exf at splitdec=375\def\exf at tmp{\exf at intfrac{\exf at splitint}{3}{8}}\fi%
- \ifnum\exf at splitdec=625\def\exf at tmp{\exf at intfrac{\exf at splitint}{5}{8}}\fi%
- \ifnum\exf at splitdec=875\def\exf at tmp{\exf at intfrac{\exf at splitint}{7}{8}}\fi%
+ \ifnum\exf at splitdec=5\def\exf at tmp{\exf at config@frac{\exf at splitint}{1}{2}}\fi%
+ \ifnum\exf at splitdec=25\def\exf at tmp{\exf at config@frac{\exf at splitint}{1}{4}}\fi%
+ \ifnum\exf at splitdec=75\def\exf at tmp{\exf at config@frac{\exf at splitint}{3}{4}}\fi%
+ \ifnum\exf at splitdec=125\def\exf at tmp{\exf at config@frac{\exf at splitint}{1}{8}}\fi%
+ \ifnum\exf at splitdec=375\def\exf at tmp{\exf at config@frac{\exf at splitint}{3}{8}}\fi%
+ \ifnum\exf at splitdec=625\def\exf at tmp{\exf at config@frac{\exf at splitint}{5}{8}}\fi%
+ \ifnum\exf at splitdec=875\def\exf at tmp{\exf at config@frac{\exf at splitint}{7}{8}}\fi%
\ifx\exf at splitminus\exf at empty\else$\exf at splitminus$\fi\exf at tmp%
}
% \end{macrocode}
-% \macro{\exf at intfrac}
+% \macro{\exf at config@frac}
% Display a vulgar fraction
% such as 12$^3\mskip-4mu/\mskip-2mu_4$:
% \begin{macrocode}
-\newcommand{\exf at intfrac}[3]{%
+\newcommand{\exf at config@frac}[3]{%
\ifnum#1=0\else#1\fi%
\ifnum#2=0\else$%
^{\exf at text{#2}}%
@@ -4629,10 +4976,13 @@
{\exf at formatpoints{#1}{#2}}}}
% \end{macrocode}
% \macro{\getsheetpoints}
-% Read sheet points stored in |.aux| file:
+% Read points for current sheet or from |.aux| file:
% \begin{macrocode}
-\newcommand{\getsheetpoints}[1]{\ifcsname exf at sheetpoints@#1\endcsname%
- \csname exf at sheetpoints@#1\endcsname\else 0\fi}
+\newcommand{\getsheetpoints}[1]{\if&%
+ \ifdefined\exf at sheet@points%
+ \expandafter\exf at formatpoints\exf at sheet@points\else 0\fi%
+ \else\ifcsname exf at sheetpoints@#1\endcsname%
+ \csname exf at sheetpoints@#1\endcsname\else 0\fi\fi}
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -4657,21 +5007,34 @@
{\exf at formatpoints{#1}{#2}}}}
% \end{macrocode}
% \macro{\getproblempoints}
-% Read problem points stored in |.aux| file:
+% Read points for current problem or from |.aux| file:
% \begin{macrocode}
-\newcommand{\getproblempoints}[1]{\ifcsname exf at problempoints@#1\endcsname%
- \csname exf at problempoints@#1\endcsname\else 0\fi}
+\newcommand{\getproblempoints}[1]{\if&%
+ \ifdefined\exf at problem@points%
+ \expandafter\exf at formatpoints\exf at problem@points\else 0\fi%
+ \else\ifcsname exf at problempoints@#1\endcsname%
+ \csname exf at problempoints@#1\endcsname\else 0\fi\fi}
% \end{macrocode}
+% \macro{\getsubproblempoints}
+% Read points for current subproblem:
+% \begin{macrocode}
+\newcommand{\getsubproblempoints}[1]{\if&%
+ \ifdefined\exf at subproblem@points%
+ \expandafter\exf at formatpoints\exf at subproblem@points\else 0\fi%
+ \else 0\fi}
+% \end{macrocode}
% \macro{\showpoints}
% Show points within a problem or subproblem:
% \begin{macrocode}
\newcommand{\showpoints}{%
- \ifdefined\exf at in@subproblem\exf at outpoints{\exf at ensuretext}%
- {\exf at config@composepointspairbody}{\exf at subproblem@points}%
+ \ifdefined\exf at in@solution\exf at outpoints{\exf at ensuretext}%
+ {\exf at config@composepointspairbodysolution}{\exf at solution@points at show}%
+ \else\ifdefined\exf at in@subproblem\exf at outpoints{\exf at ensuretext}%
+ {\exf at config@composepointspairbodysubproblem}{\exf at subproblem@points at show}%
\else\ifdefined\exf at in@problem\exf at outpoints{\exf at ensuretext}%
- {\exf at config@composepointspairbody}{\exf at problem@points at show}%
- \fi\fi}
+ {\exf at config@composepointspairbodyproblem}{\exf at problem@points at show}%
+ \fi\fi\fi}
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -4701,17 +5064,23 @@
\newcommand{\awardpoints}{\@ifstar\exf at awardpointsalt\exf at awardpointsreg}
% \end{macrocode}
+% \macro{\getsolutionpoints}
+% Read points for current solution:
+% \begin{macrocode}
+\newcommand{\getsolutionpoints}[1]{\if&%
+ \ifdefined\exf at solution@points%
+ \expandafter\exf at formatpoints\exf at solution@points\else 0\fi%
+ \else 0\fi}
+% \end{macrocode}
+
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \subsection{Environments}
-% \label{sec:imp-env}
+% \subsection{Sheet Environment}
+% \label{sec:imp-sheet}
%
-% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \paragraph{Sheets.}
-%
% \macro{exf at sheet}
% Define options for |sheet| environment:
% \begin{macrocode}
-\define at key{exf at sheet}{points}{\exf at scanpoints\exf at points@given#1++&}
+\define at key{exf at sheet}{points}{\exf at scanpoints\exf at sheet@points#1++&}
\define at key{exf at sheet}{number}{\setcounter{\exf at sheetcounter}{#1}}
\define at key{exf at sheet}{label}{\def\exf at label{#1}}
\define at key{exf at sheet}{tag}{\def\sheettag{#1}}
@@ -4738,7 +5107,7 @@
% \end{macrocode}
% Reset optional arguments, process arguments:
% \begin{macrocode}
- \let\exf at points@given\@undefined%
+ \let\exf at sheet@points\@undefined%
\def\sheettag{\csname the\exf at sheetcounter\endcsname}%
\let\exf at sheet@points at total\@undefined%
\let\exf at label\@undefined%
@@ -4751,12 +5120,13 @@
% \end{macrocode}
% Set points from explicit input or from |.aux| storage:
% \begin{macrocode}
- \let\exf at sheet@points\@undefined%
- \ifdefined\exf at points@given%
- \let\exf at sheet@points\exf at points@given%
- \else\ifcsname exf at sheetpoints@\sheettag\endcsname%
- \exf at csdotwo\let\exf at tmp{exf at sheetpoints@\sheettag}%
- \exf at exptwo\exf at scanpoints\exf at sheet@points\exf at tmp++&%
+ \ifdefined\exf at sheet@points%
+ \let\exf at sheet@points at given\exf at empty%
+ \else%
+ \let\exf at sheet@points at given\@undefined%
+ \ifcsname exf at sheetpoints@\sheettag\endcsname%
+ \exf at csdotwo\let\exf at tmp{exf at sheetpoints@\sheettag}%
+ \exf at exptwo\exf at scanpoints\exf at sheet@points\exf at tmp++&%
\fi\fi%
% \end{macrocode}
% Process metadata:
@@ -4782,7 +5152,7 @@
% End of environment;
% perform sanity check on total points if given explicitly:
% \begin{macrocode}
- {\ifdefined\exf at points@given%
+ {\ifdefined\exf at sheet@points at given%
\exf at warnmismatch{\exf at sheetname}{\exf at sheetcounter}%
{\exf at sheet@points at total}{\exf at sheet@points}%
% \end{macrocode}
@@ -4832,22 +5202,26 @@
\thispagestyle{empty}\hbox{}\newpage\fi\fi}
% \end{macrocode}
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Problem Environment}
+% \label{sec:imp-problem}
+%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \paragraph{Problems.}
+% \paragraph{Print Problems.}
%
% \macro{exf at problem}
% Define options for |problem| environment:
% \begin{macrocode}
-\define at key{exf at problem}{points}{\exf at scanpoints\exf at points@given#1++&}
+\define at key{exf at problem}{points}{\exf at scanpoints\exf at problem@points#1++&}
\define at key{exf at problem}{label}{\def\exf at label{#1}}
\define at key{exf at problem}{tag}{\def\problemtag{#1}}
\define at key{exf at problem}{sollabel}{\xdef\exf at sollabel{#1}}
% \end{macrocode}
-% \macro{problem}
-% Define |problem| environment (potentially using custom name):
+% \macro{printproblem}
+% Define |printproblem| environment:
% \begin{macrocode}
-\newenvironment{\exf at problemname}[1][]{%
+\newenvironment{printproblem}[1]{%
% \end{macrocode}
% Start with new paragraph, set text style, add vspace:
% \begin{macrocode}
@@ -4879,11 +5253,11 @@
% \begin{macrocode}
\exf at init@block{\exf at config@skipprobleminfo}%
\def\problemtag{\csname the\exf at problemcounter\endcsname}%
- \let\exf at points@given\@undefined%
+ \let\exf at problem@points\@undefined%
\let\exf at label\@undefined%
\global\let\exf at sollabel\@undefined%
\let\exf at problem@points at total\@undefined%
- \setkeys{exf at problem,exf at probleminfo}{#1}%
+ \setkeys{exf at problem,exf at probleminfo,exf at scanproblem}{#1}%
% \end{macrocode}
% Process automatic and manual labels:
% \begin{macrocode}
@@ -4908,12 +5282,13 @@
% \end{macrocode}
% Set points from explicit input or from |.aux| storage:
% \begin{macrocode}
- \let\exf at problem@points\@undefined%
- \ifdefined\exf at points@given%
- \let\exf at problem@points\exf at points@given%
- \else\ifcsname exf at problempoints@\problemtag\endcsname%
- \exf at csdotwo\let\exf at tmp{exf at problempoints@\problemtag}%
- \exf at exptwo\exf at scanpoints\exf at problem@points\exf at tmp++&%
+ \ifdefined\exf at problem@points%
+ \let\exf at problem@points at given\exf at empty%
+ \else%
+ \let\exf at problem@points at given\@undefined%
+ \ifcsname exf at problempoints@\problemtag\endcsname%
+ \exf at csdotwo\let\exf at tmp{exf at problempoints@\problemtag}%
+ \exf at exptwo\exf at scanpoints\exf at problem@points\exf at tmp++&%
\fi\fi%
\global\let\exf at prevpoints\exf at problem@points%
\let\exf at problem@points at show\@undefined%
@@ -4929,9 +5304,9 @@
% expand points into argument and remove points:
% \begin{macrocode}
\exf at ifis\exf at pointsat{start}{\exf at outpoints{\exf at append@intro}%
- {\exf at config@composepointspairstart}{\exf at problem@points at show}}%
+ {\exf at config@composepointspairstartproblem}{\exf at problem@points at show}}%
\exf at ifis\exf at pointsat{start*}{\exf at outpoints{\exf at prepend@intro}%
- {\exf at config@composepointspairstart}{\exf at problem@points at show}}%
+ {\exf at config@composepointspairstartproblem}{\exf at problem@points at show}}%
% \end{macrocode}
% Insert hook code, set problem body style:
% \begin{macrocode}
@@ -5001,7 +5376,7 @@
% \end{macrocode}
% Perform sanity checks on total points if given explicitly:
% \begin{macrocode}
- \ifdefined\exf at points@given%
+ \ifdefined\exf at problem@points at given%
\exf at warnmismatch{\exf at problemname}{\exf at problemcounter}%
{\exf at problem@points at total}{\exf at problem@points}%
% \end{macrocode}
@@ -5026,12 +5401,12 @@
\PackageWarning{exframe}{no points defined for \exf at problemname}%
\fi\fi%
% \end{macrocode}
-% Solutions to subproblems must be declared within problem block:
+% Solutions to subproblems must be declared within problem environment:
% \begin{macrocode}
\global\let\exf at prevsubprob\@undefined%
\global\let\exf at prevsubprobhref\@undefined%
% \end{macrocode}
-% End paragraph and block:
+% End paragraph and environment:
% \begin{macrocode}
\par\exf at close@block%
% \end{macrocode}
@@ -5068,8 +5443,209 @@
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \paragraph{Subproblems.}
+% \paragraph{Read Problem Environment.}
%
+% \macro{exf at scanproblem}
+% Define options for |problem| environment:
+% \begin{macrocode}
+\define at boolkey{exf at scanproblem}[exf at scanproblem@]{disable}[true]{}
+% \end{macrocode}
+
+% \macro{exf at problem@direct}
+% Define direct output version of |problem| environment;
+% pass on to |printproblem| environment:
+% \begin{macrocode}
+\newenvironment{exf at problem@direct}[1][]%
+ {\printproblem{#1}}{\endprintproblem\ignorespacesafterend}
+% \end{macrocode}
+
+% \macro{exf at problem@scan}
+% \macro{exf at scanproblem}
+% Define scan version of |problem| environment;
+% use |\exf at scanblock| to properly parse optional argument
+% and pass on to |exf at scanproblem|:
+% \begin{macrocode}
+\newenvironment{exf at problem@scan}%
+ {\exf at scanblock{\exf at scanproblem}}{\endexf at scanproblem}%
+\newenvironment{exf at scanproblem}[2]{%
+% \end{macrocode}
+% Determine problem display:
+% \begin{macrocode}
+ \exf at scanproblem@disablefalse%
+ \setkeys*{exf at scanproblem}{#1}%
+ \exf at config@insertproblemselect{#1}%
+% \end{macrocode}
+% Write separator and |printproblem| environment to buffer:
+% \begin{macrocode}
+ \ifexf at scanproblem@disable%
+ \def\exf at verbatim@process{\@gobble}%
+ \else%
+ \ifexf at lineno\exf at addline\exf at probbuf{\exf at linesep}%
+ \exf at addline\exf at probbuf{\exf at lineno}\fi%
+ \exf at addline\exf at probbuf%
+ {\@backslashchar begin{printproblem}{#1}}%
+ \def\exf at verbatim@process{\exf at append@buf\exf at probbuf}%
+ \fi%
+% \end{macrocode}
+% Start verbatim processing:
+% \begin{macrocode}
+ \exf at verbatim#2}%
+% \end{macrocode}
+% End verbatim processing; close |printproblem| environment:
+% \begin{macrocode}
+ {\exf at endverbatim%
+ \ifexf at scanproblem@disable\else%
+ \exf at addline\exf at probbuf{\@backslashchar end{printproblem}}%
+ \global\exf at probbuf@cleanfalse%
+ \fi%
+% \end{macrocode}
+% Write buffer to file if output file open:
+% \begin{macrocode}
+ \ifexf at probfile@open%
+ \exf at write@buf\exf at probfile\exf at probbuf%
+ \exf at clear@probbuf%
+ \fi%
+% \end{macrocode}
+% Output buffer immediately:
+% \begin{macrocode}
+ \ifexf at problemmanual\else%
+ \exf at source@buf\exf at probbuf%
+ \exf at clear@probbuf%
+ \fi%
+% \end{macrocode}
+% Done:
+% \begin{macrocode}
+ \ignorespacesafterend}
+% \end{macrocode}
+
+% \macro{problem}
+% Define |problem| environment
+% (potentially using custom name)
+% to choose between direct and buffered version:
+% \begin{macrocode}
+\newenvironment{\exf at problemname}%
+ {\ifexf at problembuf\let\exf at tmp\exf at problem@scan%
+ \else\let\exf at tmp\exf at problem@direct\fi%
+ \exf at tmp}%
+ {\ifexf at problembuf\let\exf at tmp\endexf at problem@scan%
+ \else\let\exf at tmp\endexf at problem@direct\fi%
+ \exf at tmp}
+% \end{macrocode}
+
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Problem Blocks}
+% \label{sec:imp-problems}
+%
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \paragraph{Problem Block Handling.}
+%
+% \macro{\exf at problemstitle}
+% Compose the title for a problem block section:
+% \begin{macrocode}
+\newcommand{\exf at problemstitle}{%
+% \end{macrocode}
+% Check whether title is empty:
+% \begin{macrocode}
+ \protected at edef\exf at problemstitleexp{\exf at config@composetitleproblems}%
+ \ifx\exf at problemstitleexp\exf at empty\else%
+% \end{macrocode}
+% Output section line:
+% \begin{macrocode}
+ \exf at section{\exf at config@skipproblemstitle}%
+ {\exf at config@styletitle\exf at config@styletitleproblems%
+ \exf at problemstitleexp}%
+ \exf at addcontentsline{\exf at config@toclevelproblems}%
+ {\exf at config@composetocproblems}%
+ \fi}
+% \end{macrocode}
+
+% \macro{\exf at showproblemsin}
+% Output problem block intro:
+% \begin{macrocode}
+\newcommand{\exf at showproblemsin}{%
+% \end{macrocode}
+% Set problem body style; add vertical space; insert hook code:
+% \begin{macrocode}
+ \par\exf at config@styletext\addvspace{\exf at config@skipproblemsabove}%
+ \exf at config@insertproblemsbefore}
+% \end{macrocode}
+
+% \macro{\exf at showproblemsout}
+% Output problem block outro:
+% \begin{macrocode}
+\newcommand{\exf at showproblemsout}{%
+% \end{macrocode}
+% Insert hook code; close paragraph; add vertical space:
+% \begin{macrocode}
+ \exf at config@insertproblemsafter%
+ \par\exf at config@styletext\addvspace{\exf at config@skipproblemsbelow}}
+% \end{macrocode}
+
+% \macro{\exf at showproblems}
+% Output problem block in buffer:
+% \begin{macrocode}
+\newcommand{\exf at showproblems}{%
+% \end{macrocode}
+% Do nothing if buffer is empty (avoid titles):
+% \begin{macrocode}
+ \ifexf at probbuf@clean\else\begingroup%
+% \end{macrocode}
+% Execute output problem block intro:
+% \begin{macrocode}
+ \exf at showproblemsin%
+ \exf at problemstitle%
+% \end{macrocode}
+% Source and clear buffer:
+% \begin{macrocode}
+ \exf at source@buf\exf at probbuf%
+ \exf at clear@probbuf%
+% \end{macrocode}
+% Execute output problem block outro:
+% \begin{macrocode}
+ \exf at showproblemsout%
+ \endgroup\fi}
+% \end{macrocode}
+
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \paragraph{Problems Buffer Interface.}
+%
+% \macro{\writeproblems}
+% Open a file |#1.prb| for writing problems;
+% default is present main file name:
+% \begin{macrocode}
+\newcommand{\writeproblems}[1][\jobname]{%
+ \exf at close@probfile\exf at start@probfile{#1}}
+% \end{macrocode}
+
+% \macro{\closeproblems}
+% Close problems output file (if open):
+% \begin{macrocode}
+\newcommand{\closeproblems}{\exf at close@probfile}
+% \end{macrocode}
+
+% \macro{\readproblems}
+% Read problems from file |#1.prb|;
+% default is present main file name;
+% switch layout and add heading:
+% \begin{macrocode}
+\newcommand{\readproblems}[1][\jobname]{\exf at close@probfile%
+ \begingroup%
+ \exf at config@styletext\exf at config@styletextproblem%
+ \exf at problemstitle%
+ \input{#1\exf at config@extproblems}%
+ \endgroup}
+% \end{macrocode}
+
+% \macro{\insertproblems}
+% Show problems buffer:
+% \begin{macrocode}
+\newcommand{\insertproblems}{\exf at showproblems}
+% \end{macrocode}
+
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Subproblem Environment}
+% \label{sec:imp-subproblem}
+%
% \macro{exf at subproblem}
% Define options for |subproblem| environment:
% \begin{macrocode}
@@ -5115,6 +5691,14 @@
\csname theH\exf at subproblemcounter\endcsname}%
\fi%
% \end{macrocode}
+% Remeber points for display;
+% disable points display if desired:
+% \begin{macrocode}
+ \let\exf at subproblem@points at show\@undefined%
+ \ifdefined\exf at subproblem@points%
+ \let\exf at subproblem@points at show\exf at subproblem@points\fi%
+ \exf at ifis\exf at subpointsat{off}{\let\exf at subproblem@points at show\@undefined}%
+% \end{macrocode}
% Add given points to problem total:
% \begin{macrocode}
\ifdefined\exf at subproblem@points%
@@ -5129,17 +5713,13 @@
\fi%
\fi%
% \end{macrocode}
-% Disable points display if desired:
-% \begin{macrocode}
- \exf at ifis\exf at subpointsat{off}{\let\exf at subproblem@points\@undefined}%
-% \end{macrocode}
% Display points in opening line if desired;
% expand points into argument and remove points:
% \begin{macrocode}
\exf at ifis\exf at subpointsat{start}{\exf at outpoints{\exf at append@intro}%
- {\exf at config@composepointspairstart}{\exf at subproblem@points}}%
+ {\exf at config@composepointspairstartsubproblem}{\exf at subproblem@points at show}}%
\exf at ifis\exf at subpointsat{start*}{\exf at outpoints{\exf at prepend@intro}%
- {\exf at config@composepointspairstart}{\exf at subproblem@points}}%
+ {\exf at config@composepointspairstartsubproblem}{\exf at subproblem@points at show}}%
% \end{macrocode}
% Insert hook code:
% \begin{macrocode}
@@ -5179,7 +5759,7 @@
% \begin{macrocode}
\exf at ifis\exf at subpointsat{margin}{%
\exf at outpoints{\exf at prepend@def\exf at introitem}%
- {\exf at makepointsmargin}{\exf at subproblem@points}}%
+ {\exf at makepointsmargin}{\exf at subproblem@points at show}}%
% \end{macrocode}
% Write out opening line:
% \begin{macrocode}
@@ -5193,7 +5773,7 @@
% \begin{macrocode}
{\exf at ifis\exf at subpointsat{end}{\showpoints}%
% \end{macrocode}
-% End paragraph and block:
+% End paragraph and environment:
% \begin{macrocode}
\par\exf at close@block%
% \end{macrocode}
@@ -5222,6 +5802,10 @@
\ignorespacesafterend}
% \end{macrocode}
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Solution Environment}
+% \label{sec:imp-solution}
+%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Print Solutions.}
%
@@ -5240,7 +5824,7 @@
% \macro{printsolution}
% Define |printsolution| environment
-% to display a previously read |solution| block;
+% to display a previously read |solution| environment;
% this works analogously to |problem| and |subproblem|:
% \begin{macrocode}
\newenvironment{printsolution}[1]{%
@@ -5262,12 +5846,14 @@
\let\theHequation\theHexf at solutionequation%
\fi%
% \end{macrocode}
-% Start a block, initialise variables, process arguments:
+% Start a group, initialise variables, process arguments:
% \begin{macrocode}
\begingroup%
+ \def\exf at in@solution{}%
\def\exf at solprob{}%
\def\exf at solsubprob{}%
\let\exf at label\@undefined%
+ \let\exf at solution@points\@undefined%
\let\exf at solution@points at total\@undefined%
\def\exf at solhref{}%
\exf at init@block{\exf at config@skipsolutioninfo}%
@@ -5283,6 +5869,22 @@
% \begin{macrocode}
\ifdefined\exf at label\label{\exf at label}\fi%
% \end{macrocode}
+% Remeber points for display;
+% disable points display if desired:
+% \begin{macrocode}
+ \let\exf at solution@points at show\@undefined%
+ \ifdefined\exf at solution@points%
+ \let\exf at solution@points at show\exf at solution@points\fi%
+ \exf at ifis\exf at solpointsat{off}{\let\exf at solution@points at show\@undefined}%
+% \end{macrocode}
+% Display points in opening line if desired;
+% expand points into argument and remove points:
+% \begin{macrocode}
+ \exf at ifis\exf at solpointsat{start}{\exf at outpoints{\exf at append@intro}%
+ {\exf at config@composepointspairstartsolution}{\exf at solution@points at show}}%
+ \exf at ifis\exf at solpointsat{start*}{\exf at outpoints{\exf at prepend@intro}%
+ {\exf at config@composepointspairstartsolution}{\exf at solution@points at show}}%
+% \end{macrocode}
% Insert hook code, set solution body style:
% \begin{macrocode}
\exf at config@insertsolutioninfo%
@@ -5325,7 +5927,7 @@
\fi\exf at config@composeitemsolutionsep}%
\fi%
% \end{macrocode}
-% Set item label up depending on problem or subproblem:
+% Set item label depending on problem or subproblem:
% \begin{macrocode}
\ifx\exf at solsubprob\exf at empty%
\protected at edef\exf at solution@item%
@@ -5344,6 +5946,13 @@
\exf at config@composeitemproblemsep}}%
\fi%
% \end{macrocode}
+% Write points into margin if desired;
+% expand points into argument and remove points:
+% \begin{macrocode}
+ \exf at ifis\exf at solpointsat{margin}{%
+ \exf at outpoints{\exf at prepend@def\exf at introitem}%
+ {\exf at makepointsmargin}{\exf at solution@points at show}}%
+% \end{macrocode}
% Write out opening line:
% \begin{macrocode}
\exf at open@block{\exf at config@skipsolutiontitle}%
@@ -5354,10 +5963,11 @@
% \end{macrocode}
% End environment, show points if desired, perform sanity check:
% \begin{macrocode}
- {\exf at warnmismatch{\exf at solutionname}{\exf at solutioncounter}%
+ {\exf at ifis\exf at solpointsat{end}{\showpoints}%
+ \exf at warnmismatch{\exf at solutionname}{\exf at solutioncounter}%
{\exf at solution@points at total}{\exf at solution@points}%
% \end{macrocode}
-% End paragraph and block:
+% End paragraph and envionment:
% \begin{macrocode}
\par\exf at close@block%
% \end{macrocode}
@@ -5383,7 +5993,7 @@
% \end{macrocode}
% \macro{\solutionssection}
-% Define a section for a problem within a block with multiple solutions:
+% Define a section for a problem within a solution block:
% \begin{macrocode}
\newcommand{\solutionssection}[1]{\begingroup%
% \end{macrocode}
@@ -5397,56 +6007,34 @@
\setkeys{exf at solution}{#1}%
% \end{macrocode}
% Select title (and table of contents entry)
-% corresponding to multiple problems vs. single problem:
+% corresponding to multiple problems vs.\ single problem:
% \begin{macrocode}
\let\exf at composetitle\exf at config@composetitlesolutionsproblemmulti%
- \def\exf at solutionstoc{\exf at addcontentsline{\exf at config@toclevelsolution}%
- {\exf at config@composetocsolution{\exf at solprob}{\exf at solprobtitle}}}%
\exf at ifis\exf at solutionbelow{problem}{\let\exf at composetitle%
\exf at config@composetitlesolutionsproblemsingle}%
\exf at ifis\exf at solutionbelow{problem*}{\let\exf at composetitle%
\exf at config@composetitlesolutionsproblemsingle}%
+ \def\exf at solutionstoc{\exf at addcontentsline{\exf at config@toclevelsolution}%
+ {\exf at config@composetocsolution{\exf at solprob}{\exf at solprobtitle}}}%
% \end{macrocode}
% Write section line:
% \begin{macrocode}
+ \addvspace{\exf at config@skipsolutionsproblemabove}%
\exf at solutionssection{\exf at config@styletitlesolutionsproblem}%
{\exf at composetitle{\exf at solprob}{\exf at solprobtitle}}%
- {\exf at config@skipsolutionsproblem}%
+ {\exf at config@skipsolutionsproblemtitle}%
{\exf at solutionstoc}{\exf at label}{\exf at solhref}%
\endgroup}
% \end{macrocode}
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \paragraph{Read Solution Block to Buffer.}
+% \paragraph{Read Solution Environment.}
%
-% \macro{solution}
-% Define |solution| environment (potentially using custom name);
-% pass to |exf at scansolution| environment via
-% |\exf at scanblock| mechanism;
-% redefine |\exf at scanblock| in |solutionbelow=here*| mode:
-% \begin{macrocode}
-\newenvironment{\exf at solutionname}%
- {\exf at ifis\exf at solutionbelow{here*}{%
- \newcommand{\exf at scanblockplain}[1][]{\exf at scansolution{##1}{}}%
- \def\exf at scanblock##1{\exf at scanblockplain}}%
- \exf at scanblock{\exf at scansolution}}{\endexf at scansolution}%
-% \end{macrocode}
-
-% \macro{exf at scansolution}
-% Define |exf at scansolution| to read solution to buffer and process:
-% \begin{macrocode}
-\newenvironment{exf at scansolution}[2]{%
-% \end{macrocode}
-% If solution is to be displayed immediately,
-% make sure to display points first:
-% \begin{macrocode}
- \exf at ifis\exf at solutionbelow{here}{\showpoints}%
- \exf at ifis\exf at solutionbelow{here*}{\showpoints}%
- \global\exf at bufcleanfalse%
-% \end{macrocode}
+% \macro{\exf at process@solnewsec}
% If this is the first solution within a new section,
-% display section heading:
+% write section heading to buffer:
% \begin{macrocode}
+\newcommand{\exf at process@solnewsec}{%
\ifdefined\exf at problem@solnewsec%
\def\exf at probarg{\ifdefined\exf at prevprob prob={\exf at prevprob}\fi%
\ifdefined\exf at prevprobtitle,probtitle={\exf at prevprobtitle}\fi%
@@ -5453,25 +6041,24 @@
\ifdefined\exf at prevprobhref,href={\exf at prevprobhref}\fi%
\ifdefined\exf at sollabel,label={\exf at sollabel}\fi}%
\exf at ifis\exf at solutionbelow{here}{\let\exf at probarg\@undefined}%
- \exf at ifis\exf at solutionbelow{here*}{\let\exf at probarg\@undefined}%
\exf at ifis\exf at solutionbelow{subproblem}{\let\exf at probarg\@undefined}%
\exf at ifis\exf at solutionbelow{subproblem*}{\let\exf at probarg\@undefined}%
\ifdefined\exf at probarg%
- \ifexf at lineno\exf at addbufline{\exf at linesep}\exf at addbufline{\exf at lineno}\fi%
- \exf at addbufline{\@backslashchar solutionssection{\exf at probarg}}%
- \exf at addbufline{}%
+ \ifexf at lineno\exf at addline\exf at solbuf{\exf at linesep}%
+ \exf at addline\exf at solbuf{\exf at lineno}\fi%
+ \exf at addline\exf at solbuf{\@backslashchar solutionssection{\exf at probarg}}%
+ \exf at addline\exf at solbuf{}%
\fi%
\global\let\exf at problem@solnewsec\@undefined%
- \fi%
+ \fi}%
% \end{macrocode}
-% Write separator to buffer:
-% \begin{macrocode}
- \ifexf at lineno\exf at addbufline{\exf at linesep}\exf at addbufline{\exf at lineno}\fi%
-% \end{macrocode}
+
+% \macro{\exf at process@solnewsec}
% Declare additional arguments to |printsolution|
% to describe corresponding problem and tags:
% \begin{macrocode}
- \def\exf at subprobarg{%
+\newcommand{\exf at generate@solprobarg}{%
+ \edef\exf at solprobarg{%
\ifdefined\exf at prevprob prob={\exf at prevprob},\fi%
\ifdefined\exf at prevsubprob subprob={\exf at prevsubprob},%
\ifdefined\exf at prevsubprobhref href={\exf at prevsubprobhref},\fi%
@@ -5483,48 +6070,76 @@
\ifdefined\sheettag sheettag={\sheettag},\fi%
\ifdefined\problemtag problemtag={\problemtag},\fi}%
% \end{macrocode}
-% Write |printsolution| opening to buffer:
-% \begin{macrocode}
- \exf at addbufline{\@backslashchar begin{printsolution}{\exf at subprobarg#1}}%
-% \end{macrocode}
% Clean up:
% \begin{macrocode}
\global\let\exf at prevsubprob\@undefined%
\global\let\exf at prevsubprobhref\@undefined%
- \global\let\exf at prevpoints\@undefined%
+ \global\let\exf at prevpoints\@undefined}%
% \end{macrocode}
-% In |here*| mode, output solution immediately;
-% overwrite verbatim macros to display solution:
+
+% \macro{exf at solution@direct}
+% Define direct output version of |solution| environment;
+% pass on to |printsolution| environment:
% \begin{macrocode}
- \exf at ifis\exf at solutionbelow{here*}{%
- \def\exf at verbatim{\exf at clearbuf\begingroup%
- \edef\exf at subprobarg{\exf at subprobarg}%
- \exf at showsolutionsin{\exf at config@composetitlesolutionsingle}%
- \exf at exptwo\printsolution{\exf at subprobarg#1}}%
- \def\exf at endverbatim{\endprintsolution\exf at showsolutionsout\endgroup}}%
+\newenvironment{exf at solution@direct}[1][]%
+ {\showpoints%
+ \global\let\exf at problem@solnewsec\@undefined%
+ \exf at generate@solprobarg%
+ \exf at showsolutionsin%
+ \let\exf at composetitle\exf at config@composetitlesolutionsingle%
+ \exf at exptwo\printsolution{\exf at solprobarg#1}}%
+ {\endprintsolution%
+ \exf at showsolutionsout%
+ \ignorespacesafterend}%
% \end{macrocode}
-% Verbatim read block to buffer:
+
+% \macro{exf at solution@scan}
+% \macro{exf at scansolution}
+% Define scan version of |solution| environment;
+% use |\exf at scanblock| to properly parse optional argument
+% and pass on to |exf at scansolution|:
% \begin{macrocode}
+\newenvironment{exf at solution@scan}%
+ {\exf at scanblock{\exf at scansolution}}{\endexf at scansolution}%
+\newenvironment{exf at scansolution}[2]{%
+% \end{macrocode}
+% If solution is to be displayed immediately,
+% make sure to display points first;
+% insert solution section heading in buffer;
+% compose additional arguments to |printsolution|:
+% \begin{macrocode}
+ \exf at ifis\exf at solutionbelow{here}{\showpoints}%
+ \exf at process@solnewsec%
+ \exf at generate@solprobarg%
+% \end{macrocode}
+% Write separator and |printsolution| environment to buffer:
+% \begin{macrocode}
+ \ifexf at lineno\exf at addline\exf at solbuf{\exf at linesep}%
+ \exf at addline\exf at solbuf{\exf at lineno}\fi%
+ \exf at addline\exf at solbuf%
+ {\@backslashchar begin{printsolution}{\exf at solprobarg#1}}%
+% \end{macrocode}
+% Start verbatim processing:
+% \begin{macrocode}
+ \def\exf at verbatim@process{\exf at append@buf\exf at solbuf}%
\exf at verbatim#2}%
% \end{macrocode}
-% End environment; stop reading buffer:
+% End verbatim processing; close |printsolution| environment:
% \begin{macrocode}
{\exf at endverbatim%
+ \exf at addline\exf at solbuf{\@backslashchar end{printsolution}}%
+ \global\exf at solbuf@cleanfalse%
% \end{macrocode}
-% Write |printsolution| closing to buffer:
-% \begin{macrocode}
- \exf at addbufline{\@backslashchar end{printsolution}}%
-% \end{macrocode}
% Write buffer to file if output file open:
% \begin{macrocode}
- \ifexf at infile%
- \exf at writebuf%
- \exf at clearbuf%
+ \ifexf at solfile@open%
+ \exf at write@buf\exf at solfile\exf at solbuf%
+ \exf at clear@solbuf%
\fi%
% \end{macrocode}
% Drop buffer if solutions not to be displayed:
% \begin{macrocode}
- \ifsolutions\else\exf at clearbuf\fi%
+ \ifsolutions\else\exf at clear@solbuf\fi%
% \end{macrocode}
% Display solution immediately in various cases:
% \begin{macrocode}
@@ -5546,11 +6161,29 @@
\ignorespacesafterend}
% \end{macrocode}
+% \macro{solution}
+% Define |solution| environment
+% (potentially using custom name)
+% to choose between direct and buffered version:
+% \begin{macrocode}
+\newenvironment{\exf at solutionname}%
+ {\ifexf at solutionbuf\let\exf at tmp\exf at solution@scan%
+ \else\let\exf at tmp\exf at solution@direct\fi%
+ \exf at tmp}%
+ {\ifexf at solutionbuf\let\exf at tmp\endexf at solution@scan%
+ \else\let\exf at tmp\endexf at solution@direct\fi%
+ \exf at tmp}
+% \end{macrocode}
+
+% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \subsection{Solution Blocks}
+% \label{sec:imp-solutions}
+%
% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \paragraph{Solution Block Handling.}
%
% \macro{\exf at solutionssection}
-% Output solutions section:
+% Output solution block section:
% \begin{macrocode}
\newcommand{\exf at solutionssection}[6]{%
% \end{macrocode}
@@ -5576,7 +6209,7 @@
% \end{macrocode}
% \macro{\exf at solutionstitle}
-% Compose the title for a solution section:
+% Compose the title for a solution block:
% \begin{macrocode}
\newcommand{\exf at solutionstitle}{\exf at solutionssection%
{\exf at config@styletitlesolutions}{%
@@ -5586,51 +6219,49 @@
% \end{macrocode}
% \macro{\exf at showsolutionsin}
-% Output solutions intro:
+% Output solution block intro:
% \begin{macrocode}
-\newcommand{\exf at showsolutionsin}[1]{%
+\newcommand{\exf at showsolutionsin}{%
% \end{macrocode}
% Set solution body style; add vertical space; insert hook code:
% \begin{macrocode}
\par\exf at config@styletext\addvspace{\exf at config@skipsolutionsabove}%
\exf at config@styletextsolution%
- \exf at config@insertsolutionsbefore%
- \let\exf at composetitle#1}
+ \exf at config@insertsolutionsbefore}
% \end{macrocode}
% \macro{\exf at showsolutionsout}
-% Output solutions outro:
+% Output solution block outro:
% \begin{macrocode}
\newcommand{\exf at showsolutionsout}{%
% \end{macrocode}
-% Ignore most recent skip; insert hook code;
-% close paragraph; add vertical space:
+% Insert hook code; close paragraph; add vertical space:
% \begin{macrocode}
- \removelastskip%
\exf at config@insertsolutionsafter%
- \par\exf at config@styletext\addvspace{\exf at config@skipsolutionbelow}}
+ \par\exf at config@styletext\addvspace{\exf at config@skipsolutionsbelow}}
% \end{macrocode}
% \macro{\exf at showsolutions}
-% Output solutions in buffer:
+% Output solution block in buffer:
% \begin{macrocode}
\newcommand{\exf at showsolutions}[2]{%
% \end{macrocode}
% Do nothing if buffer is empty (avoid titles):
% \begin{macrocode}
- \ifexf at bufclean\else\begingroup%
+ \ifexf at solbuf@clean\else\begingroup%
% \end{macrocode}
-% Execute output solutions intro:
+% Execute output solution block intro:
% \begin{macrocode}
- \exf at showsolutionsin{#1}%
+ \exf at showsolutionsin%
+ \let\exf at composetitle#1%
#2%
% \end{macrocode}
% Source and clear buffer:
% \begin{macrocode}
- \exf at sourcebuf%
- \exf at clearbuf%
+ \exf at source@buf\exf at solbuf%
+ \exf at clear@solbuf%
% \end{macrocode}
-% Execute output solutions outro:
+% Execute output solution block outro:
% \begin{macrocode}
\exf at showsolutionsout%
\endgroup\fi}
@@ -5643,13 +6274,14 @@
% Open a file |#1.sol| for writing solutions;
% default is present main file name:
% \begin{macrocode}
-\newcommand{\writesolutions}[1][\jobname]{\exf at closefile\exf at startfile{#1}}
+\newcommand{\writesolutions}[1][\jobname]{%
+ \exf at close@solfile\exf at start@solfile{#1}}
% \end{macrocode}
% \macro{\closesolutions}
-% Close output file (if open):
+% Close solutions output file (if open):
% \begin{macrocode}
-\newcommand{\closesolutions}{\exf at closefile}
+\newcommand{\closesolutions}{\exf at close@solfile}
% \end{macrocode}
% \macro{\readsolutions}
@@ -5657,17 +6289,17 @@
% default is present main file name;
% switch layout and add heading:
% \begin{macrocode}
-\newcommand{\readsolutions}[1][\jobname]{\exf at closefile%
+\newcommand{\readsolutions}[1][\jobname]{\exf at close@solfile%
\ifsolutions\begingroup%
\exf at config@styletext\exf at config@styletextsolution%
- \let\exf at config@composetitlesolution\exf at config@composetitlesolutionmulti%
+ \let\exf at composetitle\exf at config@composetitlesolutionmulti%
\exf at solutionstitle%
- \input{#1.sol}%
+ \input{#1\exf at config@extsolutions}%
\endgroup\fi}
% \end{macrocode}
% \macro{\insertsolutions}
-% Show solution buffer:
+% Show solutions buffer:
% \begin{macrocode}
\newcommand{\insertsolutions}{\exf at showsolutions%
{\exf at config@composetitlesolutionmulti}{\exf at solutionstitle}}
Modified: trunk/Master/texmf-dist/tex/latex/exframe/exframe.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/exframe/exframe.sty 2019-06-16 22:04:20 UTC (rev 51387)
+++ trunk/Master/texmf-dist/tex/latex/exframe/exframe.sty 2019-06-16 22:04:41 UTC (rev 51388)
@@ -17,7 +17,7 @@
%% version 2005/12/01 or later.
%%
\NeedsTeXFormat{LaTeX2e}[1996/12/01]
-\ProvidesPackage{exframe}[2019/05/01 v3.2 Framework for Exercise Problems]
+\ProvidesPackage{exframe}[2019/06/15 v3.3 Framework for Exercise Problems]
\RequirePackage{verbatim}
\RequirePackage{xkeyval}
@@ -83,6 +83,9 @@
\define at boolkey{exf at setup}[exf@]{autolabelsheet}[true]{}
\define at boolkey{exf at setup}[exf@]{autolabelproblem}[true]{}
\define at boolkey{exf at setup}[exf@]{warntext}[true]{}
+\define at boolkey{exf at setup}[exf@]{solutionbuf}[true]{}
+\exf at solutionbuftrue
+\define at boolkey{exf at setup}[exf@]{problembuf}[true]{}
\ProcessOptionsX<exframe.sty,exf at setup>
@@ -123,6 +126,7 @@
\exerciseconfig{styletitlesolution}{}
\exerciseconfig{styletitlesolutionsproblem}{\small}
\exerciseconfig{styletitlesolutions}{\normalsize}
+\exerciseconfig{styletitleproblems}{\Large}
\exerciseconfig{skipproblemabove}{3.25ex plus 1ex minus 1.5ex}
\exerciseconfig{skipproblembelow}{3pt plus 1pt minus 1pt}
@@ -145,9 +149,15 @@
\exerciseconfig{skipsolutionsabove}{1.5ex plus 0.5ex minus 1ex}
\exerciseconfig{skipsolutionsbelow}{1.5ex plus 0.5ex minus 1ex}
-\exerciseconfig{skipsolutionsproblem}{1.0ex plus 0ex minus 0.5ex}
+\exerciseconfig{skipsolutionsproblemabove}{1.0ex plus 0ex minus 0.5ex}
+\exerciseconfig{skipsolutionsproblemtitle}{1.0ex plus 0ex minus 0.5ex}
+\exerciseconfig{skipsolutionsproblem}{\exf at config@skipsolutionsproblemtitle}
\exerciseconfig{skipsolutionstitle}{1.0ex plus 0ex minus 0.5ex}
+\exerciseconfig{skipproblemsabove}{1.5ex plus 0.5ex minus 1ex}
+\exerciseconfig{skipproblemsbelow}{1.5ex plus 0.5ex minus 1ex}
+\exerciseconfig{skipproblemstitle}{1.0ex plus 0ex minus 0.5ex}
+
\exerciseconfig{insertsheettitle}{\centerline{\getsheetdata{title}}}
\exerciseconfig{insertsheetclearpage}{\exercisecleardoublepage}
\exerciseconfig{insertsheetbefore}{}
@@ -154,10 +164,13 @@
\exerciseconfig{insertsheetafter}{}
\exerciseconfig{insertsolutionsbefore}{}
\exerciseconfig{insertsolutionsafter}{}
+\exerciseconfig{insertproblemsbefore}{}
+\exerciseconfig{insertproblemsafter}{}
\exerciseconfig{insertproblembefore}{}
\exerciseconfig{insertproblemafter}{}
\exerciseconfig{insertproblemsolution}{}
\exerciseconfig{insertprobleminfo}{}
+\exerciseconfig{insertproblemselect}[1]{}
\exerciseconfig{insertsubproblembefore}{}
\exerciseconfig{insertsubproblemafter}{}
\exerciseconfig{insertsubprobleminfo}{}
@@ -198,8 +211,12 @@
{\getexerciseconfig{composetocproblem}{#1}{#2}}
\exerciseconfig{composetitlesolutions}%
{\getexerciseconfig{termsolutions}}
+\exerciseconfig{composetitleproblems}%
+ {\getexerciseconfig{termproblems}}
\exerciseconfig{composetocsolutions}%
{\getexerciseconfig{composetitlesolutions}}
+\exerciseconfig{composetocproblems}%
+ {\getexerciseconfig{composetitleproblems}}
\exerciseconfig{composetitlesolutionsproblemsingle}[2]%
{\getexerciseconfig{termsolution}}
\exerciseconfig{composetitlesolutionsproblemmulti}[2]%
@@ -250,6 +267,18 @@
\ifdim#2pt=0pt\getexerciseconfig{composepointsawardalt}{#1}{#3}\else%
(\getexerciseconfig{composepointspair}{#1}{#2}*%
\exerciseifnotempty{#3}{; #3})\fi}
+\exerciseconfig{composepointspairbodyproblem}[2]{%
+ \getexerciseconfig{composepointspairbody}{#1}{#2}}
+\exerciseconfig{composepointspairbodysubproblem}[2]{%
+ \getexerciseconfig{composepointspairbody}{#1}{#2}}
+\exerciseconfig{composepointspairbodysolution}[2]{%
+ \getexerciseconfig{composepointspairbody}{#1}{#2}}
+\exerciseconfig{composepointspairstartproblem}[2]{%
+ \getexerciseconfig{composepointspairstart}{#1}{#2}}
+\exerciseconfig{composepointspairstartsubproblem}[2]{%
+ \getexerciseconfig{composepointspairstart}{#1}{#2}}
+\exerciseconfig{composepointspairstartsolution}[2]{%
+ \getexerciseconfig{composepointspairstart}{#1}{#2}}
\exerciseconfig{insertpointsmargin}[1]{\marginpar{\footnotesize #1}}
@@ -272,9 +301,13 @@
\exerciseconfig{toclevelsheet}{}
\exerciseconfig{toclevelproblem}{}
+\exerciseconfig{toclevelproblems}{}
\exerciseconfig{toclevelsolution}{}
\exerciseconfig{toclevelsolutions}{}
+\exerciseconfig{extsolutions}{.sol}
+\exerciseconfig{extproblems}{.prb}
+
\newcommand{\defexercisestylearg}[3][]{%
\def\exf at tmp{#1}\ifx\exf at tmp\exf at empty%
\define at key{exf at style}{#2}{#3}\else%
@@ -285,20 +318,31 @@
{\csname ifexf at style@#1\endcsname\csname exf at style@code@#1\endcsname\fi}}
\newcommand{\exercisestyle}[1]{\exf at expsetkeys{exf at style}{#1}}
+\define at boolkey{exf at style}[exf@]{problemmanual}[true]{}
+\exf at problemmanualfalse
\def\exf at solutionbelow{subproblem}
\define at choicekey{exf at style}{solutionbelow}%
- {here,here*,subproblem,subproblem*,problem,problem*,sheet,manual}%
- {\ifexf at infile\else\def\exf at solutionbelow{#1}\fi}
+ {here,subproblem,subproblem*,problem,problem*,sheet,manual}%
+ {\ifexf at solfile@open\else\gdef\exf at solutionbelow{#1}\fi}
\defexercisestyle{sheetequation}{}
\defexercisestyle{problemequation}{}
\defexercisestyle{solutionequation}{}
\exf at style@solutionequationtrue
\def\exf at pointsat{start}
+\define at choicekey{exf at style}{problempointsat}%
+ {start,start*,margin,end,manual,off}{\def\exf at pointsat{#1}}
\define at choicekey{exf at style}{pointsat}%
{start,start*,margin,end,manual,off}{\def\exf at pointsat{#1}}
\def\exf at subpointsat{end}
+\define at choicekey{exf at style}{subproblempointsat}%
+ {start,start*,margin,end,manual,off}{\def\exf at subpointsat{#1}}
\define at choicekey{exf at style}{subpointsat}%
{start,start*,margin,end,manual,off}{\def\exf at subpointsat{#1}}
+\def\exf at solpointsat{off}
+\define at choicekey{exf at style}{solutionpointsat}%
+ {start,start*,margin,end,manual,off}{\def\exf at solpointsat{#1}}
+\define at choicekey{exf at style}{solpointsat}%
+ {start,start*,margin,end,manual,off}{\def\exf at solpointsat{#1}}
\defexercisestylearg{problemby}{\exf at numberproblemwithin{#1}}
\defexercisestylearg{equationby}{\exf at numberequationwithin{#1}}
\defexercisestyle{pagebysheet}{%
@@ -310,7 +354,7 @@
\defexercisestyle{equationbysheet}%
{\exf at numberequationwithin{\exf at sheetcounter}}
\defexercisestyle{fracpoints}%
- {\exerciseconfig{composepointsnum}[1]{\protect\exf at nicefrac{##1}}}
+ {\exerciseconfig{composepointsnum}[1]{\protect\showfracpoints{##1}}}
\defexercisestylearg[true]{twoside}{\exercisesetup{twoside={#1}}}
\ifexf at extstyle
@@ -325,7 +369,8 @@
\exerciseconfigappend{styletextproblem}{\color[gray]{0.2}}}
\defexercisestyle{solutionsep}{%
\exerciseconfig{insertsolutionsbefore}{\hrule\nopagebreak[3]\vspace{0.5ex}}%
- \exerciseconfig{insertsolutionsafter}{\nopagebreak[3]\vspace{1.0ex}\hrule}}
+ \exerciseconfig{insertsolutionsafter}%
+ {\removelastskip\nopagebreak[3]\vspace{1.0ex}\hrule}}
\defexercisestyle{plainheader}{%
\exerciseconfig{styleheadertitle}{\Large\bfseries}%
\exerciseconfig{styleheadercourse}{\sffamily}%
@@ -386,6 +431,7 @@
\exf at csdo\def{exf at data@sheet@#1}{}%
\define at key{exf at sheet}{#1}%
{\exf at csdo\def{exf at data@sheet@#1}{##1}}}
+\newcommand{\setsheetdata}[1]{\setkeys{exf at sheet}{#1}}
\newcommand{\getsheetdata}[1]{\csname exf at data@sheet@#1\endcsname}
\newcommand{\sheetdataempty}[3]{\exf at csdo\ifx{exf at data@sheet@#1}\exf at empty%
#2\else#3\fi}
@@ -407,6 +453,7 @@
\exf at csdo\def{exf at data@problem@#1}{}%
\define at key{exf at problem}{#1}%
{\exf at csdo\def{exf at data@problem@#1}{##1}}}
+\newcommand{\setproblemdata}[1]{\setkeys{exf at problem,exf at scanproblem}{#1}}
\newcommand{\getproblemdata}[1]{\csname exf at data@problem@#1\endcsname}
\newcommand{\problemdataempty}[3]{\exf at csdo\ifx{exf at data@problem@#1}\exf at empty%
#2\else#3\fi}
@@ -544,10 +591,12 @@
\def\theHexf at solutionequation%
{\csname theH#1\endcsname.sol.\arabic{equation}}}
-\newif\ifexf at infile\exf at infilefalse
-\newwrite\exf at out
+\newif\ifexf at solfile@open\exf at solfile@openfalse
+\newif\ifexf at probfile@open\exf at probfile@openfalse
+\newwrite\exf at solfile
+\newwrite\exf at probfile
-\newcommand{\exf at writeline}[1]{\immediate\write\exf at out{#1}}
+\newcommand{\exf at writeline}[2]{\immediate\write#1{#2}}
\newcommand{\exf at linesep}%
{\@percentchar---------------------------------------}
@@ -555,46 +604,69 @@
\ifdefined\currfilename\currfilename\space\fi%
l.\the\inputlineno}
-\newcommand{\exf at startfile}[1]{%
- \ifexf at infile\else%
- \global\exf at infiletrue%
- \gdef\exf at solutionbelow{manual}%
+\newcommand{\exf at start@solfile}[1]{%
+ \ifexf at solfile@open\else%
+ \exercisestyle{solutionbelow=manual}%
+ \global\exf at solfile@opentrue%
\edef\exf at tmp{#1}%
- \immediate\openout\exf at out\exf at tmp.sol%
- \exf at writeline{\@percentchar%
+ \immediate\openout\exf at solfile\exf at tmp\exf at config@extsolutions\relax%
+ \exf at writeline\exf at solfile{\@percentchar%
generated from file `\jobname' by exframe.sty}%
- \ifexf at lineno\exf at writeline{\exf at lineno}\fi%
- \exf at writeline{}%
+ \ifexf at lineno\exf at writeline\exf at solfile{\exf at lineno}\fi%
+ \exf at writeline\exf at solfile{}%
\fi}
-\newcommand{\exf at closefile}{%
- \ifexf at infile%
- \ifexf at lineno%
- \exf at writeline{\exf at linesep}\exf at writeline{\exf at lineno}\fi%
- \exf at writeline{\@backslashchar endinput}%
- \immediate\closeout\exf at out%
- \global\exf at infilefalse%
+\newcommand{\exf at close@solfile}{%
+ \ifexf at solfile@open%
+ \ifexf at lineno\exf at writeline\exf at solfile{\exf at linesep}%
+ \exf at writeline\exf at solfile{\exf at lineno}\fi%
+ \exf at writeline\exf at solfile{\@backslashchar endinput}%
+ \immediate\closeout\exf at solfile%
+ \global\exf at solfile@openfalse%
\fi}
-\AtEndDocument{\exf at closefile}
+\newcommand{\exf at start@probfile}[1]{%
+ \ifexf at probfile@open\else%
+ \global\exf at probfile@opentrue%
+ \edef\exf at tmp{#1}%
+ \immediate\openout\exf at probfile\exf at tmp\exf at config@extproblems\relax%
+ \exf at writeline\exf at probfile{\@percentchar%
+ generated from file `\jobname' by exframe.sty}%
+ \ifexf at lineno\exf at writeline\exf at probfile{\exf at lineno}\fi%
+ \exf at writeline\exf at probfile{}%
+ \fi}
-\newtoks\exf at buf
-\newif\ifexf at bufclean\exf at bufcleantrue
+\newcommand{\exf at close@probfile}{%
+ \ifexf at probfile@open%
+ \ifexf at lineno\exf at writeline\exf at probfile{\exf at linesep}%
+ \exf at writeline\exf at probfile{\exf at lineno}\fi%
+ \exf at writeline\exf at probfile{\@backslashchar endinput}%
+ \immediate\closeout\exf at probfile%
+ \global\exf at probfile@openfalse%
+ \fi}
-\def\exf at clearbuf{\global\exf at bufcleantrue\global\exf at buf={}}
-\def\exf at append@buf#1{\global\exf at buf=\expandafter{\the\exf at buf#1}}
-\def\exf at addbufline#1{{\protected at edef\exf at tmp{#1}%
- \exf at exptwo\exf at append@buf{\exf at tmp^^J}}}
+\AtEndDocument{\exf at close@solfile\exf at close@probfile}
-\def\exf at sourcebuf{\exf at exptwo\scantokens{\the\exf at buf}}
-\def\exf at writebuf{\exf at writeline{\the\exf at buf}}
+\newtoks\exf at solbuf
+\newtoks\exf at probbuf
+\newif\ifexf at solbuf@clean\exf at solbuf@cleantrue
+\newif\ifexf at probbuf@clean\exf at probbuf@cleantrue
+\def\exf at clear@solbuf{\global\exf at solbuf@cleantrue\global\exf at solbuf={}}
+\def\exf at clear@probbuf{\global\exf at probbuf@cleantrue\global\exf at probbuf={}}
+\def\exf at append@buf#1#2{\global#1=\expandafter{\the#1#2}}
+\def\exf at addline#1#2{{\protected at edef\exf at tmp{#2}%
+ \exf at exparg{\exf at append@buf#1}{\exf at tmp^^J}}}
+\def\exf at source@buf#1{\exf at exptwo\scantokens{\the#1}}
+\def\exf at write@buf#1#2{\exf at writeline#1{\the#2}}
+
\newcommand{\exf at verbatim}{%
\begingroup%
\@bsphack%
\let\do\@makeother\dospecials%
\catcode`\^^M\active%
- \def\verbatim at processline{\exf at exptwo\exf at append@buf{\the\verbatim at line^^J}}%
+ \def\verbatim at processline{\exf at exptwo\exf at verbatim@process%
+ {\the\verbatim at line^^J}}%
\verbatim at start}
\newcommand{\exf at endverbatim}{\@esphack\endgroup}
@@ -645,6 +717,15 @@
\exf at exptwo\exf at scanpoints\exf at tmp\exf at tmp++&%
\expandafter#1\exf at tmp}
+\newcommand{\switchpoints}[5]{\edef\exf at tmp{#5}%
+ \exf at exptwo\exf at scanpoints\exf at tmp\exf at tmp++&%
+ \expandafter\exf at switchpoints\exf at tmp{#1}{#2}{#3}{#4}}
+\newcommand{\exf at switchpoints}[6]{%
+ \ifdim#2pt=0pt\ifdim#1pt=0pt\def\exf at tmp##1##2{#6}%
+ \else\def\exf at tmp##1##2{#3}\fi%
+ \else\ifdim#1pt=0pt\def\exf at tmp##1##2{#4}%
+ \else\def\exf at tmp##1##2{#5}\fi\fi\exf at tmp{#1}{#2}}
+
\newcommand{\exf at makepointsmargin}[2]{%
\exf at config@insertpointsmargin{\exf at config@composepointspairmargin{#1}{#2}}}
@@ -670,7 +751,7 @@
\def\exf at splitsign#1-#2-#3&{\def\exf at splitnum{#1#2}\def\exf at splitminus{#3}}
\def\exf at splitdecimal#1.#2.#3&{\def\exf at splitint{#1}\def\exf at splitdec{#2}}
-\newcommand{\exf at nicefrac}[1]{%
+\newcommand{\showfracpoints}[1]{%
\edef\exf at tmp{#1}%
\expandafter\exf at splitsign\exf at tmp--&%
\expandafter\exf at splitdecimal\exf at splitnum..&%
@@ -678,17 +759,17 @@
\if&\exf at splitdec&\def\exf at splitdec{0}\fi%
\def\exf at tmp{\exf at splitint.\exf at splitdec}%
\ifnum\exf at splitdec=0\def\exf at tmp{\exf at splitint}\fi%
- \ifnum\exf at splitdec=5\def\exf at tmp{\exf at intfrac{\exf at splitint}{1}{2}}\fi%
- \ifnum\exf at splitdec=25\def\exf at tmp{\exf at intfrac{\exf at splitint}{1}{4}}\fi%
- \ifnum\exf at splitdec=75\def\exf at tmp{\exf at intfrac{\exf at splitint}{3}{4}}\fi%
- \ifnum\exf at splitdec=125\def\exf at tmp{\exf at intfrac{\exf at splitint}{1}{8}}\fi%
- \ifnum\exf at splitdec=375\def\exf at tmp{\exf at intfrac{\exf at splitint}{3}{8}}\fi%
- \ifnum\exf at splitdec=625\def\exf at tmp{\exf at intfrac{\exf at splitint}{5}{8}}\fi%
- \ifnum\exf at splitdec=875\def\exf at tmp{\exf at intfrac{\exf at splitint}{7}{8}}\fi%
+ \ifnum\exf at splitdec=5\def\exf at tmp{\exf at config@frac{\exf at splitint}{1}{2}}\fi%
+ \ifnum\exf at splitdec=25\def\exf at tmp{\exf at config@frac{\exf at splitint}{1}{4}}\fi%
+ \ifnum\exf at splitdec=75\def\exf at tmp{\exf at config@frac{\exf at splitint}{3}{4}}\fi%
+ \ifnum\exf at splitdec=125\def\exf at tmp{\exf at config@frac{\exf at splitint}{1}{8}}\fi%
+ \ifnum\exf at splitdec=375\def\exf at tmp{\exf at config@frac{\exf at splitint}{3}{8}}\fi%
+ \ifnum\exf at splitdec=625\def\exf at tmp{\exf at config@frac{\exf at splitint}{5}{8}}\fi%
+ \ifnum\exf at splitdec=875\def\exf at tmp{\exf at config@frac{\exf at splitint}{7}{8}}\fi%
\ifx\exf at splitminus\exf at empty\else$\exf at splitminus$\fi\exf at tmp%
}
-\newcommand{\exf at intfrac}[3]{%
+\newcommand{\exf at config@frac}[3]{%
\ifnum#1=0\else#1\fi%
\ifnum#2=0\else$%
^{\exf at text{#2}}%
@@ -702,8 +783,11 @@
\newcommand{\exf at writesheetpoints}[2]%
{\immediate\write\@auxout{\string\exf at notesheetpoints{\sheettag}%
{\exf at formatpoints{#1}{#2}}}}
-\newcommand{\getsheetpoints}[1]{\ifcsname exf at sheetpoints@#1\endcsname%
- \csname exf at sheetpoints@#1\endcsname\else 0\fi}
+\newcommand{\getsheetpoints}[1]{\if&%
+ \ifdefined\exf at sheet@points%
+ \expandafter\exf at formatpoints\exf at sheet@points\else 0\fi%
+ \else\ifcsname exf at sheetpoints@#1\endcsname%
+ \csname exf at sheetpoints@#1\endcsname\else 0\fi\fi}
\newcommand{\exf at noteproblempoints}[2]{%
\exf at csdo\gdef{exf at problempoints@#1}{#2}}
@@ -712,15 +796,24 @@
\newcommand{\exf at writeproblempoints}[2]%
{\immediate\write\@auxout{\string\exf at noteproblempoints{\problemtag}%
{\exf at formatpoints{#1}{#2}}}}
-\newcommand{\getproblempoints}[1]{\ifcsname exf at problempoints@#1\endcsname%
- \csname exf at problempoints@#1\endcsname\else 0\fi}
+\newcommand{\getproblempoints}[1]{\if&%
+ \ifdefined\exf at problem@points%
+ \expandafter\exf at formatpoints\exf at problem@points\else 0\fi%
+ \else\ifcsname exf at problempoints@#1\endcsname%
+ \csname exf at problempoints@#1\endcsname\else 0\fi\fi}
+\newcommand{\getsubproblempoints}[1]{\if&%
+ \ifdefined\exf at subproblem@points%
+ \expandafter\exf at formatpoints\exf at subproblem@points\else 0\fi%
+ \else 0\fi}
\newcommand{\showpoints}{%
- \ifdefined\exf at in@subproblem\exf at outpoints{\exf at ensuretext}%
- {\exf at config@composepointspairbody}{\exf at subproblem@points}%
+ \ifdefined\exf at in@solution\exf at outpoints{\exf at ensuretext}%
+ {\exf at config@composepointspairbodysolution}{\exf at solution@points at show}%
+ \else\ifdefined\exf at in@subproblem\exf at outpoints{\exf at ensuretext}%
+ {\exf at config@composepointspairbodysubproblem}{\exf at subproblem@points at show}%
\else\ifdefined\exf at in@problem\exf at outpoints{\exf at ensuretext}%
- {\exf at config@composepointspairbody}{\exf at problem@points at show}%
- \fi\fi}
+ {\exf at config@composepointspairbodyproblem}{\exf at problem@points at show}%
+ \fi\fi\fi}
\newcommand{\exf at awardpointsalt}[2][]{\exf at scanpoints\exf at tmp#2++&%
\exf at exptwo\exf at ensuretext{%
@@ -732,7 +825,12 @@
\expandafter\exf at config@composepointspairaward\exf at tmp{#1}}}
\newcommand{\awardpoints}{\@ifstar\exf at awardpointsalt\exf at awardpointsreg}
-\define at key{exf at sheet}{points}{\exf at scanpoints\exf at points@given#1++&}
+\newcommand{\getsolutionpoints}[1]{\if&%
+ \ifdefined\exf at solution@points%
+ \expandafter\exf at formatpoints\exf at solution@points\else 0\fi%
+ \else 0\fi}
+
+\define at key{exf at sheet}{points}{\exf at scanpoints\exf at sheet@points#1++&}
\define at key{exf at sheet}{number}{\setcounter{\exf at sheetcounter}{#1}}
\define at key{exf at sheet}{label}{\def\exf at label{#1}}
\define at key{exf at sheet}{tag}{\def\sheettag{#1}}
@@ -746,7 +844,7 @@
\let\theequation\theexf at sheetequation%
\let\theHequation\theHexf at sheetequation%
\fi%
- \let\exf at points@given\@undefined%
+ \let\exf at sheet@points\@undefined%
\def\sheettag{\csname the\exf at sheetcounter\endcsname}%
\let\exf at sheet@points at total\@undefined%
\let\exf at label\@undefined%
@@ -753,12 +851,13 @@
\setkeys{exf at sheet}{#1}%
\ifexf at autolabelsheet\label{\exf at config@labelsheet{\sheettag}}\fi%
\ifdefined\exf at label\label{\exf at label}\fi%
- \let\exf at sheet@points\@undefined%
- \ifdefined\exf at points@given%
- \let\exf at sheet@points\exf at points@given%
- \else\ifcsname exf at sheetpoints@\sheettag\endcsname%
- \exf at csdotwo\let\exf at tmp{exf at sheetpoints@\sheettag}%
- \exf at exptwo\exf at scanpoints\exf at sheet@points\exf at tmp++&%
+ \ifdefined\exf at sheet@points%
+ \let\exf at sheet@points at given\exf at empty%
+ \else%
+ \let\exf at sheet@points at given\@undefined%
+ \ifcsname exf at sheetpoints@\sheettag\endcsname%
+ \exf at csdotwo\let\exf at tmp{exf at sheetpoints@\sheettag}%
+ \exf at exptwo\exf at scanpoints\exf at sheet@points\exf at tmp++&%
\fi\fi%
\exf at ifis\exf at metadata{sheet}{\exf at writemetadata{sheet}}%
\exf at config@insertsheetbefore%
@@ -768,7 +867,7 @@
{\exf at config@composetocsheet{\csname the\exf at sheetcounter\endcsname}%
{\exf at data@sheet at rawtitle}}%
\exf at config@insertsheettitle}%
- {\ifdefined\exf at points@given%
+ {\ifdefined\exf at sheet@points at given%
\exf at warnmismatch{\exf at sheetname}{\exf at sheetcounter}%
{\exf at sheet@points at total}{\exf at sheet@points}%
\else%
@@ -792,12 +891,12 @@
\clearpage\ifexf at twoside\ifodd\value{page}\else%
\thispagestyle{empty}\hbox{}\newpage\fi\fi}
-\define at key{exf at problem}{points}{\exf at scanpoints\exf at points@given#1++&}
+\define at key{exf at problem}{points}{\exf at scanpoints\exf at problem@points#1++&}
\define at key{exf at problem}{label}{\def\exf at label{#1}}
\define at key{exf at problem}{tag}{\def\problemtag{#1}}
\define at key{exf at problem}{sollabel}{\xdef\exf at sollabel{#1}}
-\newenvironment{\exf at problemname}[1][]{%
+\newenvironment{printproblem}[1]{%
\par\exf at config@styletext\addvspace{\exf at config@skipproblemabove}%
\refstepcounter{\exf at problemcounter}%
\exf at config@insertproblembefore%
@@ -811,11 +910,11 @@
\fi%
\exf at init@block{\exf at config@skipprobleminfo}%
\def\problemtag{\csname the\exf at problemcounter\endcsname}%
- \let\exf at points@given\@undefined%
+ \let\exf at problem@points\@undefined%
\let\exf at label\@undefined%
\global\let\exf at sollabel\@undefined%
\let\exf at problem@points at total\@undefined%
- \setkeys{exf at problem,exf at probleminfo}{#1}%
+ \setkeys{exf at problem,exf at probleminfo,exf at scanproblem}{#1}%
\ifexf at autolabelproblem\label{\exf at config@labelproblem{\problemtag}}\fi%
\ifdefined\exf at label\label{\exf at label}\fi%
\gdef\exf at problem@solnewsec{}%
@@ -831,12 +930,13 @@
\fi%
\global\let\exf at prevsubprob\@undefined%
\global\let\exf at prevsubprobhref\@undefined%
- \let\exf at problem@points\@undefined%
- \ifdefined\exf at points@given%
- \let\exf at problem@points\exf at points@given%
- \else\ifcsname exf at problempoints@\problemtag\endcsname%
- \exf at csdotwo\let\exf at tmp{exf at problempoints@\problemtag}%
- \exf at exptwo\exf at scanpoints\exf at problem@points\exf at tmp++&%
+ \ifdefined\exf at problem@points%
+ \let\exf at problem@points at given\exf at empty%
+ \else%
+ \let\exf at problem@points at given\@undefined%
+ \ifcsname exf at problempoints@\problemtag\endcsname%
+ \exf at csdotwo\let\exf at tmp{exf at problempoints@\problemtag}%
+ \exf at exptwo\exf at scanpoints\exf at problem@points\exf at tmp++&%
\fi\fi%
\global\let\exf at prevpoints\exf at problem@points%
\let\exf at problem@points at show\@undefined%
@@ -845,9 +945,9 @@
\fi%
\exf at ifis\exf at pointsat{off}{\let\exf at problem@points at show\@undefined}%
\exf at ifis\exf at pointsat{start}{\exf at outpoints{\exf at append@intro}%
- {\exf at config@composepointspairstart}{\exf at problem@points at show}}%
+ {\exf at config@composepointspairstartproblem}{\exf at problem@points at show}}%
\exf at ifis\exf at pointsat{start*}{\exf at outpoints{\exf at prepend@intro}%
- {\exf at config@composepointspairstart}{\exf at problem@points at show}}%
+ {\exf at config@composepointspairstartproblem}{\exf at problem@points at show}}%
\exf at config@insertprobleminfo%
\exf at config@styletextproblem%
\ifdim\exf at config@skipproblemitem=0pt%
@@ -883,7 +983,7 @@
{\exf at data@problem at rawtitle}}%
\@afterindentfalse}%
{\exf at ifis\exf at pointsat{end}{\showpoints}%
- \ifdefined\exf at points@given%
+ \ifdefined\exf at problem@points at given%
\exf at warnmismatch{\exf at problemname}{\exf at problemcounter}%
{\exf at problem@points at total}{\exf at problem@points}%
\else%
@@ -915,6 +1015,91 @@
\exf at showsolutions{\exf at config@composetitlesolutionmulti}{}}%
\ignorespacesafterend}
+\define at boolkey{exf at scanproblem}[exf at scanproblem@]{disable}[true]{}
+
+\newenvironment{exf at problem@direct}[1][]%
+ {\printproblem{#1}}{\endprintproblem\ignorespacesafterend}
+
+\newenvironment{exf at problem@scan}%
+ {\exf at scanblock{\exf at scanproblem}}{\endexf at scanproblem}%
+\newenvironment{exf at scanproblem}[2]{%
+ \exf at scanproblem@disablefalse%
+ \setkeys*{exf at scanproblem}{#1}%
+ \exf at config@insertproblemselect{#1}%
+ \ifexf at scanproblem@disable%
+ \def\exf at verbatim@process{\@gobble}%
+ \else%
+ \ifexf at lineno\exf at addline\exf at probbuf{\exf at linesep}%
+ \exf at addline\exf at probbuf{\exf at lineno}\fi%
+ \exf at addline\exf at probbuf%
+ {\@backslashchar begin{printproblem}{#1}}%
+ \def\exf at verbatim@process{\exf at append@buf\exf at probbuf}%
+ \fi%
+ \exf at verbatim#2}%
+ {\exf at endverbatim%
+ \ifexf at scanproblem@disable\else%
+ \exf at addline\exf at probbuf{\@backslashchar end{printproblem}}%
+ \global\exf at probbuf@cleanfalse%
+ \fi%
+ \ifexf at probfile@open%
+ \exf at write@buf\exf at probfile\exf at probbuf%
+ \exf at clear@probbuf%
+ \fi%
+ \ifexf at problemmanual\else%
+ \exf at source@buf\exf at probbuf%
+ \exf at clear@probbuf%
+ \fi%
+ \ignorespacesafterend}
+
+\newenvironment{\exf at problemname}%
+ {\ifexf at problembuf\let\exf at tmp\exf at problem@scan%
+ \else\let\exf at tmp\exf at problem@direct\fi%
+ \exf at tmp}%
+ {\ifexf at problembuf\let\exf at tmp\endexf at problem@scan%
+ \else\let\exf at tmp\endexf at problem@direct\fi%
+ \exf at tmp}
+
+\newcommand{\exf at problemstitle}{%
+ \protected at edef\exf at problemstitleexp{\exf at config@composetitleproblems}%
+ \ifx\exf at problemstitleexp\exf at empty\else%
+ \exf at section{\exf at config@skipproblemstitle}%
+ {\exf at config@styletitle\exf at config@styletitleproblems%
+ \exf at problemstitleexp}%
+ \exf at addcontentsline{\exf at config@toclevelproblems}%
+ {\exf at config@composetocproblems}%
+ \fi}
+
+\newcommand{\exf at showproblemsin}{%
+ \par\exf at config@styletext\addvspace{\exf at config@skipproblemsabove}%
+ \exf at config@insertproblemsbefore}
+
+\newcommand{\exf at showproblemsout}{%
+ \exf at config@insertproblemsafter%
+ \par\exf at config@styletext\addvspace{\exf at config@skipproblemsbelow}}
+
+\newcommand{\exf at showproblems}{%
+ \ifexf at probbuf@clean\else\begingroup%
+ \exf at showproblemsin%
+ \exf at problemstitle%
+ \exf at source@buf\exf at probbuf%
+ \exf at clear@probbuf%
+ \exf at showproblemsout%
+ \endgroup\fi}
+
+\newcommand{\writeproblems}[1][\jobname]{%
+ \exf at close@probfile\exf at start@probfile{#1}}
+
+\newcommand{\closeproblems}{\exf at close@probfile}
+
+\newcommand{\readproblems}[1][\jobname]{\exf at close@probfile%
+ \begingroup%
+ \exf at config@styletext\exf at config@styletextproblem%
+ \exf at problemstitle%
+ \input{#1\exf at config@extproblems}%
+ \endgroup}
+
+\newcommand{\insertproblems}{\exf at showproblems}
+
\define at key{exf at subproblem}{points}{\exf at scanpoints\exf at subproblem@points#1++&}
\define at key{exf at subproblem}{label}{\def\exf at label{#1}}
@@ -934,7 +1119,11 @@
\xdef\exf at prevsubprobhref{\exf at subproblemcounter.%
\csname theH\exf at subproblemcounter\endcsname}%
\fi%
+ \let\exf at subproblem@points at show\@undefined%
\ifdefined\exf at subproblem@points%
+ \let\exf at subproblem@points at show\exf at subproblem@points\fi%
+ \exf at ifis\exf at subpointsat{off}{\let\exf at subproblem@points at show\@undefined}%
+ \ifdefined\exf at subproblem@points%
\global\let\exf at prevpoints\exf at subproblem@points%
\exf at exptwo\exf at addtopoints\exf at problem@points at total\exf at subproblem@points%
\else%
@@ -942,11 +1131,10 @@
\PackageWarning{exframe}{no points defined for \exf at subproblemname}%
\fi%
\fi%
- \exf at ifis\exf at subpointsat{off}{\let\exf at subproblem@points\@undefined}%
\exf at ifis\exf at subpointsat{start}{\exf at outpoints{\exf at append@intro}%
- {\exf at config@composepointspairstart}{\exf at subproblem@points}}%
+ {\exf at config@composepointspairstartsubproblem}{\exf at subproblem@points at show}}%
\exf at ifis\exf at subpointsat{start*}{\exf at outpoints{\exf at prepend@intro}%
- {\exf at config@composepointspairstart}{\exf at subproblem@points}}%
+ {\exf at config@composepointspairstartsubproblem}{\exf at subproblem@points at show}}%
\exf at config@insertsubprobleminfo%
\ifdim\exf at config@skipsubproblemitem=0pt%
\exf at prepend@intro{{%
@@ -970,7 +1158,7 @@
\fi%
\exf at ifis\exf at subpointsat{margin}{%
\exf at outpoints{\exf at prepend@def\exf at introitem}%
- {\exf at makepointsmargin}{\exf at subproblem@points}}%
+ {\exf at makepointsmargin}{\exf at subproblem@points at show}}%
\exf at open@block{\exf at config@skipsubproblemtitle}%
\@afterindentfalse}%
{\exf at ifis\exf at subpointsat{end}{\showpoints}%
@@ -1004,9 +1192,11 @@
\let\theHequation\theHexf at solutionequation%
\fi%
\begingroup%
+ \def\exf at in@solution{}%
\def\exf at solprob{}%
\def\exf at solsubprob{}%
\let\exf at label\@undefined%
+ \let\exf at solution@points\@undefined%
\let\exf at solution@points at total\@undefined%
\def\exf at solhref{}%
\exf at init@block{\exf at config@skipsolutioninfo}%
@@ -1015,6 +1205,14 @@
{\exf at config@composeitemsolutionlabel{\exf at solprob}{\exf at solsubprob}}%
\refstepcounter{\exf at solutioncounter}%
\ifdefined\exf at label\label{\exf at label}\fi%
+ \let\exf at solution@points at show\@undefined%
+ \ifdefined\exf at solution@points%
+ \let\exf at solution@points at show\exf at solution@points\fi%
+ \exf at ifis\exf at solpointsat{off}{\let\exf at solution@points at show\@undefined}%
+ \exf at ifis\exf at solpointsat{start}{\exf at outpoints{\exf at append@intro}%
+ {\exf at config@composepointspairstartsolution}{\exf at solution@points at show}}%
+ \exf at ifis\exf at solpointsat{start*}{\exf at outpoints{\exf at prepend@intro}%
+ {\exf at config@composepointspairstartsolution}{\exf at solution@points at show}}%
\exf at config@insertsolutioninfo%
\exf at config@styletext\exf at config@styletextsolution%
\ifx\exf at solsubprob\exf at empty%
@@ -1058,9 +1256,13 @@
\else\exf at solution@item\fi%
\exf at config@composeitemproblemsep}}%
\fi%
+ \exf at ifis\exf at solpointsat{margin}{%
+ \exf at outpoints{\exf at prepend@def\exf at introitem}%
+ {\exf at makepointsmargin}{\exf at solution@points at show}}%
\exf at open@block{\exf at config@skipsolutiontitle}%
\@afterindentfalse}%
- {\exf at warnmismatch{\exf at solutionname}{\exf at solutioncounter}%
+ {\exf at ifis\exf at solpointsat{end}{\showpoints}%
+ \exf at warnmismatch{\exf at solutionname}{\exf at solutioncounter}%
{\exf at solution@points at total}{\exf at solution@points}%
\par\exf at close@block%
\ifexf at style@solutionequation%
@@ -1080,28 +1282,20 @@
\let\exf at solhref\@undefined%
\setkeys{exf at solution}{#1}%
\let\exf at composetitle\exf at config@composetitlesolutionsproblemmulti%
- \def\exf at solutionstoc{\exf at addcontentsline{\exf at config@toclevelsolution}%
- {\exf at config@composetocsolution{\exf at solprob}{\exf at solprobtitle}}}%
\exf at ifis\exf at solutionbelow{problem}{\let\exf at composetitle%
\exf at config@composetitlesolutionsproblemsingle}%
\exf at ifis\exf at solutionbelow{problem*}{\let\exf at composetitle%
\exf at config@composetitlesolutionsproblemsingle}%
+ \def\exf at solutionstoc{\exf at addcontentsline{\exf at config@toclevelsolution}%
+ {\exf at config@composetocsolution{\exf at solprob}{\exf at solprobtitle}}}%
+ \addvspace{\exf at config@skipsolutionsproblemabove}%
\exf at solutionssection{\exf at config@styletitlesolutionsproblem}%
{\exf at composetitle{\exf at solprob}{\exf at solprobtitle}}%
- {\exf at config@skipsolutionsproblem}%
+ {\exf at config@skipsolutionsproblemtitle}%
{\exf at solutionstoc}{\exf at label}{\exf at solhref}%
\endgroup}
-\newenvironment{\exf at solutionname}%
- {\exf at ifis\exf at solutionbelow{here*}{%
- \newcommand{\exf at scanblockplain}[1][]{\exf at scansolution{##1}{}}%
- \def\exf at scanblock##1{\exf at scanblockplain}}%
- \exf at scanblock{\exf at scansolution}}{\endexf at scansolution}%
-
-\newenvironment{exf at scansolution}[2]{%
- \exf at ifis\exf at solutionbelow{here}{\showpoints}%
- \exf at ifis\exf at solutionbelow{here*}{\showpoints}%
- \global\exf at bufcleanfalse%
+\newcommand{\exf at process@solnewsec}{%
\ifdefined\exf at problem@solnewsec%
\def\exf at probarg{\ifdefined\exf at prevprob prob={\exf at prevprob}\fi%
\ifdefined\exf at prevprobtitle,probtitle={\exf at prevprobtitle}\fi%
@@ -1108,18 +1302,19 @@
\ifdefined\exf at prevprobhref,href={\exf at prevprobhref}\fi%
\ifdefined\exf at sollabel,label={\exf at sollabel}\fi}%
\exf at ifis\exf at solutionbelow{here}{\let\exf at probarg\@undefined}%
- \exf at ifis\exf at solutionbelow{here*}{\let\exf at probarg\@undefined}%
\exf at ifis\exf at solutionbelow{subproblem}{\let\exf at probarg\@undefined}%
\exf at ifis\exf at solutionbelow{subproblem*}{\let\exf at probarg\@undefined}%
\ifdefined\exf at probarg%
- \ifexf at lineno\exf at addbufline{\exf at linesep}\exf at addbufline{\exf at lineno}\fi%
- \exf at addbufline{\@backslashchar solutionssection{\exf at probarg}}%
- \exf at addbufline{}%
+ \ifexf at lineno\exf at addline\exf at solbuf{\exf at linesep}%
+ \exf at addline\exf at solbuf{\exf at lineno}\fi%
+ \exf at addline\exf at solbuf{\@backslashchar solutionssection{\exf at probarg}}%
+ \exf at addline\exf at solbuf{}%
\fi%
\global\let\exf at problem@solnewsec\@undefined%
- \fi%
- \ifexf at lineno\exf at addbufline{\exf at linesep}\exf at addbufline{\exf at lineno}\fi%
- \def\exf at subprobarg{%
+ \fi}%
+
+\newcommand{\exf at generate@solprobarg}{%
+ \edef\exf at solprobarg{%
\ifdefined\exf at prevprob prob={\exf at prevprob},\fi%
\ifdefined\exf at prevsubprob subprob={\exf at prevsubprob},%
\ifdefined\exf at prevsubprobhref href={\exf at prevsubprobhref},\fi%
@@ -1130,24 +1325,41 @@
{\expandafter\exf at formatpoints\exf at prevpoints},\fi%
\ifdefined\sheettag sheettag={\sheettag},\fi%
\ifdefined\problemtag problemtag={\problemtag},\fi}%
- \exf at addbufline{\@backslashchar begin{printsolution}{\exf at subprobarg#1}}%
\global\let\exf at prevsubprob\@undefined%
\global\let\exf at prevsubprobhref\@undefined%
- \global\let\exf at prevpoints\@undefined%
- \exf at ifis\exf at solutionbelow{here*}{%
- \def\exf at verbatim{\exf at clearbuf\begingroup%
- \edef\exf at subprobarg{\exf at subprobarg}%
- \exf at showsolutionsin{\exf at config@composetitlesolutionsingle}%
- \exf at exptwo\printsolution{\exf at subprobarg#1}}%
- \def\exf at endverbatim{\endprintsolution\exf at showsolutionsout\endgroup}}%
+ \global\let\exf at prevpoints\@undefined}%
+
+\newenvironment{exf at solution@direct}[1][]%
+ {\showpoints%
+ \global\let\exf at problem@solnewsec\@undefined%
+ \exf at generate@solprobarg%
+ \exf at showsolutionsin%
+ \let\exf at composetitle\exf at config@composetitlesolutionsingle%
+ \exf at exptwo\printsolution{\exf at solprobarg#1}}%
+ {\endprintsolution%
+ \exf at showsolutionsout%
+ \ignorespacesafterend}%
+
+\newenvironment{exf at solution@scan}%
+ {\exf at scanblock{\exf at scansolution}}{\endexf at scansolution}%
+\newenvironment{exf at scansolution}[2]{%
+ \exf at ifis\exf at solutionbelow{here}{\showpoints}%
+ \exf at process@solnewsec%
+ \exf at generate@solprobarg%
+ \ifexf at lineno\exf at addline\exf at solbuf{\exf at linesep}%
+ \exf at addline\exf at solbuf{\exf at lineno}\fi%
+ \exf at addline\exf at solbuf%
+ {\@backslashchar begin{printsolution}{\exf at solprobarg#1}}%
+ \def\exf at verbatim@process{\exf at append@buf\exf at solbuf}%
\exf at verbatim#2}%
{\exf at endverbatim%
- \exf at addbufline{\@backslashchar end{printsolution}}%
- \ifexf at infile%
- \exf at writebuf%
- \exf at clearbuf%
+ \exf at addline\exf at solbuf{\@backslashchar end{printsolution}}%
+ \global\exf at solbuf@cleanfalse%
+ \ifexf at solfile@open%
+ \exf at write@buf\exf at solfile\exf at solbuf%
+ \exf at clear@solbuf%
\fi%
- \ifsolutions\else\exf at clearbuf\fi%
+ \ifsolutions\else\exf at clear@solbuf\fi%
\exf at ifis\exf at solutionbelow{here}{\exf at showsolutions%
{\exf at config@composetitlesolutionsingle}{}}%
\ifdefined\exf at in@subproblem\else%
@@ -1162,6 +1374,14 @@
\exf at showsolutions{\exf at config@composetitlesolutionmulti}{}}\fi%
\ignorespacesafterend}
+\newenvironment{\exf at solutionname}%
+ {\ifexf at solutionbuf\let\exf at tmp\exf at solution@scan%
+ \else\let\exf at tmp\exf at solution@direct\fi%
+ \exf at tmp}%
+ {\ifexf at solutionbuf\let\exf at tmp\endexf at solution@scan%
+ \else\let\exf at tmp\endexf at solution@direct\fi%
+ \exf at tmp}
+
\newcommand{\exf at solutionssection}[6]{%
\protected at edef\exf at solutionstitleexp{#2}%
\ifx\exf at solutionstitleexp\exf at empty\else%
@@ -1181,36 +1401,36 @@
{\exf at addcontentsline{\exf at config@toclevelsolutions}%
{\exf at config@composetocsolutions}}{\@undefined}{\@undefined}}
-\newcommand{\exf at showsolutionsin}[1]{%
+\newcommand{\exf at showsolutionsin}{%
\par\exf at config@styletext\addvspace{\exf at config@skipsolutionsabove}%
\exf at config@styletextsolution%
- \exf at config@insertsolutionsbefore%
- \let\exf at composetitle#1}
+ \exf at config@insertsolutionsbefore}
\newcommand{\exf at showsolutionsout}{%
- \removelastskip%
\exf at config@insertsolutionsafter%
- \par\exf at config@styletext\addvspace{\exf at config@skipsolutionbelow}}
+ \par\exf at config@styletext\addvspace{\exf at config@skipsolutionsbelow}}
\newcommand{\exf at showsolutions}[2]{%
- \ifexf at bufclean\else\begingroup%
- \exf at showsolutionsin{#1}%
+ \ifexf at solbuf@clean\else\begingroup%
+ \exf at showsolutionsin%
+ \let\exf at composetitle#1%
#2%
- \exf at sourcebuf%
- \exf at clearbuf%
+ \exf at source@buf\exf at solbuf%
+ \exf at clear@solbuf%
\exf at showsolutionsout%
\endgroup\fi}
-\newcommand{\writesolutions}[1][\jobname]{\exf at closefile\exf at startfile{#1}}
+\newcommand{\writesolutions}[1][\jobname]{%
+ \exf at close@solfile\exf at start@solfile{#1}}
-\newcommand{\closesolutions}{\exf at closefile}
+\newcommand{\closesolutions}{\exf at close@solfile}
-\newcommand{\readsolutions}[1][\jobname]{\exf at closefile%
+\newcommand{\readsolutions}[1][\jobname]{\exf at close@solfile%
\ifsolutions\begingroup%
\exf at config@styletext\exf at config@styletextsolution%
- \let\exf at config@composetitlesolution\exf at config@composetitlesolutionmulti%
+ \let\exf at composetitle\exf at config@composetitlesolutionmulti%
\exf at solutionstitle%
- \input{#1.sol}%
+ \input{#1\exf at config@extsolutions}%
\endgroup\fi}
\newcommand{\insertsolutions}{\exf at showsolutions%
More information about the tex-live-commits
mailing list