summaryrefslogtreecommitdiff
path: root/macros/latex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-01-18 03:01:23 +0000
committerNorbert Preining <norbert@preining.info>2020-01-18 03:01:23 +0000
commit22d3a7ddeb2b2637308cf883f9bd3590e649aa20 (patch)
treee5887f868c532734a8cac1c7833f5492370effb5 /macros/latex
parente71ffee2103e3f137bbc9ee526858bc277e95908 (diff)
CTAN sync 202001180301
Diffstat (limited to 'macros/latex')
-rw-r--r--macros/latex/contrib/chemmacros/README2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.history3
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.acid-base.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.all.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.base.code.tex13
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.charges.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.chemformula.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.errorcheck.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.greek.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.isotopes.code.tex11
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.lang.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.mechanisms.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.newman.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.nomenclature.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.orbital.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.particles.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.phases.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.polymers.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.reactions.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.redox.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.scheme.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.spectroscopy.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.symbols.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.thermodynamics.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.tikz.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.units.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.module.xfrac.code.tex2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros.sty6
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros4.sty2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros5.sty2
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros_en.pdfbin947092 -> 947206 bytes
-rw-r--r--macros/latex/contrib/chemmacros/chemmacros_en.tex2
-rw-r--r--macros/latex/contrib/enotez/README4
-rw-r--r--macros/latex/contrib/enotez/enotez.sty9
-rw-r--r--macros/latex/contrib/enotez/enotez_en.pdfbin449693 -> 450196 bytes
-rw-r--r--macros/latex/contrib/enotez/enotez_en.tex2
-rw-r--r--macros/latex/contrib/enotez/enotez_split_example.tex2
-rw-r--r--macros/latex/contrib/jmlr/CHANGES49
-rw-r--r--macros/latex/contrib/jmlr/README4
-rw-r--r--macros/latex/contrib/jmlr/jmlr.dtx143
-rw-r--r--macros/latex/contrib/jmlr/jmlr.ins4
-rw-r--r--macros/latex/contrib/jmlr/jmlr.pdfbin615617 -> 617852 bytes
-rw-r--r--macros/latex/contrib/jmlr/sample-books/jmlrbook-sample.pdfbin319039 -> 319067 bytes
-rw-r--r--macros/latex/contrib/jmlr/sample-books/proceedings-sample.pdfbin419217 -> 419199 bytes
-rw-r--r--macros/latex/contrib/jmlr/sample-papers/jmlr-sample.pdfbin308987 -> 309456 bytes
-rw-r--r--macros/latex/contrib/jmlr/sample-papers/jmlrwcp-sample.pdfbin297750 -> 297814 bytes
-rw-r--r--macros/latex/contrib/mathtools/empheq.pdfbin311443 -> 311438 bytes
-rw-r--r--macros/latex/contrib/mathtools/mathtools.dtx64
-rw-r--r--macros/latex/contrib/mathtools/mathtools.pdfbin447874 -> 448435 bytes
-rw-r--r--macros/latex/contrib/mathtools/mhsetup.pdfbin235863 -> 235863 bytes
-rw-r--r--macros/latex/contrib/thorshammer/README.md33
-rw-r--r--macros/latex/contrib/thorshammer/container.pdfbin0 -> 49921 bytes
-rw-r--r--macros/latex/contrib/thorshammer/docs/install-action-seq.pdfbin0 -> 345357 bytes
-rw-r--r--macros/latex/contrib/thorshammer/docs/thmclass.pdfbin0 -> 207656 bytes
-rw-r--r--macros/latex/contrib/thorshammer/docs/thmclass.tex970
-rw-r--r--macros/latex/contrib/thorshammer/docs/thors-the-man.pdfbin0 -> 1388897 bytes
-rw-r--r--macros/latex/contrib/thorshammer/docs/thors-the-man.tex2178
-rw-r--r--macros/latex/contrib/thorshammer/docs/thorshammer.pdfbin0 -> 6227257 bytes
-rw-r--r--macros/latex/contrib/thorshammer/examples/cfgs/thexcfg1.tex152
-rw-r--r--macros/latex/contrib/thorshammer/examples/cfgs/thexcfg2-star.tex168
-rw-r--r--macros/latex/contrib/thorshammer/examples/cfgs/thexcfg2.tex158
-rw-r--r--macros/latex/contrib/thorshammer/examples/cfgs/thorsclass1.cfg43
-rw-r--r--macros/latex/contrib/thorshammer/examples/cfgs/thorsclass2.cfg44
-rw-r--r--macros/latex/contrib/thorshammer/examples/cfgs/thorsclass3-star.cfg9
-rw-r--r--macros/latex/contrib/thorshammer/examples/cfgs/thorsclass3.cfg8
-rw-r--r--macros/latex/contrib/thorshammer/examples/cfgs/thorsclassx.cfg6
-rw-r--r--macros/latex/contrib/thorshammer/examples/misc/thexrt.tex319
-rw-r--r--macros/latex/contrib/thorshammer/examples/nosolns/thexb.tex147
-rw-r--r--macros/latex/contrib/thorshammer/examples/nosolns/thexbd.tex146
-rw-r--r--macros/latex/contrib/thorshammer/examples/nosolns/thexr.tex175
-rw-r--r--macros/latex/contrib/thorshammer/examples/nosolns/thexrt.tex222
-rw-r--r--macros/latex/contrib/thorshammer/examples/nosolns/thexub.tex147
-rw-r--r--macros/latex/contrib/thorshammer/examples/nosolns/thexuc.tex152
-rw-r--r--macros/latex/contrib/thorshammer/examples/ordinary-option/get-hash-string.tex35
-rw-r--r--macros/latex/contrib/thorshammer/examples/ordinary-option/quiz-pwd-to-correct-AA.tex190
-rw-r--r--macros/latex/contrib/thorshammer/examples/ordinary-option/quiz-pwd-to-correct-AR.tex174
-rw-r--r--macros/latex/contrib/thorshammer/folder-js/aeb-reader.js50
-rw-r--r--macros/latex/contrib/thorshammer/folder-js/aeb_pro.js158
-rw-r--r--macros/latex/contrib/thorshammer/system-scripts/standalone/altclasspaths.txt1
-rw-r--r--macros/latex/contrib/thorshammer/system-scripts/standalone/cpquizzes.ps151
-rw-r--r--macros/latex/contrib/thorshammer/system-scripts/standalone/mkcfg.ps171
-rw-r--r--macros/latex/contrib/thorshammer/system-scripts/standalone/mkfolders.ps160
-rw-r--r--macros/latex/contrib/thorshammer/system-scripts/standalone/rmquizzes.ps151
-rw-r--r--macros/latex/contrib/thorshammer/system-scripts/standalone/runps1.bat2
-rw-r--r--macros/latex/contrib/thorshammer/system-scripts/standalone/sample-list.csv3
-rw-r--r--macros/latex/contrib/thorshammer/system-scripts/thors-structure/runps1.bat2
-rw-r--r--macros/latex/contrib/thorshammer/system-scripts/thors-structure/sample-vars.txt8
-rw-r--r--macros/latex/contrib/thorshammer/system-scripts/thors-structure/thmclass.ps1713
-rw-r--r--macros/latex/contrib/thorshammer/terminate-batch.pdfbin0 -> 25334 bytes
-rw-r--r--macros/latex/contrib/thorshammer/thorshammer.cfg52
-rw-r--r--macros/latex/contrib/thorshammer/thorshammer.dtx2398
-rw-r--r--macros/latex/contrib/thorshammer/thorshammer.ins62
92 files changed, 9411 insertions, 115 deletions
diff --git a/macros/latex/contrib/chemmacros/README b/macros/latex/contrib/chemmacros/README
index d97f1818e4..7483ec9d3f 100644
--- a/macros/latex/contrib/chemmacros/README
+++ b/macros/latex/contrib/chemmacros/README
@@ -8,7 +8,7 @@ Clemens Niederberger
Web: https://github.com/cgnieder/chemmacros/
E-Mail: contact@mychemistry.eu
--------------------------------------------------------------------------
-Copyright 2011-2019 Clemens Niederberger
+Copyright 2011--2020 Clemens Niederberger
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.history b/macros/latex/contrib/chemmacros/chemmacros.history
index ac061221f7..fc78d0e120 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.history
+++ b/macros/latex/contrib/chemmacros/chemmacros.history
@@ -12,7 +12,7 @@ contact@mychemistry.eu
If you have any ideas, questions, suggestions or bugs to report, please
feel free to contact me.
--------------------------------------------------------------------------
-Copyright 2011-2019 Clemens Niederberger
+Copyright 2011--2020 Clemens Niederberger
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either version 1.3
@@ -385,3 +385,4 @@ Version history
2019/11/17 - version 5.9 - correction: torr -> Torr (units)
- define latin phrases on the go instead of at begin
document
+2020/01/16 - version 5.9a - adapt to renaming of string case changing functions
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.acid-base.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.acid-base.code.tex
index 1024cd4fac..fe1706e476 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.acid-base.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.acid-base.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.all.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.all.code.tex
index fa14ed3fdb..6201308fa4 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.all.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.all.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.base.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.base.code.tex
index 1ea731b25c..3f84c9097b 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.base.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.base.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -25,7 +25,7 @@
%
% The Current Maintainer of this work is Clemens Niederberger.
% --------------------------------------------------------------------------
-\ChemModule{base}{2017/08/28 basic chemmacros module}
+\ChemModule{base}{2020/01/16 basic chemmacros module}
% for the document hooks
\ChemCompatibilityFrom{5.1}
@@ -63,7 +63,7 @@
\exp_args:Nc \NewDocumentCommand
{
NewChem
- \str_upper_case:f { \tl_head:n {#1} }
+ \str_uppercase:f { \tl_head:n {#1} }
\tl_tail:n {#1}
}
{#2}
@@ -75,7 +75,7 @@
\exp_args:Nc \NewDocumentCommand
{
RenewChem
- \str_upper_case:f { \tl_head:n {#1} }
+ \str_uppercase:f { \tl_head:n {#1} }
\tl_tail:n {#1}
}
{#2}
@@ -87,7 +87,7 @@
\exp_args:Nc \NewDocumentCommand
{
DeclareChem
- \str_upper_case:f { \tl_head:n {#1} }
+ \str_uppercase:f { \tl_head:n {#1} }
\tl_tail:n {#1}
}
{#2}
@@ -95,7 +95,7 @@
\exp_args:Nc \NewDocumentCommand
{
ProvideChem
- \str_upper_case:f { \tl_head:n {#1} }
+ \str_uppercase:f { \tl_head:n {#1} }
\tl_tail:n {#1}
}
{#2}
@@ -484,3 +484,4 @@
\ChemFancyrefSupport
2016/05/04 - fix \ChemCleverefSupport
2017/08/28 - add missing hyperref check
+2020/01/16 - adapt to renaming of string case changing functions
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.charges.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.charges.code.tex
index 981d9d272e..4dfa1018ee 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.charges.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.charges.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.chemformula.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.chemformula.code.tex
index 6a6c45d1f2..292b90747a 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.chemformula.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.chemformula.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.errorcheck.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.errorcheck.code.tex
index 07499ef5f2..faf91b06ff 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.errorcheck.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.errorcheck.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.greek.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.greek.code.tex
index d3c9ee87ae..afe973899d 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.greek.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.greek.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.isotopes.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.isotopes.code.tex
index 1d7ec5466c..6463f05d74 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.isotopes.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.isotopes.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -45,9 +45,9 @@
\chemmacros_if_is_int:nTF {#1}
{ \tl_set:Nn #2 {#1} }
{
- \cs_if_exist:cTF { @elements@atom@number@ \str_lower_case:n {#1} }
- { \tl_set:Nx #2 { \use:c { @elements@atom@number@ \str_lower_case:n {#1} } } }
- { \tl_set:Nx #2 { \use:c { @elements@atom@name@num@ \str_lower_case:n {#1} } } }
+ \cs_if_exist:cTF { @elements@atom@number@ \str_lowercase:n {#1} }
+ { \tl_set:Nx #2 { \use:c { @elements@atom@number@ \str_lowercase:n {#1} } } }
+ { \tl_set:Nx #2 { \use:c { @elements@atom@name@num@ \str_lowercase:n {#1} } } }
}
}
\cs_generate_variant:Nn \chemmacros_get_atom_number:nN { V }
@@ -233,3 +233,6 @@
{ \chemmacros_isotope:nn {#1} {#2} }
% --------------------------------------------------------------------------
+\file_input_stop:
+2015/07/22 - first version
+2020/01/16 - adapt to renaming of string case changing functions
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.lang.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.lang.code.tex
index 7ae37a2f9f..5d00030d82 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.lang.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.lang.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.mechanisms.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.mechanisms.code.tex
index 22624538b6..2f272bb740 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.mechanisms.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.mechanisms.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.newman.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.newman.code.tex
index 7c8caa10a5..69754e8a2d 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.newman.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.newman.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.nomenclature.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.nomenclature.code.tex
index 9cb5969ed2..1175b3151e 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.nomenclature.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.nomenclature.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.orbital.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.orbital.code.tex
index 79153b0d11..4671eb3ea7 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.orbital.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.orbital.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.particles.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.particles.code.tex
index 9d68712f81..3149f9789f 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.particles.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.particles.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.phases.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.phases.code.tex
index da3365c038..1ddcc094bb 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.phases.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.phases.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.polymers.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.polymers.code.tex
index f7d71c8565..d316a3b188 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.polymers.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.polymers.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.reactions.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.reactions.code.tex
index f261611bfb..c30c5fac89 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.reactions.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.reactions.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.redox.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.redox.code.tex
index 01e629028f..cbc0b2e242 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.redox.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.redox.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.scheme.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.scheme.code.tex
index 059741fe0c..057acbf70c 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.scheme.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.scheme.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.spectroscopy.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.spectroscopy.code.tex
index 748a4cb19e..a1be3187aa 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.spectroscopy.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.spectroscopy.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.symbols.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.symbols.code.tex
index 314eeda81a..ebf201330d 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.symbols.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.symbols.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.thermodynamics.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.thermodynamics.code.tex
index 82306cc0ea..424054f1c0 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.thermodynamics.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.thermodynamics.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.tikz.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.tikz.code.tex
index a656e70e5e..11d1e9bd81 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.tikz.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.tikz.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.units.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.units.code.tex
index 4584c8a631..7b90faad3a 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.units.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.units.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.module.xfrac.code.tex b/macros/latex/contrib/chemmacros/chemmacros.module.xfrac.code.tex
index 735632beb4..a013d9b6af 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.module.xfrac.code.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros.module.xfrac.code.tex
@@ -11,7 +11,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros.sty b/macros/latex/contrib/chemmacros/chemmacros.sty
index 3865e1a860..e18a84fe95 100644
--- a/macros/latex/contrib/chemmacros/chemmacros.sty
+++ b/macros/latex/contrib/chemmacros/chemmacros.sty
@@ -12,7 +12,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -31,10 +31,10 @@
% --------------------------------------------------------------------------
% package information:
-\tl_const:Nn \c_chemmacros_date_tl {2019/11/17}
+\tl_const:Nn \c_chemmacros_date_tl {2020/01/16}
\tl_const:Nn \c_chemmacros_version_major_number_tl {5}
\tl_const:Nn \c_chemmacros_version_minor_number_tl {9}
-\tl_const:Nn \c_chemmacros_version_subrelease_tl {}
+\tl_const:Nn \c_chemmacros_version_subrelease_tl {a}
\tl_const:Nx \c_chemmacros_version_number_tl
{
\c_chemmacros_version_major_number_tl .
diff --git a/macros/latex/contrib/chemmacros/chemmacros4.sty b/macros/latex/contrib/chemmacros/chemmacros4.sty
index ae86ebc47d..a9f6b2dfd3 100644
--- a/macros/latex/contrib/chemmacros/chemmacros4.sty
+++ b/macros/latex/contrib/chemmacros/chemmacros4.sty
@@ -12,7 +12,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros5.sty b/macros/latex/contrib/chemmacros/chemmacros5.sty
index c9578f737b..1f5ecbc939 100644
--- a/macros/latex/contrib/chemmacros/chemmacros5.sty
+++ b/macros/latex/contrib/chemmacros/chemmacros5.sty
@@ -12,7 +12,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/chemmacros/chemmacros_en.pdf b/macros/latex/contrib/chemmacros/chemmacros_en.pdf
index ee2ecb6eee..5619833757 100644
--- a/macros/latex/contrib/chemmacros/chemmacros_en.pdf
+++ b/macros/latex/contrib/chemmacros/chemmacros_en.pdf
Binary files differ
diff --git a/macros/latex/contrib/chemmacros/chemmacros_en.tex b/macros/latex/contrib/chemmacros/chemmacros_en.tex
index 3fccfe7634..9bf20e8789 100644
--- a/macros/latex/contrib/chemmacros/chemmacros_en.tex
+++ b/macros/latex/contrib/chemmacros/chemmacros_en.tex
@@ -16,7 +16,7 @@
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% --------------------------------------------------------------------------
-% Copyright 2011-2019 Clemens Niederberger
+% Copyright 2011--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/enotez/README b/macros/latex/contrib/enotez/README
index 105c5d1170..93aad12bac 100644
--- a/macros/latex/contrib/enotez/README
+++ b/macros/latex/contrib/enotez/README
@@ -1,5 +1,5 @@
--------------------------------------------------------------------------
-the ENOTEZ package v0.10a 2019/10/12
+the ENOTEZ package v0.10b 2020/01/16
Endnotes for LaTeX2e
@@ -8,7 +8,7 @@ Clemens Niederberger
Web: https://bitbucket.org/cgnieder/enotez/
E-Mail: contact@mychemistry.eu
--------------------------------------------------------------------------
-Copyright 2012--2019 Clemens Niederberger
+Copyright 2012--2020 Clemens Niederberger
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/enotez/enotez.sty b/macros/latex/contrib/enotez/enotez.sty
index c82b386e56..4019b65791 100644
--- a/macros/latex/contrib/enotez/enotez.sty
+++ b/macros/latex/contrib/enotez/enotez.sty
@@ -8,7 +8,7 @@
% Web: https://bitbucket.org/cgnieder/enotez/
% E-Mail: contact@mychemistry.eu
% --------------------------------------------------------------------------
-% Copyright 2012--2019 Clemens Niederberger
+% Copyright 2012--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -31,8 +31,8 @@
\RequirePackage {expl3,xparse,l3keys2e,xtemplate}
\ProvidesExplPackage
{enotez}
- {2019/10/12}
- {0.10a}
+ {2020/01/16}
+ {0.10b}
{Endnotes for LaTeX2e}
% --------------------------------------------------------------------------
@@ -690,7 +690,7 @@
\cs_generate_variant:Nn \tl_set_rescan:Nnn { NnV }
\cs_new_protected:Npn \enotez_first_upper:n #1
- { \tl_upper_case:n { \tl_head:n {#1} } \tl_tail:n {#1} }
+ { \text_titlecase_first:n {#1} }
\cs_generate_variant:Nn \enotez_first_upper:n { V }
\tl_new:N \l__enotez_last_split_id_tl
@@ -1023,3 +1023,4 @@
- implement issue #13
- implement issue #9
2019/10/12 v0.10a - remove unnecessary package dependencies
+2020/01/16 v0.10b - adapt to renaming of string case changing functions
diff --git a/macros/latex/contrib/enotez/enotez_en.pdf b/macros/latex/contrib/enotez/enotez_en.pdf
index d7b1aabd56..42bbcede66 100644
--- a/macros/latex/contrib/enotez/enotez_en.pdf
+++ b/macros/latex/contrib/enotez/enotez_en.pdf
Binary files differ
diff --git a/macros/latex/contrib/enotez/enotez_en.tex b/macros/latex/contrib/enotez/enotez_en.tex
index d169e186c1..637122aa0e 100644
--- a/macros/latex/contrib/enotez/enotez_en.tex
+++ b/macros/latex/contrib/enotez/enotez_en.tex
@@ -12,7 +12,7 @@
% Web: http://www.mychemistry.eu/forums/forum/enotez/
% E-Mail: contact@mychemistry.eu
% --------------------------------------------------------------------------
-% Copyright 2012--2019 Clemens Niederberger
+% Copyright 2012--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/enotez/enotez_split_example.tex b/macros/latex/contrib/enotez/enotez_split_example.tex
index 7c58fa56df..5959a0d3a3 100644
--- a/macros/latex/contrib/enotez/enotez_split_example.tex
+++ b/macros/latex/contrib/enotez/enotez_split_example.tex
@@ -8,7 +8,7 @@
% Web: https://bitbucket.org/cgnieder/enotez/
% E-Mail: contact@mychemistry.eu
% --------------------------------------------------------------------------
-% Copyright 2012--2019 Clemens Niederberger
+% Copyright 2012--2020 Clemens Niederberger
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/jmlr/CHANGES b/macros/latex/contrib/jmlr/CHANGES
index 27268561ab..41a78e7693 100644
--- a/macros/latex/contrib/jmlr/CHANGES
+++ b/macros/latex/contrib/jmlr/CHANGES
@@ -1,18 +1,29 @@
-v1.24:
+v1.25 (2020-01-17):
+
+ * jmlr.cls:
+
+ - Added check for graphics.sty 2019/07/01 (which now detokenizes
+ filename)
+
+ * jmlrutils.sty:
+
+ - Added \proofname
+
+v1.24 (2017-08-01):
* moved non-class related code into new package jmlrutils.sty
* fixed bug in \includeteximage
-v1.23:
+v1.23 (2017-03-09):
* added pmlr class option
-v1.22:
+v1.22 (2015-04-11):
* added oneside and twoside class options
-v1.21:
+v1.21 (2015-02-24):
* jmlr.cls
@@ -25,19 +36,19 @@ v1.21:
- added \nopagebreak after \@editorialteam
-v1.20:
+v1.20 (2014-10-15):
* jmlrbook.cls
- added \jmlrprefaceheader, \jmlrlocation
-v1.19:
+v1.19 (2014-09-29):
* jmlrbook.cls
- changed \chapter* to \chapter in preface environment
-v1.18:
+v1.18 (2013-10-17):
* jmlrbook.cls
@@ -58,7 +69,7 @@ v1.18:
- Added \theorembodyfont, \theoremheaderfont, \theorempostheader
and \theoremsep
-v1.17:
+v1.17 (2012-05-30):
* jmlr.cls
@@ -79,7 +90,7 @@ v1.17:
- added optional argument to \logo
-v1.16:
+v1.16 (2012-05-15):
* jmlr.cls
@@ -89,7 +100,7 @@ v1.16:
- added code to deal with \c@lenddoca clash
-v1.15:
+v1.15 (2012-05-12):
* jmlrbook.cls
@@ -102,7 +113,7 @@ v1.15:
- added \markleft
-v1.14:
+v1.14 (2012-04-24):
* jmlrbook.cls
@@ -110,7 +121,7 @@ v1.14:
information to aux file
- fixed bug in fetching time zone information
-v1.13:
+v1.13 (2012-02-25):
* jmlrbook.cls
@@ -122,7 +133,7 @@ v1.13:
- added \@pre@hyperref hook
-v1.12:
+v1.12 (2012-01-05):
* jmlr.cls
@@ -163,7 +174,7 @@ v1.12:
- added debugging option --noexecute
-v1.11:
+v1.11 (2011-03-24):
* jmlr.cls
@@ -193,7 +204,7 @@ v1.11:
- abstract html source files now input original aux files to allow
for citations.
-v1.10:
+v1.10 (2011-01-05):
jmlr.cls
@@ -236,7 +247,7 @@ v1.10:
* added time stamp at the end of each of the generated html file.
-v1.09:
+v1.09 (2010-12-01):
jmlr.cls
@@ -265,16 +276,16 @@ v1.09:
* Added \label to \jmlrmaketitlehook
-v1.08:
+v1.08 (2010-07-27):
* Fixed \thanks so that the footnote symbol is raised and isn't
followed by a full stop.
-v1.07:
+v1.07 (2010-06-30):
* Added check for two column
-v1.06:
+v1.06 (2010-06-17):
jmlr.cls
diff --git a/macros/latex/contrib/jmlr/README b/macros/latex/contrib/jmlr/README
index 92ce503fcf..fc8800b9eb 100644
--- a/macros/latex/contrib/jmlr/README
+++ b/macros/latex/contrib/jmlr/README
@@ -1,6 +1,6 @@
-LaTeX Class : jmlr bundle v1.24
+LaTeX Class : jmlr bundle v1.25
-Last Modified : 2017-08-01
+Last Modified : 2020-01-17
Author : Nicola L. C. Talbot
diff --git a/macros/latex/contrib/jmlr/jmlr.dtx b/macros/latex/contrib/jmlr/jmlr.dtx
index 57d9136911..22a9621139 100644
--- a/macros/latex/contrib/jmlr/jmlr.dtx
+++ b/macros/latex/contrib/jmlr/jmlr.dtx
@@ -8,7 +8,7 @@
% -author "Nicola Talbot"
% -section "chapter"
% jmlr
-% Created on 2017/8/1 16:57
+% Created on 2020/1/17 16:46
%\fi
%\iffalse
%<*package>
@@ -31,7 +31,7 @@
%\fi
% \iffalse
% Doc-Source file to use with LaTeX2e
-% Copyright (C) 2017 Nicola Talbot, all rights reserved.
+% Copyright (C) 2020 Nicola Talbot, all rights reserved.
% \fi
% \iffalse
%<*driver>
@@ -52,7 +52,7 @@ Research (PMLR)},
\doxitem{Option}{option}{package options}
-\CheckSum{5030}
+\CheckSum{5241}
\newcommand*{\appopt}[1]{\texttt{-{}-#1}}
@@ -70,7 +70,7 @@ Research (PMLR)},
% \author{Nicola L. C. Talbot\\[10pt]
%\url{http://www.dickimaw-books.com/}}
%
-% \date{2017-08-01 (version 1.24)}
+% \date{2020-01-17 (version 1.25)}
% \maketitle
%\tableofcontents
%
@@ -1749,7 +1749,7 @@ Research (PMLR)},
%Non-class dependent code. This package is automatically loaded by
%\cls{jmlr} but may be used with other classes.
% \begin{macrocode}
-\ProvidesPackage{jmlrutils}[2017/08/01]
+\ProvidesPackage{jmlrutils}[2020/01/17 v1.25 (NLCT)]
% \end{macrocode}
% Package options:
%\begin{macro}{\ifjmlrutilsmaths}
@@ -2414,12 +2414,18 @@ Research (PMLR)},
\newcommand{\jmlrQED}{\hfill\jmlrBlackBox\par\bigskip}
% \end{macrocode}
%\end{macro}
+%\begin{macro}{\proofname}
+%\changes{1.25}{2020-01-17}{new}
+% \begin{macrocode}
+\providecommand{\proofname}{Proof}
+% \end{macrocode}
+%\end{macro}
%\begin{environment}{proof}
% Proof environment
% \begin{macrocode}
\newenvironment{proof}%
{%
- \par\noindent{\bfseries\upshape Proof\ }%
+ \par\noindent{\bfseries\upshape \proofname\ }%
}%
{\jmlrQED}
% \end{macrocode}
@@ -2670,7 +2676,7 @@ Research (PMLR)},
% Declare class and required TeX format:
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
-\ProvidesClass{jmlr}[2017/08/01 v1.24 (NLCT) Journal of Machine Learning Research]
+\ProvidesClass{jmlr}[2020/01/17 v1.25 (NLCT) Journal of Machine Learning Research]
% \end{macrocode}
%\changes{1.10}{2011-01-05}{hyperref now loaded by jmlr instead of
%jmlrbook}
@@ -2730,7 +2736,7 @@ Research (PMLR)},
% Can't load \sty{jmlrutils} here but need the \cs{iftablecaptiontop}
% conditional for the class options.
%\begin{macro}{\iftablecaptiontop}
-%\changes{1.07}{2010-06-17}{new}
+%\changes{1.06}{2010-06-17}{new}
% \begin{macrocode}
\newif\iftablecaptiontop
\tablecaptiontoptrue
@@ -2956,7 +2962,7 @@ Research (PMLR)},
\setlength\algomargin{0pt}
% \end{macrocode}
%Load \sty{jmlrutils} before \sty{hyperref}.
-%\changes{1.24}{??}{added \styfmt{jmlrutils}}
+%\changes{1.24}{2017-08-01}{added \styfmt{jmlrutils}}
% \begin{macrocode}
\RequirePackage{jmlrutils}
% \end{macrocode}
@@ -2972,7 +2978,7 @@ Research (PMLR)},
\@ifundefined{@pre@hyperref}{}{\@pre@hyperref}
% \end{macrocode}
% Load \sty{hyperref}:
-%\changes{1.19}{??}{replaced \cs{usepackage} with \cs{RequirePackage}}
+%\changes{1.19}{2014-09-29}{replaced \cs{usepackage} with \cs{RequirePackage}}
% \begin{macrocode}
\RequirePackage{hyperref}
\RequirePackage{nameref}
@@ -3954,12 +3960,22 @@ Keywords:} \ignorespaces}%
%\end{macro}
%
% Modify \cs{includegraphics} so that it can pick up the greyscale
-% version of images if this is the print version.
-%% \begin{macrocode}
+% version of images if this is the print version. (Extension
+% shouldn't be specified.)
+% \begin{macrocode}
\ifjmlrhtml
\else
\let\@org@Ginclude@graphics\Ginclude@graphics
- \def\Ginclude@graphics#1{%
+% \end{macrocode}
+% Since \sty{graphics} 2019/07/01, the file name parsing has changed
+% to allow for UTF-8 characters. So provide patches for the old and
+% new versions and work out which one to use.
+%\changes{1.25}{2020-01-17}{added check for graphics.sty version}
+%\begin{macro}{\@jmlr@old@Ginclude@graphics}
+%\changes{1.25}{2020-01-17}{new}
+%This is a patched version of the old \cs{Ginclude@graphics}.
+% \begin{macrocode}
+ \def\@jmlr@old@Ginclude@graphics#1{%
\begingroup
\let\input@path\Ginput@path
\ifprint{\filename@parse{#1-gray}}{\filename@parse{#1}}%
@@ -3995,6 +4011,101 @@ Keywords:} \ignorespaces}%
\csname Gin@rule@\Gin@ext\endcsname{\Gin@base\Gin@ext}}%
\fi
\endgroup}
+% \end{macrocode}
+%\end{macro}
+%\begin{macro}{\@jmlr@new@Ginclude@graphics}
+%\changes{1.25}{2020-01-17}{new}
+%This is a patch of the new version.
+% \begin{macrocode}
+\def\@jmlr@new@Ginclude@graphics#1{%
+ \ifx\detokenize\@undefined\else
+ \edef\Gin@extensions{\detokenize\expandafter{\Gin@extensions}}%
+ \fi
+ \begingroup
+ \let\input@path\Ginput@path
+ \ifprint{\set@curr@file{#1-gray}}{\set@curr@file{#1}}%
+ \expandafter\filename@parse\expandafter{\@curr@file}%
+ \ifx\filename@ext\Gin@gzext
+ \expandafter\filename@parse\expandafter{\filename@base}%
+ \ifx\filename@ext\relax
+ \let\filename@ext\Gin@gzext
+ \else
+ \edef\Gin@ext{\Gin@ext\Gin@sepdefault\Gin@gzext}%
+ \fi
+ \fi
+ \let\@jmlr@filename@ext\filename@ext
+ \ifx\filename@ext\relax
+ \@for\Gin@temp:=\Gin@extensions\do{%
+ \ifx\Gin@ext\relax
+ \Gin@getbase\Gin@temp
+ \fi}%
+ \ifprint
+ {\ifx\Gin@ext\relax
+ \set@curr@file{#1}%
+ \expandafter\filename@parse\expandafter{\@curr@file}%
+ \ifx\filename@ext\Gin@gzext
+ \expandafter\filename@parse\expandafter{\filename@base}%
+ \ifx\filename@ext\relax
+ \let\filename@ext\Gin@gzext
+ \else
+ \edef\Gin@ext{\Gin@ext\Gin@sepdefault\Gin@gzext}%
+ \fi
+ \fi
+ \let\@jmlr@filename@ext\filename@ext
+ \ifx\filename@ext\relax
+ \@for\Gin@temp:=\Gin@extensions\do{%
+ \ifx\Gin@ext\relax
+ \Gin@getbase\Gin@temp
+ \fi}%
+ \fi
+ \fi}{}%
+ \fi
+ \ifx\@jmlr@filename@ext\relax
+ \else
+ \Gin@getbase{\Gin@sepdefault\filename@ext}%
+ \ifx\Gin@ext\relax
+ \let\Gin@savedbase\filename@base
+ \let\Gin@savedext\filename@ext
+ \edef\filename@base{\filename@base\Gin@sepdefault\filename@ext}%
+ \let\filename@ext\relax
+ \@for\Gin@temp:=\Gin@extensions\do{%
+ \ifx\Gin@ext\relax
+ \Gin@getbase\Gin@temp
+ \fi}%
+ \ifx\Gin@ext\relax
+ \let\filename@base\Gin@savedbase
+ \let\filename@ext\Gin@savedext
+ \fi
+ \fi
+ \ifx\Gin@ext\relax
+ \@warning{File `#1' not found}%
+ \def\Gin@base{\filename@area\filename@base}%
+ \edef\Gin@ext{\Gin@sepdefault\filename@ext}%
+ \fi
+ \fi
+ \ifx\Gin@ext\relax
+ \@latex@error{File `#1' not found}%
+ {I could not locate the file with any of these extensions:^^J%
+ \Gin@extensions^^J\@ehc}%
+ \else
+ \@ifundefined{Gin@rule@\Gin@ext}%
+ {\ifx\Gin@rule@*\@undefined
+ \@latex@error{Unknown graphics extension: \Gin@ext}\@ehc
+ \else
+ \expandafter\Gin@setfile\Gin@rule@*{\Gin@base\Gin@ext}%
+ \fi}%
+ {\expandafter\expandafter\expandafter\Gin@setfile
+ \csname Gin@rule@\Gin@ext\endcsname{\Gin@base\Gin@ext}}%
+ \fi
+ \endgroup
+}
+% \end{macrocode}
+%\end{macro}
+%Determine which one to use:
+% \begin{macrocode}
+ \@ifpackagelater{graphics}{2019/07/01}
+ {\let\Ginclude@graphics\@jmlr@new@Ginclude@graphics}%
+ {\let\Ginclude@graphics\@jmlr@old@Ginclude@graphics}%
\fi
% \end{macrocode}
%
@@ -4678,7 +4789,7 @@ Keywords:} \ignorespaces}%
% \end{macrocode}
% Declare class:
% \begin{macrocode}
-\ProvidesClass{jmlrbook}[2017/08/01 v1.24 (NLCT) JMLR Book Style]
+\ProvidesClass{jmlrbook}[2020/01/17 v1.25 (NLCT) JMLR Book Style]
% \end{macrocode}
% Need \sty{xkeyval} package to have key=value class options
% \begin{macrocode}
@@ -5947,7 +6058,7 @@ Keywords:} \ignorespaces}%
}
\begin{papers}[]
% \end{macrocode}
-%\changes{1.07}{2010-07-30}{Added check for two column style}
+%\changes{1.07}{2010-06-30}{Added check for two column style}
% \begin{macrocode}
\if@twocolumn
\def\@jmlr@restore{\twocolumn}%
@@ -6541,7 +6652,7 @@ not permitted outside `jmlrpapers' environment}{}%
\newcommand*\l@chapterauthor[2]{%
\ifnum \c@tocdepth >\m@ne
% \end{macrocode}
-%\changes{1.11}{2011/01/06}{removed penalty}
+%\changes{1.11}{2011-03-24}{removed penalty}
% \begin{macrocode}
\begingroup
\parindent \z@
diff --git a/macros/latex/contrib/jmlr/jmlr.ins b/macros/latex/contrib/jmlr/jmlr.ins
index 0fff82ddfd..bb4ec3dbfb 100644
--- a/macros/latex/contrib/jmlr/jmlr.ins
+++ b/macros/latex/contrib/jmlr/jmlr.ins
@@ -1,10 +1,10 @@
-% jmlr.ins generated using makedtx version 1.2 2017/8/1 16:57
+% jmlr.ins generated using makedtx version 1.2 2020/1/17 16:46
\input docstrip
\preamble
jmlr.dtx
- Copyright 2017 Nicola Talbot
+ Copyright 2020 Nicola Talbot
This work may be distributed and/or modified under the
conditions of the LaTeX Project Public License, either version 1.3
diff --git a/macros/latex/contrib/jmlr/jmlr.pdf b/macros/latex/contrib/jmlr/jmlr.pdf
index 6a75b8d526..bf6565a3a1 100644
--- a/macros/latex/contrib/jmlr/jmlr.pdf
+++ b/macros/latex/contrib/jmlr/jmlr.pdf
Binary files differ
diff --git a/macros/latex/contrib/jmlr/sample-books/jmlrbook-sample.pdf b/macros/latex/contrib/jmlr/sample-books/jmlrbook-sample.pdf
index 4d2cabbda9..9dff0e770a 100644
--- a/macros/latex/contrib/jmlr/sample-books/jmlrbook-sample.pdf
+++ b/macros/latex/contrib/jmlr/sample-books/jmlrbook-sample.pdf
Binary files differ
diff --git a/macros/latex/contrib/jmlr/sample-books/proceedings-sample.pdf b/macros/latex/contrib/jmlr/sample-books/proceedings-sample.pdf
index e71265841b..2dacde7e1a 100644
--- a/macros/latex/contrib/jmlr/sample-books/proceedings-sample.pdf
+++ b/macros/latex/contrib/jmlr/sample-books/proceedings-sample.pdf
Binary files differ
diff --git a/macros/latex/contrib/jmlr/sample-papers/jmlr-sample.pdf b/macros/latex/contrib/jmlr/sample-papers/jmlr-sample.pdf
index 4b6c39852f..0bf2de4a70 100644
--- a/macros/latex/contrib/jmlr/sample-papers/jmlr-sample.pdf
+++ b/macros/latex/contrib/jmlr/sample-papers/jmlr-sample.pdf
Binary files differ
diff --git a/macros/latex/contrib/jmlr/sample-papers/jmlrwcp-sample.pdf b/macros/latex/contrib/jmlr/sample-papers/jmlrwcp-sample.pdf
index 6115f7cbf2..a2207ec188 100644
--- a/macros/latex/contrib/jmlr/sample-papers/jmlrwcp-sample.pdf
+++ b/macros/latex/contrib/jmlr/sample-papers/jmlrwcp-sample.pdf
Binary files differ
diff --git a/macros/latex/contrib/mathtools/empheq.pdf b/macros/latex/contrib/mathtools/empheq.pdf
index f2430fb326..f0fbac2512 100644
--- a/macros/latex/contrib/mathtools/empheq.pdf
+++ b/macros/latex/contrib/mathtools/empheq.pdf
Binary files differ
diff --git a/macros/latex/contrib/mathtools/mathtools.dtx b/macros/latex/contrib/mathtools/mathtools.dtx
index c9effb2b78..0a08c4fb26 100644
--- a/macros/latex/contrib/mathtools/mathtools.dtx
+++ b/macros/latex/contrib/mathtools/mathtools.dtx
@@ -68,7 +68,7 @@
\input docstrip.tex
\Msg{************************************************************************}
\Msg{* Installation}
-\Msg{* Package: mathtools 2019/07/31 v1.22}
+\Msg{* Package: mathtools 2020/01/17 v1.23}
\Msg{************************************************************************}
\keepsilent
@@ -131,7 +131,7 @@ and the derived files
%<*driver>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{mathtools.drv}%
- [2019/07/31 v1.22 mathematical typesetting tools]
+ [2020/01/17 v1.23 mathematical typesetting tools]
\documentclass{ltxdoc}
\IfFileExists{fourier.sty}{\usepackage{fourier}}{}
\addtolength\marginparwidth{-25pt}
@@ -573,7 +573,7 @@ colorlinks,
% \cramped[\scriptstyle]{x^2} \leftrightarrow {\scriptstyle x^2}
% \]
% You may be surprised how often the cramped style can be
-% beneficial yo your output. Take a look at this example:
+% beneficial to your output. Take a look at this example:
% \begin{verbatim}
% \begin{quote}
% The 2005 Euro\TeX{} conference is held in Abbaye des
@@ -781,7 +781,7 @@ colorlinks,
% \label{sec:swapping}
%
% One feature that the plain old \env{equation} environment has that
-% the \AmS\ environments does not (because of thechnical reasons), is
+% the \AmS\ environments does not (because of technical reasons), is
% the feature of using less space above the equation if the situation
% presents itself. The \AmS\ environments cannot do this, but one can
% manually, using
@@ -1547,7 +1547,7 @@ colorlinks,
% relation within the first line, then all lines in the display
% should be aligned at the left most edge of the first line, and all
% subsequent lines should be indented by 2\,em (or if needed by a
-% smaller amount). That is we are talking about displayes that end up
+% smaller amount). That is we are talking about displays that end up
% looking like this
% \begin{align*}
% \MoveEqLeft \framebox[10cm][c]{Long first line}\\
@@ -1582,14 +1582,20 @@ colorlinks,
% & + \framebox[4cm][c]{ last part}
% \end{align*}
%
+%
+% \noindent\textbf{Caveat regarding \cs{MoveEqLeft}}: If the first
+% part of the equation starts with say \verb|[a]|, \cs{MoveEqLeft} may
+% attempt to eat it! You can prevent this by specifying the optional
+% argument (remember the default is the same as \cs{MoveEqLeft[2]} or
+% by using \cs{MoveEqLeft\{\}}.
+%
% \subsubsection{Boxing a single line in an alignment}
%
-% The \texttt{amsmath} package provie the \cs{boxed} macro to box
+% The \texttt{amsmath} package provides the \cs{boxed} macro to box
% material in math mode. But this of course will not work if the box
% should cross an alignment point. We provide a macro that
-% can.\footnote{Note that internally \cs{Aboxed} does use \cs{boxed}.}
-% \hskip1sp
-% \marginpar{%
+% can.\footnote{Note that internally \cs{Aboxed} does use
+% \cs{boxed}.} \hskip1sp \marginpar{%
% \parbox[b]{\marginparwidth}{\small\sffamily\raggedright
% \strut Evolved from a request by\\Merciadri Luca\\
% 2010/06/28\\on comp.text.tex%
@@ -1737,10 +1743,10 @@ colorlinks,
% \shortvdotswithin{=}
% & = d
% \end{align*}
-% Thus \verb?\vdotswithin{=}? create a box corersponding to
-% \verb?{}={}? and typeset a >>$\vdots$<< centered inside it. When doing
-% this as a normal line in an alignment leaves us with excessive space
-% which \verb?\shortvdotswithin{=}? takes care with for us.
+% Thus \verb?\vdotswithin{=}? creates a box corresponding to
+% \verb?{}={}? and typeset a >>$\vdots$<< centered inside it. When
+% doing this as a normal line in an alignment leaves us with excessive
+% space which \verb?\shortvdotswithin{=}? takes care with for us.
%
% \verb?\shortvdotswithin{=}? corresponds to
% \begin{verbatim}
@@ -1820,7 +1826,7 @@ colorlinks,
% \cs{shortintertext} and \cs{intertext}. \tsxPosting{Tobias Weh
% \\(referring to a suggestion by Chung-chieh Shan)}{2011/05/29}
% It can be illustrated using the following example, an interested
-% reader, can apply it with and with out the original \cs{intertext}
+% reader, can apply it with and without the original \cs{intertext}
% and \cs{shortintertext}.
% \begin{verbatim}
% % the original \intertext and \shortintertext
@@ -1838,7 +1844,7 @@ colorlinks,
% \end{verbatim}
%
% We now fix this internaly for both \cs{intertext} and
-% \cs{shortintertext}, plus we add the posibility to fine tune
+% \cs{shortintertext}, plus we add the possibility to fine tune
% spacing around these constructions. The original versions can be
% brought back using the \texttt{original-x} keys below.
% \begin{codesyntax}
@@ -2056,7 +2062,7 @@ colorlinks,
% aloud. Also we hide the `given' symbol for easy
% replacement.\footnote{The \cs{nonscript} construction removes the
% \cs{:} in sub- and superscript, this might not always be
-% peferable. You can use
+% preferable. You can use
% \cs{mathchoice\{}\cs{:\}\{}\cs{:\}\{}\cs{,\}\{}\cs{,\}} instead of \cs{nonscript}\cs{:}.}
%
% Combining with \pkg{etoolbox} it becomes easy to make a function
@@ -2120,9 +2126,10 @@ colorlinks,
% of arguments. We will consider this for a future release.
%
% \medskip\noindent\textbf{Note 2:} If you want to define your own
-% manual scaler macros, it is importent that you besides \cs{foo} also
+% manual scaler macros, it is important that you besides \cs{foo} also
% defines \cs{fool} and \cs{foor}. When a scaler is specified, in say
-% \cs{abs[\cs{big}]}\marg{arg}, we actually use \cs{bigl} and \cs{bigr}.
+% \cs{abs[\cs{big}]}\marg{arg}, we actually use \cs{bigl} and
+% \cs{bigr}.
%
%
% \subsubsection{Expert use}
@@ -2131,7 +2138,7 @@ colorlinks,
% \cs{DeclarePairedDelimiterX} we make a few changes such that the
% auto scaled \cs{left} and \cs{right} fences behave as opening and
% closing fences, i.e.\ $\sin(x)$ vs. $\sin\left(x\right)$ (the later
-% made via \verb|$\sin\left(x\right)$|), notice the gab between
+% made via \verb|$\sin\left(x\right)$|), notice the gap between
% '$\sin$' and '('. In some special cases it may be useful to be
% able to tinker with the behavior.
% \begin{codesyntax}
@@ -2160,7 +2167,7 @@ colorlinks,
% The two \texttt{nostar...} versions look the same, but they are
% not. In most (math) fonts, the first item in this list will be
% different from the rest (the superscript sits
-% higher).\footnote{Interestingly it dod not show up in the font of
+% higher).\footnote{Interestingly it did not show up in the font of
% this manual, which uses the \pkg{fourier} font set.}
% \begin{verbatim}
% \mathclose{\rvert}^2\mathclose\rvert^2\rvert^2
@@ -2420,10 +2427,11 @@ colorlinks,
%
% \medskip\noindent \textbf{Caveat:} Italic correction is a
% treacherous area. For example any penalties will cancel the italic
-% correction inserted by \verb|\(| (for an explanation see
-% \cite{TBT}, section 4.3.3). We have changed Michaels original to
-% accomodate one specific penalty construction: the \emph{tie}, i.e.,
-% >>\verb|text~\(|<< will work as expected (as~of July, 2014).
+% correction inserted by
+% \verb|\(| (for an explanation see \cite{TBT}, section 4.3.3). We
+% have changed Michaels original to accommodate one specific penalty
+% construction: the \emph{tie}, i.e.,
+% >>\verb|text~\(|<< will work as expected (as~of July, 2014).
%
% \subsection{Left sub/superscripts}
%
@@ -2798,7 +2806,7 @@ colorlinks,
% \begin{macrocode}
%<*package>
\ProvidesPackage{mathtools}%
- [2019/07/31 v1.22 mathematical typesetting tools]
+ [2020/01/17 v1.23 mathematical typesetting tools]
% \end{macrocode}
% \changes{v1.10}{2011/02/12}{Might as well make sure that we need the
% latest version of \texttt{mhsetup}}
@@ -3109,8 +3117,10 @@ colorlinks,
% \changes{v1.12}{2011/06/08}{Added the falsification of manual tag
% when show manual tags is off and maual tag is not referred to}
% \changes{v1.19}{2017/03/31}{Added MH\_ prefix}
+% \changes{v1.23}{2020/01/17}{Added \cs{kern1sp} in a few places to
+% make sure the tag has a non zero width.}
% \begin{macrocode}
- { \global\MH_set_boolean_F:n {manual_tag} }
+ { \global\MH_set_boolean_F:n {manual_tag} \kern1sp } % kern added 2020
{ \MT_prev_tagform:n {#1} }
\@safe@activesfalse
}
@@ -3118,7 +3128,7 @@ colorlinks,
{
\@safe@activestrue
\@ifundefined{MT_r_\df@label}
- { }
+ { \kern1sp }% kern added 2020
{ \refstepcounter{equation}\MT_prev_tagform:n {#1} }
\@safe@activesfalse
}
diff --git a/macros/latex/contrib/mathtools/mathtools.pdf b/macros/latex/contrib/mathtools/mathtools.pdf
index b0f1857b61..2c468fadbe 100644
--- a/macros/latex/contrib/mathtools/mathtools.pdf
+++ b/macros/latex/contrib/mathtools/mathtools.pdf
Binary files differ
diff --git a/macros/latex/contrib/mathtools/mhsetup.pdf b/macros/latex/contrib/mathtools/mhsetup.pdf
index 1657783ed3..8f608c74ae 100644
--- a/macros/latex/contrib/mathtools/mhsetup.pdf
+++ b/macros/latex/contrib/mathtools/mhsetup.pdf
Binary files differ
diff --git a/macros/latex/contrib/thorshammer/README.md b/macros/latex/contrib/thorshammer/README.md
new file mode 100644
index 0000000000..f4c622a13c
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/README.md
@@ -0,0 +1,33 @@
+The thorshammer Package
+Author: D. P. Story
+Dated: 2020-01-13
+
+WARNING: Adobe Acrobat DC or Adobe Acrobat XI is required for
+post PDF-creation. Any PDF-creator application is supported.
+
+This package implements an idea by Thorsten G. for assessment
+using PDF quizzes produced by the exerquiz package. Thorsten not
+only wanted to pose multiple choice, multiple selection, and
+fill-in type questions, but also wanted to ask extended response
+questions that would be manually evaluated. Once the quiz is
+graded, the instructor may optionally pass the quizzes through
+an Acrobat action sequence to extract the student's name and
+grade from the quizzes. The extracted information is saved to a
+tab-delimited TXT file. The instructor can later merge this file
+into a larger spreadsheet.
+
+Note: Unzip action-sequences.zip to obtain the action-sequences folder.
+
+If intriguing, install thorshammer and try this workflow.
+
+Enjoy!
+
+Now, I must get back to my retirement.
+
+
+D. P. Story
+www.acrotex.net
+dpstory@uakron.edu
+dpstory@acrotex.net
+
+
diff --git a/macros/latex/contrib/thorshammer/container.pdf b/macros/latex/contrib/thorshammer/container.pdf
new file mode 100644
index 0000000000..5a1285820b
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/container.pdf
Binary files differ
diff --git a/macros/latex/contrib/thorshammer/docs/install-action-seq.pdf b/macros/latex/contrib/thorshammer/docs/install-action-seq.pdf
new file mode 100644
index 0000000000..e7a68382e0
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/docs/install-action-seq.pdf
Binary files differ
diff --git a/macros/latex/contrib/thorshammer/docs/thmclass.pdf b/macros/latex/contrib/thorshammer/docs/thmclass.pdf
new file mode 100644
index 0000000000..50e2da723a
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/docs/thmclass.pdf
Binary files differ
diff --git a/macros/latex/contrib/thorshammer/docs/thmclass.tex b/macros/latex/contrib/thorshammer/docs/thmclass.tex
new file mode 100644
index 0000000000..1603ce6c93
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/docs/thmclass.tex
@@ -0,0 +1,970 @@
+\RequirePackage[use=publish]{spdef}
+\documentclass{article}
+\usepackage[fleqn]{amsmath}
+\usepackage[designi,forcolorpaper,latextoc,extended]{web}
+\usepackage{eforms}
+\usepackage{dirtree}
+\usepackage{fancyvrb}
+
+\usepackage{xbmks}
+\xbmksetup{colors={int=red},styles={intbf}}
+%\DeclareInitView{layoutmag={navitab:UseOutlines}}
+\hypersetup{pdfpagemode=UseOutlines}
+
+
+\ifpublish % developer packages
+\def\useThese{\usepackage[altbullet]{lucidbry}
+\usepackage[active]{srcltx}}
+\expandafter\useThese\fi
+
+\newcommand\newtopic{\par\ifdim\lastskip>0pt\relax\vskip-\lastskip\fi
+\vskip\medskipamount}
+
+\tocPartTitle{\tops{\protect\makebox[0pt][r]{\thepart\hspace{1em}}}{\thepart\space}#1}
+\let\partSave\part
+\def\part#1{\par\addvspace{4ex}\bgroup\let\newpage\relax\partSave{#1}\egroup\addvspace{2ex}}
+
+\let\tops\texorpdfstring
+
+\DeclareDocInfo
+{
+ university={Acro\negthinspace\TeX.Net},
+% title={The \textsf{thorshammer} package\tops{\\[1ex]}{: }%
+% Documentation for \tops{\textsf}{}{thmclass.ps1}},
+ title={The \textsf{thorshammer} package\tops{\\[1ex]}{: }%
+ Documentation for the system scripts},
+ author={D. P. Story \& Thorsten Grothe},
+ email={dpstory@acrotex.net},
+ subject=Documentation for thmclass.ps1,
+ talksite={\url{www.acrotex.net}},
+ version={1.5.7, 2020/01/13},
+ Keywords={LaTeX, AcroTeX, Powershell, thorshammer},
+ copyrightStatus=True,
+ copyrightNotice={Copyright (C) \the\year, D. P. Story},
+ copyrightInfoURL={http://www.acrotex.net}
+}
+
+
+\useFullWidthForPaper
+
+\def\dps{$\mbox{$\mathfrak D$\kern-.3em\mbox{$\mathfrak P$}%
+ \kern-.6em \hbox{$\mathcal S$}}$}
+\let\pkg\textsf
+\def\cs#1{\texttt{\char`\\#1}}
+\let\opt\textsf
+\let\app\textsf
+\let\uif\textsf
+\def\thescript{\texttt{thmclass.ps1}}
+\def\thebatch{\texttt{runps1.bat}}
+\def\dtt#1{\texttt{\$#1}}
+\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}}
+\def\meta#1{\textsl{\texttt{#1}}}
+\def\darg#1{\texttt{\char123\relax#1\char125\relax}}
+\newenvironment{lquote}
+ {\list{}{}%
+ \item\relax}
+ {\endlist}
+
+\makeatletter
+%\setlength{\DT@offset}{(\linewidth-1.4in)/2}
+\renewcommand{\paragraph}
+ {\@startsection{paragraph}{4}{0pt}{6pt}{-3pt}{\bfseries}}
+\renewcommand{\subparagraph}
+ {\@startsection{subparagraph}{5}{\parindent}{6pt}{-3pt}%
+ {\normalfont\normalsize\bfseries}}
+\def\chnglabelname#1{\edef\@currentlabelname{#1}}
+\makeatother
+
+\begin{document}
+
+\maketitle
+
+\pdfbookmarkx[1]{Title Page}[action={\Named{FirstPage}}]{TitlePage}
+\pdfbookmarkx[1]{The thorshammer package}[action={\GoToR/F(thors-the-man.pdf)/D[0 /Fit]},color=blue,style={bf}]{thorhammer}
+\pdfbookmarkx[1]{Links to AcroTeX.Net}[action={/S/GoTo/D(undefined)},%
+ color=magenta,style={bf}]{acrotex}
+\belowpdfbookmarkx{http://www.acrotex.net}[action={\URI{http://www.acrotex.net}},%
+ color=magenta,style={bf}]{home}
+\belowpdfbookmarkx{http://blog.acrotex.net}[action={\URI{http://blog.acrotex.net}},%
+ color=magenta,style={bf}]{blog}
+
+
+\selectColors{linkColor=black}
+\tableofcontents
+\selectColors{linkColor=webgreen}
+
+\section{Introduction}
+
+\textbf{\hyperref[PartI]{Part I}} describes how to execute {\thescript} and
+documents all the subordinate files and folders it generates.
+The \thescript\space file is a \app{Powershell} script file
+written, for the most part, \emph{by the great Thor himself} to
+meet the needs of his classes. It can be used ``as is'' or
+modified to conform it to your requirements. The script is
+designed to be used with the \pkg{thorshammer} package, but this
+is not a requirement.
+
+The file structure of Thor may not be for everyone, \textbf{\hyperref[PartII]{Part II}} describes a set
+of ``standalone'' scripts, which were derived from the scripts in \textbf{Part I}.
+
+\paragraph*{From the Acro\negthinspace\TeX{} Legal Department.}
+We offer no guarantees and accept no liabilities. Test the
+scripts extensively to be sure they are working for you. Modify the script
+as you will, but don't bother us with your changes, unless they are improvements. %\verb|:-{)|
+
+
+\paragraph*{Platforms.} The script has been tested on
+\textsf{Windows OS} and \app{Linux}. It is our understanding
+that \app{Powershell} can be installed and executed on
+\textsf{MacOS}, so this script \emph{may} have use on that
+platform as well.
+
+\part{Using the Thor system}\label{PartI}
+
+\noindent Thor has developed his own file structure for his class, this
+structure may be useful to your own classroom. Here, we describe the system
+that has been developed. Carefully read this part of the documentation to
+determine if Thor's scheme can work for you. \medskip
+
+\section{Deploying {\thescript} \textsl{et al}}
+
+Locate the three files \thescript, \thebatch, and \texttt{sample-vars.txt}
+from the \texttt{system-scripts} folder of the
+\pkg{thorshammer} distribution.
+
+\paragraph*{The first things first.} (1) \emph{Copy}
+\thescript, \thebatch, and \texttt{sample-vars.txt} to a
+working folder. (2) Open the \app{Powershell} file \thescript{}
+in a text editor and edit the value of the variable appropriate to your platform
+\texttt{\$pathThorshammerWin} or \texttt{\$pathThorshammerLin},
+being sure the default path points to your \pkg{thorshammer}
+folder, and if not, modify the path to point to the folder
+of the \pkg{thorshammer} distribution on your computer.\footnote{The purpose of this is to
+grab the two support files \texttt{container.pdf} and
+\texttt{terminate-batch.pdf}. If your {\TeX} installation has
+installed these two files elsewhere, find them, and modify the
+path to point to the folder containing these two files.}
+
+\section{Executing \thescript}
+
+On \app{Windows}, the easiest way to execute \thescript\space is
+through the BAT file \thebatch.\footnote{The authors have little
+knowledge of how to do this on \app{Mac OS}. An interested user
+on \app{Mac OS} would need to advise us.} Running the script
+requires the input of eight (8) values for variables, these are
+listed below and described in the order they are expected to be
+input.
+
+\paragraph*{Eight basic variables}\label{para:eight}
+\begin{enumerate}
+ \item \dtt{class}: The name of the class, could be name as
+ listed in the college catalog (MAT101, STA221, HH21B,
+ A21A, WF23, \dots) or something more understandable (calc1,
+ alg1, euhist, \dots)\footnote{The value of this variable is used in the file name
+ of the TEX template file; consequently, this value should be kept short, yet meaningful.}
+
+ \item \dtt{number}: The quiz or exam number. The value of
+ this variable is not required to be a number.\footnotemark[\thefootnote]
+
+ \item \dtt{subject}: Field of study, such as Math, German,
+ History, and so on.\footnotemark[\thefootnote]
+
+ \item \dtt{theme}: The topic of this exam: factoring, grammar, 20thcentury, etc.\footnotemark[\thefootnote]
+
+
+ \item \dtt{instrName}: Instructor's name. The name should be
+ a single word that identifies the instructor (Thor,
+ Newton, Banach, and so on).\footnotemark[\thefootnote]
+
+
+ \item \dtt{date}: The date of the exam.
+
+
+ \item \dtt{time}: The length of the exam; this is, the time
+ the students have to work on the exam.
+
+ \item \dtt{classPath}: The full path to the folder that
+ contains the quizzes of the class.
+
+\end{enumerate}
+
+\begin{comment}
+\goodbreak
+\section{Execution modes: interactive and automatic}
+
+There are two execution modes: (1) interactive and (2)
+automatic.
+
+\subparagraph*{(1) Interactive:} If you execute \thebatch\space on the
+ \uif{Command Prompt}, you are offered three options:\footnote{Instructions are in German or English}\par\medskip
+ \begin{minipage}{\linewidth-\parindent}
+ \begin{enumerate}
+ \item[(1)] interactive query of individual variables (class,
+ teacher abbreviation, \dots)
+
+ Here, you are asked in enter the values for each of the
+ above listed eight variables.
+ \item[(2)] No query: test with default values
+
+ Used for testing purposes; automatically sets the values
+ of the eight variables.
+ \item[(q)] Exit the script
+ \end{enumerate}
+ \end{minipage}
+\subparagraph*{(2) Automatic:} For the automatic, the script gets
+ the values for the eight variables from a TXT file. It is
+ this option that is the main approach to building your file
+ structure, and is the topic of the rest of the discussion in
+ the documentation.
+\end{comment}
+
+\subsection{On running \thescript}\label{Focus}
+
+Now that you have read a brief description of the eight variables, rename the
+file \texttt{sample-vars.txt} in your working folder to something short yet
+appropriate to your work (perhaps rename it to just \texttt{class.txt}). In
+this document, we shall refer to the renamed TXT file as
+\texttt{\ameta{varlist}.txt}. Open \texttt{\ameta{varlist}.txt} in a text
+editor and modify the left column to values appropriate to your class. The
+contents of \ameta{varlist}\texttt{.txt} has the following form (shown with
+default values which need to be changed):
+\begin{Verbatim}[xleftmargin=\parindent]
+alg1 # class
+1 # number
+maths # subject
+factoring # theme or topic
+THOR # instrName
+01.01.2019 # date
+60 Min. # time
+C:/temp # classPath
+\end{Verbatim}
+Now execute \thebatch\space with arguments \texttt{thmclass} and
+\texttt{\ameta{varlist}.txt} from the \uif{Command Prompt}:\footnote{The \uif{Command Prompt} needs
+to be located in the folder that contains \thescript, \thebatch, and \texttt{sample-vars.txt}}
+\begin{equation}
+ \fbox{\ttfamily runps1 thmclass \ameta{varlist}\texttt{.txt}}\label{dis:thmclass}
+\end{equation}
+\thescript\space reads the data contained in
+\ameta{varlist}\texttt{.txt}. Using a batch file is the easiest way of executing the
+\thescript\space with argument \texttt{\ameta{varlist}.txt}.
+
+\subsubsection{The results of running \tops{\thebatch}{runps1.bat}}
+
+Executing `\texttt{runps1 thmclass \ameta{varlist}.txt}', as
+just described (see display~(\ref{dis:thmclass})), creates a
+series of folders and files within the same folder in which
+{\thebatch}, {\thescript}, and \texttt{\ameta{varlist}.txt}
+reside.\medskip
+
+Suppose \texttt{\ameta{varlist}.txt} has the following symbolic
+values:
+\begin{quote}\ttfamily\obeyspaces\catcode`\#=12
+\ameta{class} # class\\
+\ameta{number} # number\\
+\ameta{subject} # subject\\
+\ameta{theme} # theme or topic\\
+\ameta{instrName} # instrName\\
+\ameta{date} # date\\
+\ameta{time} # time\\
+\ameta{classPath} # classPath
+\end{quote}
+
+
+\subsubsection{Structure displayed} Figure~\ref{fig:struct} represents the structure created by \thescript.
+
+\begin{figure}[htb]
+\bgroup
+\hfuzz120pt
+%\makeatletter
+%\hspace*{1.4in}
+\fboxsep0pt\let\BOX\relax
+\begin{center}\BOX{\begin{minipage}{3.5in}
+\dirtree{%
+.1 \ameta{working folder}.
+.2 {runps1.bat}.
+.2 {sample-vars.txt}\DTcomment{rename and edit\footnote{Generically referred to as \texttt{\ameta{varlist}.txt}}}.
+.2 {thmclass.ps1}.
+.2 \ameta{class}.
+.3 \ameta{instrName}.
+.4 backup.
+.4 anSUS (toStudents).
+.4 vonSUS (fromStudents).
+.4 {runps1.bat}.
+%.4 {classFolders.bat}.
+.4 {csvTOcfg.ps1}.
+.4 {classFolders.ps1}.
+%.4 {csvTOcfg.bat}.
+.4 {copyka.ps1}.
+.4 {delka.ps1}.
+.4 {moveka.ps1}.
+.4 {sample-list.csv}\DTcomment{rename and edit\footnote{Generically referred to as \texttt{\ameta{list}.csv}}}.
+.4 {container.pdf}.
+.4 {terminate-batch.pdf}.
+.3 {00-\ameta{class}.cfg}.
+.3 {genquiz.ps1}.
+.3 {runps1.bat}.
+.3 {tex-template.tex}.
+.3 {web.cfg}.
+}
+\end{minipage}}\hfill
+\end{center}
+\egroup
+\caption{Structure created by \thescript}\label{fig:struct}
+\end{figure}
+
+\subsubsection{Structure explained}
+
+We now attempt the Herculean task of explaining each of these.
+\begin{description}
+ \item[\normalfont\ameta{class}] (folder) The folder created by the \ameta{class} variable. This folder
+ contains all the working files and folders of the class you are teaching.
+ \item[\normalfont\ameta{instrName}] (folder) This is a short name for the instructor. This folder contains
+ a number of other folders and files.
+ \begin{description}
+ \item[\normalfont\texttt{backup}] A folder that will contain the
+ instructor's copies of the quizzes generated. When
+ you open the file \texttt{00-\ameta{class}.cfg}, you
+ will find:
+ \verb|\instrPath*{|\ameta{instrName}\texttt{/backup}\verb|}|.
+ \item[\normalfont\texttt{anSUS} (\texttt{toStudents})] A folder to
+ drop the graded quizzes into. This folder name is
+ \texttt{anSUS} when the local language is German and
+ \texttt{toStudents} otherwise.
+ \item[\normalfont\texttt{vonSUS} (\texttt{fromStudents})] The
+ target destination of the script file
+ \texttt{copyka.ps1}. This folder name is
+ \texttt{vonSUS} when the local language is German
+ and \texttt{fromStudents} otherwise.
+
+% \item[\texttt{classFolders.bat}] This batch file that
+% takes the contents of its argument and creates the
+% class folder structure within the \ameta{classPath}
+% folder. See the section on \texttt{classFolders}
+% below for more details.
+ \item[\normalfont\texttt{csvTocfg.ps1}] A \app{Powershell} script
+ that reads the contents of the configuration file \texttt{\ameta{list}.csv} and modifies
+ \texttt{00-\ameta{class}.cfg} by appending appropriate \cs{classMember}
+ statements.
+ \item[\normalfont\texttt{classFolders.ps1}] A \app{Powershell}
+ script file that creates class folders based on the
+ contents of the \texttt{00-\ameta{class}.cfg}
+ file.\footnote{The sysadmin may now allow creation
+ of folders on the system drive; this script may be
+ used for testing on the instructor's own drive.}
+ \item[\normalfont\texttt{copyka.ps1}] A \app{Powershell} script that
+ copies the completed student quizzes from their
+ student folders to the folder \texttt{vonSUS}
+ (\texttt{fromStudents}) where the instructor can
+ operate on them.
+% \item [\texttt{csvTocfg.bat}] A batch file that takes
+% the contents of its argument and modifies
+% \texttt{00-\ameta{class}.cfg}, one level up. It
+% appends the \cs{classMember} data lines.
+% See the section on \texttt{classFolders} below for more
+% details.
+ \item[\normalfont\texttt{delka.ps1}] A \app{Powershell} script
+ that deletes the student quizzes from their personal
+ student folders. (This is done after they are copied
+ using \texttt{copyka.ps1}.)
+ \item[\normalfont\texttt{moveka.ps1}] The \app{Powershell} script
+ that copies and deletes the student quizzes from
+ their personal student folders. \textbf{Not
+ recommended!} I prefer to copy them and verify that
+ they are all successfully copied before deleted them
+ from the personal student folders.
+ \item[\normalfont\texttt{sample-list.csv}] A comma (or semi-colon) delimited file. Each line
+ of the file consists of three entries and has two formulations:
+ \begin{quote}\ttfamily
+ \ameta{first},\ameta{last},\ameta{rel-path}\\[3pt]
+ \ameta{first},\ameta{last},*\ameta{full-path}
+ \end{quote}
+ In the first case, \ameta{rel-path} is the path, relative to the argument of the \cs{classPath},
+ to the student folder; in the second case, \ameta{full-path} is the full path to the student
+ folder.
+
+ You should rename this file and modify its contents to
+ reflect the class names and folder names of your class.
+
+ \item[\normalfont\texttt{container.pdf}] A PDF file used by
+ \textsf{Thor's way} action script. See the manual
+ for the \pkg{thorshammer} package for details.
+ \item[\normalfont\texttt{terminate-batch.pdf}] A PDF file used by
+ \textsf{Thor's way} action script. See the manual
+ for the \pkg{thorshammer} package for details.
+ \end{description}
+\end{description}
+At the top most level of this folder structure are four files.
+\begin{description}
+ \item[\normalfont\texttt{genquiz.ps1}]\label{item:genquiz} A \app{Powershell} script
+ that works in concert with \texttt{tex-template.tex}. When executed,
+ it reads the \ameta{varlist}\texttt{.txt} file (one level up), the
+ variable list file used to create the folders and files, it then
+ creates a TEX file named
+ \texttt{\ameta{number}-\ameta{class}-\ameta{subject}.tex}, which is a
+ copy of \texttt{tex-template.tex}, with certain tagged variables in
+ \texttt{tex-template.tex} replaced with their values based on
+ \ameta{varlist}\texttt{.txt}; for example, the tagged variable
+ \texttt{\#class} in \texttt{tex-template.tex} is replaced by the
+ value of the class variable declared in \ameta{varlist}\texttt{.txt}
+ (perhaps it is replaced by ``alg1'').
+
+ \textbf{Steps to change the default name.} You can
+ change the default name of the generated TEX file by
+ following these steps: (1) open \texttt{genquiz.ps1} in
+ your favorite text editor; (2) find the line,
+\begin{quote}\ttfamily\catcode`\$=12
+ $templateName="$number-$class-$subject.tex"
+\end{quote}
+and, finally, (3) change the assignment, perhaps to a function
+of one or more of the above above variables.
+
+ \item[\normalfont\texttt{tex-template.tex}] There are two renditions (or versions) for the TEX
+ template: (1) a German language version, and (2) an English language
+ version. The \app{Powershell} script \texttt{thmclass.ps1} detects
+ the language as set by your operating system and writes the proper
+ TEX template. The TEX template, which is \texttt{tex-template.tex}
+ by name, contains tagged variables {\def\AND{{\normalfont and
+ }}\catcode`\,=\active\def,{{\normalfont\string,
+ }\ignorespaces}\ttfamily\catcode`\#=12\relax #class,
+ #number,#subject,#theme,#instrName,#date, \AND #time}, which are
+ replaced by their counterparts {\def\AND{{\normalfont and
+ }}\catcode`\,=\active\def,{{\normalfont\string,
+ }\ignorespaces}\ttfamily\catcode`\$=12\relax $class,
+ $number,$subject,$theme,$instrName,$date, \AND $time}, as declared in
+ \ameta{varlist}\texttt{.txt}.
+
+ \textbf{German.} This \texttt{tex-template.tex} file is
+ Thor's visualization of what his quizzes should look
+ like. When \texttt{genquiz.ps1} is executed, it reads
+ this file and saves it again under a different name, as
+ discussed above.
+
+ \textbf{English.} This form of the TEX template is more
+ basic, without Thor's specialized features.
+
+ The contents of \texttt{tex-template.tex} can be
+ modified to suite your own understanding of what your
+ quiz should look like. Use the tagged variables as you
+ wish in your personal template file.
+
+ \item[\normalfont\texttt{00-\ameta{class}.cfg}] The configuration file
+ for building a quiz for the class. Initially, it has the
+ following form:
+\begin{Verbatim}[fontsize=\small,commandchars={^~@}]
+% Reset the paths for \instrPath and \classPath for your system
+% Use relative paths here for instructor according to dir, where tex file is located
+\classPath{^ameta~classPath@}
+\instrPath*{^ameta~instrName@/backup}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Syntax:
+% \classMember{firstname}{lastname}{rel-path}
+% \classMember{firstname}{lastname}*{full-path}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\end{Verbatim}
+Running \texttt{csvTocfg.ps1} appends \cs{classMember} to the file. On running, it might now read,
+\begin{Verbatim}[fontsize=\small,commandchars={^~@}]
+% Reset the paths for \instrPath and \classPath for your system
+% Use relative paths here for instructor according to dir, where tex file is located
+\classPath{^ameta~classPath@}
+\instrPath*{^ameta~instrName@/backup}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Syntax:
+% \classMember{firstname}{lastname}{rel-path}
+% \classMember{firstname}{lastname}*{full-path}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\classMember{Muehle}{Waeter}{MW634B/^ameta~instrName@}
+\classMember{Anton}{Mueller}{AM256M/^ameta~instrName@}
+\classMember{Laura}{Voegt}{LM356B/^ameta~instrName}@
+\end{Verbatim}
+
+
+% \item[\ameta{number}-\ameta{class}-\ameta{subject}-\ameta{theme}\texttt{.tex}]
+% This is the TEX template file. This awkward, extremely
+% long and painful file name is a result of German
+% education. The file itself is a quiz template that uses
+% the \pkg{web}, \pkg{exerquiz} packages, in addition to
+% the \pkg{thorshammer} package. Bring this file into your
+% favorite {\LaTeX} editor and modify as desired, or write
+% your own from scratch. Of course, a change of name might
+% be in order as well.
+
+\item[\normalfont\texttt{web.cfg}] The TEX template file uses the
+ \pkg{web} package, and as such, uses many
+ \pkg{web}-defined commands. These commands can be
+ redefined through the \texttt{web.cfg}. The file
+ \thescript{} creates its own \texttt{web.cfg}, for local
+ use. If you open this created file, its contents are,
+\begin{Verbatim}
+%
+% AeB Web Configuration file
+%
+\ExecuteOptions{dvips}
+\bWebCustomize
+% Insert redefinitions between these two marks
+\eWebCustomize
+\end{Verbatim}
+To illustrate the use of the \texttt{web.cfg}, modify the file to now read,
+\begin{Verbatim}
+%
+% AeB Web Configuration file
+%
+\ExecuteOptions{dvips}
+\bWebCustomize
+\author{Herr Dr. Thor}
+\university{AcroTeX.edu}
+\eWebCustomize
+\end{Verbatim}
+Above, we have declared \verb|\author{Herr Dr. Thor}| and
+\verb|\university{AcroTeX.edu}|. (The \cs{author} and \cs{university}
+commands are defined in the \pkg{web} package.) There are no restrictions, other
+redefinitions of commands defined by other packages are permitted. Freely
+use the special character `\texttt{@}' without having to type
+\cs{makeatletter}/\allowbreak\cs{makeatother} combination.
+
+ The \pkg{thorshammer} package defines a new command,
+ that will be picked by \pkg{web} itself; the command is
+ \cs{inputWebCfg}. This command has been embedded in the
+ preamble of the TEX template.
+\end{description}
+
+\paragraph*{Additional comments on the eight variables.} We
+document how the eight variables are used throughout the files generated by
+\thescript.
+\begin{description}
+ \item[\normalfont\ameta{class}] is used to construct a top-level folder
+ containing all the files generated by \thescript. This
+ variable is the base name of the CFG file
+ (\texttt{00-\ameta{class}.cfg}).
+ \texttt{00-\ameta{class}.cfg} is input by the template
+ file using the \cs{InputClassData} macro. It also
+ appears as the argument of the \cs{thQzHeaderL} and
+ \cs{title} commands in the template file.
+
+ \item[\normalfont\ameta{number}] This variable appears in the TEX template file as
+ the argument of the \cs{DeclareQuiz} and of the \cs{version} commands.
+
+ \item[\normalfont\ameta{subject}] This variable appears as an argument
+ of \cs{thQzHeaderCQ} and \cs{subject} in the TEX
+ template file.
+
+ \item[\normalfont\ameta{theme}] This variable appears as the argument of \cs{thQzName}.
+
+ \item[\normalfont\ameta{instrName}] This variable appears in several
+ \uif{Powershell} script files: \app{copyka.ps1}, \app{moveka.ps1},
+ \app{delka.ps1}, \app{csvTOcfg.ps1}, and \app{classFolders.ps1}. In
+ the TEX template file, it appears as the argument of \cs{author}.
+ Within \texttt{00-\ameta{class}.cfg}, \ameta{instrName} appears as an
+ argument of \cs{instrPath}.
+
+ \item[\normalfont\ameta{date}] This variable is an argument of
+ \cs{copyrightyears} in the TEX template file.
+
+ \item[\normalfont\ameta{time}] This variable appears in the argument of \cs{keywords}
+
+ \item[\normalfont\ameta{classPath}] This variable is used in various
+ places: \app{copyka.ps1}, \app{moveka.ps1},
+ \app{delka.ps1}, and \app{classFolders.ps1}. It also
+ appears as the argument of \cs{classPath} within
+ \texttt{00-\ameta{class}.cfg}.
+
+\end{description}
+
+\section{Procedures after running \texttt{thmclass.ps1}}
+
+After the folders and files of
+\hyperref[fig:struct]{Figure~\ref*{fig:struct}} are created, go
+into the \ameta{class} folder, you will see \ameta{instrName} (a
+folder) and the two files \texttt{00-\ameta{class}.cfg} and
+\texttt{tex-template.tex}. Now, change directories by moving
+into the \ameta{instrName} folder. Now perform the following
+tasks.
+\begin{enumerate}
+ \item \textbf{Edit \texttt{sample-list.csv}.}\label{item:Editlist} Change the
+ name, if desired, of the file \texttt{sample-list.csv}
+ and open the renamed file in your text editor. For the
+ purpose of this documentation, we shall refer to the
+ renamed file \texttt{sample-list.csv} as
+ \texttt{\ameta{list}.csv}. The format of each line is
+ exemplified by the three sample lines provided. More
+ symbolically, each line consists of a comma (or
+ semi-colon) delimited list:
+\begin{quote}
+ \ameta{first},\ameta{last},\ameta{rel-path} or\\
+ \ameta{first};\ameta{last};\ameta{rel-path}
+\end{quote}
+One or more lines in this file may have an alternate syntax:
+\begin{quote}
+ \ameta{first},\ameta{last},*\ameta{full-path}
+\end{quote}
+where the first character of the third entry is an \texttt*,
+the rest of the entry is a full-path to the student's
+folder.\footnote{This is done when the student's does not lie
+in the path pointed to by the argument of \cs{classPath}.}
+
+To continue, enter the first and last names of each student in
+the class, followed by the relative path (relative to \cs{classPath})
+to that student's folder. The sample file reads,
+\begin{equation}
+\begin{minipage}{.5\linewidth}
+\begin{Verbatim}[commandchars=!()]
+M!"(u)hle;W!"(a)ter;MW634B
+Anton,M!"(u)ller,AM256M
+Laura,V!"(o)gt,LM356B
+\end{Verbatim}
+\end{minipage}\label{disp:list}
+\end{equation}
+These sample entries are to be deleted and replaced by the
+names and folders of the class members. If there are any
+student exception---one whose student folder is outside
+\cs{classPath}---, then a typical entry is has the following
+form,
+\begin{equation*}
+\begin{minipage}{.5\linewidth}
+\begin{Verbatim}[commandchars=!()]
+Laura,V!"(o)gt,*C:/Users/dpstory/Desktop/TestFolder/myOtherClass/LM356B
+\end{Verbatim}
+\end{minipage}
+\end{equation*}
+For the last entry, the third element begins with an \texttt*, which signals that
+what follows is full path to this student's folder.
+
+ \item \textbf{Run \texttt{csvTOcfg.ps1}:} Now, execute
+ \texttt{csvTocfg.ps1} using the general purpose batch
+ file \texttt{run1.bat} with a command line arguments of
+ \texttt{csvTocfg} and \ameta{list} (a CSV file); for example,
+ on the \app{Command Prompt}, type,
+\begin{equation}
+ \fbox{\ttfamily runps1 csvTocfg \ameta{list}}\label{dis:csvTocfg}
+\end{equation}
+
+% \item \textbf{Run \texttt{csvTOcfg}.} Now, run the batch
+% file \texttt{csvTOcfg.bat} with a command line argument
+% of the CVS file; for example, on the \app{Command
+% Prompt}, type.
+%\begin{quote}\ttfamily
+% csvTocfg sample-list
+%\end{quote}
+and execute by pressing the \uif{Enter} key. \emph{Do not
+include the extension in the command line argument}. This will
+append the student information to the end of the
+\texttt{00-\ameta{class}.cfg} one level up. Each student has
+an entry in \texttt{00-\ameta{class}.cfg} of
+\cs{classMember\darg{\ameta{first}}\relax
+\darg{\ameta{last}}\darg{\ameta{folder-name}}}.
+\texttt{csvTocfg} also replaces all German umlauts with
+non-problematic characters like so: \"{u} \texttt{->} ue,
+\"{o} \texttt{->} oe, etc.
+
+ \item \textbf{Run \texttt{classFolders.ps1}:} The next step,
+ if needed, creates the personal student
+ folders.\footnote{The sysadmin may not allow creation of
+ folders on the system system drive; this script may be
+ used for testing on the instructor's own drive.} This
+ step may not be needed if the folders already exist. Run
+ the \texttt{runps1.bat} with a command line arguments of
+ \texttt{classFolders} and the CVS file; for example, on
+ the \app{Command Prompt}, type,
+\begin{equation}
+ \fbox{\ttfamily runps1 classFolders \ameta{list}}\label{dis:classFolders}
+\end{equation}
+and execute by pressing the \uif{Enter} key. \emph{Do not
+include the extension in the command line argument}. If the
+folders already exist, the script does not destroy them and
+create them again. No harm done, I hope.
+\item \textbf{Run \texttt{genquiz.ps1}:} (Optional) If you
+ want to use the \texttt{tex-template.tex} file to create a
+ TEX file for your quiz, run \texttt{genquiz.ps1} with
+ the following \uif{Command prompt}:
+\begin{equation}
+ \fbox{\ttfamily runps1 genquiz}\label{dis:genquiz}
+\end{equation}
+Executing this line produces a TEX template file named
+`\texttt{\ameta{number}-\ameta{class}-\ameta{subject}.tex}'. The file
+\texttt{genquiz.ps1}, when executed, reads the
+\texttt{\ameta{varlist}.txt}, located one directory up, to get the current
+values of \ameta{number}, \ameta{class}, and \ameta{subject}.
+
+\end{enumerate}
+
+\paragraph*{Preliminaries are done! Have fun!} You are ready to
+compose your quiz/exam! Open the TEX template file and modify
+its contents to suite your needs, removing easy questions and
+adding difficult ones, or copy one of the demo files from the
+\texttt{examples} folder and modify it. For this part of the
+process you must be knowledgable of \pkg{exerquiz} and the
+documentation of the \pkg{thorshammer} package. The sample files
+of \pkg{thorshammer} will help to compose the quiz using the
+approach you want.
+
+
+\paragraph*{Repeat.} There is no need to run `\texttt{runps1 thmclass \ameta{varlist}.txt}'
+more than once a semester. As you work through the semester, you can copy an
+old quiz with a new file with a new name and modify for the new material
+studied or run \texttt{genquiz.ps1} to obtain a new clean template file:
+\[
+ \fbox{\ttfamily runps1 genquiz}
+\]
+The file \texttt{genquiz.ps1} reads the
+\texttt{\ameta{varlist}.txt} one level up; you might want to
+first edit this file and change the value of \ameta{number}.
+
+The contents of \texttt{00-\ameta{class}.cfg} remains unchanged; if students
+drop out of the course simply delete that student's line from
+\texttt{00-\ameta{class}.cfg} or if students add the course simply append a
+line to \texttt{00-\ameta{class}.cfg} using the template
+\cs{classMember\darg{\ameta{first}}\relax
+\darg{\ameta{last}}\darg{\ameta{folder-name}}}. Read the discussion on how to
+handle \nameref{para:exceptions} to these general rules.
+
+\section{Deploying the quizzes}
+
+The quizzes may be deployed to the student folders in two ways:
+\begin{enumerate}
+ \item When a quiz is compiled with the \opt{usebatch} option, the
+ \cs{sadQuizzes} command executes JavaScript lines when first opened
+ in \app{Acrobat}, which builds and distributes the quizzes to the
+ designated instructor folder and deploys individualized quizzes to
+ the correct student folder.
+ \item When the \opt{batchdistr} option is specified,
+ \cs{sadQuizzes} does its thing, but does not send the
+ quizzes to the individualized student folders. To
+ deploy them, either use the action sequence
+ \textsf{Thor protects and distributes} or just
+ \textsf{Thor distributes}. The end result of these two
+ is to deploy the quizzes to their designated student
+ folders.
+\end{enumerate}
+
+\section{Retrieving the quizzes}
+
+After the exam period is over the quizzes need to be retrieved
+from the student folders and placed in a folder where the
+instructor can grade them. The mechanics of doing this are
+explained next:
+\begin{itemize}
+ \item \texttt{copyka.ps1} copies the quizzes from their respective student folders
+ in the class folder declared by the \cs{classPath} command to the folder designated
+ by the \cs{instrPath}. These two declarations can be found in \texttt{00-\ameta{class}.cfg}.
+ \item \texttt{delka.ps1} delete the quizzes from their
+ respective student folders in the class folder declared
+ by the \cs{classPath} command.
+ \textcolor{red}{\textbf{Important:}} Do not run this
+ script until you've first run \texttt{copyka.ps1}
+ \emph{and} you've \emph{verified} all files have indeed been
+ transferred.
+ \item \texttt{moveka.ps1} copies and then deletes the
+ quizzes. \textbf{Not recommended}, use a \texttt{copyka.ps1} $\rightarrow$ verify
+ $\rightarrow$ \texttt{delka.ps1} workflow.
+\end{itemize}
+\paragraph*{\color{red}Danger Will Robinson!} These scripts dig
+down deep into the folder structure (pointed to by \cs{classPath}
+or any exception paths (refer to \nameref{para:exceptions}) looking for PDFs in the student's folder, in
+the subfolder named \ameta{instr}. If there are more than one
+PDF in this folder, the scripts will copy, delete, and move all
+PDFs found in the \ameta{instr} subfolder.
+
+\paragraph*{Running these scripts:} In the \uif{Command Prompt} and with the cursor in the same folder
+as the scripts you are to execute, type,
+\begin{align*}
+ &\fbox{\ttfamily runps1 copyka}\\[1ex]
+ &\fbox{\ttfamily runps1 delka}\\[1ex]
+ &\fbox{\ttfamily runps1 moveka}
+\end{align*}
+\paragraph*{Exceptions:}\chnglabelname{Exceptions}\label{para:exceptions} In an ideal semester, each of the students
+takes the class for the first time and no additional information
+is needed by the above three scripts; however, for students who
+are taking the class again, their class folder may not be
+located on the \cs{classPath}. The three scripts make a
+provision for this. The above PS1 files look for a file named
+\texttt{altclasspaths.txt} in the current directory. The
+contents of this file is a list of \emph{alternate class paths}. For example, suppose
+we declare
+\begin{quote}
+\verb|\classPath{/C/Users/dpstory/Desktop/myClass}|
+\end{quote}
+but there are students whose class folder is located on the path
+\begin{quote}
+\verb|/C/Users/dpstory/Desktop/TestFolder/myOtherClass|
+\end{quote}
+To service these `exceptional' students, create a file named
+\texttt{altclasspaths.txt} and add the following line to that TXT file
+\begin{quote}
+\verb|/C/Users/dpstory/Desktop/TestFolder/myOtherClass|
+\end{quote}
+BTW, on \app{Windows}, you can use standard \app{Windows} notation (with forward slashes) as well:
+\begin{quote}
+\verb|C:/Users/dpstory/Desktop/TestFolder/myOtherClass|
+\end{quote}
+When any of the above three scripts is run, it will first perform its task for the main
+\cs{classPath}, then it will perform the same task for the paths listed in
+\texttt{altclasspaths.txt}.
+
+\section{Redeploying the quizzes}
+
+After the quizzes are marked and saved in a folder of the instructor's
+choice, you can (optionally) return the graded quizzes to the students. To do
+this, use the \textsf{Thor distributes} action sequence.
+
+\section{How to execute a PS1 file without a BAT file} There are two methods.
+\begin{description}
+ \item [\normalfont Using the \texttt{\app{Powershell} App}:] From
+ \uif{File Explorer}, open a window and navigate to the
+ folder containing the PS1 file. Now select \uif{File}
+ \texttt{>} \uif{Open Windows Powershell} (or perhaps
+ the administrator version). In the \app{Powershell} command prompt, type
+\begin{quote}\ttfamily
+Powershell -ExecutionPolicy Bypass -Command .\cs{\ameta{basename}.ps1}
+\end{quote}
+The \texttt{-ExecutionPolicy Bypass} allows the script to run
+without security warnings.
+
+To run a PS1 file with argument,
+\begin{quote}\ttfamily
+Powershell -ExecutionPolicy Bypass -Command .\cs{thmclass.ps1} myVars.txt
+\end{quote}
+
+\item [\normalfont Using the \texttt{\app{Powershell} ISE App}:] This
+ application has a built-in editor. Start \app{Powershell}
+ ISE. Here you can load in your PS1 file by simply dragging
+ and dropping it into the window. Be sure the command
+ prompt is showing the folder where the script file is
+ located. Change directories using the \uif{cd} command, as
+ needed. For a PS1 file that does not have an argument,
+ simple press on the \uif{Run Script} icon on the toolbar,
+ or choose the \uif{Run} menu item from the \uif{File}
+ menu.
+
+ To run a PS1 file with argument, type, for example,
+\begin{quote}\ttfamily
+Powershell -ExecutionPolicy Bypass -Command .\cs{thmclass.ps1} myVars.txt
+\end{quote}
+into the command prompt window and press the \uif{Enter} key to execute that line.
+\end{description}
+
+\part{Using a standalone system}\label{PartII}
+
+\noindent
+Using the Thor system of class structure (see \hyperref[fig:struct]{Figure~\ref*{fig:struct}}) may not be for
+everyone. For this reason, some standalone scripts are provided
+in the \texttt{standalone} folder of the \texttt{system-scripts}
+folder.
+
+\newtopic\noindent
+\textbf{Important:} The contents of the \texttt{standalone} folder should be
+copied to your working folder, the one that contains the source files for
+your quizzes you are developing.
+
+\newtopic\noindent
+Within the \texttt{system-scripts/standalone} folder, the following files are provided:\medskip
+\begin{description}
+\item[\normalfont\texttt{cpquizzes.ps1}] A renamed and modified version of \texttt{copyka.ps1}. To use this script,
+first open it in your editor and modify the following lines:
+\end{description}
+\begin{quote}\ttfamily
+\$baseName="\ameta{baseName}"\\
+\$classPath="\ameta{classPath}"\\
+\$destPath="\ameta{destPath}"
+\end{quote}
+\begin{itemize}
+\item[]
+The value of \texttt{\$baseName} is usually one word that
+represents the instructor (eg, THOR), but it does not have to be
+the instructor's name. \texttt{\$classPath} is the path to the
+class folders. The script searches \texttt{\$classPath} and
+copies all PDFs within \emph{any} subfolder with
+\texttt{\$baseName} as its name. It copies the PDFs to
+\texttt{\$destPath}. The quizzes all must be uniquely named
+because they are all copied to the same destination folder
+(\texttt{\$destPath}). Any older PDFs (perhaps from earlier
+quizzes, or actually any latent PDFs) are also copied, so you
+must set up your protocols appropriately. Execute this script
+from the \uif{Command Prompt}:
+\begin{flushleft}
+ \fbox{\ttfamily runps1 cpquizzes}
+\end{flushleft}
+\end{itemize}
+\begin{description}
+\item[\normalfont\texttt{rmquizzes.ps1}] After you've run \texttt{cpquizzes.ps1} and verified that all required
+files have been copied, you can safely delete (or remove) the quizzes from the student quiz folders.
+Open \texttt{rmquizzes.ps1} in your editor, and modify the values of this variables:
+\end{description}
+\begin{quote}\ttfamily
+\$baseName="\ameta{baseName}"\\
+\$classPath="\ameta{classPath}"
+\end{quote}
+\begin{itemize}
+\item[] The meanings of the variables \texttt{\$baseName} and \texttt{\$classPath} are the same as above in the
+description of \texttt{cpquizzes.ps1}. Run the script as follows:
+\begin{flushleft}
+ \fbox{\ttfamily runps1 rmquizzes}
+\end{flushleft}
+\item[] These first two scripts are basic and the class can be conducted using only \texttt{cpquizzes.ps1}
+and \texttt{rmquizzes.ps1}. The next two scripts can be considered optional.
+\end{itemize}
+\begin{description}
+\item[\normalfont\texttt{mkcfg.ps1}] This is a modified and renamed
+ version of \texttt{csvTOcfg.ps1}, refer to the description of \texttt{csvTOcfg.ps1}. Prior to using this
+ script, delete the file \texttt{00-web.cfg} in the current
+ folder (this file is created by \texttt{mkcfg.ps1}). Open
+ your editor and modify the values of the following
+ variables:
+\end{description}
+\begin{quote}\ttfamily
+\$classPath="\ameta{classPath}"\\
+\$instrPath="\ameta{instrPath}"
+\end{quote}
+\begin{itemize}
+\item[] The values of these variables correspond to \cs{classPath} and
+\cs{instrPath}, respectively. The script is executed from the
+\uif{Command Prompt} as follows:
+\begin{equation*}
+ \fbox{\ttfamily runps1 mkcfg \ameta{list}}
+\end{equation*}
+\item[] where the argument \ameta{list} is a list of class members and
+ folder locations data, as described in `Edit \texttt{sample-list.csv}'
+ on page~\pageref{item:Editlist}.
+
+The purpose of this script is to create the \texttt{00-web.cfg}
+file. Once created, move this file to the same file as your
+quizzes; input this file using \cs{InputClassData\darg{00-web}}. Examples of the use
+of \cs{InputClassData} are found in the \texttt{examples/cfgs} folder.
+As described earlier, the format of this file is,
+\begin{Verbatim}[commandchars=!()]
+\classPath{!ameta(classPath)}
+\instrPath{!ameta(instrPath)}
+\classMember{Muehle}{Waeter}{MW634B/_Thor}
+\classMember{Anton}{Mueller}{AM256M/_Thor}
+\classMember{Laura}{Voegt}{LM356B/_Thor}
+\end{Verbatim}
+\item[] Here, the sample class members of \texttt{sample-list.csv} are
+shown. For the \cs{classPath} and \cs{instrPath}, \emph{use only full
+paths}. Refer to `\textbf{Edit \texttt{sample-list.csv}}' on
+page~\pageref{item:Editlist} for more information.
+\end{itemize}
+\begin{description}
+\item[\normalfont\texttt{mkfolders.ps1}] This is a modified and renamed
+ version of \texttt{classFolders.ps1}. This script is used for testing
+ purposes; it can also be used to set up class folders provided you have
+ the necessary permissions. Run this script from the \uif{Command prompt}:
+\end{description}
+\begin{itemize}
+\item[] Open the file and edit the variable
+\begin{quote}\ttfamily
+\$classPath="\ameta{classPath}"
+\end{quote}
+where \ameta{classPath} is the full path to the root of the class folders. Run this script
+from the \uif{Command prompt}:
+\begin{equation*}
+ \fbox{\ttfamily runps1 mkfolders \ameta{list}}
+\end{equation*}
+where the argument \ameta{list} is a list of class members and
+ folder locations data, as described in `Edit \texttt{sample-list.csv}'
+ on page~\pageref{item:Editlist}.
+\end{itemize}
+%\end{description}
+
+\part{My retirement}
+
+Now, I simply must get back to it. \dps
+
+\end{document}
diff --git a/macros/latex/contrib/thorshammer/docs/thors-the-man.pdf b/macros/latex/contrib/thorshammer/docs/thors-the-man.pdf
new file mode 100644
index 0000000000..d67db59e20
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/docs/thors-the-man.pdf
Binary files differ
diff --git a/macros/latex/contrib/thorshammer/docs/thors-the-man.tex b/macros/latex/contrib/thorshammer/docs/thors-the-man.tex
new file mode 100644
index 0000000000..be267d6764
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/docs/thors-the-man.tex
@@ -0,0 +1,2178 @@
+\documentclass{article}
+\usepackage{amstext}
+\usepackage[
+ web={centertitlepage,designv,forcolorpaper,tight*,latextoc,extended},
+ eforms={usealtadobe,setcorder},aebxmp
+]{aeb_pro}
+%\usepackage[ImplMulti]{dljslib}
+\usepackage{graphicx,array,fancyvrb}
+\usepackage{aeb_mlink}
+%\usepackage{myriadpro}
+%\usepackage{calibri}
+\usepackage[altbullet]{lucidbry}
+
+\usepackage{xbmks}
+\DeclareInitView{layoutmag={navitab:UseOutlines}}
+\xbmksetup{colors={int=red},styles={intbf}}
+
+
+\makeatletter
+\renewcommand*\l@section[2]{%
+ \ifnum \c@tocdepth >\z@
+ \addpenalty\@secpenalty
+ \addvspace{.75em \@plus\p@}% make less space
+ \setlength\@tempdima{1.5em}%
+ \begingroup
+ \parindent \z@ \rightskip \@pnumwidth
+ \parfillskip -\@pnumwidth
+ \leavevmode \bfseries
+ \advance\leftskip\@tempdima
+ \hskip -\leftskip
+ #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
+ \endgroup
+ \fi}
+\makeatother
+
+\let\tops\texorpdfstring
+
+\def\FmtMP#1{\marginpar{\small\itshape\raggedleft#1}}
+
+\hfuzz2pt
+%\makePDasXOn
+
+%\previewOn\pmpvOn
+
+\def\hardspace{{\fontfamily{cmtt}\selectfont\symbol{32}}}
+\let\uif\textsf
+
+\advance\marginparwidth12pt
+
+\usepackage{acroman}
+\usepackage[active]{srcltx}
+
+\edef\amtIndent{\the\parindent}
+
+\addtolength{\marginparwidth}{2pt}
+
+\urlstyle{tt}
+
+\def\STRUT{\rule{0pt}{14pt}}
+
+\makeatletter
+\newcount\hesheCnt \hesheCnt=-1
+\def\heshe{\@ifstar{\heshei}{\global\advance\hesheCnt1\relax\heshei}}
+\def\heshei{\ifodd\hesheCnt she\else he\fi}
+\def\HeShe{\@ifstar{\HeShei}{\global\advance\hesheCnt1\relax\HeShei}}
+\def\HeShei{\ifodd\hesheCnt She\else He\fi}
+\def\hisher{\@ifstar{\hisheri}{\global\advance\hesheCnt1\relax\hisheri}}
+\def\hisheri{\ifodd\hesheCnt her\else his\fi}
+\def\himher{\@ifstar{\himheri}{\global\advance\hesheCnt1\relax\himheri}}
+\def\himheri{\ifodd\hesheCnt her\else him\fi}
+\makeatother
+
+\DeclareDocInfo
+{
+ university={\AcroTeX.Net},
+ title={The \textsf{thorshammer} Package},
+ author={D. P. Story},
+ email={dpstory@acrotex.net},
+ subject=Documentation for the thorshammer package,
+ talksite={\url{www.acrotex.net}},
+ version={1.5.7, 2020/01/13},
+ Keywords={assessment workflow, LaTeX, AcroTeX},
+ copyrightStatus=True,
+ copyrightNotice={Copyright (C) \the\year, D. P. Story},
+ copyrightInfoURL={http://www.acrotex.net}
+}
+
+\universityLayout{fontsize=Large}
+\titleLayout{fontsize=LARGE}
+\authorLayout{fontsize=Large}
+\tocLayout{fontsize=Large,color=aeb}
+\sectionLayout{indent=-62.5pt,fontsize=large,color=aeb}
+\subsectionLayout{indent=-31.25pt,color=aeb}
+\subsubsectionLayout{indent=0pt,color=aeb}
+\subsubDefaultDing{\tops{$\bullet$}{\textrm\textbullet}}
+
+
+\chngDocObjectTo{\newDO}{doc}
+\begin{docassembly}
+var titleOfManual="The thorshammer Package";
+var manualfilename="Manual_BG_Print_thorshammer.pdf";
+var manualtemplate="Manual_BG_Brown.pdf"; // Blue, Green, Brown
+var _pathToBlank="C:/Users/Public/Documents/ManualBGs/"+manualtemplate;
+var doc;
+var buildIt=false;
+if ( buildIt ) {
+ console.println("Creating new " + manualfilename + " file.");
+ doc = \appopenDoc({cPath: _pathToBlank, bHidden: true});
+ var _path=this.path;
+ var pos=_path.lastIndexOf("/");
+ _path=_path.substring(0,pos)+"/"+manualfilename;
+ \docSaveAs\newDO ({ cPath: _path });
+ doc.closeDoc();
+ doc = \appopenDoc({cPath: manualfilename, oDoc:this, bHidden: true});
+ f=doc.getField("ManualTitle");
+ f.value=titleOfManual;
+ doc.flattenPages();
+ \docSaveAs\newDO({ cPath: manualfilename });
+ doc.closeDoc();
+} else {
+ console.println("Using the current "+manualfilename+" file.");
+}
+var _path=this.path;
+var pos=_path.lastIndexOf("/");
+_path=_path.substring(0,pos)+"/"+manualfilename;
+\addWatermarkFromFile({
+ bOnTop:false,
+ bOnPrint:false,
+ cDIPath:_path
+});
+\executeSave();
+\end{docassembly}
+
+\begin{document}
+
+\maketitle
+
+\pdfbookmarkx[1]{Title Page}[action={\Named{FirstPage}}]{TitlePage}
+\pdfbookmarkx[1]{Documentation of the system scripts}[action={\GoToR/F(thmclass.pdf)/D[0 /Fit]},color=blue,style={bf}]{sysscripts}
+\pdfbookmarkx[1]{How to install Action sequences}[action={\GoToR/F(install-action-seq.pdf)/D[0 /Fit]},color=blue,style={bf}]{instAS}
+\pdfbookmarkx[1]{Links to AcroTeX.Net}[action={/S/GoTo/D(undefined)},%
+ color=magenta,style={bf}]{acrotex}
+\belowpdfbookmarkx{http://www.acrotex.net}[action={\URI{http://www.acrotex.net}},%
+ color=magenta,style={bf}]{home}
+\belowpdfbookmarkx{http://blog.acrotex.net}[action={\URI{http://blog.acrotex.net}},%
+ color=magenta,style={bf}]{blog}
+
+
+\selectColors{linkColor=black}
+\tableofcontents
+\selectColors{linkColor=webgreen}
+
+\section{Acknowledgements}
+
+The author would like to acknowledge Thorsten G. (a.k.a., Thor) who proposed
+this workflow and who contributed many ideas, the proposed workflow I found
+to be interesting and worth my time developing the idea; and to J\"{u}rgen G.
+(a.k.a., Loki) who also contributed many good ideas, enthusiasm, questions,
+bug detection, and motivation. High regards and respect to both.
+\begin{flushright}
+D. P. Story (a.k.a., Odon)
+\end{flushright}
+
+\begin{center}
+ \fbox{%
+ \parbox{.75\linewidth}{\textbf{\textcolor{red}{Warning!}} The workflow of the \pkg{thorshammer}
+ package requires the instructor to use \textbf{\textsf{Adobe Acrobat
+ XI}}, or later. Any PDF creator may be used to build the quizzes,
+ however, but \app{Acrobat} is needed to execute one-time JavaScript
+ (\cs{sadQuizzes}) and to run the action sequences (formerly called batch
+ sequence by \app{Adobe}) such as \textsf{Thor's way}. Only \app{Adobe
+ Reader} is required for the students. Of course, this is the
+ full-featured \app{Adobe Reader} of a desktop or laptop, not the
+ \app{Adobe Reader} found on tablets, smartphones, and such.
+ }}%
+\end{center}
+
+\section{Introduction}\label{intro}
+
+Thor has asked me to assist him in creating a quiz system, based on
+Acro\negthinspace\TeX, to be delivered to his classes. His workflow for this
+assessment system is as follows:\footnote{As my occasional friend J\"{u}rgen
+says, this workflow is a real hammer, so I titled this package `Thors(ten)
+hammer', or simply \pkg{thorshammer}.}
+\begin{enumerate}
+ \item The \env{quiz} environment is used to pose the questions, which
+ consist of MC, numerical fill-in the blank, and \emph{extended response
+ questions}.\footnote{Extended response questions are the interesting
+ part.} Though the \env{quiz} environment is used, the score is not
+ reported to the student upon finishing the quiz.
+ \item The students takes the quiz in a computer lab, each student has
+ {\hisher} own personal student folder. The quizzes are dropped into the
+ personal folders.
+ \item When the student finishes the exam, taken in \app{AR},\footnote{\app{AR}
+ refers to \app{Adobe Reader DC}.} {\heshe} presses the \textsf{End
+ Quiz} control and saves the document.
+ \item At some point, the instructor's script moves the student quizzes
+ to the instructor's folder.
+ \item The instructor opens the PDF and finishes marking the extended
+ response questions and assigns a grade.
+ \item System scripts then returns the quizzes to the students.
+\end{enumerate}
+The original concept was expanded considerably as the package was developed:
+extensive \hyperref[s:sysscrpts]{system scripts} were written to support the
+system; and \hyperref[actSeq]{action sequences} were written, also to support
+Thor's way.
+
+
+\section{Preliminaries}
+
+Most important is the correct installation of \pkg{thorshammer} along with
+its required packages and folder JavaScript files.
+
+\subsection{Package requirements}
+
+The most recent version of the packages \pkg{insdljs} (2019/10/23),
+\pkg{exerquiz} (2019/10/13), \pkg{eq-save} (2019/08/07) are required. These three packages
+were modified slightly to obtain features needed by \pkg{thorshammer}.
+
+The \pkg{thorshammer} package ships with two folder JavaScript files
+\texttt{aeb\_pro.js}\FmtMP{\textsf{aeb\_pro.js}} (Version 1.7.2 or later,
+required) and \texttt{aeb-reader.js}\FmtMP{\textsf{aeb-reader.js}} (Version
+1.0 or later); these two are found in \texttt{folder-js}
+folder\FmtMP{\texttt{folder-js} folder}. The latter is a new JavaScript file,
+the former ships with the \pkg{aeb\_pro} package. These files give access to
+security restricted JavaScript methods. If you already have \pkg{aeb\_pro}
+installed, be sure you have Version 1.7.2 of \texttt{aeb\_pro.js}, if not,
+install Version 1.7.2 provided by this distribution.
+
+The \texttt{aeb\_pro.js} is used on the instructor's system, along with
+\app{Acrobat} (\app{AA}), to author quizzes. \app{Distiller} is not used unless the
+author prefers a TEX $\rightarrow$ DVI $\rightarrow$ PS $\rightarrow$ PDF
+workflow, using \app{Distiller} as the PDF creator. For this workflow,
+\app{pdflatex}, \app{lualatex}, and \app{xelatex} will work as PDF creators;
+however, \app{Acrobat} ia needed to execute the JavaScript code generated by
+the command \cs{sadQuizzes} and to execute the action sequences provided by
+this package.
+
+Once the quizzes are created, the author can take the quizzes in \app{Adobe
+Reader} (\app{AR}) to get the same experience as his students. Additionally,
+\texttt{aeb-reader.js} can be installed on the instructor's system and on the
+student's work environment, if possible/permitted. \texttt{aeb-reader.js}
+contains a subset of JavaScript methods taken from \texttt{aeb\_pro.js} that
+\emph{will enhance student experience}. The author can install this file on
+his system to take the quizzes in the same environment, again using
+\app{Adobe Reader}. \textbf{Warning:}\FmtMP{\textbf{Warning}} Do not install
+\texttt{aeb\_pro.js} in any folder where an \app{Adobe Reader} used by
+students would read it.
+
+\paragraph*{Other enhancements to user experience.} \app{Adobe Reader} is by default in \uif{Protected Mode}.
+Then \uif{Protected Mode} is enabled, one or more security dialog boxes popup
+as the student saves his/her document. To eliminate this annoyance, clear the
+\uif{Enable Protected Mode at startup} checkbox, as shown in the
+\hyperref[fig:PM]{Figure~\ref*{fig:PM}}. On your personal system, open
+\app{AR}, press \uif{Ctrl+K}\FmtMP{\uif{Ctrl+K}}, select \uif{Security
+(Enhanced)} from the \uif{Categories} panel, finally, clear the checkbox, as
+shown in \hyperref[fig:PM]{Figure~\ref*{fig:PM}}.\footnote{For \app{AA}, this
+checkbox is cleared by default.} The installation of \texttt{aeb-reader.js}
+and clearing the checkbox to disable \uif{Protected Mode} most likely require
+the sysadmin\FmtMP{sysadmin permission} to make those changes.
+\begin{figure}[htb]\centering
+\includegraphics[width=\linewidth]{graphics/protected-mode}
+\caption{Clear \textsf{Protected Mode} checkbox}\label{fig:PM}
+\end{figure}
+
+%which gives access to security restricted JavaScript methods used by this
+%package.\footnote{If you have the \pkg{aeb\_pro} package already installed,
+%the you also have \texttt{aeb\_pro.js} (Version 1.7.2 or later, required);
+%you can use \texttt{aeb\_pro.js} instead of \texttt{aeb-reader.js}.}
+%Additionally, the file \texttt{aeb\_pro.js}\FmtMP{\textsf{aeb\_pro.js}} is
+%required to be correctly installed on your computer. The file comes with the
+%\pkg{aeb\_pro} package, though the package itself is not required. As a convenience,
+%\texttt{aeb\_pro.js} is also include in the \texttt{folder-js} folder.
+
+\paragraph*{Installation of JS files for \app{Acrobat}.} The JavaScript file \texttt{aeb-reader.js}
+is provided in the \texttt{folder-js} folder. Discussion of how and where to
+install folder JavaScript files is found in the file
+\texttt{docs/install\_jsfiles.pdf}. Read and follow the directions carefully.
+
+\paragraph*{Installation of JS files for \app{Adobe Reader}.} The folder JavaScript
+file \texttt{aeb-reader.js} may be installed for use by \app{Adobe Reader} as
+well. Installing \texttt{aeb-reader.js} enhances the experience of the
+students as they save their quiz document after completing the quiz.
+Normally, it is not possible to install such a JavaScript file for use by
+students; however, if the students take the quiz in a Computer Lab, the
+sysadmin can install \texttt{aeb-reader.js} on all the computers used in the
+Computer Lab. Discussion of how and where to install folder JavaScript files
+is found in the file \texttt{docs/install\_jsfiles.pdf}. Read and follow the
+directions carefully. (\app{Reader} looks for its folder JavaScript files in
+the same location where \app{Acrobat} would look for them.)
+
+
+\subsection{Package options}
+
+There are seven options for this package.
+\begin{description}
+ \item[\opt{nocfg}] There is a language localization file, discussed in
+ Section~\ref{s:lang}, that is loaded as a matter of course. When this
+ option is taken, the configuration file is not loaded. In this case,
+ the default English language definitions are used for all strings.
+ \item[\opt{testmode}] When this option is specified, the quizzes are
+ regular quizzes that can be tested in the usual \pkg{exerquiz}-way. A
+ \textsf{Correct} button is available to correct the quiz.
+ \item[\opt{!testmode}] A convenience option for putting the document into
+ the default mode: Quizzes are ready to be taken by the students,
+ pressing the \textsf{End Quiz} does not give any score for their
+ effort, but students are prompted to save the quiz.
+ \item[\opt{useclass}] Use this option to bring in additional code to
+ declare each member of the class, to automatically build a custom quiz
+ for each class member, to distribute these quizzes to a designated
+ folder of the instructor, and to distribute the quizzes the respective
+ class folder. Refer to Section~\ref{ss:uc} for details.
+ \item[\opt{usebatch}] This option executes the \opt{useclass} option;
+ however, there is a batch sequence, called \textsf{Thor's way}, that
+ the instructor uses to process all class quizzes after the class has
+ finished with them. Refer to Section~\ref{ss:ub} for details.
+ \item[\opt{batchdistr}] The option automatically passes the
+ \opt{usebatch} and the \opt{useclass} options.
+ Additionally, the document assembly script does not
+ distribute copies of the quizzes to the student folders,
+ rather, it is expected the author uses either
+ \textsf{Thor distributes} or \textsf{Thor protects and
+ distributes} action wizards to perform the distribution
+ task. The quizzes can later be distributed using an
+ operating system script. Refer to Section~\ref{ss:bd}
+ for details.
+ \item[\opt{ordinary}] When this option is passed, ordinary
+ quizzes are created, \emph{ones that do not follow Thor's
+ Hammer workflow}. The \opt{testmode} option is
+ automatically executed, as well as other changes. Refer
+ to section~\ref{ordinary} for more details and examples.
+\end{description}
+
+\section{Necessary conditions that would make this system work}
+
+In recent years, browser technology has \emph{devolved} to the point that
+\app{Adobe Reader} is no longer supported---with the exception of Microsoft's
+\app{Internet Explorer~11}---within a browser window. For documents using
+\pkg{exerquiz}, which relies heavily on \app{Acrobat} JavaScript API,
+interactive quizzes can no longer be taken within a brower; hence, if an
+instructor wants to use \pkg{exerquiz} to author quizzes to be taken by
+{\hisher} students, the quizzes must be taken on a desktop or laptop from
+within the \app{Adobe Reader} application.\footnote{At this time, \app{Adobe
+Reader} on mobile and tablets do not support form fields and JavaScript.}
+
+\subsection{The effectiveness of using PDF quizzes for assessment}
+
+The effectiveness of an in-class quiz is closely tied to quiz security. In a
+normal classroom setting, students take the quiz/test---all at the same
+time---under the glaring gaze of responsible adult. This is to ensure there
+is no `cheating.' This is the method used for paper quizzes/tests that are a
+major part of the students grade. However, security becomes more lax when
+students work on assignments with lesser weight in the final grade. Homework
+assignments are an example.
+
+For PDF quizzes, the philosophy is the same, for lesser credit, the students
+can take the quizzes on their own. If the quizzes are for major credit in the
+course, then one would expect stricter security.
+
+\paragraph*{The ideal condition.} The following list comprises the ideal conditions
+for assessment using PDF quizzes.
+\begin{itemize}
+ \item \textbf{An exam period.} There is a definite (time) period the
+ students are to take the quizzes. The quizzes are moved to the
+ private student folders at the beginning of the assessment period,
+ and removed again at the end of the assessment.
+ \item The ideal condition is for the students to take the quiz only in a
+ CBT lab (computer-based testing lab) under supervision.
+
+ \item \textbf{CBT Lab.} The student must use \app{Adobe Reader}, must not
+ use email or a thumb-drive (to transmit the PDF quiz), and must not
+ print the quiz. For Thor's workflow, the student finds the quiz in
+ the his/her personal folder.
+
+ \item \textbf{No access to private folder.} The students do not have access to the private folder outside of
+ the CBT lab.
+\end{itemize}
+The workflows devised in this package will work well for class quizzes taken under these ideal conditions.
+
+\subsection{Authoring a quiz}
+
+The \pkg{thorshammer} package uses post-pdf creation JavaScript methods. For
+these methods to have any effect, the document author must use the \app{Adobe
+Acrobat}\FmtMP{\app{Acrobat} required} application. The PDF creation can be
+any of the usual {\LaTeX} workflows: \app{dvips/Adobe Distiller},
+\app{pdflatex}, \app{lualatex}, or \app{xelatex}. In all cases, after PDF
+creation, the newly created file must be opened in \app{Acrobat} before any
+auxiliary files are deleted. When opened in \app{Acrobat} the first time,
+certain code lines of JavaScript execute to perform a number of tasks.
+
+There is another JS file that needs to be either located or created, the file
+name is \texttt{config.js}\FmtMP{edit \textsf{config.js}}. It is a standard
+\app{Acrobat} file and is located in the same folder in which
+\texttt{aeb-reader.js} (or, perhaps, \texttt{aeb\_pro.js}) reside. The file
+\texttt{install\_jsfiles.pdf}, found in the \texttt{docs} folder, discusses
+where \app{Acrobat} expects to find folder JavaScript files. Find or create
+\texttt{config.js} and insert the following line:
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!~@]
+var _thorshammer=true;!quad//!sffamily~ secret variable@
+\end{Verbatim}
+This JavaScript variable plays an interesting role: Certain form elements in
+the quiz only appear when this variable is present, in particular, the
+\textsf{Mark it} control only appears when the document is opened in
+\app{Acrobat} and the above script line appears in the \texttt{config.js}
+file.\footnote{\textbf{Important!} Do not install \texttt{config.js} where
+any \app{AR} used by a student; otherwise, the \textsf{Mark It} control will
+be displayed to the student, which we don't want.} You'll have to see it to
+believe it.
+
+\newtopic\noindent
+Once the quiz has been built, the quizzes themselves require only \app{Adobe
+Reader} to take.
+
+\newpage
+
+\section{Workflows for interactive assessment using PDF}
+
+The document author has several choices for student/instructor experience. We
+discuss these in this section.
+
+\subsection{Basic methods}\label{ss:BMs}
+
+A \emph{basic method}\FmtMP{basic method} is one in which none of the ``class options'' are used; these
+are \opt{useclass}, \opt{usebatch}, and \opt{batchdistr}.
+This method is illustrated in sample file \texttt{thexb.tex}. Compiling this file
+produces a single quiz, which is distributed to the class.
+
+\subsubsection{Preamble}
+
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars={!~@}]
+\documentclass{article}
+\usepackage{amstext} %!textsf~ (optional, used in a minor way below)@
+\usepackage{web} %!textsf~ (optional)@
+\usepackage[usealtadobe]{insdljs}
+\usepackage[usesumrytbls]{exerquiz}
+!textbf~\usepackage{thorshammer}@ %!textsf~ (basic methods imply no options taken)@
+
+\setInitMag{fitwidth} %!textsf~ (optional, defined in this package)@
+\hypersetup{pdfpagelayout=OneColumn} %!textsf~ (optional, from hyperref )@
+
+%!textsf~ Optional customizations@
+%\useNameToCustomize
+%\enumQuizzes{3}
+%\instrPath{/C/Users/!ameta~username@/Desktop/Test Folder/target/_Thor}
+%\classPath{/C/Users/!ameta~username@/Desktop/Test Folder/target/myClass}
+%\distrQuizzes{{A/_Thor}{B/_Thor}{C/_Thor}}
+
+\reversemarginpar
+\showCreditMarkup %!textsf~ always include this command, it is required@
+%\previewOn\pmpvOn
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+\useMCCircles
+
+%!textsf~ Declare the quiz name@
+\DeclareQuiz{q1}
+%!textsf~ Post document creation JavaScript@
+\begin{docassembly}
+\sadQuizzes
+\end{docassembly}
+\begin{document}
+...
+\end{Verbatim}
+There are two new commands and one new environment above to mention:
+\bVerb\small\takeMeasure{\string\setInitMag\darg{fitpage|actualsize|fitwidth|fitheight|fitvisible|inheritzoom}}%
+\begin{dCmd}[fontsize=\small]{\bxSize}
+\setInitMag{fitpage|actualsize|fitwidth|fitheight|fitvisible|inheritzoom}
+\end{dCmd}
+\eVerb This command determines the initial magnification. There are a choice
+of six values for the argument; the default is \texttt{fitpage}.
+
+\paragraph*{Optional customizations.}\label{para:OCs} There are a several commands to customize the creation of
+the quizzes.
+\bVerb\small\takeMeasure{\string\distrQuizzes\darg{\darg{*\ameta{path\SUB1}}\darg{*\ameta{path\SUB2}}...\darg{*\ameta{path\SUB{num}}}}}%
+\begin{dCmd}[fontsize=\small,commandchars=!()]{\bxSize}
+\useNameToCustomize
+\enumQuizzes{!ameta(num)}
+\instrPath{!ameta(path)}
+\classPath{!ameta(path)}
+\distrQuizzes{{*!ameta(path!SUB1)}{*!ameta(path!SUB2)}...{*!ameta(path!SUB(num))}}
+\end{dCmd}
+\eVerb When none of these commands appear in the preamble, compiling the quiz
+document, produces a single quiz; e.g., compiling \texttt{thexb.tex} produces
+\texttt{thexb.pdf}. Otherwise, compiling \texttt{thexb.tex} produces, for
+example, enumerated copies of the quiz files:
+\texttt{thexb-1.pdf}, \texttt{thexb-2.pdf}, \dots,
+\texttt{thexb-\meta{num}.pdf}.
+\begin{description}
+ \item[\cs{useNameToCustomize}] When the instructor makes the final
+ assessment, {\heshe} presses the \textsf{Mark It} button and a
+ \textsf{Save As} dialog box opens: by default, the name of the
+ current file is pre-filled into the \textsf{File name} input field;
+ if \cs{useNameToCustomize} is in force, however, when \textsf{Mark
+ It} is pressed, the suggested file name in the \textsf{Save As}
+ dialog box is pre-filled as
+ \texttt{\cs{jobname}-\ameta{first}\_\ameta{last}-g.pdf}, where
+ \cs{jobname} is the base name of the original {\LaTeX} source file.
+ The values of \ameta{first} and \ameta{last} are taken from the
+ name fields of the document, where the student is expected to enter
+ {\hisher} name.
+ \item[\cs{enumQuizzes\darg{\ameta{num}}}] When this command is present
+ in the preamble, the command \cs{sadQuizzes} (described below)
+ creates \ameta{num} copies of the quiz, and labels them
+ \cs{jobname-1.pdf}, \cs{jobname-2.pdf}, \dots,
+ \cs{jobname-\meta{num}.pdf}.
+ \item [\cs{instrPath\darg{\ameta{path}}}] (The instructor folder) The
+ \cs{instrPath} command is the path to the folder of the instructor.
+ A copy of all quizzes produced are placed at the end of this path.
+ \item [\cs{classPath\darg{\ameta{path}}}] (The class folder root) The
+ \cs{classPath} command is the path to the root of the class folders
+ of the students.
+ \item[\cs{distrQuizzes\darg{*\darg{\ameta{path\SUB1}}\darg{*\ameta{path\SUB2}}...\darg{*\ameta{path\SUB{num}}}}}]
+ The argument takes a series of paths: (1) if the star-option
+ (\texttt*) is \emph{not present}, then \ameta{path} is the relative
+ path to the student folder, relative to the class folder root; (2)
+ if the star-option (\texttt*) is present, the \ameta{path} is the
+ full path to the student folder. Each folder path is enclosed in
+ braces (\darg{}).
+\begin{Verbatim}[fontsize=\small]
+\classPath{/C/Users/dpstory/Desktop/Test Folder/target/myClass}
+\newcommand{\altClassPath}
+ {/C/Users/dpstory/Desktop/Test Folder/target/myOtherClass}
+\distrQuizzes{{A/_Thor}{*\altClassPath/B/_Thor}{C/_Thor}}
+\end{Verbatim}
+Quizzes are placed (by \cs{sadQuizzes}) in the student folders:
+\begin{Verbatim}[fontsize=\small]
+/C/Users/dpstory/Desktop/Test Folder/target/myClass/A/_Thor}
+/C/Users/dpstory/Desktop/Test Folder/target/myOtherClass/B/_Thor}
+/C/Users/dpstory/Desktop/Test Folder/target/myClass/C/_Thor}
+\end{Verbatim}
+When the \cs{classPath}/\cs{distrQuizzes} combination is used, the
+\cs{enumQuizzes} command is ignored. The number of quizzes to be created is
+determined by the number of folder paths listed in \cs{distrQuizzes}.
+\end{description}
+
+\paragraph*{Declaring quiz name.} Also in preamble is the declaration of the quiz name.
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars={!~@}]
+\DeclareQuiz{!ameta~qz-name@}!quad%!textsf~ defined in exerquiz@
+\end{Verbatim}
+The \ameta{qz-name} should consist of alpha-numeric characters only (eg,
+\texttt{quiz1}), and no umlauts, Loki!\footnote{I am informed by the mighty
+Thor himself that umlauts can simply rendered in German with `ue' instead of
+\"{u}, `oe' instead of \"{o}, and so on; however, we don't want to encourage
+Loki. I wish he would have told Loki years ago, it would have saved me a lot
+of headaches.} The command saves the quiz name in several ways:
+\begin{itemize}
+ \item As equivalent text macros, \cs{thisQuiz} and \cs{currQuiz}. Either of these
+ of these two must be used to reference the quiz name when you set up the \env{quiz}
+ environment; for example,
+\begin{Verbatim}[fontsize=\small,commandchars={!~@}]
+\DeclareQuiz{q1}
+...
+\begin{document}
+...
+\begin{quiz*}{\thisQuiz}!quad%!textsf~ or @\begin{quiz*}{\currQuiz}
+...
+\end{quiz}
+\end{Verbatim}
+ \item As the text macro \cs{thQuizName}\FmtMP{\cs{thQuizName}}. This
+ command was created to solve a problem with the Thor's hammer. (Can
+ you believe it?) When a parent file has multiple renditions of the
+ quiz, Thor's hammer names them differently. For example, if we
+ declare \cs{DeclareQuiz\darg{q1}}, in the first rendition, the quiz
+ name is \texttt{q1a}, in the second rendition, the quiz name is
+ \texttt{q1b}, and so on. (There is a limitation of 26 renditions,
+ though the use of alphabetic letters can easily be changed to
+ numbers.) The command \cs{thQuizName} always expands the original
+ quiz name.
+\end{itemize}
+While on the topic of quiz names, Thor has forged with his mighty hammer, a
+convenience command,
+\bVerb\small\takeMeasure{\string\thQzName\darg{\ameta{text}}}%
+\setlength{\eflength}{\widthof{\sffamily(\cs{thQuizName})}}%
+\edef\x{\the\eflength}%
+\setlength{\eflength}{\bxSize}%
+\def\1{\rlap{\hskip\eflength\rlap{\hskip\x\relax\qquad\cs{def}\cs{thqzname\darg{\ameta{text}}}}\sffamily(\cs{theQuizName})}}
+\begin{dCmd}[fontsize=\small,commandchars=!()]{\bxSize}
+!1\thQzName{!ameta(text)}
+\end{dCmd}
+\eVerb The expression in the parentheses above is the default value; in the third column is the underlying
+text macro definition. Declaring \cs{theQzName\darg{Quiz \#1}} defines the text macro \cs{thqzname} that
+expands to `Quiz \#1'.
+
+\paragraph*{Post document creation JavaScript.} It is important to insert the \cs{sadQuizzes}
+command just above \verb~\begin{document}~, within the \env{docassembly}
+environment.
+\bVerb\takeMeasure{\string\begin\darg{docassembly}}\par\vskip3pt %\vskip-\baselineskip
+\begin{dCmd}[commandchars=!~@]{\bxSize}
+\begin{docassembly}
+!textbf~\sadQuizzes@
+\end{docassembly}
+\end{dCmd}
+\eVerb The \env{docassembly} environment (also available in the
+\pkg{aeb\_pro} package) is a verbatim write environment; it writes its
+contents verbatim to the file \texttt{docassembly.cut} then inputs it back in
+immediately. In this application, place \cs{sadQuizzes} in the body of the
+environment.
+
+\paragraph*{What does \cs{sadQuizzes} do?} The command expands to a series of
+JavaScript lines. What is does depends on several factors.
+\begin{itemize}
+ \item The script identifies the solution pages, extracts and saves them
+ to the current folder under the name
+ \cs{jobname-thsolns4-\ameta{qz-name}.pdf}; it then removes the
+ solution pages from the parent document. The solution pages are later
+ appended to the quiz after the students take the quiz by the instructor
+ when {\heshe} presses the \textsf{Freeze Quiz} button.
+ \item If \cs{enumQuizzes\darg{\ameta{num}}} is used, \cs{sadQuizzes} makes
+ \meta{num} copies of the quiz, labeling them \cs{jobname-1.pdf},
+ \cs{jobname-2.pdf}, and so on. Files are saved to the folder of the
+ source file.
+ \item If the \cs{classPath}/\cs{distrQuizzes} combination is used, \cs{sadQuizzes} makes enumerated
+ copies of the quiz and places each in a separate folder designated by the argument
+ of \cs{distrQuizzes}.
+\end{itemize}
+
+\subsubsection{The body of the document}
+
+%The first item in the body is the declaration of the quiz name.
+%\begin{Verbatim}[xleftmargin=\amtIndent,commandchars={!~@}]
+%\DeclareQuiz{!ameta~qz-name@}!quad%!textsf~ defined in exerquiz@
+%\end{Verbatim}
+%The \ameta{qz-name} should consist of alpha-numeric characters only (eg,
+%\texttt{quiz1}), and no umlauts, Loki!\footnote{I am informed by the mighty
+%Thor himself that umlauts can simply rendered in German with `ue' instead of
+%\"{u}, `oe' instead of \"{o}, and so on; however, we don't want to encourage
+%Loki. I wish he would have told Loki years ago, it would have saved me a lot
+%of headaches.} The command saves the quiz name in several ways:
+%\begin{itemize}
+% \item As equivalent text macros, \cs{thisQuiz} and \cs{currQuiz}. Either of these
+% of these two must be used to reference the quiz name when you set up the \env{quiz}
+% environment; for example,
+%\begin{Verbatim}[fontsize=\small,commandchars={!~@}]
+%\DeclareQuiz{q1}
+%...
+%\begin{document}
+%...
+%\begin{quiz*}{\thisQuiz}!quad%!textsf~ or @\begin{quiz*}{\currQuiz}
+%...
+%\end{quiz}
+%\end{Verbatim}
+% \item As the text macro \cs{thQuizName}\FmtMP{\cs{thQuizName}}. This
+% command was created to solve a problem with the Thor's hammer. (Can
+% you believe it?) When a parent file has multiple renditions of the
+% quiz, Thor's hammer names them differently. For example, if we
+% declare \cs{DeclareQuiz\darg{q1}}, in the first rendition, the quiz
+% name is \texttt{q1a}, in the second rendition, the quiz name is
+% \texttt{q1b}, and so on. (There is a limitation of 26 renditions,
+% though the use of alphabetic letters can easily be changed to
+% numbers.) The command \cs{thQuizName} always expands the original
+% quiz name.
+%\end{itemize}
+%While on the topic of quiz names, Thor has forged with his mighty hammer, a
+%convenience command,
+%\bVerb\small\takeMeasure{\string\thQzName\darg{\ameta{text}}}%
+%\setlength{\eflength}{\widthof{\sffamily(\cs{thQuizName})}}%
+%\edef\x{\the\eflength}%
+%\setlength{\eflength}{\bxSize}%
+%\def\1{\rlap{\hskip\eflength\rlap{\hskip\x\relax\qquad\cs{def}\cs{thqzname\darg{\ameta{text}}}}\sffamily(\cs{theQuizName})}}
+%\begin{dCmd}[fontsize=\small,commandchars=!()]{\bxSize}
+%!1\thQzName{!ameta(text)}
+%\end{dCmd}
+%\eVerb The expression in the parentheses above is the default value; in the third column is the underlying
+%text macro definition. Declaring \cs{theQzName\darg{Quiz \#1}} defines the text macro \cs{thqzname} that
+%expands to `Quiz \#1'.
+
+
+\newtopic\noindent
+Thor \emph{requires}\FmtMP{required} a first and last name field.
+\bVerb\takeMeasure{\string\FirstName[\ameta{opts}]\darg{\ameta{wd}}\darg{\ameta{ht}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\FirstName[!ameta(opts)]{!ameta(wd)}{!ameta(ht)}
+\LastName[!ameta(opts)]{!ameta(wd)}{!ameta(ht)}
+\end{dCmd}
+\eVerb The \ameta{opts} argument is for changing the appearance of these text
+fields. These fields are placed at the top of the quiz.
+\bVerb\takeMeasure{\string\thfullnameFmt\darg{\ameta{how-to-format}}}%
+\setlength{\eflength}{\bxSize}%
+\def\1{\rlap{\hskip\eflength\textsf{(See \texttt{examples/misc/thexrt.tex})}}}
+\def\2{\rlap{\hskip\eflength\textsf{(Default: \texttt{\string\thfullnameFmt\darg{\#1+" "+\#2}})}}}
+\begin{dCmd}[commandchars=!()]{\bxSize}
+!1\FullName[!ameta(opts)]{!ameta(wd)}{!ameta(ht)}
+!2\thfullnameFmt{!ameta(how-to-format)}
+\end{dCmd}
+\eVerb The \cs{FirstName} and \cs{LastName} fields are required; however, the
+\cs{FullName} command can explicitly appear as well, perhaps on the cover
+page. This command gets its value from the values of the \cs{FirstName} and
+\cs{LastName} fields; \ameta{how-to-format} is a JavaScript string that
+displays how you want the full name to appear. Within the argument of
+\cs{thfullnameFmt}, \texttt{\#1} is the first name and \texttt{\#2} is the
+second name. Another example of this formatting is
+\verb~\thfullnameFmt{#2+", "+#1}~, here, the full name is presented as last name first, followed by a
+command, then the first name. These ideas are demonstrated in
+\texttt{examples/misc/thexrt.tex}.
+
+\newtopic
+The name fields\FmtMP{importance of the \emph{required} name fields} play a
+critical role in Thor's way of doing things. In addition to providing text
+fields for the student to identify \himher self, the \emph{required} name
+fields are used to mark the beginning of a quiz page. \emph{The required name
+fields must appear at the top of the page} and above the beginning of the
+quiz. Some of the JavaScript of \pkg{thorshammer} interprets the page on
+which the required name fields appear as the page that marks the beginning of
+the quiz.
+
+\newtopic\noindent
+The following fields are an integral part of Thor's way:
+\bVerb\takeMeasure{\string\displaySumryTbl[\ameta{opts}]\darg{\string\currQuiz}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\markQz[!ameta(opts)]{!ameta(wd)}{!ameta(ht)}
+\freezeOrSave[!ameta(opts)]{!ameta(wd)}{!ameta(ht)}
+\studentReport[!ameta(opts)]{!ameta(wd)}{!ameta(ht)}
+\studentGrade[!ameta(opts)]{!ameta(wd)}{!ameta(ht)}
+\begin{sumryTblAux}{\currQuiz}
+\displaySumryTbl[!ameta(opts)]{\currQuiz}
+\end{sumryTblAux}
+\end{dCmd}
+\eVerb These commands and environments are aesthetically arranged at the top of the quiz file along with
+the name fields, though the \cs{displaySumryTbl} can be placed anywhere (see the \pkg{exequiz} documentation
+on this summary table structure).
+\begin{description}
+\item[\cs{markQz}] This button appears in \app{Acrobat} only when the
+ secret variable is detected. After the students have taken the quiz and
+ they are back in the possession of the instructor, the instructor opens
+ each completed quiz and presses this button, whose default caption is
+ \textsf{Mark It}. The underlying script marks up the quiz, showing
+ which problems were answered correctly, how many points received for
+ each response, etc.
+
+ One of the features of Thor's way is to have extended response
+ questions. The student responses to this type of question must be read and
+ corresponding points must be assigned in the box provided.
+\item[\cs{freezeOrSave}] This button appears only after the \textsf{Mark It} button has been pressed.
+ It has two different forms:
+ \begin{enumerate}
+ \item When the \opt{usebatch} option (or higher) is \emph{not in
+ effect}, this button appears with caption \textsf{Freeze Quiz}.
+ The action of this button is to attach any solution pages and
+ make all form fields \emph{in the entire document} readonly. It
+ also flattens all annotations in the document. \emph{Press this
+ button only} after all markups are finished and document is ready
+ to be moved into the student's folder.
+
+ \item[] \textbf{Control of flattening.} There are options to have the
+ \textsf{Freeze Quiz} button to flatten or not.
+\cs{thQuizHeader} and \cs{thQuizHeaderLayout}:
+\bVerb\takeMeasure{\string\flattenOn\quad\string\flattenOff}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\flattenOn!quad\flattenOff
+\end{dCmd}
+\eVerb For basic methods, the default is \cs{flattenOff}, while for
+ \opt{useclass} it is \cs{flattenOn}. Normally, when you use the
+ \opt{useclass} option, all fields are flattened when the \textsf{Freeze
+ Quiz} button is pressed. This means you cannot run the quizzes through
+ \textsf{Thor's way} to extract the grades; recording of grades is done
+ in the tradional way, by hand. However, turning \cs{flattenOff} enables
+ you to use \texttt{Thor's way} even with the \opt{useclass} option. (Or,
+ simple change the option to \opt{usebatch}.)
+
+ \item[] \textbf{Applies to basic methods.} The following command is
+ obeyed only when there is no ``class option'' option specified.
+\bVerb\takeMeasure{\string\useNameToCustomize}%
+\setlength{\eflength}{\bxSize}%
+\def\1{\rlap{\hskip\eflength\sffamily{\enspace Obeyed for basic methods only}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+!1\useNameToCustomize
+\end{dCmd}
+\eVerb When the \cs{freezeorSave} button is pressed, the \textsf{Save As}
+ dialog is opened to save the file, the file name offered is
+ either \cs{jobname.pdf} (the default) or
+ \cs{jobname-\ameta{first}\_\ameta{last}-g.pdf} (provided
+ \cs{useNameToCustomize} has been expanded in the preamble.
+ \item When the \opt{usebatch} option (or higher) option \emph{is in
+ effect}, the caption is \textsf{Save \& Close}. As the caption
+ suggests, the action is to save the document the current folder
+ and close the document in \app{Acrobat}. With the \opt{usebatch}
+ option, the implication is that the instructor is to use one of
+ the action-wizards to continue processing the students' quizzes.
+ \end{enumerate}
+\item[\cs{studentReport}] (text field) This readonly field shows the number
+ of points awarded and the total points (eg, 15 / 20). The field is initially hidden,
+ and becomes visible when \textsf{Mark It} is pressed.
+\item[\cs{studentGrade}] (text field) A field for assigning some sort of
+ grade, which can be a letter or number. The field is initially hidden,
+ and becomes visible when \textsf{Mark It} is pressed.
+\end{description}
+Speaking of aesthetically pleasing arrangement, \pkg{thorshammer} defines,
+\cs{thQuizHeader} and \cs{thQuizHeaderLayout}:
+\bVerb\takeMeasure{\string\thQuizHeaderLayout}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\thQuizHeader*
+\thQuizHeaderLayout
+\end{dCmd}
+\eVerb The \cs{thQuizHeader} command does nothing more than to test for the presence of
+the \texttt{*} option; if \emph{not present}, a \cs{newpage} command is
+issued, otherwise, no \cs{newpage} is forced. Throughout the sample files,
+\cs{thQuizHeader} is used. The \cs{thQuizHeaderLayout} is the command that
+actually contains the arrangement of the design elements. Do not redefine
+\cs{thQuizHeader}; but you may define \cs{thQuizHeaderLayout}; look at
+\pkg{thorshammer.dtx} for the definition \cs{thQuizHeaderLayout}, this will
+give you insight for any redefinition.
+
+\paragraph*{Placement.} \cs{DeclareQuiz} is preferably placed in the preamble\FmtMP{preamble} and
+\cs{thQuizHeader} is placed prior to the first quiz.
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()]
+...
+\DeclareQuiz{!ameta(qz-name)}
+...
+\begin{document}
+...
+\thQuizHeader
+...
+!sffamily!ameta(begin-quiz)
+\end{Verbatim}
+Following the above elements comes some instructions\FmtMP{instructions} for the students, then
+an \pkg{exerquiz} quiz environment,
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()]
+\begin{quiz*}{\currQuiz}
+!textsf(Solve each of these problems, passing is 100\%.)
+\begin{questions}
+...
+\end{questions}
+\end{Verbatim}
+The quiz itself is a standard \pkg{exerquiz} quiz, which, if you are using
+this package, you should be familiar with. Thor's way, however, incorporates
+extended response questions into it that must be personally evaluated by the
+instructor. For extended response questions, \pkg{exerquiz} provides the
+command \cs{RespBoxEssay}. This command has rarely been used. Below is the
+syntax for this command as well as one support command (\cs{essayQ}),
+contained in a rough quiz outline below.
+\bVerb\takeMeasure{ \%\textsf{ allow space to respond to the question}}%
+\setlength{\eflength}{\linewidth-(\bxSize)-\fboxsep}%
+\edef\x{\the\eflength}%
+\setlength{\eflength}{\bxSize}%
+\def\1{\rlap{\hskip\eflength\smash{\parbox[t]{\x}{\sffamily
+Use the \cs{essayQ} command prior to the use of \cs{RespBoxEssay}. The argument
+of \cs{essayQ} is the number of points for the question. The number of points
+is repeated again with the \cs{PTs} command.
+}}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\begin{quiz}{\currQuiz}
+...
+\begin{questions}
+\item !ameta(a question)
+...
+!1!textbf(\essayQ{!ameta(nPts)})
+\item\PTs{!ameta(nPts)} !ameta(pose-question)\par
+ %!textsf( allow space to respond to the question)
+ !textbf(\RespBoxEssay[!ameta(opts)]{!ameta(wd)}{!ameta(ht)})
+
+!textbf(\essayitem{!ameta(nPts)}) !ameta(pose-question)\par
+ %!textsf( allow space to respond to the question)
+ !textbf(\RespBoxEssay[!ameta(opts)]{!ameta(wd)}{!ameta(ht)})
+...
+\end{questions}
+\end{quiz} ...
+\end{dCmd}
+\eVerb The \cs{essayQ} generates a text field in the margin. During the
+instructor review phrase, the instructor can award points for the essay
+problem by entering a numerical value into the text field. The value entered
+will be figured into the totals displayed by the text field created by
+\cs{LngPtsFld} (discussed below). The (default) width and height of the \cs{essayQ}
+are \verb~\def\EsW{33bp}\def\EsH{14bp}~. The \cs{essayitem} is a convenience command,
+it expands to \cs{essayQ\darg{\ameta{nPts}}}\allowbreak\cs{item}\cs{PTs\darg{\ameta{nPts}}}.
+
+%\essayQ
+%\essayitem{!ameta(nPts)}
+%\item[\cs{essayitem}] A convenience macro, expands to
+%\cs{essayQ\darg{\ameta{nPts}}}\allowbreak\cs{item}\cs{PTs\darg{\ameta{nPts}}}
+
+
+\newtopic\noindent
+Following the quiz are several form fields. %{\PtFW}{\DefaultHeightOfWidget}
+\bVerb\takeMeasure{\string\completeMsgFld[\ameta{opts}]\darg{\ameta{wd}}\darg{\ameta{ht}}}%
+\setlength{\eflength}{\bxSize}%
+\def\1{\rlap{\hskip\eflength\textsf{wd:\,}\cs{PTFW}\textsf{, ht:\,}\cs{DefaultHeightOfWidget}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\completeMsgFld[!ameta(opts)]{!ameta(wd)}{!ameta(ht)}
+\stuSaveBtn[!ameta(opts)]{!ameta(wd)}{!ameta(ht)}
+!1\ShrtPtsFld[!ameta(opts)]{\currQuiz}
+!1\LngPtsFld[!ameta(opts)]{\currQuiz}
+!1\TotalsFld[!ameta(opts)]{\currQuiz}
+\end{dCmd}
+\eVerb These form elements are arranged according your design preferences.
+\begin{description}
+\item[\cs{completeMsgFld}] Initially hidden, the text field becomes
+ visible when the student presses the \textsf{End Quiz} control. The
+ appearing text field reminds the student to save the quiz.
+
+\item[\cs{stuSaveBtn}] Initially hidden, the button becomes visible
+ when the student presses the \textsf{End Quiz} control. When the
+ student presses the button, the document is presented with a dialog to
+ save the document. After saving, the document is automatically closed.
+
+\item[\cs{ShrtPtsFld}] Initially hidden, the text field changes to visible
+ when the instructor presses the \textsf{Mark It} control. This field
+ is the \cs{PointsField} command of \pkg{exerquiz}, and contains the number
+ of points award for all non-extended response problems.
+
+\item[\cs{LngPtsFld}] Initially hidden, the text field becomes visible
+ when the instructor presses the \textsf{Mark It} control. It is a field
+ that will hold the total points awarded by the instructor for extended response
+ questions.
+
+\item[\cs{TotalsFld}] Initially hidden, the text field becomes visible
+ when the instructor presses the \textsf{Mark It} control. This field holds
+ the total of \cs{ShrtPtsFld} and \cs{LngPtsFld}.
+\end{description}
+The above elements may be used directly in the document, but it is easier to
+use the command \cs{thQuizTrailer}:
+\bVerb\takeMeasure{\string\end\darg{quiz*}\string\quad\string\thQuizTrailer}%
+\edef\LW{\the\linewidth}%
+\setlength{\eflength}{\bxSize}%
+\def\1{\rlap{\hskip\eflength\enspace\sffamily\bfseries Skeleton outline of a quiz}}%
+\def\2{\rlap{\hskip\eflength\enspace\smash{\parbox[t]{\LW-\eflength-1em}{\sffamily\raggedright%
+The placement of the \cs{thQuizHeader} and \cs{thQuizTrailer} commands}}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+!1\DeclareQuiz{!ameta(qz-name)}
+!2\begin{document}
+!textbf(\thQuizHeader)
+\begin{quiz*}{\currQuiz}
+!ameta(!sffamily(Instructions))
+\begin{questions}
+...
+\end{questions}
+\end{quiz*}\quad!textbf(\thQuizTrailer)
+\end{dCmd}
+\eVerb which incorporates the design elements described above. Throughout the
+sample files, bothe \cs{thQuizHeader} and \cs{thQuizTrailer} are used.
+
+
+\paragraph*{Student's experience.}\label{para:basic-SE} The student is presented with a quiz built
+from \env{quiz} environment of the \pkg{exerquiz} package. To begin the quiz,
+{\heshe*} presses the \textsf{Begin Quiz} control. If {\heshe*} has not
+filled the name fields, an alert box appears to instruct {\himher*} fill in
+the name fields. {\HeShe*} cannot begin the quiz until that occurs. Once the
+name fields are filled, the student can once again press the \textsf{Begin
+Quiz} and is allowed to respond to the questions. On finishing, the student
+presses the \textsf{End Quiz} control. An alert box appears querying the
+student whether {\heshe*} truly wants to end the quiz. (Ending the quiz means
+the student cannot make any changes to {\hisher*} responses without having to
+start over again.) After the student responds by pressing the \textsf{Yes}
+control on the alert box, the \textsf{Save} control appears, and the student
+can press it and open a \textsf{Save As PDF} dialog, which eventually ends
+with saving the file (hopefully in the student's private folder). After a
+successful save, the document is immediately closed.
+
+\paragraph*{Instructor's experience.}\label{para:basic-IE} When the
+instructor opens a completed quiz, {\heshe} presses the \textsf{Mark It}
+control. The \textsf{Freeze Quiz} control appears; the fields
+\cs{completeMsgFld} and \cs{stuSaveBtn} are hidden; and the fields
+\cs{ShrtPtsFld}, \cs{LngPtsFld}, and \cs{TotalsFld} become visible.
+Additionally, the credit mark up fields appear in the margins indicating the
+number of points the student received for each response. If there are any
+extended response questions, the instructor enters an evaluation of the
+student's responses in the \cs{essayQ} field. Changes in score are reflected
+in the \cs{LngPtsFld}, \cs{TotalsFld}, and in the summary table. To complete
+{\hisher*} evaluation of the quiz, {\heshe*} enters a value into the
+\cs{studentGrade} (this is required, saving the file is not permitted,
+otherwise) and then presses the \textsf{Freeze \& Save} control. The file is
+saved under the name \cs{jobname-\ameta{first}\_\ameta{last}}, where
+\ameta{first} and \ameta{last} are the values entered into the name fields by
+the student. The instructor must manually record\FmtMP{manually record} the
+student's score.
+
+\newtopic\noindent That is the simple case! Again, see the sample file \texttt{theb.tex}.
+
+\begin{figure}[p]\fboxsep0pt \centering
+\parbox[b][215pt][t]{.45\linewidth}{\fbox{\includegraphics[width=\linewidth-2\fboxrule]{graphics/quiz-1}}\vfill
+\centering (a) Student's view: quiz taken}\hfill
+\parbox[b][215pt][t]{.45\linewidth}{\fbox{\includegraphics[width=\linewidth-2\fboxrule]{graphics/quiz-2}}\vfill
+\centering (b) Instructor's view: Mark It pressed}\\[16pt]
+\parbox[b][215pt][t]{.45\linewidth}{\fbox{\includegraphics[width=\linewidth-2\fboxrule]{graphics/quiz-3}}\vfill
+\centering (c) Instructor's view: quiz is marked}\hfill
+\parbox[b][215pt][t]{.45\linewidth}{\fbox{\includegraphics[width=\linewidth-2\fboxrule]{graphics/quiz-4}}\vfill
+\centering (d) Student view: quiz returned frozen}
+\caption{Student and Instructor experiences}\label{fig:qwf}
+\end{figure}
+
+\newtopic\noindent
+\hyperref[fig:qwf]{Figure~\ref*{fig:qwf}} on page~\pageref*{fig:qwf} shows
+the workflow: (a) The student views and takes the quiz; the screenshot is
+just before the \textsf{End} control is pressed; (b) shows the same quiz
+after the instructor has pressed the \textsf{Mark It} control; (c) the
+instructor has given some points in the extended response question (5 pts)
+and set the grade as 4; (d) this screenshot shows the quiz after the
+\textsf{Save \& Close} button is pressed.
+
+\subsection{Quizzes that specify the \tops{\protect\opt{useclass}}{useclass} option}\label{ss:uc}
+
+A \textit{class method}\FmtMP{class method} is one in which one of the ``class options'' are used;
+these are \opt{useclass}, \opt{usebatch}, and \opt{batchdistr}.
+
+\newtopic\noindent
+The sample file for this section is \texttt{thexuc.tex}.
+
+\newtopic\noindent
+All the elements of the basic methods of Section~\ref{ss:BMs} are still
+critical to the construction of the quiz, additionally, we use the
+\opt{useclass} option. When this option is taken, it is expected that class
+information is read into the document, see the discussion below.
+
+\subsubsection{Preamble}
+
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars={!~@}]
+\documentclass{article}
+\usepackage{amstext} %!textsf~ (optional, used in a minor way below)@
+\usepackage{web} %!textsf~ (optional)@
+\usepackage[usesumrytbls]{exerquiz}
+!textbf~\usepackage[useclass]{thorshammer}@ %!textsf~ (because I am a classy guy)@
+
+\setInitMag{fitwidth} %!textsf~ (optional, defined in this package)@
+\hypersetup{pdfpagelayout=OneColumn} %!textsf~ (optional, from hyperref )@
+\reversemarginpar
+\showCreditMarkup
+%\previewOn\pmpvOn
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+\useMCCircles
+
+!ameta~!sffamily~insertion of class info@@
+
+%!textsf~ Perform certain tasks when opened in Acrobat the first time@
+\begin{makeClassFiles}
+\sadQuizzes
+\end{makeClassFiles}
+\begin{document}
+...
+\end{Verbatim}
+Information on the \ameta{\sffamily{insertion of class info}}, on the
+\env{makeClassFiles} environment, and on the \cs{sadQuizzes} command are
+found in the next two sections.
+
+\subsubsection{The insertion of class information}\label{sss:CI}
+
+Thor's way states that quizzes are distributed to student private folders, and copies
+are saved to the instructor folder.
+
+\newtopic\noindent\textbf{Required information:}
+\begin{itemize}
+ \item The path to the instructor folder
+ \item The path to the class folder
+ \item For each student in the class, the first name, last name, and path to the student's folder, relative
+ to the class folder.
+\end{itemize}
+These three items are passed to \pkg{thorshammer} through the following commands.
+\bVerb\takeMeasure{\string\classMember*\darg{\ameta{first}}\darg{\ameta{last}}*\darg{\ameta{full-path}}}%
+\setlength{\eflength}{\bxSize}%
+\def\1{\rlap{\hskip\eflength\textsf{wd:\,}\cs{PTFW}\textsf{, ht:\,}\cs{DefaultHeightOfWidget}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\instrPath*{!ameta(path)}
+\classPath*{!ameta(path)}
+\classMember*{!ameta(first)}{!ameta(last)}{!ameta(folder)}
+\classMember*{!ameta(first)}{!ameta(last)}*{!ameta(full-path)}
+\end{dCmd}
+\eVerb Details of these commands are found next.
+\begin{description}
+ \item[\cs{instrPath}] The path to the instructor's folder. Copies of all
+ files are dumped into this folder. The instructor uses this folder to
+ archive the quizzes. The \ameta{path} may be a full path, which is the
+ default, or a path relative to the folder the source file is being
+ compiled in. The \ameta{path} is interpreted as relative to the
+ current path when the \texttt*-option is taken; for example:
+\setlength\eflength{\widthof{\ttfamily\small\string\instrPath*\darg{myclass}\quad}}
+\def\1{\rlap{\hskip\eflength\%\sffamily\space assumes source is in the algebra folder}}
+\begin{Verbatim}[fontsize=\small,commandchars=!()]
+\instrPath{/c/users/thor/documents/myuni/spr19/algebra/myclass}
+!1\instrPath*{myclass}
+\end{Verbatim}
+ \item[\cs{classPath}] The path to the class folder. The \ameta{path} is an absolute
+ path by default, or a relative path, relative to the source folder. For example,
+
+\setlength\eflength{\widthof{\ttfamily\small\string\instrPath*\darg{myclass/staging}\quad}}
+\begin{Verbatim}[fontsize=\small,commandchars=!()]
+\classPath{/c/users/thor/documents/myuni/spr19/algebra/myclass/staging}
+!1\classPath*{myclass/staging}
+\end{Verbatim}
+ \item[\cs{classMember}] The arguments for this command provide the basic
+ information needed for Thor's way. When the \emph{first} \texttt*-option is taken,
+ the three arguments are filtered through \cs{pdfstringdef}
+ (\pkg{hyperref}). When the \emph{second} \texttt*-option is present, the last required
+ argument \ameta{full-path} must be full path to the student folder.\footnote{In a perfect world,
+ all student folders are at the end of the (current) class path; however, some students' class folder
+ may be elsewhere, this second \texttt*-option is designed for these ``exceptional'' students.}
+
+ There needs to be one \cs{classMember} command for
+ each member of the class.
+
+ \textbf{On the topic of accents.} The first and last name arguments
+ may contain accents from a local language. There are several ways of
+ handling them.
+ \begin{itemize}
+ \item (\texttt*-option) \verb~\classMember*{J\"{u}rgen}{Loki}{JL53456/thor}~
+ \item (octal-method) \verb~\classMember{J\oct374rgen}{Loki}{JL53456/thor}~
+ \item (unicode-method) \verb~\classMember{J\u00FCrgen}{Loki}{JL53456/thor}~
+ \end{itemize}
+\end{description}
+There are three methods of introducing the required class information into the quiz document.
+
+\paragraph*{Direct placement in the source file.}
+This is the method that messes up your preamble the most:
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small]
+\instrPath{/c/users/thor/documents/myuni/spr19/algebra/myclass}
+\classPath{/c/users/thor/documents/myuni/spr19/algebra/myclass/staging}
+\classMember{Fred}{Flintstone}{FF34345/thor}
+\classMember*{J\"{u}rgen}{Loki}{JL53456/thor}
+...
+\classMember{Peter}{Pan}{PP75464/thor}
+\end{Verbatim}
+If the third argument of the \cs{classMember} command is empty, the corresponding
+quiz is placed in the folder determined by the path given in
+\cs{classPath}.
+
+\newtopic\noindent
+The next two methods use a (class) configuration file to load the info.
+
+\paragraph*{Use \cs{InputClassData} to input class info.} This is the simplest method.
+It consists of the direct method cut and pasted into a CFG file.
+\bVerb\small\takeMeasure{\string\InputClassData\darg{\ameta{base-name}}}%
+\setlength{\eflength}{\bxSize}%
+\def\1{\rlap{\hskip\eflength\%\textsf{ preamble only}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+!1\InputClassData{!ameta(base-name)}
+\end{dCmd}
+\eVerb This command inputs the configuration file
+\texttt{\ameta{base-name}.cfg}. To repeat, the contents of
+\texttt{\ameta{base-name}.cfg} is simply the lines as displayed in the direct
+placement method above.
+
+\paragraph*{Use \cs{InputFormattedClass} to input class info.} This is a more flexible method
+of inputting class info. The syntax for \cs{InputFormattedClass} is,
+\bVerb\small\takeMeasure{\string\InputFormattedClass[\ameta{\cs{cmd}}]\darg{\ameta{base-name}}}%
+\setlength{\eflength}{\bxSize}%
+\def\1{\rlap{\hskip\eflength\%\textsf{ preamble only}}}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+!1\InputFormattedClass[!ameta(\cmd)]{!ameta(base-name)}
+\end{dCmd}
+\eVerb The optional \ameta{\cs{cmd}} is used to process each class member's info and ultimately
+builds the \cs{classMember} command for that class member. The default for \ameta{\cs{cmd}}
+is the command \cs{classMember}. The name of the configuration file is
+\texttt{\ameta{base-name}.cfg}. The file format is as follow:
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+\instrPath{!ameta(path)}
+\classPath{!ameta(path)}
+\bClassData
+!ameta(entry1)
+!ameta(entry2)
+...
+\end{Verbatim}
+Above the \cs{bClassData} marker, direct input is performed, so the \cs{instrPath}
+and \cs{classPath} command are placed there. Below the \cs{bClassData} marker is the
+class members individual data, represented here by \ameta{entry}. When
+the configuration file is input, \ameta{\cs{cmd}} is prefixed to each entry:
+\begin{flushleft}\ttfamily
+\ameta{\cs{cmd}}\ameta{entry1}\\
+\ameta{\cs{cmd}}\ameta{entry2}\\
+...
+\end{flushleft}
+A straightforward example is,
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small]
+\instrPath{/c/users/thor/documents/myuni/spr19/algebra/myclass}
+\classPath{/c/users/thor/documents/myuni/spr19/algebra/myclass/staging}
+\bClassData
+{Fred}{Flintstone}{FF34345/thor}
+*{J\"{u}rgen}{Loki}{JL53456/thor}
+...
+{Peter}{Pan}{PP75464/thor}
+\end{Verbatim}
+When we expand \cs{InputFormattedClass\darg{algclass}}, the lines below
+\cs{bClassData} marker are read in as:
+\begin{flushleft}\ttfamily
+\cs{classMember}\darg{Fred}\darg{Flintstone}\darg{FF34345/thor}\\
+\cs{classMember}*\darg{J\string\"\darg{u}rgen}\darg{Loki}\darg{JL53456/thor}\\
+...\\
+\cs{classMember}\darg{Peter}\darg{Pan}\darg{PP75464/thor}
+\end{flushleft}
+To illustrate the greater flexibility, we offer up this example.
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+\instrPath{/c/users/thor/documents/myuni/spr19/algebra/myclass}
+\classPath{/c/users/thor/documents/myuni/spr19/algebra/myclass/staging}
+\bClassData
+{Fred}{Flintstone}{!ameta(other-data)}{FF34345/thor}
+*{J\"{u}rgen}{Loki}{!ameta(other-data)}{JL53456/thor}
+...
+{Peter}{Pan}{!ameta(other-data)}{PP75464/thor}
+\end{Verbatim}
+Notice the entry has an addition piece of information (perhaps a university ID number). Here,
+each \ameta{entry} has more information than is required, so we need to extract what we need.
+For this purpose, we define \cs{ParseClassMember} and input it as the optional argument
+of \cs{InputFormattedClass}.
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+\newcommand\ParseClassMember[4]{\classMember{#1}{#2}{#4}}
+\InputFormattedClass[\ParseClassMember]{myalgclass}
+\end{Verbatim}
+The first \ameta{entry} is processed as follows:
+\begin{Verbatim}[xleftmargin=\amtIndent,fontsize=\small,commandchars=!()]
+\ParseClassMember{Fred}{Flintstone}{!ameta(other-data)}{FF34345/thor}
+\end{Verbatim}
+which, in turn, expands to \verb~\classMember{Fred}{Flintstone}{FF34345/thor}~.
+
+In theory, \ameta{entry} can be quite general, but the \ameta{\cs{cmd}} must to be able to parse
+it and generate the expected data (\cs{classMember*\darg{\ameta{first}}\darg{\ameta{last}}\darg{\ameta{folder}}}).
+
+\subsubsection{The \tops{\protect\cs{sadQuizzes}}{\textbackslash{sadQuizzes}} command}\label{sss:sadQs}
+
+We now discuss the insertion of the following environment and command:
+\bVerb\takeMeasure{\string\begin\darg{makeClassFiles}}%
+\begin{dCmd}{\bxSize}
+\begin{makeClassFiles}
+\sadQuizzes
+\end{makeClassFiles}
+\end{dCmd}
+\eVerb The \env{makeClassFiles} environment is a simplified version of the
+\env{execJS} environment of the \pkg{insdljs} package and is similar to
+\env{docassembly} introduced earlier. The \cs{sadQuizzes} command (it does not
+mean sad news for the students on this quiz) expands to some JavaScript that
+\underbar{s}aves \underbar{a}nd \underbar{d}istributes the quizzes of the
+students to the designated folders, but \cs{sadQuizzes} do more than that:
+\begin{itemize}
+ \item If solution pages are present, these pages are extracted from the
+ parent document, saved to the instructor's folder, and then deleted from
+ the parent document.
+ \item If there are cover pages, these are removed and saved to the
+ instructor's folder.
+ \item For each member of the class, it builds a customize quiz
+ \begin{itemize}
+ \item It reinserts the cover pages, if any.
+ \item It populates the name fields with the first and last name of the
+ current class member being processed.
+ \item It saves each (customized) quiz to the appropriate student folder
+ with the file name \cs{jobname-\ameta{first}\_\ameta{last}.pdf}
+ \item It saves a copy of the (customized) quiz to the instructor's
+ designated folder.
+ \end{itemize}
+\end{itemize}
+
+\paragraph*{Student's experience.} Same as \textbf{Student's experience}, as described in
+Section~\ref{ss:BMs} on page~\pageref{para:basic-SE}, but the student does
+not enter {\hisher} name in the name fields. One of the tasks of
+\cs{sadQuizzes} is to pre-populate the name fields with the names of the
+students.
+
+\paragraph*{Instructor's experience.} Same as \textbf{Instructor's experience}, as described in
+Section~\ref{ss:BMs}on page~\pageref{para:basic-IE}. The instructor must manually record\FmtMP{manually record} the
+student's score.
+
+%\subsection{Quizzes that specify \tops{\protect\opt{usebatch}}{usebatch} option}\label{ss:ub}
+\subsection{The \tops{\protect\opt{usebatch}}{usebatch} option: single rendition source}\label{ss:ub}
+
+The demonstration file for this section is \texttt{theexub.tex}.
+
+\newtopic\noindent
+There can be only one quiz (as declared by the
+\cs{DeclareQuiz\darg{\ameta{qz-name}}} command); however, there can be more
+than one \textit{rendition}\FmtMP{rendition discussed} (or one variation) of the quiz. In this section,
+we deal with the simplest case: the source file has only one rendition of the
+quiz. In \hyperref[ss:mr]{Section~\ref*{ss:mr}}, the case of multiple renditions is covered.
+
+\paragraph*{File construction.} A quiz constructed with the \opt{usebatch} option is the same as one that
+uses \opt{useclass} (see \hyperref[ss:uc]{Section~\ref*{ss:uc}}); in fact,
+specifying the \opt{usebatch} option automatically passes the \opt{useclass}
+option to \pkg{thorshammer}. The difference is in the instructor's
+experience; when the instructor presses the \textsf{Mark It} control, instead
+of the \textsf{Freeze Quiz} button appearing, the \textsf{Save \& Close}
+button appears. After the instructor is finished marking up the quiz, as
+described in \textbf{Instructor's experience} on
+page~\pageref{para:basic-IE}, {\heshe*} presses the \textsf{Save \& Close}
+button, which saves and closes the quiz document. After the instructor has
+inspected each of the quizzes, {\heshe*} is ready to use \textsf{Thor's way}
+action-wizard (or batch sequence).
+
+\subsubsection{How to use the \textsf{Thor's way} action}\label{sss:TW}
+
+A powerful feature of the \app{Acrobat} application is the \textsf{Action
+Wizard}. The user-interface allows you to define a custom action that
+performs a series of tasks on each PDF in the list of PDFs to be processed.
+The \pkg{thorshammer} package provides its own action-wizard titled
+`\textsf{Thor's way}'.
+
+\paragraph*{What does \textsf{Thor's way} do?} For each of the quizzes that are
+designated as the files to be processed, this action-wizard performs the following tasks:
+\begin{enumerate}
+ \item If solutions were provided for this quiz, the solution pages are
+ retrieved from the instructor's folder and inserted onto the end of
+ the quiz.
+ \item Gets the values for the name, student report and student grade
+ fields, and holds them as JavaScript variables.
+ \item Freezes the document (makes all fields readonly and flattens all
+ pages)
+ \item Saves the frozen quiz under the name
+ \texttt{\ameta{filename}-g.pdf}. Recall the \texttt{filename} is
+ \texttt{\cs{jobname}-\ameta{first}\_\ameta{last}}, where \cs{jobname}
+ is the base name of the (parent) {\LaTeX} source file that generated
+ the quizzes to begin with. The file is saved to the folder designated
+ as the `save folder.'
+\end{enumerate}
+Additional details are contained in the paragraph \textbf{How to use
+\textsf{Thor's way}} found below.
+
+\paragraph*{How to install \textsf{Thor's way}.}
+\begin{enumerate}
+ \item Start \app{Acrobat}
+ \item select \textsf{Tools} from the toolbar
+ \item Find and open the \textsf{Action Wizard}
+ \item Select \textsf{Manage Actions}
+ \item In the \textsf{Manage Actions} dialog box, press the
+ \textsf{Import} button on the right-hand side
+ \item Navigate to the \texttt{action-wizards} folder of the
+ \pkg{thorshammer} package and choose either \textsf{Thor's way (en).sequ}
+ or \textsf{Thor's way (de).sequ} (both can be installed).
+ The wizard is now installed.
+ \item Back out of where you are, saving as you go
+\end{enumerate}
+
+\paragraph*{How to use \textsf{Thor's way}.}\label{para:UTW} Use this action after
+the instructor has finished reviewing each of the quizzes by first pressing the
+\textsf{Mark It} button, assigning additional points as needed, and pressing
+the \textsf{Save \& Close} button.
+
+\newtopic\noindent\textbf{Preliminaries}\vspace{-6pt}\relax
+\begin{enumerate}
+\item[] This package comes with two files: \texttt{control.pdf} and
+ \texttt{terminate-batch.pdf}. \emph{These two files are always placed in
+ the same folder together}.\footnote{Source files for these two PDFs are provided so you
+ can localize any instructions to the land of your choice.} Copy these two files to some folder convenient to the
+ work you are doing.
+\end{enumerate}
+
+%\goodbreak
+
+\newtopic\noindent\textbf{Preparation phase}\vspace{-6pt}\relax
+\begin{enumerate}
+ \item Open the \texttt{container.pdf} file in the \app{Acrobat} window,
+ see Figure~\ref{cap:container}. Purpose of this file is to provide
+ the \textsf{Thor's way} some needed basic information, it also holds
+ the summary of the quiz results as an attachment. The document contains
+ two push buttons, two text fields, and two check boxes.
+
+\begin{figure}[tbh]\centering\setlength\fboxsep{0pt}
+\fbox{\includegraphics[width=.67\linewidth]{graphics/container}}\\
+\caption{\texttt{container.pdf}}\label{cap:container}
+\end{figure}
+
+\item With the \texttt{container.pdf} file open, in the top most text field,
+ enter a name for the quiz. This will be the base name for the
+ tab-delimited TXT file that is attached to \texttt{container.pdf}
+\item In the bottom most text field, enter the folder (path) where the quiz files
+ are to be saved. (These are the ones named \texttt{\cs{filename-g.pdf}})
+ The folder path you enter can be a relative to the folder that contains \texttt{container.pdf},
+ or it can be a full (absolute) path to the folder. eg,
+ \begin{flushleft}\ttfamily
+ /c/users/thor/documents/myuni/spr19/algebra/myclass/graded
+ \end{flushleft}
+ Notice the method of referencing the path, this is the
+ device-independent file path reference in the Acrobat JavaScript API Reference manual.
+ See the short article at \href{https://acrobatusers.com/tutorials/print/file-paths-acrobat-javascript}{AcrobatUsers.com}
+ for more information.\footnote{On \app{Windows}, a \app{Windows} path seems to work as well: \texttt{c:\string\users\string\thor\string\...\string\graded}}
+\item \checkBox[\DV{Yes}\V{Yes}\Ff\FfReadOnly]{apslns}{11bp}{11bp}{Yes} \uif{Append solutions, if they exist}\\
+ This check box is checked by default. Clear this box if you don't want
+ any solutions to the quiz appended. The \uif{Thor's way} action
+ sequence appends the solutions or not according to the state of this
+ checkbox.
+\item \checkBox[\DV{Yes}\V{Yes}\Ff\FfReadOnly]{rcddt}{11bp}{11bp}{Yes}
+ \uif{Record class data}\\
+ This check box is checked by default. If you don't want to record the
+ class data, clear this check box. Normally, this box is always checked;
+ however, if you run \uif{Thor's way} with \uif{Append solutions, if
+ they exist} cleared and at a later time you want to append the
+ solutions, run \uif{Thor's way} again on the same set of quizzes with
+ \uif{Record class data} cleared. The quiz data file attached to the
+ \texttt{container.pdf} will be preserved.
+\item Now press the button labeled \textsf{Push}. The information of the
+ text fields are saved as global JavaScript variables that can be
+ accessed by the batch sequence. When you press \textsf{Push}, the file
+ \texttt{container.pdf} closes, don't worry.
+\end{enumerate}
+
+\newtopic\noindent\textbf{Action phase}\vspace{-6pt}\relax
+\begin{enumerate}\setcounter{enumi}{4}
+ \item Open the \textsf{Action Wizard} and choose \FmtMP{{Action: }\textsf{Thor's
+ way}}\textsf{Thor's way} from
+ the list of actions.
+
+\begin{figure}[tbh]\centering\setlength\fboxsep{0pt}
+\includegraphics[width=.33\linewidth]{graphics/action-down-arrow}\\
+\caption{\textsf{Select files to be processed}}\label{cap:ada}
+\end{figure}
+
+ \item \textbf{Select files to be processed.} Click on the down arrow
+ control, as indicated in Figure~\ref{cap:ada}. Choose the \textsf{Add
+ Folders...} control if your quizzes are in a folder structure,
+ \app{Acrobat} should find all PDFs in the folder (including
+ subfolders) and list them. Choose the \textsf{Add Files...} controls
+ if the quizzes are all in the same folder and you can select them
+ all.
+
+\begin{figure}[tbh]\centering\setlength\fboxsep{0pt}
+\includegraphics[width=.67\linewidth]{graphics/ManageFiles}\\
+\caption{\textsf{ManageFiles dialog box}}\label{cap:fmd}
+\end{figure}
+
+ \item \textbf{Select \texttt{terminate-batch.pdf}.} With the \textsf{Add
+ Files...}\ control, select the package file \texttt{terminate-batch.pdf}, which resides
+ in the same folder as \texttt{control.pdf}. This file must be last in
+ the list of files to be processed; if necessary, press the down arrow
+ control and select \textsf{Manage Files} (see Figure~\ref{cap:ada}).
+ The \textsf{Manage Files} dialog box, Figure~\ref{cap:fmd}, lists all
+ the files to be processed. Using the down arrow control in the right,
+ move the \texttt{terminate-batch.pdf} to it is last in the list.
+
+\item Keeping your fingers crossed and press the \textsf{Start} control. Each
+ of the quizzes is brought into the \app{Acrobat} window, form field
+ information is extracted, frozen, saved, and closed.
+
+\item When the \texttt{terminate-batch.pdf} is reached (bottom of the
+ list), no extracting or freezing occurs, but what happens is the
+ \texttt{control.pdf} document is opened once again.
+
+\begin{figure}[tbh]\centering\setlength\fboxsep{0pt}
+\includegraphics[width=.67\linewidth]{graphics/quiz-results}\\
+\caption{\textsf{Results displayed}}\label{cap:qr}
+\end{figure}
+
+\item Look at the \textsf{Attachments} panel, using the user-interface,
+ save the attachment to where you want it. Figure~\ref{cap:qr} shows the
+ results of a test run of \textsf{Thor's way}. The produced TXT file is
+ a tab-delimited file that can be opened in \textsf{Microsoft Excel}.
+ These saved quiz results can be merged, no doubt, into a parent
+ \textsf{Excel} spreadsheet.
+
+\end{enumerate}
+
+\subsection{The \tops{\protect\opt{usebatch}}{usebatch} option: multiple renditions source}\label{ss:mr}
+
+The demonstration files for this section are \texttt{thexr.tex} and \texttt{thexrt.tex}.
+
+\newtopic\noindent
+In this section we discuss techniques for introducing multiple renditions of
+a quiz into the workflow. To be fair the student, the renditions should be roughly equivalent or the students will cry
+``foul!'' We don't want that to happen, we have enough troubles.
+
+\subsubsection{Preamble}
+
+Same preamble as previously described, including the use of \cs{sadQuizzes}.
+
+\subsubsection{The body of the document}
+
+Following the \cs{DeclareQuiz} command, declare one or more quiz body names using
+the \cs{declareQuizBody} command. Each quiz body declaration has a corresponding quiz
+body environment that contains a quiz. A rough outline is seen below.
+
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()]
+%!textsf( declare the name of this quiz)
+\DeclareQuiz{!ameta(quiz-name)}
+
+%!textsf( declare the names of the renditions)
+\declareQuizBody{!ameta(qb-name!SUB1)}
+...
+\declareQuizBody{!ameta(qb-name!SUB(k))}
+
+%!textsf( each rendition is a complete quiz within its own environment)
+%!textsf( call these environments ``quiz body'' environments)
+\begin{!ameta(qb-name!SUB1)}
+ !ameta(quiz-rendition!SUB1)
+\begin{!ameta(qb-name!SUB1)}
+...
+\begin{!ameta(qb-name!SUB(k))}
+ !ameta(quiz-rendition!SUB(k))
+\begin{!ameta(qb-name!SUB(k))}
+\end{Verbatim}
+Actually, there may be only one rendition ($k=1$), but there is randomness built into
+the single rendition to produce a different, yet equivalent, version of the quiz.
+
+The \env{\ameta{qb-name}} environments are verbatim environments that write their contents
+to a CUT file, which are later input back into the document.
+
+\newtopic\noindent Following the \env{\ameta{qb-name}} environments comes the final step,
+we input these back into the document.
+\begin{Verbatim}[xleftmargin=\amtIndent,commandchars=!()]
+\InputQuizBody{!ameta(qb-name!SUB1)}
+...
+\InputQuizBody{!ameta(qb-name!SUB(k))}
+\end{Verbatim}
+You can input some or all of the declared quiz bodies, and the quiz bodies may be input several
+times, especially useful if a quiz body has a degree of randomness built into it.
+
+When you \cs{DeclareQuizBody}, there is an associated version (or rendition)
+number in the form of the text macro \cs{QzVer}\FmtMP{\cs{QzVer}}, that
+expands to a number (1, 2, 3, and so on). This number can be incorporated
+into various section titles, such as in the \cs{sqslsectitle},
+\cs{thQzHeader}, and \cs{thQzHeaderCS} commands, for example. Refer to
+\texttt{examples/misc/thexrt.tex} for illustrations.
+
+\subsubsection{The \tops{\protect\cs}{\textbackslash}{sadQuizzes} command (revisited)}
+
+When you compile a multi-rendition file, and bring the resulting PDF into a
+PDF viewer, you'll see you have $n$-quizzes contained in the document, where
+$n$ is the number of \cs{InputQuizBody} commands used. Here is a brief
+description of the action of \cs{sadQuizzes} in a multi-rendition document.
+\begin{itemize}
+ \item If solution pages are present, these pages are extracted from the
+ parent document, saved to the instructor's folder, and then
+ deleted from the parent document.
+ \item If there are cover pages, these are removed and saved to the
+ instructor's folder.
+ \item As the script goes through the list of students, it extracts one of
+ the $n$ quizzes in the parent document and populates it with the name
+ data.
+ \item If there are cover pages for this quiz set, the cover pages are
+ retrieved from the instructor's folder and inserted onto the front of
+ the quiz.
+ \item The extraction of a subset of pages preserves the document JavaScript,
+ but some elements vital to the whole workflow are lost. The script
+ restore these lost elements.
+ \item It saves each (customized) quiz to the appropriate student folder
+ with the file name \cs{jobname-\ameta{first}\_\ameta{last}.pdf}
+ \item It saves a copy of the (customized) quiz to the instructor's
+ designated folder.
+\end{itemize}
+What you should get is several versions assigned to the class members:
+\begin{itemize}
+ \item class member 1 gets the first rendition
+ \item class member 2 gets the second rendition
+ \item[]...
+ \item class member $n$ gets the $n^{\text{th}}$ rendition, where $n = \text{number of \cs{InputQuizBody}}$ statements
+ \item class member $n+1$ gets the first rendition
+ \item[]...
+\end{itemize}
+When the parent document is opened in \app{Acrobat}, \cs{sadQuizzes}
+executes creates and distributes the quizzes to the instructor's folder and
+to the student's individual folder. It's just that simple.
+
+\paragraph*{Student's experience.} Same as their earlier experience, hopefully, this time around it will
+be a better experience, better results, happier student, we can only hope.
+
+\paragraph*{Instructor's experience.} Same as above, except {\heshe} has different quizzes to evaluate within
+a class. Poor instructor. After {\heshe*} has finished marking the quizzes,
+{\heshe*} runs them through \textsf{Thor's way} (\Nameref{sss:TW}), which
+leads to happiness for the instructor. The student's score is automatically
+recorded\FmtMP{automatically recorded} by the \textsf{Thor's way} action
+sequence.
+
+\subsection{Quizzes that specify the \tops{\protect\opt{batchdistr}}{batchdistr} option}\label{ss:bd}
+
+The \opt{batchdistr} option is the same as the \opt{usebatch} option, with
+only one difference: After the source file is compiled and opened in
+\app{Acrobat}, the newly created quizzes are distributed to the instructor's
+folder (as declared by \cs{instrPath}), but \emph{the quizzes are not
+distributed to the student folders}. The quizzes are distributed to the
+student's folder using batch sequences, to be detailed in subsequent
+paragraphs.
+
+\paragraph*{Apply security before distributing quizzes.} The real purpose of
+delaying the distribution of the quizzes to the student folders is to place
+\emph{password security} on the quiz files. After building the instructor's
+copies of the quizzes, the instructor can use the action \textsf{Thor
+protects and distributes}. The details of the workflow follows:
+\begin{enumerate}
+\item \textbf{Build:} Build the source quiz file using the \opt{batchdistr} option.
+
+\item[] When the source file is opened in \app{Acrobat} the first time, the
+ custom-named quiz files are saved into the instructor's folder (as
+ specified by \cs{instrPath}); no quizzes are deposited in the student
+ folders yet.
+
+\item \textbf{Secure and distribute:} With the \app{Acrobat} window empty,
+ open the \textsf{Action Wizard} and select the \FmtMP{{Action: }\textsf{Thor
+ protects and distributes}}\textsf{Thor protects and distributes} action.
+ For the \textsf{Files to be processed}, select the quizzes that have
+ just been dropped into the instructor's folder. Perform the action by
+ pressing \textsf{Start}.
+
+ Note: To delay the distribution of the quizzes, apply
+ \textsf{Thor protects} and later apply \textsf{Thor distributes}.
+
+\item \textbf{Examination period:} Now the students take the quiz, the quiz
+ has password security so the student cannot snoop around with the file,
+ even if the student has access to \app{Acrobat}.
+
+\item \textbf{Marking period:} Following the exam period, the instructor
+ examines each quiz: Press the \textsf{Mark It} button, award any points
+ for extended response questions, assign a student grade, and press the
+ \textsf{Save \& Close} button.
+
+\item \textbf{Remove security:}\label{item:RS} Press \textsf{Ctrl+K} to
+ open the \textsf{Preferences} dialog box. In the left-hand panel,
+ select \textsf{Action Wizard}. In the right-hand panel change
+ \textsf{Security Method}, using the dropdown menu to \textsf{Password
+ Security}. Save your changes by pressing the \textsf{OK} control in the
+ lower-right corner.
+
+\item[] With the \app{Acrobat} window empty, open the \textsf{Action
+ Wizard} and select the \FmtMP{{Action: }\textsf{Thor removes
+ protection}}\textsf{Thor removes protection} action. For the
+ \textsf{Files to be processed}, select the quizzes in the student
+ folders. Use either \textsf{Add Folder...} or \textsf{Add Files...} to
+ select all the quizzes. Perform the action by pressing \textsf{Start}.
+
+\item Press \textsf{Ctrl+K} to open the
+ \textsf{Preferences} dialog box. In the left-hand panel, select
+ \textsf{Action Wizard}. In the right-hand panel change \textsf{Security
+ Method}, using the dropdown menu to \textsf{Do not ask for password}. Save
+ your changes by pressing the \textsf{OK} control in the lower-right
+ corner.
+
+%Thor allows changes (password) student folders container
+\item \textbf{Thor's way:} Now apply the \FmtMP{{Action: }\textsf{Thor's
+ way}}\textsf{Thor's way} action, as described in the paragraph
+ \textbf{\nameref{para:UTW}} on page~\pageref{para:UTW}.
+\end{enumerate}
+
+\section{Bells and whistles}
+
+\subsection{Running Headers}
+
+ The scheme used here assumes no other {\LaTeX} package has been used to take over the running
+ headers (and footers). If that is the case, use the values of the commands below to design
+ your own.
+\bVerb\small\takeMeasure{\string\thQzHeaderCQ\darg{\ameta{text}}}%
+\setlength{\eflength}{\widthof{\sffamily(Solutions: \cs{thQuizName})}}%
+\edef\x{\the\eflength}%
+\setlength{\eflength}{\bxSize}%
+\def\1{\rlap{\hskip\eflength\rlap{\hskip\x\relax\quad\cs{def}\cs{th@QzHeaderLQ\darg{\ameta{text}}}}\sffamily(Thor's class)}}
+\def\2{\rlap{\hskip\eflength\rlap{\hskip\x\relax\quad\cs{def}\cs{th@QzHeaderCQ\darg{\ameta{text}}}}\sffamily(Quiz \cs{thQuizName})}}
+\def\3{\rlap{\hskip\eflength\rlap{\hskip\x\relax\quad\cs{def}\cs{th@QzHeaderCS\darg{\ameta{text}}}}\sffamily(Solutions: \cs{thQuizName})}}
+\def\4{\rlap{\hskip\eflength\rlap{\hskip\x\relax\quad\cs{def}\cs{t@hQzHeaderR\darg{\ameta{text}}}}\sffamily(\cs{thepage})}}
+\begin{dCmd}[fontsize=\small,commandchars=!()]{\bxSize}
+!1\thQzHeaderL{!ameta(text)}
+!2\thQzHeaderCQ{!ameta(text)}
+!3\thQzHeaderCS{!ameta(text)}
+!4\thQzHeaderR{!ameta(text)}
+\end{dCmd}
+\eVerb These command declarations allow you to set the left, center (for quiz
+pages and solution pages), and right running headers. The content of the
+parentheses to the right are the default values, which obviously need to be
+changed, except, perhaps, for the right header. The declarations in the first column,
+define text macros, whose definitions are given in the third column.
+
+The special command \cs{thQuizName} expands to the name of the \ameta{qz-name}, where \ameta{qz-name}
+was declare earlier by \cs{DeclareQuiz\darg{\ameta{qz-name}}}. Typically, the choice
+for the quiz name very simple, such as \texttt{q1}. You can have a more meaningful
+name by declaring \cs{thQzName\darg{\ameta{friendly-qz-name}}}; such a declaration
+defines the text macro \cs{thqzname} that expands to \ameta{friendly-qz-name}. The package
+initially declares \cs{thQzName\darg{\cs{thQuizName}}}; for example,
+\begin{Verbatim}[xleftmargin=\amtIndent]
+\thQzHeaderCQ{Pr\"{u}fung: \thqzname}
+\thQzHeaderCS{L\"{o}sungen: \thqzname}
+\thQzName{Grammatik 1}
+\end{Verbatim}
+The \cs{rhPgNumsOnly}\FmtMP{\cs{rhPgNumsOnly} discussed} command removes all
+running headers, except for the page number in the right header. Expand in
+the preamble.
+
+\subsection{Solution pages}
+
+Thor's hammer does support solutions to questions via the usual
+\env{solution} environment. When the parent document is built and opened in
+\app{Acrobat}, the solution pages are identified, extracted, saved to the
+instructor's folder,\footnote{For a parent document that uses basic methods
+(no options), the solutions are saved to the current folder of the parent
+document.} and deleted from the parent document. As a result, the quiz the
+student sees does not contain the solution pages.
+
+
+\subsection{Cover pages}
+
+While Thor is hammering away on the solution pages, Thor's hammer also
+supports the notion cover pages, these are one or more pages appearing in the
+front of the parent document (prior to any quizzes). These pages are normally
+ignored when the process of building the custom quizzes for the class;
+however, if you declare in the \emph{preamble}\FmtMP{preamble only},
+\bVerb\small\takeMeasure{\string\DeclareCoverPage\darg{\ameta{bPg[-ePg]}}}%
+%\setlength{\eflength}{\bxSize}%
+\begin{dCmd}[fontsize=\small,commandchars=!()]{\bxSize}
+\DeclareCoverPage{!ameta(bPg[-ePg])}
+\end{dCmd}
+\eVerb where \ameta{bPg[-ePg]} are the beginning (\meta{bPg}) and ending
+(\meta{ePg}) page numbers; this forms a range of page numbers. As indicated
+by the syntax, \cs{ePg} is optional. The values of these page numbers are
+0-based\FmtMP{0-based numbering}; that is 0 is the first page of the parent
+document, 1 is the second page, and so on. \cs{DeclareCoverPage\darg{0}}
+states that page~0 is a cover page, while \cs{DeclareCoverPage\darg{0-1}}
+declares the first two pages in the parent document are cover pages. (Page~0
+might be a title page, page~1 might be extensive instructions and other
+information.) Use your knowledge of {\LaTeX} so that there are no page numbers\FmtMP{no page numbers on cover pages}
+on the cover pages.
+
+\subsection{Switches to control program flow}
+
+In this section, we provide switches that give control over the behavior the creation
+and function of a quiz.
+\bVerb\small\takeMeasure{\string\distrToStudentsOn \string\distrToStudentsOff}%
+%\setlength{\eflength}{\bxSize}%
+%\def\1{\rlap{\hskip\eflength D}}
+\begin{dCmd}[fontsize=\small,commandchars=!()]{\bxSize}
+\autoCopyOn \autoCopyOff
+
+\instrAutoSaveOn \instrAutoSaveOff
+\instrAutoCloseOn \instrAutoCloseOff
+
+\stuAutoSaveOn \stuAutoSaveOff
+\stuAutoCloseOn \stuAutoCloseOff
+
+\distrToInstrOn \distrToInstrOff
+\distrToStudentsOn \distrToStudentsOff
+\end{dCmd}
+\eVerb The defaults for the above commands are the `On' versions.
+\begin{description}
+\item[\cmd\autoCopyOn] During document development, you don't want to copy
+ the files each time you build and review the document in \app{Acrobat}.
+ Set \cs{autoCopyOff} during quiz development, and declare
+ \cs{autoCopyOn} when you want to distribute. The default is
+ \cs{autoCopyOn}.
+
+\item[\cs{instrAutoSaveOn}] When the instructor presses the freeze quiz
+ control, there is an option to automatically save the document or not.
+ \cs{instrAutoSaveOn} saves the document; however, if
+ \cs{instrAutoSaveOff} is expanded in the preamble, no automatic save is
+ performed. The default is \cs{instrAutoSaveOn}.
+
+\item[\cs{instrAutoCloseOn}] When the instructor presses the freeze quiz control, there is an option
+ to silently close the document or not. \cs{instrAutoCloseOn} closes the document; however, if
+ \cs{instrAutoCloseOff} is expanded in the preamble, no automatic
+ closing occurs. The default is \cmd{\instrAutoCloseOn}.
+
+\item[\cs{stuAutoSaveOn}] When expanded in the preamble, a save button will appear
+ (created by \cs{stuSaveBtn}) when the \textsf{End Quiz} control is pressed. A
+ dialog appears to save the file, the student can choose the file
+ location and the file name at that time. When \cs{stuAutoSaveOff} is in
+ effect, the save button does not appear, and the student must press the
+ save button the on \app{Adobe Reader} toolbar. The default is
+ \cs{stuAutoSaveOn}.
+
+\item[\cs{stuAutoSaveOff}] This command is obeyed only if
+ \cmd{\stuAutoSaveOn} is in effect. After the student presses the save
+ button (\cmd\stuSaveBtn), the document is closed after the student save
+ the document. Note that if the student cancels saving the document and
+ if the document still needs saving, the document is not closed. The
+ default is \cmd\stuAutoCloseOn.
+
+\item[\cs{distrToInstrOff}] Allow the instructor to turn off the
+ distribution of the quizzes to himself by using \cs{distrToInstrOff},
+ the default is \cs{distrToInstrOn}.
+
+\item[\cmd\distrToStudentsOff] This switch allows the instructor to turn off
+ the distribution of the quizzes to the student folders, the default is
+ \cs{distrToStudentsOn}. (Note: The \opt{batchdistr} option expands
+ \cs{distrToStudentsOff}.
+
+\end{description}
+Except for \cs{autoCopyOn} and \cs{autoCopyOff}, there is normally no reason
+to change these switches from their defaults. They are here to provide
+additional control.
+
+\subsection{Language localization}\label{s:lang}
+
+There are a number of language dependent phrases that appear in the
+document, these have conveniently been gathered into the file
+\texttt{thorshammer.cfg}. If found on the {\LaTeX} search path, it is
+automatically loaded, unless the \opt{nocfg} option is in force. This file
+can be localized to your own language, hopefully no umlauts needed.
+
+
+\subsection{System scripts}\label{s:sysscrpts}
+
+In the course of developing this package, several
+\uif{Powershell} system scripts were written to illustrate the
+workflow to ourselves. During the long development of this
+package, the scripts were folded into a single \uif{Powershell}
+script file \texttt{thmclass.ps1}. The use of
+\texttt{thmclass.ps1} is described in the file
+\texttt{thmclass.pdf}, found in the \texttt{docs} folder.
+
+\begin{comment}
+\newtopic\noindent The scripts are assume the folder structure of mighty Thor himself
+is used. The scripts use three variables that need to be modified:
+\texttt{\$instrName} (\texttt{instrName}), \texttt{\$instrDest}
+(\texttt{instrDest}), and \texttt{\$startLocation} (\texttt{startLocation}).
+For PowerShell, variables begin with a dollar sign, where is in bash shell
+they do not.
+\begin{itemize}
+ \item \textbf{Windows PowerShell scripts}
+ \begin{itemize}
+ \item \texttt{getquizzes.ps1}\\ \emph{Copies} every PDF file residing in a folder
+ with name \texttt{\$instrName} to the folder defined
+ by the path \texttt{\$instrDest}.
+ \item \texttt{rmquizzes.ps1}\\ \emph{Removes} (deletes) every PDF file residing in a folder
+ with name \texttt{\$instrName}.
+ \item \texttt{mvquizzes.ps1}\\ \emph{Moves} every PDF file residing in a folder
+ with name \texttt{\$instrName} to the folder defined
+ by the path \texttt{\$instrDest}.
+ \end{itemize}
+\goodbreak
+ \item \textbf{Linux bash scripts}
+ \begin{itemize}
+ \item \texttt{getquizzes.sh}\\\emph{Copies} every PDF file residing in a folder
+ with name \texttt{instrName} to the folder defined
+ by the path \texttt{instrDest}
+ \item \texttt{rmquizzes.sh}\\ \emph{Removes} (deletes) every PDF file residing in a folder
+ with name \texttt{instrName}.
+ \item \texttt{mvquizzes.sh} \emph{Moves} every PDF file residing in a folder
+ with name \texttt{instrName} to the folder defined
+ by the path \texttt{instrDest}.
+ \end{itemize}
+\end{itemize}
+Having each quiz in an folder with the instructor's name (\texttt{\_Thor}, or
+some other unique name) allows the scripts to find the quiz PDFs, \emph{and no
+others}.
+
+\paragraph*{Executing these scripts.} To begin with, I'm no expert. \verb~:-{)~
+\begin{itemize}
+ \item \textbf{Windows PowerShell scripts.} You must grant the
+ permissions for the scripts to executed: open PowerShell (run as
+ administrator)1, paste \texttt{Set-ExecutionPolicy RemoteSigned} at
+ the prompt and execute this line.
+ \item[] The easiest way of working with PowerShell is through the Windows
+ PowerShell ISE app. Press the Search icon in the lower left corner of
+ windows and type in PowerShell and amongst the matches presented is
+ Windows PowerShell ISE. To executed one of the scripts, use the
+ File menu to open \texttt{getquizzes.ps1}, for example. There you can edit
+ and save the script in the editor provided. To run the script, press the Run Script (F5)
+ on the toolbar.
+ \item \textbf{Linux bash scripts} On Linux there are permissions to be granted as well, I refer
+ the interested reader to \href{https://ryanstutorials.net/bash-scripting-tutorial/bash-script.php}{this web page}.\footnote
+ {\url{https://ryanstutorials.net/bash-scripting-tutorial/bash-script.php}} This web page is just one of many
+ found by a Google search.
+\end{itemize}
+\end{comment}
+
+\section{List of sample files}
+
+The sample files are found in the \texttt{example} folder. Fundamentally,
+there are only six demonstration files, but these are replicated several times
+and distributed over several times in sub-folders of the main \texttt{examples} folder.
+The sample files, listed in increasing complexity, and their brief descriptions follow:
+\begin{description}
+ \item[\texttt{thexb.tex}] uses no option and represents the basic
+ methods described in Section~\ref{ss:BMs}.
+ \item[\texttt{theuc.tex}] uses the \opt{useclass} option, as described
+ in Section~\ref{ss:uc}.
+ \item[\texttt{thexub.tex}] uses the \opt{usebatch} option, as described
+ in Section~\ref{ss:ub}. The instructor can use \textsf{Thor's way}
+ action sequence on these quizzes to automatically record the
+ student scores.
+ \item[\texttt{thexbd.tex}] uses the \opt{batchdistr} option, as described
+ in Section~\ref{ss:bd}. For this file, distribution of the student
+ quizzes is delayed. It is expected to apply some security first.
+ \item[\texttt{ther.tex}] uses the \opt{usebatch} option with the
+ \opt{allowrandomize} option for \pkg{exerquiz}. As a results,
+ certain MC and MS choices are randomized. The \env{quizbody}
+ environment encloses the body of the quiz and input back into the
+ document twice. As a result, we obtain two versions of the same
+ quiz, with two randomized order for MC and MS choices.
+ \item[\texttt{theexrt.tex}] uses the \opt{usebatch} option with the
+ \opt{allowrandomize} option for \pkg{exerquiz} and uses the
+ \pkg{ran\_toks} package as well. The \pkg{ran\_toks} package is
+ used to randomize the order of the questions, in addition to the
+ randomization of the choices of \texttt{thexr.tex}. The
+ \env{quizbody} environment is used twice on two distinct set of
+ quiz questions, and input back in several times. The results are
+ three ``renditions'' of two distinct quizzes, the order of the
+ questions and choices are randomized.
+\end{description}
+The above files may appear in the following folders.
+\begin{description}
+ \item [\texttt{nosolns} folder:] This is the original collection of demonstration files,
+ all having no solutions associated with any of the questions. (The
+ simplest case.)
+ \item [\texttt{wthsolns} folder:] The same six demo files, but with selected solutions to
+ the questions. The \texttt{thexb.tex} demonstrates how to set of the
+ document with a screen design (\opt{designi}). It also uses the
+ \pkg{spdef} package (provided) to format the document with or without
+ a design option of \pkg{web}. Some of the files use running headers.
+ \item[\texttt{cfg} folder:] There are several files in this folder, each
+ using the \opt{usebatch} option. They illustrate how to input
+ instructor and student data through CFG files, as described in
+ section entitled \Nameref{sss:CI}.
+ \item[\texttt{misc} folder:] The \texttt{thexrt.tex} file is in this
+ folder. The file has been modified several ways.
+ \cs{thQuizHeaderLayout} is redefined to hide the \cs{FirstName} and
+ \cs{LastName} fields. (Do not delete these two commands, they are
+ required, but we can hide them.) Instead of displaying the first and
+ last name, the \cs{FullName} command is used on the cover page. The
+ \cs{FullName} command gets its value from the values of
+ \cs{FirstName} and \cs{LastName}. The changes give the quizzes a
+ slightly different look.
+ \item[\texttt{target} folder:] The demo files that use the \opt{useclass}
+ option, need a target to drop the instructor's copies of the quizzes
+ and the student copies of the files. In each of the demo files where
+ class information is provided, you need to adjust the paths to taget
+ the subfolders of the \texttt{target} folder. The \texttt{target}
+ folder may be copied to the desktop, as I did, and target the quiz
+ files there.
+\end{description}
+
+\section{Summary of action sequences provided}\label{actSeq}
+
+By ``actions sequences'' we mean batch sequences of \app{Acrobat} that
+perform a series of tasks. Refer the document
+\href{install-action-seq.pdf}{install-action-seq.pdf} for information on
+how to install action sequences, found in the \texttt{docs} folder of this
+distribution.
+\begin{itemize}
+ \item\textbf{\textsf{Thor's way} action.} This action is performed on the (student)
+ completed and (instructor) marked quizzes. Refer to
+ \textbf{\nameref{sss:TW}} on page~\pageref{sss:TW} for more information
+ on \textsf{Thor's way}.
+ \begin{itemize}
+ \item \textbf{Applies to} quizzes compiled with the
+ \opt{usebatch} or \opt{batchdistr} option.
+ \item\textbf{What it does:} For each quiz, it extracts first
+ name, last name, score, total points from the quiz and saves
+ them to an attachment of \texttt{container}; it flattens
+ the quiz and saves the flattened quiz with a suffix of
+ \texttt{"-g"} to the folder designated by the
+ \texttt{container} file.
+ \item\textbf{Steps to run the \textsf{Thor's way} action}
+ \begin{itemize}
+ \item Open the file \texttt{container.pdf}
+ (\hyperref[cap:container]{Figure~\ref*{cap:container}})
+ and fill out the fields provided and press the
+ \textsf{Push} button. The file saves the data entered in
+ the form fields then closes.
+ \item Select the tool \textsf{Action Wizard}, then select
+ \textsf{Thor's way}
+ \item\textsf{Files to be processed:} Selected the quizzes
+ (using the \textsf{Add Folder} and/or \textsf{Add Files}
+ controls), then select the special file
+ \texttt{terminate-batch.pdf}. This latter file \emph{must
+ be the last file to be processed}.
+ \item Start the batch by pressing the \textsf{Start} control
+ \end{itemize}
+ \end{itemize}
+ \item[] After the action is finished, the \texttt{control} document
+ should be in the \app{Acrobat} window. Check the console window
+ to see if there are any errors. The attachment to this file
+ contains the quiz results, save and do with them what you will,
+ perhaps merging them into a larger spreadsheet.
+ \item \textbf{\textsf{Thor protects} action.} Applies to a collection of
+ newly created quizzes that specify the \opt{batchdistr} option.
+ Running this action places security on the quizzes so the student's
+ cannot view the answers even if they are using \app{Acrobat}.
+ \item \textbf{\textsf{Thor distributes} action.} A general purpose action
+ that returns quizzes from the instructor's folder (or subfolder) to their
+ respective student folders. There are two situations where you would apply
+ this action:
+ \begin{itemize}
+ \item The \textsf{Thor's way} action drops the completed and
+ marked quizzes (with suffix \texttt{"-g"}) into the folder
+ designated in the \texttt{container} file. This action copies
+ them back into the student folders.
+ \item For a quiz this is compiled with the \opt{batchdistr}, the
+ distribution of the quizzes is delayed (possibly to place
+ security restrictions on them using the \textsf{Thor
+ protects} action). At the time where you want to deploy the
+ quizzes to the students folders, you can use \textsf{Thor
+ distributes} to accomplish that task.
+ \end{itemize}
+ \item \textbf{\textsf{Thor protects and distributes} action.} Applies to
+ a collection of newly created quizzes that specify the
+ \opt{batchdistr} option. Refer to
+ \hyperref[ss:bd]{Section~\ref{ss:bd}} for more details. The action is
+ to apply security to the quizzes and then to distribute them to the
+ student folders. This is a combination of \textsf{Thor protects} and
+ \textsf{Thor distributes}.
+
+\goodbreak
+ \item[]\textbf{Steps to run the \textsf{Thor protects and distributes} action}
+ \begin{itemize}
+ \item Select the tool \textsf{Action Wizard}, then select
+ \textsf{Thor protects and distributes}
+ \item\textsf{Files to be processed:} Selected the quizzes
+ (using the \textsf{Add Folder} and/or \textsf{Add Files}
+ controls). These are undistributed quizzes and should
+ reside in the instructor's folder.
+ \item Start the batch by pressing the \textsf{Start} control.
+ \end{itemize}
+ \item[] After this action is completed, copies of the secured files should
+ now be in the student folders.
+ \item \textbf{\textsf{Thor removes protection} action.} This action is a
+ natural continuation of \textsf{Thor protects and distributes}. It
+ removes the security previously placed on the quizzes. This is needed
+ to flatten the quizzes later in the work flow. The whole workflow is
+ described in \hyperref[ss:bd]{Section~\ref{ss:bd}}. In particular,
+ see \hyperref[item:RS]{item~\ref*{item:RS}} titled \textbf{Remove Security}.
+ After removing security, we continue with the \textsf{Thor's way} action.
+\end{itemize}
+
+\section{Further discussion of Basic Methods}
+
+The essential difference between these two methods is how the quiz files are
+named:
+\begin{itemize}
+ \item For basic methods, when multiple quiz files are produced, the
+ naming convention is \cs{jobname-1.pdf}, \cs{jobname-2.pdf}, and so
+ on. When only a single quiz file is created, it is named
+ \cs{jobname.pdf}.
+ \item For class methods, the quizzes are named as
+ \cs{jobname-\ameta{first\SUB1}\_\ameta{last\SUB1}.pdf},
+ \cs{jobname-\ameta{first\SUB2}\_\ameta{last\SUB2}.pdf}, and so on.
+\end{itemize}
+Class methods have three options \opt{useclass}, \opt{usebatch}, and \opt{batchdistr}.
+It is the \opt{useclass} that distinguishes basic and class methods.
+
+%\subsection{Basic Methods}
+\newtopic\noindent
+The following are the scenarios for basic methods:
+\begin{itemize}
+ \item None of the \textbf{\nameref{para:OCs}} listed on
+ page~\pageref{para:OCs} are specified in the preamble. A single quiz
+ is produced \emph{for each rendition} in the source file. By default flattening is off, so
+ returned quizzes can be run through \textsf{Thor's way} action
+ sequence. The source file can be compiled with \cs{flattenOff}, in
+ which case manual recording of the grades is needed.
+ \begin{itemize}
+ \item Files are created in the source file folder.
+ \item It is up to the instructor to deliver these quizzes to the
+ class.
+ \item You can place security on the files using the \textsf{Thor protects} action sequence.
+ \end{itemize}
+ \item \cs{enumQuizzes\darg{\ameta{num}}}: \ameta{num} copies of the file
+ is created (with rendition variations if they exist). All files are
+ dropped into the source file folder. Returned files can be run
+ through \textsf{Thor's way} to record results, unless \cs{flattenOff}
+ is specified in the preamble.
+ \begin{itemize}
+ \item Analogous to the \opt{usebatch} option.
+ \item Files are created in the source file folder.
+ \item It is up to the instructor to deliver these quizzes to the
+ class.
+ \item You can place security on the files using the \textsf{Thor
+ protects} action sequence. Quizzes are delivered manually. When
+ the returned quizzes are to be marked, use \textsf{Thor removes
+ protection} followed by the instructor markup step, followed by
+ \textsf{Thor's way} to record the quizzes. This roughly models
+ \textsf{batchdistr}, but without the distribution part.
+ \end{itemize}
+ \item \cs{enumQuizzes\darg{\ameta{num}}} and
+ \cs{instrPath\darg{\ameta{path}}} are specified: \ameta{num} copies of the file
+ is created (with rendition variations if they exist). Returned files can be run
+ through \textsf{Thor's way} to record results, unless \cs{flattenOff}
+ is specified in the preamble.
+ \begin{itemize}
+ \item Analogous to the \opt{usebatch} option.
+ \item All files are dropped into the folder determined by
+ \cs{instrPath}.
+ \item It is up to the instructor to deliver these quizzes to the
+ class.
+ \item You can place security on the files using the \textsf{Thor protects} action sequence.
+ \end{itemize}
+
+ \item \cs{instrPath\darg{\ameta{path}}},
+ \cs{classPath\darg{\ameta{path}}}, and
+ \cs{distrQuizzes\darg{\ameta{args}}}: \ameta{num} copies of the file
+ is created (with rendition variations if they exist), where
+ \ameta{num} is the number of folders listed in the argument of
+ \cs{distrQuizzes}. Returned files can be run through \textsf{Thor's
+ way} to record results, unless \cs{flattenOff} is specified in the
+ preamble.
+ \begin{itemize}
+ \item This combination of command best model the \opt{usebatch} option.
+ \item A copy of all quizzes are dropped into the folder determined by
+ \cs{instrPath}.
+ \item A copy of all quizzes are dropped into the student folders determined by
+ \cs{classPath}/\cs{distrQuizzes}.
+ \item Specifying \cs{distrToStudentsOff} in the preamble, you can
+ the place security on the files using the \textsf{Thor protects
+ and distributes} action sequence, which places the security on
+ the quizzes and distributes them to the student folders. This
+ would model the \opt{batchdistr}
+ \end{itemize}
+
+ \item \cs{classPath\darg{\ameta{path}}}, and
+ \cs{distrQuizzes\darg{\ameta{args}}}: Same as the previous bullet point above.
+ \begin{itemize}
+ \item This combination of command best model the \opt{usebatch} option.
+ \item A copy of all quizzes are dropped into the source folder,
+ since no \cs{instrPath} is specified.
+ \item A copy of all quizzes are dropped into the student folders determined by
+ \cs{classPath}/\cs{distrQuizzes}.
+ \item Specifying \cs{distrToStudentsOff} in the preamble, you can
+ the place security on the files using the \textsf{Thor protects
+ and distributes} action sequence, which places the security on
+ the quizzes and distributes them to the student folders. This
+ would model the \opt{batchdistr}.
+ \end{itemize}
+
+
+\end{itemize}
+
+
+\section{A final note on Thor's workflow}
+
+There are two computer drives involved in this workflow: (1) a drive on the
+instructor's work computer designated as ID (instructor's drive); and (2) a
+system drive that students have access to, designated as SD (system drive).
+\begin{enumerate}
+\item (ID) The development of the quiz occurs on ID, {\heshe} builds the
+ quizzes (perhaps individualized to the names of the students) and saves
+ them to the student folders on ID, copies are dumped into the
+ instructor's folder on ID.
+\item (ID $\mapsto$ SD) The system scripts copy the student folders on ID to
+ SD, preserving folder structure.
+\item (SD) The class takes the quiz during the quiz period.
+\item (SD $\mapsto$ ID) After the quiz period, system scripts copy the
+ completed quizzes from the SD student folders to the ID student
+ folders, and deletes the quizzes from SD.
+\item (ID) The instructor grades each quiz, awarding points for the
+ extended response questions. Graded quizzes are flattened and marked
+ with a suffix `-g'.
+\item (ID $\mapsto$ SD) The system scripts returns the graded quizzes to
+ the student folders on SD, where are met with great rejoicing or
+ gnashing of teeth.
+\end{enumerate}
+
+\section{The \tops{\protect\opt{ordinary}}{ordinary} option}\label{ordinary}
+
+This option was prompted by an \pkg{exerquiz} user who had a unique problem:
+He wanted to put password protection on the \uif{Correct} button of an
+\pkg{exerquiz} quiz. He wanted to distribute quizzes to his students. The
+students would take the quiz, and, on pressing the \uif{End Quiz} button,
+would get their score, but the \uif{Correct} button would be denied to them
+through a password mechanism.
+
+Solving this problem necessitated some of the special features of
+\pkg{thorshammer}, without the use of \cs{sadQuizzes}.
+
+To see the solution to this problem, go to the
+\texttt{examples/orginary-option} folder. There are three files in that
+folder:
+\begin{itemize}
+ \item {\ttfamily quiz-pwd-to-correct-AA.tex}: This file requires the use
+ of \app{Acrobat} to create the quizzes. The password is dynamically
+ encoded as the PDF is loaded into \app{Acrobat} for the first time.
+ \item {\ttfamily quiz-pwd-to-correct-AR.tex}: Again, the \uif{Correct}
+ button is password protected, only \app{Adobe Reader} is required
+ to build this file; however, the encrypted password cannot be built
+ dynamically. It must be first computed and hard-wired placed in the
+ source document.
+ \item {\ttfamily get-hash-string.tex}: This is a companion file to the
+ `AR' version described above. Build this file using any method.
+ Open it in \app{Adobe Reader} and press the \uif{Push} button. A
+ response dialog box opens, enter your chosen password (PIN number)
+ and press \uif{OK}. The hash string of your password appears on the
+ text field. Copy the password (or PIN) and the hash string to
+ {\ttfamily quiz-pwd-to-correct\allowbreak-AR.tex}. Comment out the human readable
+ password in your file and paste the hash string into the value of
+ the \texttt{\_PinCode} JavaScript variable, then build the file
+ {\ttfamily quiz-pwd-to\allowbreak-correct-AR.tex}. Now, the \uif{Correct}
+ button is password (PIN) protected.
+
+\end{itemize}
+
+\section{My retirement}
+
+Now, I simply must get back to it. \dps
+
+\end{document}
+
+The only user command is \cs{xbmksetup}:
+\bVerb\def\1{\qquad}\takeMeasure{\1docbundle=\darg{\ameta{doc\SUB1},\ameta{doc\SUB2},...,\ameta{doc\SUB{n}}},}%
+\begin{dCmd}[commandchars=!()]{\bxSize}
+\xbmksetup{%
+!1docbundle={!ameta(doc!SUB1),!ameta(doc!SUB2),...,!ameta(doc!SUB(n))},
+!1colors={int=!ameta(color),ext=!ameta(color)},
+!1styles={intbf,extbf,intit,extit}
+}
+\end{dCmd}
+\eVerb
+
+% This code saves a copy of the PDF with the name of each member of the class
+% appended. If you have a network drive, you can copy each PDF to their respective
+% folders in the connected drive. Here, drive Z: is connected to my PC, drive Z: is
+% actually, the C: drive on my other laptop, which is connected to my PC.
+% See if this works for you.
+%
diff --git a/macros/latex/contrib/thorshammer/docs/thorshammer.pdf b/macros/latex/contrib/thorshammer/docs/thorshammer.pdf
new file mode 100644
index 0000000000..6e6c6fba2c
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/docs/thorshammer.pdf
Binary files differ
diff --git a/macros/latex/contrib/thorshammer/examples/cfgs/thexcfg1.tex b/macros/latex/contrib/thorshammer/examples/cfgs/thexcfg1.tex
new file mode 100644
index 0000000000..613e8bdbdd
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/cfgs/thexcfg1.tex
@@ -0,0 +1,152 @@
+\documentclass{article}
+\usepackage{amstext}
+\usepackage{web}
+\usepackage[usesumrytbls]{exerquiz}
+\usepackage[usebatch]{thorshammer}
+
+\setInitMag{fitwidth}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\hypersetup{pdfpagelayout=OneColumn}
+\reversemarginpar
+
+\showCreditMarkup
+
+%\previewOn\pmpvOn
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+
+\useMCCircles
+
+% Adjust \instrPath \classPath in CFG file as needed
+\InputClassData{thorsclass1}
+
+% \autoCopyOff
+
+\begin{makeClassFiles}
+\sadQuizzes
+\end{makeClassFiles}
+
+\begin{document}
+
+\DeclareQuiz{q1}
+
+\thQuizHeader
+
+\noindent\textbf{Instructions:}
+\begin{itemize}
+\item (For the student) Press `\textsf{Start}' to begin the
+ quiz, after you've completed the quiz, press
+ `\textsf{End}'. \emph{Save the document before closing
+ it}.
+\item (For the instructor) Open the document the student has
+ saved, the `\textsf{Mark It}' and `\textsf{Freeze Quiz}'
+ are visible. Press the `\textsf{Mark It}' button and the
+ quiz will be marked. For the extended response questions,
+ enter the points assigned in the box in the left margin.
+ At your option, reset the quiz or save the quiz with the
+ markup.
+\end{itemize}
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+ \item\PTs{3} Which of these are true ?
+\begin{answers}{4}
+\Ans1 True & \Ans0 False
+\end{answers}
+
+ \item \PTs{4} Select which of the following is true.
+\begin{answers}{4}
+\Ans1 True & \Ans0 False & \Ans0 Maybe & \Ans0 Sometimes
+\end{answers}
+
+ \item\PTs{2} $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}$
+
+\essayQ{5} % num points assigned
+\item\PTs{5} Write a short history of Acro\negthinspace\TeX.\par
+\RespBoxEssay{\linewidth}{1in}
+
+\item\PTs{3} Which of the following are numbers?
+\begin{manswers}{6}
+\bChoices
+ \Ans[-1]{0}d\eAns
+ \Ans[1]{1}17\eAns
+ \Ans[-1]{0}p\eAns
+ \Ans[1]{1}88\eAns
+ \Ans[-1]{0}s\eAns
+ \Ans[1]{1}105\eAns
+\eChoices
+\end{manswers}
+
+\multipartquestion
+
+ \item\PTs{20} Answer each of the following multiple selection problems. Each correct answer
+ is worth $3$ points, and each incorrect answer is worth $-2$ points.
+ \begin{questions}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a President
+ of the United States. (Select all correct choices.)
+
+ \begin{manswers}*{2}%
+ \bChoices
+ \Ans[-2]{0} Henry Clay\eAns
+ \Ans[-2]{0} Ben Franklin\eAns
+ \Ans[3]{1}\label{aj} Andrew Jackson\eAns
+ \Ans[3]{1}\label{rr} Ronald Reagan\eAns
+ \Ans[-2]{0} George Meade\eAns
+ \Ans[3]{1}\label{gc} Grover Cleveland\eAns
+ \Ans[-2]{0} John Jay\eAns
+ \Ans[-2]{0} Paul Revere\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a Chancellor of the
+ German Republic. (Select all correct choices.)
+ \begin{manswers}*{2}%
+ \bChoices[2]
+ \Ans[-2]{0} Gustav Heinemann\eAns
+ \Ans[-2]{0} Theodor Heu{\ss}\eAns
+ \Ans[3]{1} Konrad Adenauer\eAns
+ \Ans[-2]{0} Richard von Weizs\"{a}cker\eAns
+ \Ans[3]{1} Willy Brandt\eAns
+ \Ans[-2]{0} Heinrich L\"{u}bke\eAns
+ \Ans[-2]{0} Roman Herzog\eAns
+ \Ans[3]{1} Ludwig Erhard\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{2} If you select all choices in part~(a), you will
+ receive -1 points as a penalty for bad guessing. \textbf{Question:}
+ Determine the \emph{number of correct choices} in part~(a)?
+ \begin{answers}{4}
+ \bChoices
+ \Ans0 1\eAns
+ \Ans0 2\eAns
+ \Ans1 3\eAns
+ \Ans0 4\eAns
+ \Ans0 5\eAns
+ \Ans0 6\eAns
+ \Ans0 7\eAns
+ \Ans0 8\eAns
+ \eChoices
+ \end{answers}
+ \end{questions}
+
+%\essayQ{3} % num points assigned
+%\item\PTs{3} Comment on the experience of taking a quiz the `Thorsten way.'.\par
+%\RespBoxEssay{\linewidth}{1in}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+
+\end{document}
diff --git a/macros/latex/contrib/thorshammer/examples/cfgs/thexcfg2-star.tex b/macros/latex/contrib/thorshammer/examples/cfgs/thexcfg2-star.tex
new file mode 100644
index 0000000000..278c34f79b
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/cfgs/thexcfg2-star.tex
@@ -0,0 +1,168 @@
+\documentclass{article}
+\usepackage{amstext}
+\usepackage{web}
+\usepackage[usesumrytbls]{exerquiz}
+\usepackage[usebatch]{thorshammer}
+
+\DeclareQuiz{q1}
+
+\setInitMag{fitwidth}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\hypersetup{pdfpagelayout=OneColumn}
+\reversemarginpar
+
+\showCreditMarkup
+
+%\previewOn\pmpvOn
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+
+\useMCCircles
+
+% Adjust \instrPath \classPath in CFG file as needed
+% Two methods illustrated here
+
+% When a class path uses the second star option, as thorsclass3-star.cfg does,
+% additional parsing of each line is needed, in this example, a typical data line
+% has the form: *{first}{last}{ID}*{path}. The use of * is optional
+\makeatletter
+\def\ParseClassLine{\@ifstar
+ {\def\ISStari{*}\ParseClassLine@i}
+ {\def\ISStari{}\ParseClassLine@i}}
+\def\ParseClassLine@i#1#2#3{\@ifstar
+ {\def\ISStarii{*}\ParseClassLine@ii{#1}{#2}{#3}}
+ {\def\ISStarii{}\ParseClassLine@ii{#1}{#2}{#3}}}
+\def\ParseClassLine@ii#1#2#3#4{\edef\x{\noexpand
+ \classMember\ISStari{#1}{#2}\ISStarii{#4}}\x}
+\makeatother
+\InputFormattedClass[\ParseClassLine]{thorsclass3-star}
+
+% \autoCopyOff
+
+%\distrToStudentsOff
+
+\begin{makeClassFiles}
+\sadQuizzes
+\end{makeClassFiles}
+
+\begin{document}
+
+\thQuizHeader
+
+\noindent\textbf{Instructions:}
+\begin{itemize}
+\item (For the student) Press `\textsf{Start}' to begin the
+ quiz, after you've completed the quiz, press
+ `\textsf{End}'. \emph{Save the document before closing
+ it}.
+\item (For the instructor) Open the document the student has
+ saved, the `\textsf{Mark It}' and `\textsf{Freeze Quiz}'
+ are visible. Press the `\textsf{Mark It}' button and the
+ quiz will be marked. For the extended response questions,
+ enter the points assigned in the box in the left margin.
+ At your option, reset the quiz or save the quiz with the
+ markup.
+\end{itemize}
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+ \item\PTs{3} Which of these are true ?
+\begin{answers}{4}
+\Ans1 True & \Ans0 False
+\end{answers}
+
+ \item \PTs{4} Select which of the following is true.
+\begin{answers}{4}
+\Ans1 True & \Ans0 False & \Ans0 Maybe & \Ans0 Sometimes
+\end{answers}
+
+ \item\PTs{2} $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}$
+
+\essayQ{5} % num points assigned
+\item\PTs{5} Write a short history of Acro\negthinspace\TeX.\par
+\RespBoxEssay{\linewidth}{1in}
+
+\item\PTs{3} Which of the following are numbers?
+\begin{manswers}{6}
+\bChoices
+ \Ans[-1]{0}d\eAns
+ \Ans[1]{1}17\eAns
+ \Ans[-1]{0}p\eAns
+ \Ans[1]{1}88\eAns
+ \Ans[-1]{0}s\eAns
+ \Ans[1]{1}105\eAns
+\eChoices
+\end{manswers}
+
+\multipartquestion
+
+ \item\PTs{20} Answer each of the following multiple selection problems. Each correct answer
+ is worth $3$ points, and each incorrect answer is worth $-2$ points.
+ \begin{questions}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a President
+ of the United States. (Select all correct choices.)
+
+ \begin{manswers}*{2}%
+ \bChoices
+ \Ans[-2]{0} Henry Clay\eAns
+ \Ans[-2]{0} Ben Franklin\eAns
+ \Ans[3]{1}\label{aj} Andrew Jackson\eAns
+ \Ans[3]{1}\label{rr} Ronald Reagan\eAns
+ \Ans[-2]{0} George Meade\eAns
+ \Ans[3]{1}\label{gc} Grover Cleveland\eAns
+ \Ans[-2]{0} John Jay\eAns
+ \Ans[-2]{0} Paul Revere\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a Chancellor of the
+ German Republic. (Select all correct choices.)
+ \begin{manswers}*{2}%
+ \bChoices[2]
+ \Ans[-2]{0} Gustav Heinemann\eAns
+ \Ans[-2]{0} Theodor Heu{\ss}\eAns
+ \Ans[3]{1} Konrad Adenauer\eAns
+ \Ans[-2]{0} Richard von Weizs\"{a}cker\eAns
+ \Ans[3]{1} Willy Brandt\eAns
+ \Ans[-2]{0} Heinrich L\"{u}bke\eAns
+ \Ans[-2]{0} Roman Herzog\eAns
+ \Ans[3]{1} Ludwig Erhard\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{2} If you select all choices in part~(a), you will
+ receive -1 points as a penalty for bad guessing. \textbf{Question:}
+ Determine the \emph{number of correct choices} in part~(a)?
+ \begin{answers}{4}
+ \bChoices
+ \Ans0 1\eAns
+ \Ans0 2\eAns
+ \Ans1 3\eAns
+ \Ans0 4\eAns
+ \Ans0 5\eAns
+ \Ans0 6\eAns
+ \Ans0 7\eAns
+ \Ans0 8\eAns
+ \eChoices
+ \end{answers}
+ \end{questions}
+
+%\essayQ{3} % num points assigned
+%\item\PTs{3} Comment on the experience of taking a quiz the `Thorsten way.'.\par
+%\RespBoxEssay{\linewidth}{1in}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/thorshammer/examples/cfgs/thexcfg2.tex b/macros/latex/contrib/thorshammer/examples/cfgs/thexcfg2.tex
new file mode 100644
index 0000000000..b2ade14599
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/cfgs/thexcfg2.tex
@@ -0,0 +1,158 @@
+\documentclass{article}
+\usepackage{amstext}
+\usepackage{web}
+\usepackage[usesumrytbls]{exerquiz}
+\usepackage[usebatch]{thorshammer}
+
+\DeclareQuiz{q1}
+
+\setInitMag{fitwidth}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\hypersetup{pdfpagelayout=OneColumn}
+\reversemarginpar
+
+\showCreditMarkup
+
+%\previewOn\pmpvOn
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+\useMCCircles
+
+% Neither of the two CFG files here uses the second star option, see theexcfg2-star.tex
+% Adjust \instrPath \classPath in CFG file as needed
+% Two methods illustrated here
+%\InputFormattedClass{thorsclass2}
+
+\newcommand\ParseClassLine[4]{\classMember{#1}{#2}{#4}}
+\InputFormattedClass[\ParseClassLine]{thorsclass3}
+
+% \autoCopyOff
+
+%\distrToStudentsOff
+
+\begin{makeClassFiles}
+\sadQuizzes
+\end{makeClassFiles}
+
+\begin{document}
+
+
+\thQuizHeader
+
+\noindent\textbf{Instructions:}
+\begin{itemize}
+\item (For the student) Press `\textsf{Start}' to begin the
+ quiz, after you've completed the quiz, press
+ `\textsf{End}'. \emph{Save the document before closing
+ it}.
+\item (For the instructor) Open the document the student has
+ saved, the `\textsf{Mark It}' and `\textsf{Freeze Quiz}'
+ are visible. Press the `\textsf{Mark It}' button and the
+ quiz will be marked. For the extended response questions,
+ enter the points assigned in the box in the left margin.
+ At your option, reset the quiz or save the quiz with the
+ markup.
+\end{itemize}
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+ \item\PTs{3} Which of these are true ?
+\begin{answers}{4}
+\Ans1 True & \Ans0 False
+\end{answers}
+
+ \item \PTs{4} Select which of the following is true.
+\begin{answers}{4}
+\Ans1 True & \Ans0 False & \Ans0 Maybe & \Ans0 Sometimes
+\end{answers}
+
+ \item\PTs{2} $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}$
+
+\essayQ{5} % num points assigned
+\item\PTs{5} Write a short history of Acro\negthinspace\TeX.\par
+\RespBoxEssay{\linewidth}{1in}
+
+\item\PTs{3} Which of the following are numbers?
+\begin{manswers}{6}
+\bChoices
+ \Ans[-1]{0}d\eAns
+ \Ans[1]{1}17\eAns
+ \Ans[-1]{0}p\eAns
+ \Ans[1]{1}88\eAns
+ \Ans[-1]{0}s\eAns
+ \Ans[1]{1}105\eAns
+\eChoices
+\end{manswers}
+
+\multipartquestion
+
+ \item\PTs{20} Answer each of the following multiple selection problems. Each correct answer
+ is worth $3$ points, and each incorrect answer is worth $-2$ points.
+ \begin{questions}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a President
+ of the United States. (Select all correct choices.)
+
+ \begin{manswers}*{2}%
+ \bChoices
+ \Ans[-2]{0} Henry Clay\eAns
+ \Ans[-2]{0} Ben Franklin\eAns
+ \Ans[3]{1}\label{aj} Andrew Jackson\eAns
+ \Ans[3]{1}\label{rr} Ronald Reagan\eAns
+ \Ans[-2]{0} George Meade\eAns
+ \Ans[3]{1}\label{gc} Grover Cleveland\eAns
+ \Ans[-2]{0} John Jay\eAns
+ \Ans[-2]{0} Paul Revere\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a Chancellor of the
+ German Republic. (Select all correct choices.)
+ \begin{manswers}*{2}%
+ \bChoices[2]
+ \Ans[-2]{0} Gustav Heinemann\eAns
+ \Ans[-2]{0} Theodor Heu{\ss}\eAns
+ \Ans[3]{1} Konrad Adenauer\eAns
+ \Ans[-2]{0} Richard von Weizs\"{a}cker\eAns
+ \Ans[3]{1} Willy Brandt\eAns
+ \Ans[-2]{0} Heinrich L\"{u}bke\eAns
+ \Ans[-2]{0} Roman Herzog\eAns
+ \Ans[3]{1} Ludwig Erhard\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{2} If you select all choices in part~(a), you will
+ receive -1 points as a penalty for bad guessing. \textbf{Question:}
+ Determine the \emph{number of correct choices} in part~(a)?
+ \begin{answers}{4}
+ \bChoices
+ \Ans0 1\eAns
+ \Ans0 2\eAns
+ \Ans1 3\eAns
+ \Ans0 4\eAns
+ \Ans0 5\eAns
+ \Ans0 6\eAns
+ \Ans0 7\eAns
+ \Ans0 8\eAns
+ \eChoices
+ \end{answers}
+ \end{questions}
+
+%\essayQ{3} % num points assigned
+%\item\PTs{3} Comment on the experience of taking a quiz the `Thorsten way.'.\par
+%\RespBoxEssay{\linewidth}{1in}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass1.cfg b/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass1.cfg
new file mode 100644
index 0000000000..82deb66fdd
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass1.cfg
@@ -0,0 +1,43 @@
+\instrPath{/C/Users/dpstory/Desktop/Test Folder/target/_Thor}
+\classPath{/c/Users/dpstory/Desktop/Test Folder/target/myClass}
+\classMember{Peter}{Pan}{A/_Thor}
+\classMember{J\oct374rgen}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer}{C/_Thor}
+\endinput % testing large class
+\classMember{Peter}{Pan1}{A/_Thor}
+\classMember{J\oct374rgen1}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer1}{C/_Thor}
+\classMember{Peter}{Pan2}{A/_Thor}
+\classMember{J\oct374rgen2}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer2}{C/_Thor}
+\classMember{Peter}{Pan3}{A/_Thor}
+\classMember{J\oct374rgen3}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer3}{C/_Thor}
+\classMember{Peter}{Pan4}{A/_Thor}
+\classMember{J\oct374rgen4}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer4}{C/_Thor}
+\classMember{Peter}{Pan5}{A/_Thor}
+\classMember{J\oct374rgen5}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer5}{C/_Thor}
+\classMember{Peter}{Pan6}{A/_Thor}
+\classMember{J\oct374rgen6}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer6}{C/_Thor}
+\classMember{Peter}{Pan7}{A/_Thor}
+\classMember{J\oct374rgen7}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer7}{C/_Thor}
+\classMember{Peter}{Pan8}{A/_Thor}
+\classMember{J\oct374rgen8}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer8}{C/_Thor}
+\classMember{Peter}{Pan9}{A/_Thor}
+\classMember{J\oct374rgen9}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer9}{C/_Thor}
+\classMember{Peter}{Pan10}{A/_Thor}
+\classMember{J\oct374rgen10}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer10}{C/_Thor}
+\classMember{Peter}{Pan11}{A/_Thor}
+\classMember{J\oct374rgen11}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer11}{C/_Thor}
+\classMember{Peter}{Pan12}{A/_Thor}
+\classMember{J\oct374rgen12}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer12}{C/_Thor}
+
diff --git a/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass2.cfg b/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass2.cfg
new file mode 100644
index 0000000000..0ce74346e0
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass2.cfg
@@ -0,0 +1,44 @@
+\instrPath{/C/Users/dpstory/Desktop/Test Folder/target/_Thor}
+\classPath{/c/Users/dpstory/Desktop/Test Folder/target/myClass}
+\bClassData
+{Peter}{Pan}{A/_Thor}
+*{J\"{u}rgen}{Gilg}{B/_Thor}
+{Thors}{Hammer}{C/_Thor}
+\endinput % test large class
+{Peter}{Pan1}{A/_Thor}
+{J\oct374rgen1}{Gilg}{B/_Thor}
+{Thors}{Hammer1}{C/_Thor}
+{Peter}{Pan2}{A/_Thor}
+{J\oct374rgen2}{Gilg}{B/_Thor}
+{Thors}{Hammer2}{C/_Thor}
+{Peter}{Pan3}{A/_Thor}
+{J\oct374rgen3}{Gilg}{B/_Thor}
+{Thors}{Hammer3}{C/_Thor}
+{Peter}{Pan4}{A/_Thor}
+{J\oct374rgen4}{Gilg}{B/_Thor}
+{Thors}{Hammer4}{C/_Thor}
+{Peter}{Pan5}{A/_Thor}
+{J\oct374rgen5}{Gilg}{B/_Thor}
+{Thors}{Hammer5}{C/_Thor}
+{Peter}{Pan6}{A/_Thor}
+{J\oct374rgen6}{Gilg}{B/_Thor}
+{Thors}{Hammer6}{C/_Thor}
+{Peter}{Pan7}{A/_Thor}
+{J\oct374rgen7}{Gilg}{B/_Thor}
+{Thors}{Hammer7}{C/_Thor}
+{Peter}{Pan8}{A/_Thor}
+{J\oct374rgen8}{Gilg}{B/_Thor}
+{Thors}{Hammer8}{C/_Thor}
+{Peter}{Pan9}{A/_Thor}
+{J\oct374rgen9}{Gilg}{B/_Thor}
+{Thors}{Hammer9}{C/_Thor}
+{Peter}{Pan10}{A/_Thor}
+{J\oct374rgen10}{Gilg}{B/_Thor}
+{Thors}{Hammer10}{C/_Thor}
+{Peter}{Pan11}{A/_Thor}
+{J\oct374rgen11}{Gilg}{B/_Thor}
+{Thors}{Hammer11}{C/_Thor}
+{Peter}{Pan12}{A/_Thor}
+{J\oct374rgen12}{Gilg}{B/_Thor}
+{Thors}{Hammer12}{C/_Thor}
+
diff --git a/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass3-star.cfg b/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass3-star.cfg
new file mode 100644
index 0000000000..af16fef319
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass3-star.cfg
@@ -0,0 +1,9 @@
+\instrPath {/C/Users/dpstory/Desktop/Test Folder/target/_Thor}
+\classPath {/c/Users/dpstory/Desktop/Test Folder/target/myClass}
+\def\altCPath{/C/Users/dpstory/Desktop/Test Folder/target/myOtherClass}
+\bClassData
+{Peter}{Pan}{453453}{A/_Thor}
+{J\oct374rgen}{Gilg}{5565}*{\altCPath/B/_Thor}
+{Thors}{Hammer}{534534}{C/_Thor}
+\endinput
+
diff --git a/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass3.cfg b/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass3.cfg
new file mode 100644
index 0000000000..fa53415387
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/cfgs/thorsclass3.cfg
@@ -0,0 +1,8 @@
+\instrPath{/C/Users/dpstory/Desktop/Test Folder/target/_Thor}
+\classPath{/C/Users/dpstory/Desktop/Test Folder/target/myClass}
+\bClassData
+{Peter}{Pan}{453453}{A/_Thor}
+{J\oct374rgen}{Gilg}{5565}{B/_Thor}
+{Thors}{Hammer}{534534}{C/_Thor}
+\endinput
+
diff --git a/macros/latex/contrib/thorshammer/examples/cfgs/thorsclassx.cfg b/macros/latex/contrib/thorshammer/examples/cfgs/thorsclassx.cfg
new file mode 100644
index 0000000000..ad1151ea7c
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/cfgs/thorsclassx.cfg
@@ -0,0 +1,6 @@
+\instrPath{/C/Users/dpstory/Desktop/Test Folder/target/_Thor}
+\classPath{/c/Users/dpstory/Desktop/Test Folder/target/myClass}
+\bClassData
+{Peter}{Pan}{453453}{A/_Thor}
+{J\oct374rgen}{Gilg}{5565}{B/_Thor}
+{Thors}{Hammer}{534534}{C/_Thor}
diff --git a/macros/latex/contrib/thorshammer/examples/misc/thexrt.tex b/macros/latex/contrib/thorshammer/examples/misc/thexrt.tex
new file mode 100644
index 0000000000..b9e4d2d321
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/misc/thexrt.tex
@@ -0,0 +1,319 @@
+% spdef is part of aeb-mobile package
+% I'm using it as a convenience, so I can have a dual
+% setup between the web package and not loading the
+% web package
+\RequirePackage[use=forweb]{spdef} % try !use=forweb
+\documentclass{article}
+\usepackage{amstext}
+\ifforweb\usepackage[forcolorpaper]{web}\fi
+\expexe{\usepackage[usesumrytbls,allowrandomize\ifforweb\else,forcolorpaper\fi]{exerquiz}}
+\usepackage{ran_toks}
+\usepackage[usebatch]{thorshammer}
+
+\DeclareQuiz{q1}
+\thQzName{Grammatik 1}
+
+\title{Pr\"{u}fung: \thqzname}
+\author{Odon, Thor, Loki}
+\ifforweb
+ \subject{Testing Thor's way}
+ \keywords{LaTeX, acrotex, thorshammer}
+ \university{Thor University}
+ \email{thor@valhalla.gov}
+ \version{1700 Today}
+ \versionLabel{Due by}
+ \copyrightyears{1999-\the\year}
+ \nocopyright
+ \revisionLabel{}
+\fi
+% It is important to freeze the seed to that (1) you can reproduce the exact
+% same quiz at a later time; (2) allow content written to the AUX file to
+% come up to date. This is important when using summary tables.
+\useThisSeed{1344524586}
+
+\renewcommand\sqslsectitle{L\"{o}sungen: \thqzname\space(Ver~\QzVer)}
+
+%\thQzHeaderL{Thor's Class}
+\thQzHeaderCQ{Prüfung: \thqzname\space(Ver~\QzVer)}
+\thQzHeaderCS{L\"{o}sungen: \thqzname\space(Ver~\QzVer)}
+
+\ifforweb
+ \thQzHeaderR{Seite \thepage}
+\else
+ \thQzHeaderR{Herr Thor}
+\fi
+
+\thQzName{Grammatik 1}
+
+\setInitMag{fitwidth}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\hypersetup{pdfpagelayout=OneColumn}
+\reversemarginpar
+
+\showCreditMarkup
+
+%\previewOn\pmpvOn
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+
+\useMCCircles
+
+% An example of how to re-format how the
+% \Fullname field appears.
+\thfullnameFmt{#2+", "+#1}
+
+
+\makeatletter
+% An example of redefining \thQuizHeaderLayout, here
+% we make \Firstname and \Lastname field hidden and taking
+% up no space
+\renewcommand\thQuizHeaderLayout{\noindent
+ \smash{\rlap{\FirstName[\F\FHidden]{0bp}{0bp}}\rlap{\LastName[\F\FHidden]{0bp}{0bp}}}%
+ \begin{minipage}[t]{1.2in}\kern0pt
+ \makebox[0pt][r]{\raggedleft\markQz{}{11bp}%
+ \hspace{\marginparsep}}%
+ \th@QHPoints\studentReport{\widthof{000/000}}{11bp}\vcgBdry[6pt]
+ \makebox[0pt][r]{\raggedleft\freezeOrSave{}{11bp}%
+ \hspace{\marginparsep}}%
+ \th@QHGrade\studentGrade{14bp}{14bp}\vcgBdry[6pt]
+ \end{minipage}\hfill
+ \begin{minipage}[t]{\linewidth-1em-1.2in}\kern0pt
+ \begin{sumryTblAux}{\currQuiz}
+ \displaySumryTbl[ntables=1,showmarkup]{\currQuiz}
+ \end{sumryTblAux}
+ \end{minipage}}
+\makeatother
+
+% reset the paths for \instrPath and \classPath for your system
+\instrPath{/C/Users/dpstory/Desktop/Test Folder/target/_Thor}
+\classPath{/C/Users/dpstory/Desktop/Test Folder/target/myClass}
+\classMember{Peter}{Pan}{A/_Thor}
+\classMember{J\oct374rgen}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer}{C/_Thor}
+
+\autoCopyOn
+
+%\distrToInstrOff
+%\distrToStudentsOff
+
+\DeclareCoverPage{0}
+
+\begin{makeClassFiles}
+\sadQuizzes
+\end{makeClassFiles}
+
+\begin{document}
+
+\ifforweb
+ \makeinlinetitle
+\else
+ \maketitle
+\fi
+
+\thispagestyle{empty}
+%\thQzHeaderR{Herr Thor}
+
+\noindent
+Student Name: \FullName{1.5in}{11bp}
+
+\section*{Instructions}
+
+Solve each problem to the best of your ability. Do not look a
+little to the left or a little to the right -- Thor is watching
+!! You have a time limit of 2 minutes to complete the quiz.
+
+\paragraph*{The Procedure}
+\begin{enumerate}
+ \item The quiz begins on the next page
+ \item Go to the next page \verb!:-{)!
+ \item To begin the quiz, press the `\textsf{Begin}' button
+ \item Answer each of the questions
+ \item To end the quiz, press the `\textsf{End}' button. You
+ will be asked whether you really want to end the quiz. Press the
+ `\textsf{Yes}' button, or the `\textsf{No}' button to continue with the quiz
+ \item After ending the quiz, press the `\textsf{Save}' button; save the file
+ back to the original folder
+ \item Close \textsf{Adobe Reader}, and go have lunch.
+\end{enumerate}
+Good luck, no, I wish you \emph{good knowledge} !
+
+\newpage
+
+\declareQuizBody{qzbody1}
+\declareQuizBody{qzbody2}
+
+% The qzbody env encloses the entire body of the quiz
+\begin{qzbody1}
+\bRTVToks{\currQuiz}
+
+\thQuizHeader
+
+\noindent\textbf{Instructions:} (For the student) Press
+`\textsf{Begin}' to begin the quiz; after completing the quiz,
+press `\textsf{End}'. Use the `\textsf{Save}' button to save the
+document.
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+
+\begin{rtVW}
+ \item\PTs{3} Which of these are true ?
+\begin{answers}{4}
+\Ans1 True & \Ans0 False
+\end{answers}
+\end{rtVW}
+
+\begin{rtVW}
+ \item \PTs{4} Select which of the following is true.
+\begin{answers}{4}
+\Ans1 True & \Ans0 False & \Ans0 Maybe & \Ans0 Sometimes
+\end{answers}
+\end{rtVW}
+
+\begin{rtVW}
+ \item\PTs{2} $9+8=\RespBoxMath{17}*{1}{.0001}{[0,1]}$
+\begin{solution}
+Everyone knows that $ 9 + 8 = 17$, why don't you ?
+\end{solution}
+\end{rtVW}
+
+\begin{rtVW}
+\essayQ{5} % num points assigned
+\item\PTs{5} Write a short history of Acro\negthinspace\TeX.\par
+\RespBoxEssay*{\linewidth}{1in}
+\begin{solution}
+Acro\negthinspace\TeX{} was created by D. P. Story and supported
+for many years by J\"{u}gen Gilg. Special inspiration was
+provided by K. F. Story, who suggested the name
+Acro\negthinspace\TeX.
+\end{solution}
+\end{rtVW}
+
+\begin{rtVW}
+\item\PTs{3} Which of the following are numbers?
+\begin{manswers}{6}
+\bChoices[random=true]
+ \Ans[-1]{0}d\eAns
+ \Ans[1]{1}17\eAns
+ \Ans[-1]{0}p\eAns
+ \Ans[1]{1}88\eAns
+ \Ans[-1]{0}s\eAns
+ \Ans[1]{1}105\eAns
+\eChoices
+\end{manswers}
+\end{rtVW}
+
+
+\begin{rtVW}
+\multipartquestion
+ \item\PTs{20} Answer each of the following multiple selection problems. Each correct answer
+ is worth $3$ points, and each incorrect answer is worth $-2$ points.
+ \begin{questions}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a President
+ of the United States. (Select all correct choices.)
+
+ \begin{manswers}*{2}%
+ \bChoices[random=true]
+ \Ans[-2]{0} Henry Clay\eAns
+ \Ans[-2]{0} Ben Franklin\eAns
+ \Ans[3]{1} Andrew Jackson\eAns
+ \Ans[3]{1} Ronald Reagan\eAns
+ \Ans[-2]{0} George Meade\eAns
+ \Ans[3]{1} Grover Cleveland\eAns
+ \Ans[-2]{0} John Jay\eAns
+ \Ans[-2]{0} Paul Revere\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a Chancellor of the
+ German Republic. (Select all correct choices.)
+ \begin{manswers}*{2}%
+ \bChoices[nCols=2,random=true]
+ \Ans[-2]{0} Gustav Heinemann\eAns
+ \Ans[-2]{0} Theodor Heu{\ss}\eAns
+ \Ans[3]{1} Konrad Adenauer\eAns
+ \Ans[-2]{0} Richard von Weizs\"{a}cker\eAns
+ \Ans[3]{1} Willy Brandt\eAns
+ \Ans[-2]{0} Heinrich L\"{u}bke\eAns
+ \Ans[-2]{0} Roman Herzog\eAns
+ \Ans[3]{1} Ludwig Erhard\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{2} If you select all choices in part~(a), you will
+ receive -1 points as a penalty for bad guessing. \textbf{Question:}
+ Determine the \emph{number of correct choices} in part~(a)?
+ \begin{answers}{4}
+ \bChoices[random=true]
+ \Ans0 1\eAns
+ \Ans0 2\eAns
+ \Ans1 3\eAns
+ \Ans0 4\eAns
+ \Ans0 5\eAns
+ \Ans0 6\eAns
+ \Ans0 7\eAns
+ \Ans0 8\eAns
+ \eChoices
+ \end{answers}
+ \end{questions}
+\end{rtVW}
+
+\eRTVToks
+
+% Ok, now display this questions in a random order.
+\displayListRandomly{\thisQuiz}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+
+\end{qzbody1}
+
+\begin{qzbody2}
+
+\thQuizHeader
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+
+\essayitem{3} Comment on the experience of taking a quiz the `Thorsten way.'.\par
+\RespBoxEssay*{\linewidth}{1in}
+
+\begin{solution}
+This was a very wonderful experience, I'm privileged to have been in this class with such a wonderful
+German teacher. As you can read, I am fluent in German now. Thank you Thor, wherever you are.
+
+A second paragraph should convince of my sincerity, remember me when you mark this quiz.
+\end{solution}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+
+\end{qzbody2}
+
+% Now we input the qzbody back in two times, though it can be more than that. The quiz name
+% modified in each instance.
+%
+% Each instance of the quiz has a randomized order
+%
+\InputQuizBody{qzbody1}
+
+\InputQuizBody{qzbody2}
+
+\InputQuizBody{qzbody1}
+
+
+\end{document}
diff --git a/macros/latex/contrib/thorshammer/examples/nosolns/thexb.tex b/macros/latex/contrib/thorshammer/examples/nosolns/thexb.tex
new file mode 100644
index 0000000000..04d5a65903
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/nosolns/thexb.tex
@@ -0,0 +1,147 @@
+\RequirePackage[use=withdesign]{spdef} % try !use=withdesign (spdef is distributed with aeb-mobile)
+\documentclass{article}
+\usepackage{amstext}
+\expexe{\usepackage[\ifwithdesign{designi}\else{forcolorpaper}\fi]{web}}
+\usepackage[usesumrytbls]{exerquiz}
+\usepackage[!testmode]{thorshammer}
+
+\ifwithdesign
+% Some crazy calculations to get the left margin looking good
+\fontsize{9bp}{0}\selectfont
+ \addtoWebWidth{\widthof{Freeze Quiz}}
+ \resetmargins{\incby+\widthof{Freeze Quiz}}{}{}{}
+\normalsize
+\fi
+
+\DeclareQuiz{q1}
+
+\setInitMag{fitwidth}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\hypersetup{pdfpagelayout=OneColumn}
+\reversemarginpar
+
+\enumQuizzes{3}
+
+\showCreditMarkup
+
+%\previewOn\pmpvOn
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+
+\useMCCircles
+
+%\makePDasXOn
+%\makeXasPDOn
+
+\begin{docassembly}
+\sadQuizzes
+\end{docassembly}
+
+\begin{document}
+
+\thQuizHeader
+
+\noindent\textbf{Instructions:} Enter your first and last names
+in the fields provided. Press `\textsf{Begin}' to begin the
+quiz; after completing the quiz, press `\textsf{End}'. Use the
+`\textsf{Save}' button to save the document.
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+ \item\PTs{3} Which of these are true ?
+\begin{answers}{4}
+\Ans1 True & \Ans0 False
+\end{answers}
+
+ \item \PTs{4} Select which of the following is true.
+\begin{answers}{4}
+\Ans1 True & \Ans0 False & \Ans0 Maybe & \Ans0 Sometimes
+\end{answers}
+
+ \item\PTs{2} $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}$
+
+\essayQ{5} % num points assigned
+\item\PTs{5} Write a short history of Acro\negthinspace\TeX.\par
+\RespBoxEssay{\linewidth}{1in}
+
+\item\PTs{3} Which of the following are numbers?
+\begin{manswers}{6}
+\bChoices
+ \Ans[-1]{0}d\eAns
+ \Ans[1]{1}17\eAns
+ \Ans[-1]{0}p\eAns
+ \Ans[1]{1}88\eAns
+ \Ans[-1]{0}s\eAns
+ \Ans[1]{1}105\eAns
+\eChoices
+\end{manswers}
+
+\multipartquestion
+
+ \item\PTs{20} Answer each of the following multiple selection problems. Each correct answer
+ is worth $3$ points, and each incorrect answer is worth $-2$ points.
+ \begin{questions}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a President
+ of the United States. (Select all correct choices.)
+
+ \begin{manswers}{2}%
+ \bChoices
+ \Ans[-2]{0} Henry Clay\eAns
+ \Ans[-2]{0} Ben Franklin\eAns
+ \Ans[3]{1}\label{aj} Andrew Jackson\eAns
+ \Ans[3]{1}\label{rr} Ronald Reagan\eAns
+ \Ans[-2]{0} George Meade\eAns
+ \Ans[3]{1}\label{gc} Grover Cleveland\eAns
+ \Ans[-2]{0} John Jay\eAns
+ \Ans[-2]{0} Paul Revere\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a Chancellor of the
+ German Republic. (Select all correct choices.)
+ \begin{manswers}{2}%
+ \bChoices[2]
+ \Ans[-2]{0} Gustav Heinemann\eAns
+ \Ans[-2]{0} Theodor Heu{\ss}\eAns
+ \Ans[3]{1} Konrad Adenauer\eAns
+ \Ans[-2]{0} Richard von Weizs\"{a}cker\eAns
+ \Ans[3]{1} Willy Brandt\eAns
+ \Ans[-2]{0} Heinrich L\"{u}bke\eAns
+ \Ans[-2]{0} Roman Herzog\eAns
+ \Ans[3]{1} Ludwig Erhard\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{2} If you select all choices in part~(a), you will
+ receive $-1$ points as a penalty for bad guessing. \textbf{Question:}
+ Determine the \emph{number of correct choices} in part~(a)?
+ \begin{answers}{4}
+ \bChoices
+ \Ans0 1\eAns
+ \Ans0 2\eAns
+ \Ans1 3\eAns
+ \Ans0 4\eAns
+ \Ans0 5\eAns
+ \Ans0 6\eAns
+ \Ans0 7\eAns
+ \Ans0 8\eAns
+ \eChoices
+ \end{answers}
+ \end{questions}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+
+\end{document}
diff --git a/macros/latex/contrib/thorshammer/examples/nosolns/thexbd.tex b/macros/latex/contrib/thorshammer/examples/nosolns/thexbd.tex
new file mode 100644
index 0000000000..7b9ed8f1be
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/nosolns/thexbd.tex
@@ -0,0 +1,146 @@
+\documentclass{article}
+\usepackage{amstext}
+\usepackage{web}
+\usepackage[usesumrytbls]{exerquiz}
+\usepackage[batchdistr]{thorshammer}
+
+\DeclareQuiz{q1}
+
+\setInitMag{fitwidth}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\hypersetup{pdfpagelayout=OneColumn}
+\reversemarginpar
+
+\showCreditMarkup
+
+%\previewOn\pmpvOn
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+
+\useMCCircles
+
+% reset the paths for \instrPath and \classPath for your system
+\instrPath{/C/Users/dpstory/Desktop/Test Folder/target/_Thor}
+\classPath{/C/Users/dpstory/Desktop/Test Folder/target/myClass}
+\classMember{Peter}{Pan}{A/_Thor}
+\classMember{J\oct374rgen}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer}{C/_Thor}
+
+\begin{makeClassFiles}
+\sadQuizzes
+\end{makeClassFiles}
+
+\begin{document}
+
+\thQuizHeader
+
+\noindent\textbf{Instructions:} (For the student) Press
+`\textsf{Begin}' to begin the quiz; after completing the quiz,
+press `\textsf{End}'. Use the `\textsf{Save}' button to save the
+document.
+
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+ \item\PTs{3} Which of these are true ?
+\begin{answers}{4}
+\Ans1 True & \Ans0 False
+\end{answers}
+
+ \item \PTs{4} Select which of the following is true.
+\begin{answers}{4}
+\Ans1 True & \Ans0 False & \Ans0 Maybe & \Ans0 Sometimes
+\end{answers}
+
+ \item\PTs{2} $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}$
+
+\essayQ{5} % num points assigned
+\item\PTs{5} Write a short history of Acro\negthinspace\TeX.\par
+\RespBoxEssay{\linewidth}{1in}
+
+\item\PTs{3} Which of the following are numbers?
+\begin{manswers}{6}
+\bChoices
+ \Ans[-1]{0}d\eAns
+ \Ans[1]{1}17\eAns
+ \Ans[-1]{0}p\eAns
+ \Ans[1]{1}88\eAns
+ \Ans[-1]{0}s\eAns
+ \Ans[1]{1}105\eAns
+\eChoices
+\end{manswers}
+
+\multipartquestion
+
+ \item\PTs{20} Answer each of the following multiple selection problems. Each correct answer
+ is worth $3$ points, and each incorrect answer is worth $-2$ points.
+ \begin{questions}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a President
+ of the United States. (Select all correct choices.)
+
+ \begin{manswers}*{2}%
+ \bChoices
+ \Ans[-2]{0} Henry Clay\eAns
+ \Ans[-2]{0} Ben Franklin\eAns
+ \Ans[3]{1}\label{aj} Andrew Jackson\eAns
+ \Ans[3]{1}\label{rr} Ronald Reagan\eAns
+ \Ans[-2]{0} George Meade\eAns
+ \Ans[3]{1}\label{gc} Grover Cleveland\eAns
+ \Ans[-2]{0} John Jay\eAns
+ \Ans[-2]{0} Paul Revere\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a Chancellor of the
+ German Republic. (Select all correct choices.)
+ \begin{manswers}*{2}%
+ \bChoices[2]
+ \Ans[-2]{0} Gustav Heinemann\eAns
+ \Ans[-2]{0} Theodor Heu{\ss}\eAns
+ \Ans[3]{1} Konrad Adenauer\eAns
+ \Ans[-2]{0} Richard von Weizs\"{a}cker\eAns
+ \Ans[3]{1} Willy Brandt\eAns
+ \Ans[-2]{0} Heinrich L\"{u}bke\eAns
+ \Ans[-2]{0} Roman Herzog\eAns
+ \Ans[3]{1} Ludwig Erhard\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{2} If you select all choices in part~(a), you will
+ receive -1 points as a penalty for bad guessing. \textbf{Question:}
+ Determine the \emph{number of correct choices} in part~(a)?
+ \begin{answers}{4}
+ \bChoices
+ \Ans0 1\eAns
+ \Ans0 2\eAns
+ \Ans1 3\eAns
+ \Ans0 4\eAns
+ \Ans0 5\eAns
+ \Ans0 6\eAns
+ \Ans0 7\eAns
+ \Ans0 8\eAns
+ \eChoices
+ \end{answers}
+ \end{questions}
+
+%\essayQ{3} % num points assigned
+%\item\PTs{3} Comment on the experience of taking a quiz the `Thorsten way.'.\par
+%\RespBoxEssay{\linewidth}{1in}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+
+\end{document}
+
diff --git a/macros/latex/contrib/thorshammer/examples/nosolns/thexr.tex b/macros/latex/contrib/thorshammer/examples/nosolns/thexr.tex
new file mode 100644
index 0000000000..80412858ea
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/nosolns/thexr.tex
@@ -0,0 +1,175 @@
+\documentclass{article}
+\usepackage{amstext}
+\usepackage{web}
+\usepackage[usesumrytbls,allowrandomize]{exerquiz}
+\usepackage[usebatch]{thorshammer}
+
+\DeclareQuiz{q1}
+
+% It is important to freeze the seed so that (1) you can reproduce the exact
+% same quiz at a later time; (2) allow content written to the AUX file to
+% come up to date. This is important when using summary tables.
+\useRandomSeed{380105620}
+
+\setInitMag{fitwidth}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\hypersetup{pdfpagelayout=OneColumn} %,pdfencoding=auto
+\reversemarginpar
+
+\showCreditMarkup
+
+%\previewOn\pmpvOn
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+
+\useMCCircles
+
+% reset the paths for \instrPath and \classPath for your system
+\instrPath{/C/Users/dpstory/Desktop/Test Folder/target/_Thor}
+\classPath{/C/Users/dpstory/Desktop/Test Folder/target/myClass}
+\classMember{Peter}{Pan}{A/_Thor}
+\classMember{J\oct374rgen}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer}{C/_Thor}
+
+\autoCopyOn
+\DeclareCoverPage{0}
+
+\begin{makeClassFiles}
+\sadQuizzes
+\end{makeClassFiles}
+
+\begin{document}
+
+\thispagestyle{empty}
+
+\noindent In this file, we attempt to duplicate and extend the
+work of \texttt{theexuc.tex} by developing a scheme to randomize
+the questions. We begin with the simple case, of creating two
+versions of the same quiz. We modify the preamble to include the
+option \texttt{allowrandomize} of \textsf{exerquiz}. This file
+randomizes the multiple choice and multiple selection question
+that are marked up using \verb~\bChoices/\eChoices~. The `quiz
+body' concept is used to introduced multiple equivalent quizzes.
+
+\newpage
+
+\declareQuizBody{qzbody}
+
+\begin{qzbody}
+
+\thQuizHeader
+
+\noindent\textbf{Instructions:} (For the student) Press
+`\textsf{Begin}' to begin the quiz; after completing the quiz,
+press `\textsf{End}'. Use the `\textsf{Save}' button to save the
+document.
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+ \item\PTs{3} Which of these are true ?
+\begin{answers}{4}
+\Ans1 True & \Ans0 False
+\end{answers}
+
+ \item \PTs{4} Select which of the following is true.
+\begin{answers}{4}
+\Ans1 True & \Ans0 False & \Ans0 Maybe & \Ans0 Sometimes
+\end{answers}
+
+ \item\PTs{2} $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}$
+
+\essayQ{5} % num points assigned
+\item\PTs{5} Write a short history of Acro\negthinspace\TeX.\par
+\RespBoxEssay{\linewidth}{1in}
+
+\item\PTs{3} Which of the following are numbers?
+\begin{manswers}{6}
+\bChoices[random=true]
+ \Ans[-1]{0}d\eAns
+ \Ans[1]{1}17\eAns
+ \Ans[-1]{0}p\eAns
+ \Ans[1]{1}88\eAns
+ \Ans[-1]{0}s\eAns
+ \Ans[1]{1}105\eAns
+\eChoices
+\end{manswers}
+
+\multipartquestion
+
+ \item\PTs{20} Answer each of the following multiple selection problems. Each correct answer
+ is worth $3$ points, and each incorrect answer is worth $-2$ points.
+ \begin{questions}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a President
+ of the United States. (Select all correct choices.)
+
+ \begin{manswers}*{2}%
+ \bChoices[random=true]
+ \Ans[-2]{0} Henry Clay\eAns
+ \Ans[-2]{0} Ben Franklin\eAns
+ \Ans[3]{1} Andrew Jackson\eAns
+ \Ans[3]{1} Ronald Reagan\eAns
+ \Ans[-2]{0} George Meade\eAns
+ \Ans[3]{1} Grover Cleveland\eAns
+ \Ans[-2]{0} John Jay\eAns
+ \Ans[-2]{0} Paul Revere\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a Chancellor of the
+ German Republic. (Select all correct choices.)
+ \begin{manswers}*{2}%
+ \bChoices[nCols=2,random=true]
+ \Ans[-2]{0} Gustav Heinemann\eAns
+ \Ans[-2]{0} Theodor Heu{\ss}\eAns
+ \Ans[3]{1} Konrad Adenauer\eAns
+ \Ans[-2]{0} Richard von Weizs\"{a}cker\eAns
+ \Ans[3]{1} Willy Brandt\eAns
+ \Ans[-2]{0} Heinrich L\"{u}bke\eAns
+ \Ans[-2]{0} Roman Herzog\eAns
+ \Ans[3]{1} Ludwig Erhard\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{2} If you select all choices in part~(a), you will
+ receive -1 points as a penalty for bad guessing. \textbf{Question:}
+ Determine the \emph{number of correct choices} in part~(a)?
+ \begin{answers}{4}
+ \bChoices[random=true]
+ \Ans0 1\eAns
+ \Ans0 2\eAns
+ \Ans1 3\eAns
+ \Ans0 4\eAns
+ \Ans0 5\eAns
+ \Ans0 6\eAns
+ \Ans0 7\eAns
+ \Ans0 8\eAns
+ \eChoices
+ \end{answers}
+ \end{questions}
+
+%\essayQ{3} % num points assigned
+%\item\PTs{3} Comment on the experience of taking a quiz the `Thorsten way.'\par
+%\RespBoxEssay{\linewidth}{1in}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+\end{qzbody}
+
+\typeout{!! inputting qzbody first time}
+\InputQuizBody{qzbody}
+
+\typeout{!! inputting qzbody second time}
+\InputQuizBody{qzbody}
+
+\end{document}
diff --git a/macros/latex/contrib/thorshammer/examples/nosolns/thexrt.tex b/macros/latex/contrib/thorshammer/examples/nosolns/thexrt.tex
new file mode 100644
index 0000000000..7852cdc1c0
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/nosolns/thexrt.tex
@@ -0,0 +1,222 @@
+\documentclass{article}
+\usepackage{amstext}
+\usepackage{web}
+\usepackage[usesumrytbls,allowrandomize]{exerquiz}
+\usepackage{ran_toks}
+\usepackage[usebatch]{thorshammer}
+
+\DeclareQuiz{q1}
+
+% It is important to freeze the seed so that (1) you can reproduce the exact
+% same quiz at a later time; (2) allow content written to the AUX file to
+% come up to date. This is important when using summary tables.
+\useRandomSeed{1344524586}
+
+\setInitMag{fitwidth}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\hypersetup{pdfpagelayout=OneColumn}
+\reversemarginpar
+
+\showCreditMarkup
+
+% \previewOn\pmpvOn
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+
+\useMCCircles
+
+% reset the paths for \instrPath and \classPath for your system
+\instrPath{/C/Users/dpstory/Desktop/Test Folder/target/_Thor}
+\classPath{/C/Users/dpstory/Desktop/Test Folder/target/myClass}
+\classMember{Peter}{Pan}{A/_Thor}
+\classMember{J\oct374rgen}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer}{C/_Thor}
+
+\autoCopyOn
+
+%\distrToInstrOff
+%\distrToStudentsOff
+
+\begin{makeClassFiles}
+\sadQuizzes
+\end{makeClassFiles}
+
+\begin{document}
+
+\noindent In this file, we attempt to \emph{duplicate} and
+\emph{extend} the work of \texttt{theexuc.tex} by developing a
+scheme to randomize choices and randomize the questions. To
+randomize the choices, we modify the preamble to include the
+option \texttt{allowrandomize} of \textsf{exerquiz}, to
+randomize the order of the questions, we include the
+\textsf{ran\_toks} package. The `quiz body' concept is used
+to introduced multiple equivalent quizzes.
+
+
+\newpage
+
+
+\declareQuizBody{qzbody1}
+\declareQuizBody{qzbody2}
+
+% The qzbody env encloses the entire body of the quiz
+\begin{qzbody1}
+
+\bRTVToks{\currQuiz}
+
+\thQuizHeader
+
+\noindent\textbf{Instructions:} (For the student) Press
+`\textsf{Begin}' to begin the quiz; after completing the quiz,
+press `\textsf{End}'. Use the `\textsf{Save}' button to save the
+document.
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+
+\begin{rtVW}
+ \item\PTs{3} Which of these are true ?
+\begin{answers}{4}
+\Ans1 True & \Ans0 False
+\end{answers}
+\end{rtVW}
+
+\begin{rtVW}
+ \item \PTs{4} Select which of the following is true.
+\begin{answers}{4}
+\Ans1 True & \Ans0 False & \Ans0 Maybe & \Ans0 Sometimes
+\end{answers}
+\end{rtVW}
+
+\begin{rtVW}
+ \item\PTs{2} $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}$
+\end{rtVW}
+
+\begin{rtVW}
+\essayQ{5} % num points assigned
+\item\PTs{5} Write a short history of Acro\negthinspace\TeX.\par
+\RespBoxEssay{\linewidth}{1in}
+\end{rtVW}
+
+\begin{rtVW}
+\item\PTs{3} Which of the following are numbers?
+\begin{manswers}{6}
+\bChoices[random=true]
+ \Ans[-1]{0}d\eAns
+ \Ans[1]{1}17\eAns
+ \Ans[-1]{0}p\eAns
+ \Ans[1]{1}88\eAns
+ \Ans[-1]{0}s\eAns
+ \Ans[1]{1}105\eAns
+\eChoices
+\end{manswers}
+\end{rtVW}
+
+
+\begin{rtVW}
+\multipartquestion
+ \item\PTs{20} Answer each of the following multiple selection problems. Each correct answer
+ is worth $3$ points, and each incorrect answer is worth $-2$ points.
+ \begin{questions}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a President
+ of the United States. (Select all correct choices.)
+
+ \begin{manswers}*{2}%
+ \bChoices[random=true]
+ \Ans[-2]{0} Henry Clay\eAns
+ \Ans[-2]{0} Ben Franklin\eAns
+ \Ans[3]{1} Andrew Jackson\eAns
+ \Ans[3]{1} Ronald Reagan\eAns
+ \Ans[-2]{0} George Meade\eAns
+ \Ans[3]{1} Grover Cleveland\eAns
+ \Ans[-2]{0} John Jay\eAns
+ \Ans[-2]{0} Paul Revere\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a Chancellor of the
+ German Republic. (Select all correct choices.)
+ \begin{manswers}*{2}%
+ \bChoices[nCols=2,random=true]
+ \Ans[-2]{0} Gustav Heinemann\eAns
+ \Ans[-2]{0} Theodor Heu{\ss}\eAns
+ \Ans[3]{1} Konrad Adenauer\eAns
+ \Ans[-2]{0} Richard von Weizs\"{a}cker\eAns
+ \Ans[3]{1} Willy Brandt\eAns
+ \Ans[-2]{0} Heinrich L\"{u}bke\eAns
+ \Ans[-2]{0} Roman Herzog\eAns
+ \Ans[3]{1} Ludwig Erhard\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{2} If you select all choices in part~(a), you will
+ receive -1 points as a penalty for bad guessing. \textbf{Question:}
+ Determine the \emph{number of correct choices} in part~(a)?
+ \begin{answers}{4}
+ \bChoices[random=true]
+ \Ans0 1\eAns
+ \Ans0 2\eAns
+ \Ans1 3\eAns
+ \Ans0 4\eAns
+ \Ans0 5\eAns
+ \Ans0 6\eAns
+ \Ans0 7\eAns
+ \Ans0 8\eAns
+ \eChoices
+ \end{answers}
+ \end{questions}
+\end{rtVW}
+
+\eRTVToks
+
+% Ok, now display this questions in a random order.
+\displayListRandomly{\thisQuiz}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+
+\end{qzbody1}
+
+\begin{qzbody2}
+
+\thQuizHeader
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+
+\essayQ{10} % num points assigned
+\item\PTs{10} Comment on the experience of taking a quiz the `Thorsten way.'\par
+\RespBoxEssay{\linewidth}{1in}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+
+\end{qzbody2}
+
+% Now we input the qzbody back in two times, though it can be more than that. The quiz name
+% modified in each instance.
+%
+% Each instance of the quiz has a randomized order
+%
+\InputQuizBody{qzbody1}
+
+\InputQuizBody{qzbody1}
+
+\InputQuizBody{qzbody2}
+
+
+\end{document}
diff --git a/macros/latex/contrib/thorshammer/examples/nosolns/thexub.tex b/macros/latex/contrib/thorshammer/examples/nosolns/thexub.tex
new file mode 100644
index 0000000000..4b3286f077
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/nosolns/thexub.tex
@@ -0,0 +1,147 @@
+\documentclass{article}
+\usepackage{amstext}
+\usepackage{web}
+\usepackage[usesumrytbls]{exerquiz}
+\usepackage[usebatch]{thorshammer}
+
+\DeclareQuiz{q1}
+
+\setInitMag{fitwidth}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\hypersetup{pdfpagelayout=OneColumn}
+\reversemarginpar
+
+\showCreditMarkup
+
+%\previewOn\pmpvOn
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+
+\useMCCircles
+
+% reset the paths for \instrPath and \classPath for your system
+\instrPath{/C/Users/dpstory/Desktop/Test Folder/target/_Thor}
+\classPath{/C/Users/dpstory/Desktop/Test Folder/target/myClass}
+\classMember{Peter}{Pan}{A/_Thor}
+\classMember{J\oct374rgen}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer}{C/_Thor}
+
+%\autoCopyOn % or \autoCopyOff
+
+\begin{makeClassFiles}
+\sadQuizzes
+\end{makeClassFiles}
+
+\begin{document}
+
+\thQuizHeader
+
+\noindent\textbf{Instructions:} (For the student) Press
+`\textsf{Begin}' to begin the quiz; after completing the quiz,
+press `\textsf{End}'. Use the `\textsf{Save}' button to save the
+document.
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+ \item\PTs{3} Which of these are true ?
+\begin{answers}{4}
+\Ans1 True & \Ans0 False
+\end{answers}
+
+ \item \PTs{4} Select which of the following is true.
+\begin{answers}{4}
+\Ans1 True & \Ans0 False & \Ans0 Maybe & \Ans0 Sometimes
+\end{answers}
+
+ \item\PTs{2} $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}$
+
+\essayQ{5} % num points assigned
+\item\PTs{5} Write a short history of Acro\negthinspace\TeX.\par
+\RespBoxEssay{\linewidth}{1in}
+
+\item\PTs{3} Which of the following are numbers?
+\begin{manswers}{6}
+\bChoices
+ \Ans[-1]{0}d\eAns
+ \Ans[1]{1}17\eAns
+ \Ans[-1]{0}p\eAns
+ \Ans[1]{1}88\eAns
+ \Ans[-1]{0}s\eAns
+ \Ans[1]{1}105\eAns
+\eChoices
+\end{manswers}
+
+\multipartquestion
+
+ \item\PTs{20} Answer each of the following multiple selection problems. Each correct answer
+ is worth $3$ points, and each incorrect answer is worth $-2$ points.
+ \begin{questions}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a President
+ of the United States. (Select all correct choices.)
+
+ \begin{manswers}*{2}%
+ \bChoices
+ \Ans[-2]{0} Henry Clay\eAns
+ \Ans[-2]{0} Ben Franklin\eAns
+ \Ans[3]{1}\label{aj} Andrew Jackson\eAns
+ \Ans[3]{1}\label{rr} Ronald Reagan\eAns
+ \Ans[-2]{0} George Meade\eAns
+ \Ans[3]{1}\label{gc} Grover Cleveland\eAns
+ \Ans[-2]{0} John Jay\eAns
+ \Ans[-2]{0} Paul Revere\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a Chancellor of the
+ German Republic. (Select all correct choices.)
+ \begin{manswers}*{2}%
+ \bChoices[2]
+ \Ans[-2]{0} Gustav Heinemann\eAns
+ \Ans[-2]{0} Theodor Heu{\ss}\eAns
+ \Ans[3]{1} Konrad Adenauer\eAns
+ \Ans[-2]{0} Richard von Weizs\"{a}cker\eAns
+ \Ans[3]{1} Willy Brandt\eAns
+ \Ans[-2]{0} Heinrich L\"{u}bke\eAns
+ \Ans[-2]{0} Roman Herzog\eAns
+ \Ans[3]{1} Ludwig Erhard\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{2} If you select all choices in part~(a), you will
+ receive -1 points as a penalty for bad guessing. \textbf{Question:}
+ Determine the \emph{number of correct choices} in part~(a)?
+ \begin{answers}{4}
+ \bChoices
+ \Ans0 1\eAns
+ \Ans0 2\eAns
+ \Ans1 3\eAns
+ \Ans0 4\eAns
+ \Ans0 5\eAns
+ \Ans0 6\eAns
+ \Ans0 7\eAns
+ \Ans0 8\eAns
+ \eChoices
+ \end{answers}
+ \end{questions}
+
+%\essayQ{3} % num points assigned
+%\item\PTs{3} Comment on the experience of taking a quiz the `Thorsten way.'.\par
+%\RespBoxEssay{\linewidth}{1in}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+
+\end{document}
+
diff --git a/macros/latex/contrib/thorshammer/examples/nosolns/thexuc.tex b/macros/latex/contrib/thorshammer/examples/nosolns/thexuc.tex
new file mode 100644
index 0000000000..e514552a01
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/nosolns/thexuc.tex
@@ -0,0 +1,152 @@
+\documentclass{article}
+\usepackage{amstext}
+\usepackage{web}
+\usepackage[usesumrytbls]{exerquiz}
+\usepackage[useclass]{thorshammer}
+
+\DeclareQuiz{q1}
+
+\setInitMag{fitwidth}
+\hypersetup{pdfpagemode=UseNone} % don't need to see bookmarks
+\hypersetup{pdfpagelayout=OneColumn}
+\reversemarginpar
+
+\showCreditMarkup
+
+%\previewOn\pmpvOn
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+
+\useMCCircles
+
+% reset the paths for \instrPath and \classPath for your system
+\instrPath{/C/Users/dpstory/Desktop/Test Folder/target/_Thor}
+\classPath{/C/Users/dpstory/Desktop/Test Folder/target/myClass}
+%\classMember{Peter}{Pan}{} % with third arg empty, these files will be dropped
+%\classMember{J\oct374rgen}{Gilg}{} % at root of \classPath
+%\classMember{Thors}{Hammer}{}
+\classMember{Peter}{Pan}{A/_Thor}
+\classMember{J\oct374rgen}{Gilg}{B/_Thor}
+\classMember{Thors}{Hammer}{C/_Thor}
+
+\autoCopyOn % or \autoCopyOff
+
+%\distrToStudentsOff
+
+\begin{makeClassFiles}
+\sadQuizzes
+\end{makeClassFiles}
+
+\begin{document}
+
+\thQuizHeader
+
+\noindent\textbf{Instructions:} (For the student) Press
+`\textsf{Begin}' to begin the quiz; after completing the quiz,
+press `\textsf{End}'. Use the `\textsf{Save}' button to save the
+document.
+
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+ \item\PTs{3} Which of these are true ?
+\begin{answers}{4}
+\Ans1 True & \Ans0 False
+\end{answers}
+
+ \item \PTs{4} Select which of the following is true.
+\begin{answers}{4}
+\Ans1 True & \Ans0 False & \Ans0 Maybe & \Ans0 Sometimes
+\end{answers}
+
+ \item\PTs{2} $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}$
+
+\essayQ{5} % num points assigned
+\item\PTs{5} Write a short history of Acro\negthinspace\TeX.\par
+\RespBoxEssay{\linewidth}{1in}
+
+\item\PTs{3} Which of the following are numbers?
+\begin{manswers}{6}
+\bChoices
+ \Ans[-1]{0}d\eAns
+ \Ans[1]{1}17\eAns
+ \Ans[-1]{0}p\eAns
+ \Ans[1]{1}88\eAns
+ \Ans[-1]{0}s\eAns
+ \Ans[1]{1}105\eAns
+\eChoices
+\end{manswers}
+
+\multipartquestion
+
+ \item\PTs{20} Answer each of the following multiple selection problems. Each correct answer
+ is worth $3$ points, and each incorrect answer is worth $-2$ points.
+ \begin{questions}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a President
+ of the United States. (Select all correct choices.)
+
+ \begin{manswers}{2}%
+ \bChoices
+ \Ans[-2]{0} Henry Clay\eAns
+ \Ans[-2]{0} Ben Franklin\eAns
+ \Ans[3]{1}\label{aj} Andrew Jackson\eAns
+ \Ans[3]{1}\label{rr} Ronald Reagan\eAns
+ \Ans[-2]{0} George Meade\eAns
+ \Ans[3]{1}\label{gc} Grover Cleveland\eAns
+ \Ans[-2]{0} John Jay\eAns
+ \Ans[-2]{0} Paul Revere\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{9} Select which people who served as a Chancellor of the
+ German Republic. (Select all correct choices.)
+ \begin{manswers}{2}%
+ \bChoices[2]
+ \Ans[-2]{0} Gustav Heinemann\eAns
+ \Ans[-2]{0} Theodor Heu{\ss}\eAns
+ \Ans[3]{1} Konrad Adenauer\eAns
+ \Ans[-2]{0} Richard von Weizs\"{a}cker\eAns
+ \Ans[3]{1} Willy Brandt\eAns
+ \Ans[-2]{0} Heinrich L\"{u}bke\eAns
+ \Ans[-2]{0} Roman Herzog\eAns
+ \Ans[3]{1} Ludwig Erhard\eAns
+ \eChoices
+ \end{manswers}
+
+\rowsep{3pt}
+
+ \item\PTs{2} If you select all choices in part~(a), you will
+ receive -1 points as a penalty for bad guessing. \textbf{Question:}
+ Determine the \emph{number of correct choices} in part~(a)?
+ \begin{answers}{4}
+ \bChoices
+ \Ans0 1\eAns
+ \Ans0 2\eAns
+ \Ans1 3\eAns
+ \Ans0 4\eAns
+ \Ans0 5\eAns
+ \Ans0 6\eAns
+ \Ans0 7\eAns
+ \Ans0 8\eAns
+ \eChoices
+ \end{answers}
+ \end{questions}
+
+%\essayQ{3} % num points assigned
+%\item\PTs{3} Comment on the experience of taking a quiz `Thor's way.'.\par
+%\RespBoxEssay{\linewidth}{1in}
+
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+\end{document}
+
+
diff --git a/macros/latex/contrib/thorshammer/examples/ordinary-option/get-hash-string.tex b/macros/latex/contrib/thorshammer/examples/ordinary-option/get-hash-string.tex
new file mode 100644
index 0000000000..b20c438a21
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/ordinary-option/get-hash-string.tex
@@ -0,0 +1,35 @@
+\documentclass{article}
+\usepackage[designi]{web}
+\usepackage{eforms}
+
+%\previewOn\pmpvOn
+
+\parindent0pt \parskip6pt
+
+\begin{document}
+
+\begin{defineJS}{\btnAct}
+var resp=app.response({
+ cQuestion: "Enter a PIN number",
+ cTitle: "Get Hash String"
+});
+var f=this.getField("txt");
+if (resp!=null) f.value=Collab.hashString(resp);
+\end{defineJS}
+
+Create a four digit (PIN) number and copy that number into the body of the
+definition of the \verb|\PIN| command, which is defined in the source file
+\texttt{quiz-pwd-to-correct-AR.tex}. This is to record and save the number.
+
+Push the button and enter the four digit number you just created into the
+response box. When you press the \textsf{OK} button, the hash string of the
+number you entered appears in the text field. Copy and paste this value into
+the \texttt{quiz-pwd-to-correct-AR.tex} as the value of the
+\texttt{\_PinCode} JavaScript variable. Now you're ready to compile the file
+\texttt{quiz-pwd-to-correct-AR.tex}.
+
+\pushButton[\CA{Push}\AAmouseup{\btnAct}]{btn}{}{11bp}\olBdry
+\textField[\textSize{8}]{txt}{2in}{11bp}\olBdry
+\pushButton[\CA{Reset}\AAmouseup{this.resetForm();}]{reset}{}{11bp}
+
+\end{document}
diff --git a/macros/latex/contrib/thorshammer/examples/ordinary-option/quiz-pwd-to-correct-AA.tex b/macros/latex/contrib/thorshammer/examples/ordinary-option/quiz-pwd-to-correct-AA.tex
new file mode 100644
index 0000000000..e84d9781ee
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/ordinary-option/quiz-pwd-to-correct-AA.tex
@@ -0,0 +1,190 @@
+\documentclass{article}
+\usepackage{amstext}
+\usepackage[designi]{web}
+\usepackage{exerquiz}[2019/10/14]
+
+%\previewOn\pmpvOn
+
+% save the original defn of \eq@@EndQuizButtonActions as \eq@@EndQuizButtonActionsSave
+\efsave\eq@@EndQuizButtonActions\as\eq@@EndQuizButtonActionsDefSave
+
+\usepackage[ordinary]{thorshammer}
+
+\thQzHeaderL{PWD Quizzes}
+\thQzHeaderCQ{Quiz 1}
+
+% save the revised defn of \eq@@EndQuizButtonActions as \eq@@EndQuizButtonActionsThorSave
+\efsave\eq@@EndQuizButtonActions\as\eq@@EndQuizButtonActionsThorSave
+
+\renewcommand\eqQuizPointsMsg{%
+"\eqptScore\space"+ptScore+" \eqOutOf\space"+nPointTotal}
+
+\let\app\textsf
+\let\pkg\textsf
+\let\uif\textsf
+\let\env\texttt
+\let\opt\texttt
+\def\cs#1{\texttt{\char`\\#1}}
+
+
+\execJSOn
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+% If the students have Acrobat, they can see the pin number
+% if they know how; however, if we use a hash string, the actual
+% PIN is not retained within document.
+\def\PIN{5243} % PIN number, change as desired
+
+% save \CorrBtnActionsJS as \CorrBtnActionsJSSave
+\efsave\CorrBtnActionsJS\as\CorrBtnActionsJSSave
+\begin{defineJS*}[\makeesc\@]{\CorrBtnActionsPwdJS}
+var resp=app.response({
+ cQuestion: "Enter the PIN number",
+ cTitle: "View Answers",
+ bPassword: true
+});
+var _resp=Collab.hashString(resp);
+if (_resp==_PinCode) {
+ correctQuiz("@eqBaseName",@thequestionno);
+ if (typeof correctSumryTbl == "function")
+ correctSumryTbl("@eqBaseName",@thequestionno);
+}
+\end{defineJS*}
+
+\DeclareQuiz{qz1}
+
+\begin{execJS}{execjs}
+this.addScript("Pin Code","var _PinCode = \"" + Collab.hashString("\PIN")+"\"");
+\end{execJS}
+
+\begin{document}
+
+\section{Introduction}
+
+\noindent\textbf{Goal:} Make the \uif{Correct} button password
+protected.\medskip
+
+\noindent\textbf{Discussion:} This file illustrates the methods
+of protecting the \uif{Correct} button with a password. This
+file requires \app{Acrobat} to create; while the companion file
+(\texttt{quiz-pwd-to-correct-AR.tex}) does not.
+
+If only MC and MS questions are posed, the \pkg{thorshammer}
+package is not needed; otherwise, it is needed to support the
+other types of questions.
+
+Within \pkg{exerquiz} the command that holds the JavaScript
+action of the \uif{Correct} button is \cs{CorrBtnActionsJS}. We
+save this macro, and change over to \cs{CorrBtnActionsPwdJS},
+defined in the preamble. We use the commands \cs{efsave} and
+\cs{efrestore}, defined in \pkg{eforms}, to change the default
+action to the password action, and back again. We do the same
+thing for the \uif{End Quiz} action. (\pkg{thorshammer}
+redefines \cs{eq@@EndQuizButtonActions}, the JavaScript actio of
+the \uif{End Quiz} button.)
+
+
+\newpage
+
+\section{Quiz with PIN to correct}
+
+% require students to answer all questions
+\renewcommand\minQuizResp{highThreshold} % 1
+
+For the quiz below, the \uif{Correct} button has an encrypted
+password. The password appears in parentheses for the convenience of the casual reader.
+
+% use password version of \CorrButton action
+\efrestore\CorrBtnActionsJS\from\CorrBtnActionsPwdJS
+\begin{quiz*}{\currQuiz}
+Solve each
+\begin{questions}
+ \item The sum of 1 and 1 is\dots
+\begin{answers}{5}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+\item $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}\cgBdry\CorrAnsButton{17}$
+\end{questions}
+\end{quiz*}\quad\PointsField{\currQuiz}\olBdry\CorrButton{\currQuiz} (PIN: \PIN)\vcgBdry
+
+\AnswerField{\currQuiz}
+
+\newpage
+
+\section{Quiz without PIN to correct}
+
+Now we try to create an ordinary \pkg{exerquiz} quiz without password protection.
+
+% restore \eq@@EndQuizButtonActions from its default defn
+\efrestore\eq@@EndQuizButtonActions\from\eq@@EndQuizButtonActionsDefSave
+% restore \CorrBtnActionsJS from \CorrBtnActionsJSSave
+\efrestore\CorrBtnActionsJS\from\CorrBtnActionsJSSave
+
+\renewcommand\minQuizResp{lowThreshold}
+
+\begin{quiz*}{qz2}
+Solve each
+\begin{questions}
+ \item The sum of 1 and 1 is\dots
+\begin{answers}{5}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+\item $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}\cgBdry\CorrAnsButton{17}$
+\end{questions}
+\end{quiz*}\quad\PointsField{\currQuiz}\olBdry\CorrButton{\currQuiz}\vcgBdry
+
+\AnswerField{\currQuiz}
+
+
+\newpage
+
+\section{Another quiz with PIN to correct}
+
+It is possible to have a different PIN number for this quiz (multiple PINs in one document), but
+I see no need for this.
+
+\DeclareQuiz{qz3}
+
+
+% restore \eq@@EndQuizButtonActions from \eq@@EndQuizButtonActionsThorSave
+\efrestore\eq@@EndQuizButtonActions\from\eq@@EndQuizButtonActionsThorSave
+% restore password protection for Correct button
+\efrestore\CorrBtnActionsJS\from\CorrBtnActionsPwdJS
+
+% require students to answer all questions
+\renewcommand\minQuizResp{highThreshold}
+
+\begin{quiz*}{qz3}
+Solve each
+\begin{questions}
+ \item The sum of 1 and 1 is\dots
+\begin{answers}{5}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+\item $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}\cgBdry\CorrAnsButton{17}$
+\end{questions}
+\end{quiz*}\quad\PointsField{\currQuiz}\olBdry\CorrButton{\currQuiz} (PIN: \PIN)\vcgBdry
+
+\AnswerField{\currQuiz}
+
+
+\end{document}
diff --git a/macros/latex/contrib/thorshammer/examples/ordinary-option/quiz-pwd-to-correct-AR.tex b/macros/latex/contrib/thorshammer/examples/ordinary-option/quiz-pwd-to-correct-AR.tex
new file mode 100644
index 0000000000..9123ce34d3
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/examples/ordinary-option/quiz-pwd-to-correct-AR.tex
@@ -0,0 +1,174 @@
+% Requires Acrobat
+\documentclass{article}
+\usepackage{amstext}
+\usepackage[designi]{web}
+\usepackage{exerquiz}[2019/10/11]
+
+\efsave\eq@@EndQuizButtonActions\as\eq@@EndQuizButtonActionsDefSave
+
+\usepackage[ordinary]{thorshammer}
+
+\thQzHeaderL{PWD Quiz}
+\thQzHeaderCQ{Quiz 1}
+
+\efsave\eq@@EndQuizButtonActions\as\eq@@EndQuizButtonActionsThorSave
+
+%\previewOn\pmpvOn
+
+\renewcommand\eqQuizPointsMsg{%
+"\eqptScore\space"+ptScore+" \eqOutOf\space"+nPointTotal}
+
+\let\app\textsf
+\let\pkg\textsf
+\let\env\texttt
+\let\opt\texttt
+\let\uif\textsf
+
+\execJSOn
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+
+% If the students have Acrobat, they can see the pin number
+% if they know how.
+
+\efsave\CorrBtnActionsJS\as\CorrBtnActionsJSSave
+\begin{defineJS*}[\makeesc\@]{\CorrBtnActionsPwdJS}
+var resp=app.response({
+ cQuestion: "Enter the PIN number",
+ cTitle: "View Answers",
+ bPassword: true
+});
+var _resp=Collab.hashString(resp);
+if (_resp==_PinCode) {
+ correctQuiz("@eqBaseName",@thequestionno);
+ if (typeof correctSumryTbl == "function")
+ correctSumryTbl("@eqBaseName",@thequestionno);
+}
+\end{defineJS*}
+
+\DeclareQuiz{qz}
+
+\def\PIN{5243} % PIN number, change as desired
+\begin{insDLJS}{pin}{Pin Code}
+var _PinCode = "02JRVZdRgYgCA-Rtje8VkD";
+\end{insDLJS}
+
+\parindent0pt
+\parskip6pt
+
+\begin{document}
+
+\noindent\textbf{Goal:} Make the \uif{Correct} button password protected.\medskip
+
+\noindent\textbf{Discussion:}
+This demo file uses a \emph{hash string} to encode the password for the instructor to correct
+the quiz, it avoids the use of \app{Adobe Acrobat} by getting the hash string from the
+PDF \texttt{get-hash-string}. Copy the hash string generated from \texttt{get-hash-string}
+as the value of the JavaScript variable \texttt{\_PinCode} in the \textsf{insDLJS} environment
+seen in this source file for this document. Then, compile this document and distribute.
+
+%Delay the correction of this next quiz by expanding the new command
+%\verb|\pwdCorrBtnJS|.
+
+\newpage
+
+\section{Quiz with PIN to correct}
+
+% require students to answer all questions
+\renewcommand\minQuizResp{highThreshold} % 1
+
+For the quiz below, the \uif{Correct} button has an encrypted
+password. The password appears in parentheses for the convenience of the casual reader.
+
+% use password version of \CorrButton action
+\efrestore\CorrBtnActionsJS\from\CorrBtnActionsPwdJS
+\begin{quiz*}{\currQuiz}
+Solve each
+\begin{questions}
+ \item The sum of 1 and 1 is\dots
+\begin{answers}{5}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+\item $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}\cgBdry\CorrAnsButton{17}$
+\end{questions}
+\end{quiz*}\quad\PointsField{\currQuiz}\olBdry\CorrButton{\currQuiz} (PIN: \PIN)\vcgBdry
+
+\AnswerField{\currQuiz}
+
+\newpage
+
+\section{Quiz without PIN to correct}
+
+Now we try to create an ordinary \pkg{exerquiz} quiz without password protection.
+
+% restore \eq@@EndQuizButtonActions from its default defn
+\efrestore\eq@@EndQuizButtonActions\from\eq@@EndQuizButtonActionsDefSave
+% restore \CorrBtnActionsJS from \CorrBtnActionsJSSave
+\efrestore\CorrBtnActionsJS\from\CorrBtnActionsJSSave
+
+\renewcommand\minQuizResp{lowThreshold}
+
+\begin{quiz*}{qz2}
+Solve each
+\begin{questions}
+ \item The sum of 1 and 1 is\dots
+\begin{answers}{5}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+\item $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}\cgBdry\CorrAnsButton{17}$
+\end{questions}
+\end{quiz*}\quad\PointsField{\currQuiz}\olBdry\CorrButton{\currQuiz}\vcgBdry
+
+\AnswerField{\currQuiz}
+
+
+\newpage
+
+\section{Another quiz with PIN to correct}
+
+It is possible to have a different PIN number for this quiz (multiple PINs in one document), but
+I see no need for this.
+
+\DeclareQuiz{qz3}
+
+
+% restore \eq@@EndQuizButtonActions from \eq@@EndQuizButtonActionsThorSave
+\efrestore\eq@@EndQuizButtonActions\from\eq@@EndQuizButtonActionsThorSave
+% restore password protection for Correct button
+\efrestore\CorrBtnActionsJS\from\CorrBtnActionsPwdJS
+
+% require students to answer all questions
+\renewcommand\minQuizResp{highThreshold}
+
+\begin{quiz*}{qz3}
+Solve each
+\begin{questions}
+ \item The sum of 1 and 1 is\dots
+\begin{answers}{5}
+\bChoices
+ \Ans0 0\eAns
+ \Ans0 1\eAns
+ \Ans1 2\eAns
+ \Ans0 3\eAns
+ \Ans0 4\eAns
+\eChoices
+\end{answers}
+\item $9+8=\RespBoxMath{17}{1}{.0001}{[0,1]}\cgBdry\CorrAnsButton{17}$
+\end{questions}
+\end{quiz*}\quad\PointsField{\currQuiz}\olBdry\CorrButton{\currQuiz} (PIN: \PIN)\vcgBdry
+
+\AnswerField{\currQuiz}
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/thorshammer/folder-js/aeb-reader.js b/macros/latex/contrib/thorshammer/folder-js/aeb-reader.js
new file mode 100644
index 0000000000..87783f86b7
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/folder-js/aeb-reader.js
@@ -0,0 +1,50 @@
+/*
+ AEB Adobe Acrobat Reader JavaScript Methods
+
+ Copyright (C) 2019 AcroTeX.Net
+ D. P. Story
+ http://www.acrotex.net
+
+ Version 1.0
+*/
+// console.println("Version 1.0 (Reader DC)");
+if ( typeof aebTrustedFunctions == "undefined") {
+ aebTrustedFunctions = app.trustedFunction( function ( doc, oFunction, oArgs )
+ {
+ app.beginPriv();
+ var retn = oFunction( oArgs, doc );
+ app.endPriv();
+ return retn;
+ });
+}
+aebSaveAs = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ app.execMenuItem("Save");
+ app.endPriv();
+});
+aebDocSaveAs = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ var Msg=function(e){return (aebDocSaveAs.msg==undefined)?("Doc SaveAs Error: " + e.toString()):aebDocSaveAs.msg;}
+ var Action=function(){return ((aebDocSaveAs.action==undefined)?null:eval(aebDocSaveAs.action));}
+ app.beginPriv();
+ try {
+ return retn = doc.saveAs(oArgs);
+ } catch(e){console.println(Msg(e));Action();}
+ app.endPriv();
+ aebDocSaveAs.msg=undefined;
+ aebDocSaveAs.action=undefined;
+});
+aebBrowseForDoc = app.trustPropagatorFunction( function ( oArgs )
+{
+ app.beginPriv();
+ return retn = app.browseForDoc(oArgs);
+ app.endPriv();
+});
+aebLaunchURL=app.trustPropagatorFunction ( function ( oArgs )
+{
+ app.beginPriv();
+ var retn = app.launchURL(oArgs);
+ app.endPriv();
+});
+
diff --git a/macros/latex/contrib/thorshammer/folder-js/aeb_pro.js b/macros/latex/contrib/thorshammer/folder-js/aeb_pro.js
new file mode 100644
index 0000000000..31c6c2fd7e
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/folder-js/aeb_pro.js
@@ -0,0 +1,158 @@
+/*
+ AEB Pro Document Assembly Methods
+
+ Copyright (C) 2012 -- 2019 AcroTeX.Net
+ D. P. Story
+ http://www.acrotex.net
+
+ Version 1.7.2
+*/
+// console.println("Version 1.7.2");
+if ( typeof aebTrustedFunctions == "undefined") {
+ aebTrustedFunctions = app.trustedFunction( function ( doc, oFunction, oArgs )
+ {
+ app.beginPriv();
+ var retn = oFunction( oArgs, doc );
+ app.endPriv();
+ return retn;
+ });
+}
+aebAddWatermarkFromFile = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return retn = doc.addWatermarkFromFile(oArgs);
+ app.endPriv();
+});
+aebImportIcon = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return retn = doc.importIcon(oArgs);
+ app.endPriv();
+});
+aebInsertPages = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ var Msg=function(e){return (aebInsertPages.msg==undefined)?("Insert Pages Error: " + e.toString()):aebInsertPages.msg;}
+ app.beginPriv();
+ try { doc.insertPages(oArgs); } catch(e) {console.println(Msg(e));}
+ app.endPriv();
+ aebInsertPages.msg=undefined;
+})
+aebAppOpenDoc = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ var Msg=function(e){return (aebAppOpenDoc.msg==undefined)?("App Open Doc Error: " + e.toString()):aebAppOpenDoc.msg;}
+ app.beginPriv();
+ try { var retn = app.openDoc(oArgs); } catch(e) {console.println(Msg(e));}
+ app.endPriv();
+ aebAppOpenDoc.msg=undefined;
+ return retn;
+})
+aebImportTextData = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return retn = doc.importTextData(oArgs);
+ app.endPriv();
+});
+aebImportSound = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return retn = doc.importSound(oArgs);
+ app.endPriv();
+});
+aebSaveAs = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ app.execMenuItem("Save");
+ app.endPriv();
+});
+// Version 1.7.2
+aebDocSaveAs = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ var Msg=function(e){return (aebDocSaveAs.msg==undefined)?("Doc SaveAs Error: " + e.toString()):aebDocSaveAs.msg;}
+ var Action=function(){return ((aebDocSaveAs.action==undefined)?null:eval(aebDocSaveAs.action));}
+ app.beginPriv();
+ try {
+ return retn = doc.saveAs(oArgs);
+ } catch(e){console.println(Msg(e));Action();}
+ app.endPriv();
+ aebDocSaveAs.msg=undefined;
+ aebDocSaveAs.action=undefined;
+});
+aebExtractPages = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return retn = doc.extractPages(oArgs);
+ app.endPriv();
+});
+aebMailDoc = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return retn = doc.mailDoc(oArgs);
+ app.endPriv();
+});
+aebImportDataObject = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ return retn = doc.importDataObject(oArgs);
+ app.endPriv();
+});
+aebSignatureSign = app.trustPropagatorFunction( function ( oArgs, field )
+{
+ app.beginPriv();
+ return retn = field.signatureSign(oArgs);
+ app.endPriv();
+});
+aebSecurityHandlerLogin = app.trustPropagatorFunction( function ( oArgs, securityHandler )
+{
+ app.beginPriv();
+ return retn = securityHandler.login(oArgs);
+ app.endPriv();
+});
+aebSecurityGetHandler = app.trustPropagatorFunction( function ( oArgs, security )
+{
+ app.beginPriv();
+ return retn = security.getHandler(oArgs);
+ app.endPriv();
+});
+aebAppGetPath = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ var retn = app.getPath(oArgs);
+ app.endPriv();
+ return retn;
+});
+aebSignatureSetSeedValue = app.trustPropagatorFunction( function ( oArgs, field )
+{
+ app.beginPriv();
+ return retn = field.signatureSetSeedValue(oArgs);
+ app.endPriv();
+});
+aebAddIcon=app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ app.beginPriv();
+ doc.addIcon(oArgs);
+ app.endPriv();
+});
+aebCreateTemplate = app.trustPropagatorFunction( function ( oArgs, doc )
+{
+ var Msg=function(e){return (aebCreateTemplate.msg==undefined)?("Create Template Error: " + e.toString()):aebCreateTemplate.msg;}
+ app.beginPriv();
+ try { doc.createTemplate(oArgs); } catch(e) {console.println(Msg(e));}
+ app.endPriv();
+ aebCreateTemplate.msg=undefined;
+
+})
+// Version 1.7.1 removed doc from arg in browse and launch
+aebBrowseForDoc=app.trustPropagatorFunction( function ( oArgs )
+{
+ app.beginPriv();
+ var retn = app.browseForDoc(oArgs);
+ app.endPriv();
+});
+// added aebLaunchURL Version 1.7
+aebLaunchURL=app.trustPropagatorFunction ( function ( oArgs )
+{
+ app.beginPriv();
+ var retn = app.launchURL(oArgs);
+ app.endPriv();
+});
+
diff --git a/macros/latex/contrib/thorshammer/system-scripts/standalone/altclasspaths.txt b/macros/latex/contrib/thorshammer/system-scripts/standalone/altclasspaths.txt
new file mode 100644
index 0000000000..679534938a
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/system-scripts/standalone/altclasspaths.txt
@@ -0,0 +1 @@
+# C:\Users\IEUser\Desktop\TestClass1
diff --git a/macros/latex/contrib/thorshammer/system-scripts/standalone/cpquizzes.ps1 b/macros/latex/contrib/thorshammer/system-scripts/standalone/cpquizzes.ps1
new file mode 100644
index 0000000000..04e5026655
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/system-scripts/standalone/cpquizzes.ps1
@@ -0,0 +1,51 @@
+# This script copies PDFs from the $startLocations to $destPath, but only
+# if in a $baseName folder
+$baseName="_Thor"
+$classPath="C:\Users\dpstory\Desktop\Test Folder\target\myClass"
+$destPath="C:\Users\dpstory\Desktop\Test Folder\target\_Thor\grade"
+# Strip-and-Trim function
+# Remove everything to the left of a comment character, then trim
+function Strip-and-Trim {
+ param([string]$str)
+ $pos=$str.IndexOf("#")
+ If($pos -ne -1) {
+ $str=$str.substring(0,$pos)
+ }
+ $str=$str.trim()
+ return $str
+}
+# vars
+$startLocations=@($classPath)
+Write-Host ""
+if(Test-Path -Path ./altclasspaths.txt) {
+ get-content ./altclasspaths.txt | %{
+ $str= Strip-and-Trim($_)
+ if($str) {
+ Write-Host "Reading alternate path: $str"
+ $startLocations+=$str
+ }
+ }
+}
+$instrDest="$PWD\fromStudents"
+#
+# script starts here
+#
+$currentPath=Convert-Path .
+foreach ($startLocation in $startLocations) {
+ Set-Location $startLocation
+ $numCopied=0
+ Write-Host "`nCopying any PDFs files from within a `"$baseName`" subfolder of `
+`"$startLocation`" to `
+`"$instrDest`""
+ Get-ChildItem -Path . -Filter "*.pdf" -Recurse |
+ Where-Object { $_.DirectoryName -match $baseName } -OutVariable fileName |
+ Copy-Item -Destination $destPath
+ if ($fileName.Name -eq $null) {Write-Host "`nNo files to copy"}
+ else {
+ Write-Host "`nReport:"
+ $numCopied=$fileName.Name.Count
+ $fileName.Name
+ }
+ Write-Host @( Get-ChildItem $PWD ).Count "folders examined, $numCopied files copied"
+ cd $currentPath
+}
diff --git a/macros/latex/contrib/thorshammer/system-scripts/standalone/mkcfg.ps1 b/macros/latex/contrib/thorshammer/system-scripts/standalone/mkcfg.ps1
new file mode 100644
index 0000000000..53d6794689
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/system-scripts/standalone/mkcfg.ps1
@@ -0,0 +1,71 @@
+# Make a complete cfg for thorshammer package from a csv list
+# accepted list delimiters: , or ;. Spaces ar not allowed! Replace all german umlauts
+# with ue, oe, ae, ss to avoid problems with thorshammer package
+#
+$classPath="C:\Users\dpstory\Desktop\Test Folder\target\myClass"
+$instrPath="C:\Users\dpstory\Desktop\Test Folder\target\_Thor"
+# Example list:
+# First Name|Last Name|Folder
+# Anton;Müller;AM29914M
+#\classMember{Anton}{Mueller}{AM299/instructor-name}
+# Anton;Müller;*C:/.../AM299
+#\classMember{Anton}{Mueller}*{C:/.../AM299/instructor-name}
+#
+If ( $args.Length -eq 0 ) {
+ Write-Host "A CSV file of the class members is required," `
+ "see documentation"
+ exit
+} else {
+ $listName=$args[0]
+ if(Test-Path -Path ./$listName.csv) {
+ } else {
+ Write-Host "Cannot find the file `"$listName.csv`" in the current folder," `
+ "check the spelling, do not include the extension."
+ exit
+ }
+}
+get-content "$listName.csv" | foreach {
+"\classMember{" + $_ `
++ "/_Thor}" `
+-Replace ";", "}{" `
+-Replace ",","}{" `
+-Replace "{\*", "*{" } | Set-Content "convertedList.cfg"
+
+# Store convertedList.cfg in a variable
+$convertedListCfg = get-content .\convertedList.cfg -Raw
+
+# function to replace umlauts
+# https://www.datenteiler.de/powershell-umlaute-ersetzen/
+function Replace-Umlaute ([string]$s) {
+ $UmlautObject = New-Object PSObject | Add-Member -MemberType NoteProperty -Name Name -Value $s -PassThru
+
+ # hash tables are by default case insensitive
+ # we have to create a new hash table object for case sensitivity
+
+ $characterMap = New-Object system.collections.hashtable
+ $characterMap.ä = "ae"
+ $characterMap.ö = "oe"
+ $characterMap.ü = "ue"
+ $characterMap.ß = "ss"
+ $characterMap.Ä = "Ae"
+ $characterMap.Ü = "Ue"
+ $characterMap.Ö = "Oe"
+
+ foreach ($property in "Name") {
+ foreach ($key in $characterMap.Keys) {
+ $UmlautObject.$property = $UmlautObject.$property -creplace $key,$characterMap[$key]
+ }
+ }
+ $UmlautObject
+}
+
+# replace umlauts in .cfg and make a correctedListCfg
+$correctedListCfg = Replace-Umlaute "$convertedListCfg"
+$correctedListCfg.Name
+
+# Finally append correctedListCfg to desired
+# cfg file, usually 00-class.cfg
+add-content "00-class.cfg" "\classPath{$classPath)"
+add-content "00-class.cfg" "\instrPath{$instrPath}"
+add-content "00-class.cfg" $correctedListCfg.Name
+Remove-Item convertedList.cfg
diff --git a/macros/latex/contrib/thorshammer/system-scripts/standalone/mkfolders.ps1 b/macros/latex/contrib/thorshammer/system-scripts/standalone/mkfolders.ps1
new file mode 100644
index 0000000000..7f7fcc3ef6
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/system-scripts/standalone/mkfolders.ps1
@@ -0,0 +1,60 @@
+$classPath="C:\Users\dpstory\Desktop\Test Folder\target\myClass"
+# Create class folders
+If ( $args.Length -eq 0 ) {
+ Write-Host "A CVS file of the class members is required," `
+ "see documentation"
+ exit
+} else {
+ $listName=$args[0]
+ if(Test-Path -Path ./$listName.csv) {
+ } else {
+ Write-Host "Cannot find the file `"$listName.csv`" in the current folder," `
+ "check the spelling, do not include the extension."
+ exit
+ }
+}
+get-content "$listName.csv" | foreach {
+$_ +">_Thor" -Replace ";","," } | Set-Content "commaList.csv"
+
+$argList=@()
+get-content "commaList.csv" | %{
+# Write-Host "$_"
+ $split=$_.split(",")
+# Write-Host $split[2]
+ $argList+=$split[2]
+}
+$currentPath=Convert-Path .
+cd $classPath
+Write-Host "Creating folder structure at `$classPath`"," `
+ "with some exceptions"
+for ($i=0; $i -lt $argList.length; $i++) {
+ $arg=$argList[$i]
+ $splitTwo=$argList[$i].split(">")
+ $firstName=$splitTwo[0]
+ $secondName=$splitTwo[1]
+ if ($firstName[0] -eq "*") {
+ $arg=$arg.substring(1)
+ $msg="Parsing the full path $arg" -Replace ">","/"
+ Write-Host $msg
+ Write-Host "Creating exceptional folders"
+ $firstName=$firstName.substring(1)
+#Write-Host "$firstName"
+ Write-Host " Creating folder: $firstName"
+ New-Item $firstName -ErrorAction:Ignore -ItemType directory
+ $secondName=$firstName+"/$secondName"
+#Write-Host "$secondName"
+ Write-Host " Creating folder: $secondName"
+ New-Item $secondName -ErrorAction:Ignore -ItemType directory
+ } else {
+ $msg="Parsing the relative path $arg" -Replace ">","/"
+ Write-Host $msg
+ Write-Host " Creating folder: $firstName"
+ New-Item $firstName -ErrorAction:Ignore -ItemType directory
+ cd $firstName
+ Write-Host " Creating subfolder of $firstName named: $secondName"
+ New-Item $secondName -ErrorAction:Ignore -ItemType directory
+ cd ..
+ }
+}
+cd $currentPath
+Remove-Item commaList.csv
diff --git a/macros/latex/contrib/thorshammer/system-scripts/standalone/rmquizzes.ps1 b/macros/latex/contrib/thorshammer/system-scripts/standalone/rmquizzes.ps1
new file mode 100644
index 0000000000..02b3534143
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/system-scripts/standalone/rmquizzes.ps1
@@ -0,0 +1,51 @@
+# Get-ExecutionPolicy
+# Set-ExecutionPolicy RemoteSigned
+# This script removes (deletes) PDFs from the $startLocation, but only if in a $baseName folder
+$baseName="_Thor"
+$classPath="C:\Users\dpstory\Desktop\Test Folder\target\myClass"
+#
+# Strip-and-Trim function
+# Remove everything to the left of a comment character, then trim
+function Strip-and-Trim {
+ param([string]$str)
+ $pos=$str.IndexOf("#")
+ If($pos -ne -1) {
+ $str=$str.substring(0,$pos)
+ }
+ $str=$str.trim()
+ return $str
+}
+# vars
+$startLocations=@($classPath)
+Write-Host ""
+if(Test-Path -Path ./altclasspaths.txt) {
+ get-content ./altclasspaths.txt | %{
+ $str= Strip-and-Trim($_)
+ if($str) {
+ Write-Host "Reading alternate path: $str"
+ $startLocations+=$str
+ }
+ }
+}
+$instrDest="$PWD\fromStudents"
+#
+# script starts here
+#
+$currentPath=Convert-Path .
+foreach ($startLocation in $startLocations) {
+ Set-Location $startLocation
+ $numDel=0
+ Write-Host "`nDeleting the following PDFs files from within a `"$baseName`" subfolder of `
+`"$startLocation`""
+ Get-ChildItem -Path . -Filter "*.pdf" -Recurse |
+ Where-Object { $_.DirectoryName -match $baseName } -OutVariable fileName |
+ Remove-Item
+ if ($fileName.Name -eq $null) {Write-Host "`nNo files to delete"}
+ else {
+ Write-Host "`nReport: deleting files,"
+ $numDel=$fileName.Name.Count
+ $fileName.Name
+ }
+ Write-Host @( Get-ChildItem $PWD ).Count "folders examined, $numDel files deleted"
+ cd $currentPath
+}
diff --git a/macros/latex/contrib/thorshammer/system-scripts/standalone/runps1.bat b/macros/latex/contrib/thorshammer/system-scripts/standalone/runps1.bat
new file mode 100644
index 0000000000..5960b5ba7c
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/system-scripts/standalone/runps1.bat
@@ -0,0 +1,2 @@
+rem echo "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
+PowerShell.exe -ExecutionPolicy Bypass -Command "& './%1' %2"
diff --git a/macros/latex/contrib/thorshammer/system-scripts/standalone/sample-list.csv b/macros/latex/contrib/thorshammer/system-scripts/standalone/sample-list.csv
new file mode 100644
index 0000000000..0f97aa0a68
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/system-scripts/standalone/sample-list.csv
@@ -0,0 +1,3 @@
+Mühle;Wäter;MW634B
+Anton,Müller,AM256M
+Laura,Vögt,LM356B
diff --git a/macros/latex/contrib/thorshammer/system-scripts/thors-structure/runps1.bat b/macros/latex/contrib/thorshammer/system-scripts/thors-structure/runps1.bat
new file mode 100644
index 0000000000..5960b5ba7c
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/system-scripts/thors-structure/runps1.bat
@@ -0,0 +1,2 @@
+rem echo "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
+PowerShell.exe -ExecutionPolicy Bypass -Command "& './%1' %2"
diff --git a/macros/latex/contrib/thorshammer/system-scripts/thors-structure/sample-vars.txt b/macros/latex/contrib/thorshammer/system-scripts/thors-structure/sample-vars.txt
new file mode 100644
index 0000000000..6b5a2922ab
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/system-scripts/thors-structure/sample-vars.txt
@@ -0,0 +1,8 @@
+alg1 # class
+1 # number
+maths # subject
+factoring # theme
+THOR # instrName
+01.01.2019 # date
+60 Min. # time
+C:/temp # classPath
diff --git a/macros/latex/contrib/thorshammer/system-scripts/thors-structure/thmclass.ps1 b/macros/latex/contrib/thorshammer/system-scripts/thors-structure/thmclass.ps1
new file mode 100644
index 0000000000..2dcbc65c25
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/system-scripts/thors-structure/thmclass.ps1
@@ -0,0 +1,713 @@
+# Version 1.3 changes
+# =====================================================================================================
+# copyka.ps1 allows a comment character (#)
+# delka.ps1 allows a comment character (#)
+# =====================================================================================================
+# Version 1.2 changes
+# =====================================================================================================
+# removed moveka.ps1
+# removed old version comments
+# added template for altclasspath
+# removed .ps1 from BAT helper file, that way one can easiear hit TAB for autocompletion in comamnd shell
+# OPEN line 92: copyka.ps1 --> lines starting with # are *not* ignored at least here
+# Workaround does not help: (get-content ./altclasspaths.txt) -notmatch '^#' WHY?
+
+# =====================================================================================================
+#
+# This script makes a custom class folder for thorshammer with
+# needed folders, adjusted path settings and templates for tex, cfg etc.
+#
+# Set path for thorshammer (local texmf dir} for Windows/Linux
+# This has to be done only once
+$pathThorshammerWin="C:\Users\$env:UserName\texmf\tex\latex\thorshammer" # Windows
+$pathThorshammerWin="C:\Users\Public\Documents\My TeX Files\tex\latex\aeb\thorshammer"
+$pathThorshammerLin="/home/manjothor/texmf/tex/latex/thorshammer" # Linux
+
+# Store the system locale in a var. We need them later in the script for localization
+$locale = Get-UICulture
+$myLocale = "de"
+
+# Remove everything to the left of a comment character, then trim
+function Strip-and-Trim {
+ param([string]$str)
+ $pos=$str.IndexOf("#")
+ If($pos -ne -1) {
+ $str=$str.substring(0,$pos)
+ }
+ $str=$str.trim()
+ return $str
+}
+Write-Host "There are" $args.Length "arguments";
+$argList=@()
+$listOfEight=$args[0]
+if(Test-Path -Path ./$listOfEight) {
+ get-content $args[0] | %{
+ Write-Host "Line: $_"
+ $argList+=$_
+ }
+ $class = Strip-and-Trim($argList[0])
+ $number = Strip-and-Trim($argList[1])
+ $subject = Strip-and-Trim($argList[2])
+ $theme = Strip-and-Trim($argList[3])
+ $instrName = Strip-and-Trim($argList[4])
+ $date = Strip-and-Trim($argList[5])
+ $time = Strip-and-Trim($argList[6])
+ $classPath= Strip-and-Trim($argList[7])
+
+# Remove whitespace in $class and $instrName because we don't need whitespace
+# in this two vars.
+ $class = $class.replace(' ','')
+ $instrName = $instrName.replace(' ','')
+
+############
+# folders #
+############
+ New-Item $class -ItemType directory
+ cd $class
+ New-Item $instrName -ItemType directory
+ Set-Location "$instrName"
+ New-Item backup -ItemType directory
+ If ($locale -like "*$myLocale*") {
+ New-Item vonSUS -ItemType directory
+ New-Item anSUS -ItemType directory
+ } else {
+ New-Item fromStudents -ItemType directory
+ New-Item toStudents -ItemType directory
+ }
+} else {
+ Write-Host "The file" $listOfEight "cannot be found in the current folder," `
+"check the spelling, include the extension."
+ exit
+}
+
+##############
+# copyscript #
+##############
+# Version 1.3
+New-Item copyka.ps1 -ItemType file
+Set-Content ./copyka.ps1 '# Get-ExecutionPolicy
+# Set-ExecutionPolicy RemoteSigned
+# This script copies PDFs from the $startLocation to $instrDest, but only
+# if in a $instrName folder
+#
+# Strip-and-Trim function
+# Remove everything to the left of a comment character, then trim
+function Strip-and-Trim {
+ param([string]$str)
+ $pos=$str.IndexOf("#")
+ If($pos -ne -1) {
+ $str=$str.substring(0,$pos)
+ }
+ $str=$str.trim()
+ return $str
+}
+# vars
+$instrName="#instrName"
+$startLocations=@("#classPath")
+Write-Host ""
+if(Test-Path -Path ./altclasspaths.txt) {
+ get-content ./altclasspaths.txt | %{
+ $str= Strip-and-Trim($_)
+ if($str) {
+ Write-Host "Reading alternate path: $str"
+ $startLocations+=$str
+ }
+ }
+}
+$instrDest="$PWD\#from"
+#
+# script starts here
+#
+$currentPath=Convert-Path .
+foreach ($startLocation in $startLocations) {
+ Set-Location $startLocation
+ $numCopied=0
+ Write-Host "`nCopying any PDFs files from within a `"$instrName`" subfolder of `
+`"$startLocation`" to `
+`"$instrDest`""
+ Get-ChildItem -Path . -Filter "*.pdf" -Recurse |
+ Where-Object { $_.DirectoryName -match $instrName } -OutVariable fileName |
+ Copy-Item -Destination $instrDest
+ if ($fileName.Name -eq $null) {Write-Host "`nNo files to copy"}
+ else {
+ Write-Host "`nReport:"
+ $numCopied=$fileName.Name.Count
+ $fileName.Name
+ }
+ Write-Host @( Get-ChildItem $PWD ).Count "folders examined, $numCopied files copied"
+ cd $currentPath
+}'
+# replace markers with content of vars: #instrName, #classPath
+(Get-Content -Path .\copyka.ps1) | ForEach-Object {
+ $_ -Replace '#instrName', $instrName `
+ -Replace '#classPath', $classPath } | Set-Content -Path .\copyka.ps1 -encoding UTF8
+
+If ($locale -like "*$myLocale*") {
+ (Get-Content -Path .\copyka.ps1) | ForEach-Object {
+ $_ -Replace '#from', 'vonSUS' } | Set-Content -Path .\copyka.ps1 -encoding UTF8
+} else {
+ (Get-Content -Path .\copyka.ps1) | ForEach-Object {
+ $_ -Replace '#from', 'fromStudents' } | Set-Content -Path .\copyka.ps1 -encoding UTF8
+}
+
+#################
+# delete script #
+#################
+# Version 1.3
+Set-Content ./delka.ps1 '# Get-ExecutionPolicy
+# Set-ExecutionPolicy RemoteSigned
+# This script removes (deletes) PDFs from the $startLocation, but only if in a $instrName folder
+#
+# Strip-and-Trim function
+# Remove everything to the left of a comment character, then trim
+function Strip-and-Trim {
+ param([string]$str)
+ $pos=$str.IndexOf("#")
+ If($pos -ne -1) {
+ $str=$str.substring(0,$pos)
+ }
+ $str=$str.trim()
+ return $str
+}# vars
+#
+$instrName="#instrName"
+$startLocations=@("#classPath")
+Write-Host ""
+if(Test-Path -Path ./altclasspaths.txt) {
+ get-content ./altclasspaths.txt | %{
+ $str= Strip-and-Trim($_)
+ if($str) {
+ Write-Host "Reading alternate path: $str"
+ $startLocations+=$str
+ }
+ }
+}
+$instrDest="$PWD\#from"
+#
+# script starts here
+#
+$currentPath=Convert-Path .
+foreach ($startLocation in $startLocations) {
+ Set-Location $startLocation
+ $numDel=0
+ Write-Host "`nDeleting the following PDFs files from within a `"$instrName`" subfolder of `
+`"$startLocation`""
+ Get-ChildItem -Path . -Filter "*.pdf" -Recurse |
+ Where-Object { $_.DirectoryName -match $instrName } -OutVariable fileName |
+ Remove-Item
+ if ($fileName.Name -eq $null) {Write-Host "`nNo files to delete"}
+ else {
+ Write-Host "`nReport: deleting files,"
+ $numDel=$fileName.Name.Count
+ $fileName.Name
+ }
+ Write-Host @( Get-ChildItem $PWD ).Count "folders examined, $numDel files deleted"
+ cd $currentPath
+}'
+# replace markers with content of vars: #instrName, #classPath
+(Get-Content -Path .\delka.ps1) | ForEach-Object {
+ $_ -Replace '#instrName', $instrName `
+ -Replace '#classPath', $classPath } | Set-Content -Path .\delka.ps1 -encoding UTF8
+
+If ($locale -like "*$myLocale*") {
+ (Get-Content -Path .\delka.ps1) | ForEach-Object {
+ $_ -Replace '#from', 'vonSUS' } | Set-Content -Path .\delka.ps1 -encoding UTF8
+} else {
+ (Get-Content -Path .\delka.ps1) | ForEach-Object {
+ $_ -Replace '#from', 'fromStudents' } | Set-Content -Path .\delka.ps1 -encoding UTF8
+}
+
+##Begin Version 1.2
+##########################
+# altclasspaths template #
+##########################
+Set-Content ./altclasspaths.txt -encoding UTF8 '# C:\Users\IEUser\Desktop\TestClass1'
+
+##End Version 1.2
+
+#############################
+# csv to cfg convert script #
+#############################
+Set-Content ./csvTOcfg.ps1 '# Make a complete cfg for thorshammer package from a csv list
+# accepted list delimiters: , or ;. Spaces ar not allowed! Replace all german umlauts
+# with ue, oe, ae, ss to avoid problems with thorshammer package
+#
+# Example list:
+# First Name|Last Name|Folder
+# Anton;Müller;AM29914M
+#\classMember{Anton}{Mueller}{AM299/instructor-name}
+# Anton;Müller;*C:/.../AM299
+#\classMember{Anton}{Mueller}*{C:/.../AM299/instructor-name}
+#
+If ( $args.Length -eq 0 ) {
+ Write-Host "A CSV file of the class members is required," `
+ "see documentation"
+ exit
+} else {
+ $listName=$args[0]
+ if(Test-Path -Path ./$listName.csv) {
+ } else {
+ Write-Host "Cannot find the file `"$listName.csv`" in the current folder," `
+ "check the spelling, do not include the extension."
+ exit
+ }
+}'
+######################
+# Script starts here #
+######################'
+# Now append the script itself, this way we have to maintain only one script
+# Remark: we must escape $ and ` with `$ and ``
+Add-Content ./csvTOcfg.ps1 @"
+get-content "`$listName.csv" | foreach {
+"\classMember{" + `$_ ``
++ "/`#instrName}" ``
+-Replace ";", "}{" ``
+-Replace ",","}{" ``
+-Replace "{\*", "*{" } | Set-Content "convertedList.cfg"
+
+# Store convertedList.cfg in a variable
+`$convertedListCfg = get-content .\convertedList.cfg -Raw
+
+# function to replace umlauts
+# https://www.datenteiler.de/powershell-umlaute-ersetzen/
+function Replace-Umlaute ([string]`$s) {
+ `$UmlautObject = New-Object PSObject | Add-Member -MemberType NoteProperty -Name Name -Value `$s -PassThru
+
+ # hash tables are by default case insensitive
+ # we have to create a new hash table object for case sensitivity
+
+ `$characterMap = New-Object system.collections.hashtable
+ `$characterMap.ä = "ae"
+ `$characterMap.ö = "oe"
+ `$characterMap.ü = "ue"
+ `$characterMap.ß = "ss"
+ `$characterMap.Ä = "Ae"
+ `$characterMap.Ü = "Ue"
+ `$characterMap.Ö = "Oe"
+
+ foreach (`$property in "Name") {
+ foreach (`$key in `$characterMap.Keys) {
+ `$UmlautObject.`$property = `$UmlautObject.`$property -creplace `$key,`$characterMap[`$key]
+ }
+ }
+ `$UmlautObject
+}
+
+# replace umlauts in $convertedList.cfg and make a correctedListCfg
+`$correctedListCfg = Replace-Umlaute "`$convertedListCfg"
+`$correctedListCfg.Name
+
+# Finally append correctedListCfg to desired
+# cfg file, usually $class.cfg
+add-content "..\`#class" `$correctedListCfg.Name
+Remove-Item convertedList.cfg
+"@
+
+# Set correct class name
+(Get-Content "csvTOcfg.ps1") | ForEach-Object {
+ $_ -Replace '#class', "00-$class.cfg" `
+ -Replace '#instrName', $instrName } | Set-Content "csvTOcfg.ps1" -encoding UTF8
+
+######################
+# General helper BAT #
+######################
+New-Item "runps1.bat" -ItemType file
+Set-Content "runps1.bat" `
+'rem echo "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
+PowerShell.exe -ExecutionPolicy Bypass -Command "& ''./%1'' %2"' ##Begin Version 1.2
+
+##################
+# class folders #
+##################
+New-Item classFolders.ps1 -ItemType file
+Set-Content ./classFolders.ps1 '# Create class folders
+If ( $args.Length -eq 0 ) {
+ Write-Host "A CVS file of the class members is required," `
+ "see documentation"
+ exit
+} else {
+ $listName=$args[0]
+ if(Test-Path -Path ./$listName.csv) {
+ } else {
+ Write-Host "Cannot find the file `"$listName.csv`" in the current folder," `
+ "check the spelling, do not include the extension."
+ exit
+ }
+}
+get-content "$listName.csv" | foreach {
+$_ +">#instrName" -Replace ";","," } | Set-Content "commaList.csv"
+
+$argList=@()
+get-content "commaList.csv" | %{
+# Write-Host "$_"
+ $split=$_.split(",")
+# Write-Host $split[2]
+ $argList+=$split[2]
+}
+$currentPath=Convert-Path .
+cd "#classPath"
+Write-Host "Creating folder structure at `"#classPath`"," `
+ "with some exceptions"
+for ($i=0; $i -lt $argList.length; $i++) {
+ $arg=$argList[$i]
+ $splitTwo=$argList[$i].split(">")
+ $firstName=$splitTwo[0]
+ $secondName=$splitTwo[1]
+ if ($firstName[0] -eq "*") {
+ $arg=$arg.substring(1)
+ $msg="Parsing the full path $arg" -Replace ">","/"
+ Write-Host $msg
+ Write-Host "Creating exceptional folders"
+ $firstName=$firstName.substring(1)
+#Write-Host "$firstName"
+ Write-Host " Creating folder: $firstName"
+ New-Item $firstName -ErrorAction:Ignore -ItemType directory
+ $secondName=$firstName+"/$secondName"
+#Write-Host "$secondName"
+ Write-Host " Creating folder: $secondName"
+ New-Item $secondName -ErrorAction:Ignore -ItemType directory
+ } else {
+ $msg="Parsing the relative path $arg" -Replace ">","/"
+ Write-Host $msg
+ Write-Host " Creating folder: $firstName"
+ New-Item $firstName -ErrorAction:Ignore -ItemType directory
+ cd $firstName
+ Write-Host " Creating subfolder of $firstName named: $secondName"
+ New-Item $secondName -ErrorAction:Ignore -ItemType directory
+ cd ..
+ }
+}
+cd $currentPath
+Remove-Item commaList.csv'
+#
+# replace markers with content of vars: #instrName, #classPath
+(Get-Content -Path .\classFolders.ps1) | ForEach-Object {
+ $_ -Replace "#instrName", $instrName `
+ -Replace "#classPath", $classPath } | Set-Content -Path .\classFolders.ps1
+
+############################
+# Sample csv file #
+############################
+New-Item sample-list.csv -ItemType file
+Set-Content ./sample-list.csv `
+'Mühle;Wäter;MW634B
+Anton,Müller,AM256M
+Laura,Vögt,LM356B'
+
+###########################################
+# copy container.pdf, terminate-batch.pdf #
+###########################################
+If (Test-Path $pathThorshammerWin) {
+ Copy-Item "$pathThorshammerWin\container.pdf" -Destination "$PWD"
+ Copy-Item "$pathThorshammerWin\terminate-batch.pdf" -Destination "$PWD"
+}
+If (Test-Path $pathThorshammerLin){
+Copy-Item "$pathThorshammerLin/container.pdf" -Destination "$PWD"
+Copy-Item "$pathThorshammerLin/terminate-batch.pdf" -Destination "$PWD"
+}
+
+################
+# tex template #
+################
+cd ..
+New-Item "tex-template.tex" -ItemType file
+
+If ($locale -like "*$myLocale*") {
+# German ######################################
+Set-Content "tex-template.tex" '%% Customize template ! %%
+\documentclass[fontsize=11pt]{scrartcl}
+\usepackage[%
+german,
+pro,
+usesf,
+navibar,
+forcolorpaper
+%forpaper
+]{web}
+\usepackage[top=20mm,left=20mm,right=20mm,bottom=25mm]{geometry}
+\usepackage[usesumrytbls,allowrandomize]{exerquiz}
+\usepackage{ran_toks}
+\usepackage[%
+% usebatch % copy to class folder
+batchdistr % only copy to instructors folder
+% testmode % testing quizzes
+]{thorshammer}
+\hypersetup{pdfencoding=auto} % include or remove hyperref options
+%\usepackage{thorshammerConf} % place your own sty file here
+\usepackage[autostyle=true]{csquotes} % change quotes globally
+
+\DeclareQuiz{q#number}
+\setInitMag{fitwidth}
+\hypersetup{pdfpagelayout=OneColumn}
+\reversemarginpar
+% It is important to freeze the seed to that (1) you can reproduce the exact
+% same quiz at a later time; (2) allow content written to the AUX file to
+% come up to date. This is important when using summary tables.
+\useThisSeed{1344524586}
+
+% Class Path
+\InputClassData{00-#class}
+\autoCopyOn
+% \autoCopyOff
+
+% Cover pages
+%\DeclareCoverPage{0}
+
+% Header settings
+\thQzName{#theme} % Thema
+\thQzHeaderL{#class} % Klasse
+\thQzHeaderCQ{#subject: \thqzname}
+\thQzHeaderCS{Lösungen: \thqzname}
+
+% Title
+\title{#class}
+\subject{#subject}
+\author{#instrName}
+\keywords{#time}
+\university{Freiherr-vom-Stein-Berufskolleg} % change to your institution
+\version{#number}
+\copyrightyears{#date}
+
+% input web.cfg (again) to declare or define commands
+\inputWebCfg
+
+\begin{makeClassFiles}
+\sadMultQuizzes
+\end{makeClassFiles}
+
+\begin{document}
+\makeinlinetitle
+% Instructions
+
+% Declare Quiz bodys
+\declareQuizBody{qzbody1}
+%\declareQuizBody{qzbody2}
+%\declareQuizBody{qzbody3}
+%\declareQuizBody{qzbody4}
+
+\begin{qzbody1}
+\bRTVToks{\currQuiz}
+% Change margin settings for summary tables, and set it back after
+% \thQuizHeader execution
+\newgeometry{top=20mm,left=30mm,right=20mm,bottom=25mm}
+\thQuizHeader
+\newgeometry{top=20mm,left=20mm,right=20mm,bottom=25mm}
+
+\begin{quiz*}{\currQuiz}
+% Bearbeiten Sie folgende Aufgaben.
+\begin{questions}
+\begin{rtVW}
+\section{myTitle}
+\item\PTs{2} my question text
+
+\end{rtVW}
+
+%% Change nothing here %%
+\eRTVToks\displayListRandomly{\thisQuiz}
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+\end{qzbody1}
+% Randomize questions Now we input the qzbody back in two times, though it can
+% be more than that. The quiz name modified in each instance. Each instance of
+% the quiz has a randomized order
+%
+\InputQuizBody{qzbody1}
+%\InputQuizBody{qzbody1}
+%\InputQuizBody{qzbody1}
+%\InputQuizBody{qzbody2}
+\end{document}'
+###########################################
+} else {
+# English #################################
+Set-Content "tex-template.tex" '%% Customize template ! %%
+\documentclass{article}
+\usepackage{amstext}
+\usepackage{web}
+\usepackage[usesumrytbls,allowrandomize]{exerquiz}
+\usepackage{ran_toks}
+\usepackage[usebatch]{thorshammer}
+
+\DeclareQuiz{q#number}
+
+% It is important to freeze the seed to that (1) you can reproduce the exact
+% same quiz at a later time; (2) allow content written to the AUX file to
+% come up to date. This is important when using summary tables.
+\useThisSeed{1344524586}
+
+\setInitMag{fitwidth}
+\hypersetup{pdfencoding=auto}
+\reversemarginpar
+
+\showCreditMarkup
+
+\useBeginQuizButton[\CA{Begin}]
+\useEndQuizButton[\CA{End}]
+\PTsHook{($\eqPTs^{\text{pts}}$)}
+\useMCCircles
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% For headers, title and other fine grained settings %
+% refer to the thorshammer doku! %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% Class Path
+\InputClassData{00-#class}
+\autoCopyOn
+% \autoCopyOff
+
+% Cover pages
+%\DeclareCoverPage{0}
+
+% Header settings
+\thQzName{#theme} % topic
+\thQzHeaderL{#class} % class
+\thQzHeaderCQ{#subject: \thqzname}
+\thQzHeaderCS{Solutions: \thqzname}
+
+% Title
+\title{#class}
+\subject{#subject}
+\author{#instrName}
+\keywords{#time}
+\university{AcroTeX.edu} % change to your institution
+\version{#number}
+\copyrightyears{#date}
+
+% input web.cfg (again) to declare or define commands
+\inputWebCfg
+
+\begin{makeClassFiles}
+\sadMultQuizzes
+\end{makeClassFiles}
+
+\begin{document}
+\declareQuizBody{qzbody1}
+\begin{qzbody1}
+
+\bRTVToks{\currQuiz}
+
+\thQuizHeader
+
+% Instructions
+\begin{quiz*}{\currQuiz}
+Solve each of these problems, passing is 100\%.
+\begin{questions}
+\begin{rtVW}
+ \item\PTs{3} Answer the question...
+
+\end{rtVW}
+%% Change nothing here %%
+\eRTVToks
+\displayListRandomly{\thisQuiz}
+\end{questions}
+\writeProListAux
+\end{quiz*}\quad\thQuizTrailer
+\end{qzbody1}
+% Randomize questions Now we input the qzbody back in two times, though it can
+% be more than that. The quiz name modified in each instance. Each instance of
+% the quiz has a randomized order
+%
+\InputQuizBody{qzbody1}
+%\InputQuizBody{qzbody1}
+%\InputQuizBody{qzbody1}
+%\InputQuizBody{qzbody2}
+\end{document}'
+}
+
+###################################
+# Generate TEX file from template #
+###################################
+New-Item "genquiz.ps1" -ItemType file
+Set-Content "genquiz.ps1" `
+'# Remove everything to the left of a comment character, then trim
+function Strip-and-Trim {
+ param([string]$str)
+ $pos=$str.IndexOf("#")
+ If($pos -ne -1) {
+ $str=$str.substring(0,$pos)
+ }
+ $str=$str.trim()
+ return $str
+}
+$argList=@()
+get-content ../#varsList | %{
+ Write-Host "Line: $_"
+ $argList+=$_
+ }
+$class = Strip-and-Trim($argList[0])
+$number = Strip-and-Trim($argList[1])
+$subject = Strip-and-Trim($argList[2])
+$theme = Strip-and-Trim($argList[3])
+$instrName = Strip-and-Trim($argList[4])
+$date = Strip-and-Trim($argList[5])
+$time = Strip-and-Trim($argList[6])
+$classPath= Strip-and-Trim($argList[7])
+
+$templateName="$number-$class-$subject.tex"
+Copy-Item ./tex-template.tex ./$templateName
+
+# replace markers with vars
+(Get-Content $templateName) | ForEach-Object {
+ $_ -Replace ''#instrName'', $instrName `
+ -Replace ''#class'', $class `
+ -Replace ''#time'', $time `
+ -Replace ''#number'', $number `
+ -Replace ''#theme'', $theme `
+ -Replace ''#subject'', $subject `
+ -Replace ''#date'', $date } | Set-Content $templateName -encoding UTF8`
+# Remove whitespace and umlauts from file name
+Get-ChildItem *.tex | Rename-Item -NewName {
+ $_.Name -replace '' '',''-'' `
+ -replace ''ä'',''ae'' `
+ -replace ''ö'',''oe'' `
+ -replace ''ü'',''ue'' `
+ -replace ''ß'',''ss'' }'
+(Get-Content "genQuiz.ps1") | ForEach-Object {
+ $_ -Replace '#varsList', $listOfEight } | Set-Content "genQuiz.ps1"
+# Remove whitespace from tex template file
+Get-ChildItem *.tex | Rename-Item -NewName { $_.Name -replace ' ','-' }
+
+######################
+# General helper BAT #
+######################
+New-Item "runps1.bat" -ItemType file
+Set-Content "runps1.bat" `
+'rem echo "%0" %1 %2 %3 %4 %5 %6 %7 %8 %9
+PowerShell.exe -ExecutionPolicy Bypass -Command "& ''./%1'' %2"' ##Begin Version 1.2
+
+####################
+# web.cfg template #
+####################
+New-Item "web.cfg" -ItemType file
+Set-Content "web.cfg" `
+'%
+% AeB Web Configuration file
+%
+\ExecuteOptions{dvips}
+\bWebCustomize
+% Insert redefinitions between these two marks
+\eWebCustomize'
+
+################
+# cfg template #
+################
+New-Item "00-$class.cfg" -ItemType file
+Set-Content "00-$class.cfg" '%reset the paths for \instrPath and \classPath for your system
+% Use relative (*!) paths here for instructor according to dir, where tex file is located
+\classPath{/#class}
+\instrPath*{#instrName/backup}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Syntax:
+% \classMember{firstname}{lastname}{rel-path}
+% \classMember{firstname}{lastname}*{full-path}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%'
+
+# replace markers with content of vars
+$pattern = "\\"
+$classPath = $classPath -replace $pattern, "/"
+(Get-Content "00-$class.cfg") | ForEach-Object {
+ $_ -Replace '#instrName', $instrName `
+ -Replace '#class', $classPath `
+ -Replace ':', '' } | Set-Content "00-$class.cfg" -encoding UTF8
+cd ..
diff --git a/macros/latex/contrib/thorshammer/terminate-batch.pdf b/macros/latex/contrib/thorshammer/terminate-batch.pdf
new file mode 100644
index 0000000000..61f4e3771c
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/terminate-batch.pdf
Binary files differ
diff --git a/macros/latex/contrib/thorshammer/thorshammer.cfg b/macros/latex/contrib/thorshammer/thorshammer.cfg
new file mode 100644
index 0000000000..2b59b36022
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/thorshammer.cfg
@@ -0,0 +1,52 @@
+%
+% Configuration file for Thor's Hammer
+%
+\pwdInstrFldTU{Enter password to mark this quiz}
+\markQzFldCA{Mark It}
+\markQzFldTU{Press to mark this quiz}
+\freezeQuizFldTU{Make all fields readonly, cannot be undone}
+\freezeQuizFldCA{Freeze Quiz}
+\essayQFldTU{Assign points to extended responses}
+\completeMsgFldV{Congratulations, you have completed the quiz,
+ before doing anything else, you need to save this document.}
+\ShrtPtsFldFmt{"Short Pts: "+event.value}
+\LngPtsFldFmt{"Long Pts: "+event.value}
+\TotalsFldFmt{"Total: "+event.value+" \eqOutOf "%
++NPointTotal}
+\NoNumEnteredMsg{"You did not enter a number, enter a nonnegative number only"}
+\TooMuchCreditMsg{"You've assigned too much credit for this problem, assigning the maximum instead"}
+% caption and tool tip for \stuSaveBtn
+\stuSaveBtnCA{Save}
+\stuSaveBtnTU{Press to save and close the document}
+% verify ending the quiz
+\EndQzWarningMsg{"When you end the quiz, you cannot change
+any of your answers without starting the quiz over from the
+beginning.\n\n
+Press \\"Yes\\" to end the quiz."}
+\ThorsAlertTitle{"Thor's Hammer"}
+% beginning of quiz warning if no name fields
+\InitQzMsg{"You cannot begin the quiz before entering
+ your first and last names in the fields provided.\n\n
+ Enter the name as you are known in the class; otherwise,
+ you will receive no credit for your work."}
+%
+\instrSaveFldTU{Save and close this file to the current folder}
+\instrSaveFldCA{Save \string& Close}
+%
+% Other definitions
+%
+\thQHFirstName{First name:}
+\thQHLastName{Last name:}
+\thQHPoints{Points:}
+\thQHGrade{Grade:}
+\MarkWarningMsg{"You did not award the student a final mark.\
+ \\n\\nAward the mark and then save."}
+% Second save warning, appears on dismissal of Save As dialog
+\SecondSaveMsg{"Alert! This document has not been saved, do not
+ exit before saving!"}
+
+
+
+
+
+
diff --git a/macros/latex/contrib/thorshammer/thorshammer.dtx b/macros/latex/contrib/thorshammer/thorshammer.dtx
new file mode 100644
index 0000000000..b50d035d8b
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/thorshammer.dtx
@@ -0,0 +1,2398 @@
+% \iffalse
+% makeindex -s gglo.ist -o thorshammer.gls thorshammer.glo
+% makeindex -s gind.ist -o thorshammer.ind thorshammer.idx
+%<*copyright>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% thorshammer.sty package, %%
+%% Copyright (C) 2020 D. P. Story %%
+%% dpstory@uakron.edu dpstory@acrotex.net %%
+%% %%
+%% This program can redistributed and/or modified under %%
+%% the terms of the LaTeX Project Public License %%
+%% Distributed from CTAN archives in directory %%
+%% macros/latex/base/lppl.txt; either version 1.2 of the %%
+%% License, or (at your option) any later version. %%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%</copyright>
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{thorshammer}
+%<package> [2020/01/13 v1.5.7 Support commands for Thor's way]
+%<*driver>
+\documentclass{ltxdoc}
+\usepackage[colorlinks,hyperindex=false,linktocpage,bookmarksnumbered]{hyperref}
+\usepackage{calc}
+%\def\texorpdfstring#1#2{#1}
+%\pdfstringdefDisableCommands{\let\\\textbackslash}
+\OnlyDescription % comment out for implementation details
+\EnableCrossrefs
+\CodelineIndex
+\RecordChanges
+\gdef\brpr#1{\texttt{\char123\relax#1\char125\relax}}
+\let\darg\brpr
+\let\env\texttt
+\let\opt\texttt
+\let\app\textsf
+\let\pkg\textsf
+\let\tops\texorpdfstring
+\def\EXCL{!}
+\def\nmpsep#1{\hskip-\marginparsep\texttt{#1}}
+\def\visispace{\symbol{32}}
+\def\ameta#1{\ensuremath{\langle\textit{\texttt{#1}}\rangle}}
+\def\meta#1{\textsl{\texttt{#1}}}
+\def\SUB#1{\ensuremath{{}_{\mbox{\scriptsize\ttfamily#1}}}}
+\def\CMD#1{\textbackslash#1}
+\InputIfFileExists{aebdocfmt.def}{\PackageWarning{thorshammer}{Inputting aebdocfmt.def}}
+ {\def\IndexOpt{\DescribeMacro}\def\IndexKey{\DescribeMacro}\let\setupFullwidth\relax
+ \PackageInfo{thorshammer}{aebdocfmt.def cannot be found}}
+\begin{document}
+\addtolength{\marginparwidth}{3pt}
+ \GetFileInfo{thorshammer.sty}
+ \title{The \textsf{thorshammer} Package}
+ \author{D. P. Story\footnote{The author acknowledges Thorsten G. (a.k.a., Thor) who proposed this workflow and
+who contributed many ideas; J\"{u}rgen G. (a.k.a., Loki) also contributed many good ideas, enthusiasm,
+questions, bug detecting, and motivation. High regards and respect to both. D. P. Story (a.k.a., Odon).}\\
+ Email: \texttt{dpstory@acrotex.net}}
+ \date{processed \today}
+ \maketitle
+\setcounter{secnumdepth}{5}
+\setcounter{tocdepth}{5}
+\bgroup
+\value{secnumdepth}=3
+\value{tocdepth}=3
+ \tableofcontents
+\egroup
+ \DocInput{thorshammer.dtx}
+\IfFileExists{\jobname.ind}{\newpage\setupFullwidth\par\PrintIndex}{\paragraph*{Index} The index goes here. Execute
+ \begin{quote}\texttt{makeindex -s gind.ist -o thorshammer.ind thorshammer.idx}\end{quote}
+ on the command line and recompile
+ \texttt{thorshammer.dtx}.}
+\IfFileExists{\jobname.gls}{\PrintChanges}{\paragraph*{Change History} The list of changes goes here. Execute
+ \begin{quote}
+ \texttt{makeindex -s gglo.ist -o thorshammer.gls thorshammer.glo}
+ \end{quote}
+ on the command line and recompile \texttt{thorshammer.dtx}.}
+\end{document}
+%</driver>
+% \fi
+% \MakeShortVerb{|}
+% \InputIfFileExists{aebdonotindex.def}{\PackageInfo{web}{Inputting aebdonotindex.def}}
+% {\PackageInfo{web}{cannot find aebdonotindex.def}}
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+% \section{Introduction}
+% Thorsten G.\ has asked me to assist him in creating a quiz system, based on Acro\negthinspace\TeX,
+% to be delivered to his classes. His workflow for this assessment system is a follows:\footnote{As my occassional
+% friend J\"{u}rgen says, this workflow is a real \emph{hammer}, so I titled this package `Thors(ten) hammer', or simply
+% \pkg{thorshammer}.}
+% \begin{enumerate}
+% \item The \env{quiz} environment is used to pose the questions, which consist of MC, numerical fill-in
+% the blank, and extended response questions.
+% \item[] Though the \env{quiz} environment is used, the student does not get his/her score reported
+% back immediately upon finishing the quiz.
+% \item When the student finishes the exam, taken in AR, he/she presses
+% the \textsf{End Quiz} control and saves the document as \texttt{\string\jobname-ID.pdf}, where \texttt{ID}
+% is a student identification. I am informed the ID is the student name.
+% \item At some point, the instructor's script moves the document to the instructors folder.
+% \item The instructor opens the PDF and finishes marking the extended response questions and assigns a grade.
+% \end{enumerate}
+% This package supports the Thorsten's workflow by providing the necessary form elements and JavaScript
+% to carry out his(her) plan. What happens to the quiz after that, I do not know.
+%
+%\changes{v1.4}{2019/08/11}{Begin major change to this package, leaving v1.3.8 as our best working
+% version prior to this update. }
+%
+% \section{Preliminaries}
+%
+% \begin{macrocode}
+\RequirePackage{xkeyval}
+\edef\th@dquoteCat{\the\catcode`\"}
+\catcode`\"=12\relax
+% \end{macrocode}
+% \subsection{Options for this package}
+%
+% \leavevmode\IndexOpt{nocfg} If this option is taken, \texttt{thorshammer.cfg} is not input.
+% \begin{macrocode}
+\DeclareOptionX{nocfg}{\let\th@loadCFG\dl@NO}
+\let\th@loadCFG\dl@YES
+% \end{macrocode}
+% \leavevmode\IndexOpt{testmode} If this option is taken, quizzes can be used in the normal way.
+% \begin{macrocode}
+\newif\ifthtestmode\thtestmodefalse
+\DeclareOptionX{testmode}{\thtestmodetrue}
+\DeclareOptionX{!testmode}{\thtestmodefalse}
+% \end{macrocode}
+% \leavevmode\IndexOpt{ordinary} This is an experimental option to see if we can produce
+% a regular quiz with selected features of a \pkg{thorshammer} workflow.
+% \begin{macrocode}
+\newif\ifthordinary \thordinaryfalse
+\DeclareOptionX{ordinary}{\thtestmodetrue\thordinarytrue}
+% \end{macrocode}
+% \leavevmode\IndexOpt{useclass}Use this option to bring in addition code to declare each member of
+% the class, to automatically build a quiz for each class member, to distribute these
+% quizzes to a designated folder of the instructor, and to distribute the quizzes the
+% respective class folder.
+% \begin{macrocode}
+\newif\ifbasicmethods\basicmethodstrue
+\newif\ifuseclassOpt\useclassOptfalse
+\def\bUseClass{false}
+\DeclareOptionX{useclass}{\useclassOpttrue
+ \def\bUseClass{true}\basicmethodsfalse
+}
+% \end{macrocode}
+% \leavevmode\IndexOpt{usebatch}This option should be used with the \opt{useclass} option.
+% When this option is taken, the no freeze quiz button is created. The batch sequence
+% \textsf{Thor's way} does that, and the presence of the freeze button, the instructor
+% may press it without thinking. We don't want that to happen.
+% \begin{macrocode}
+\newif\ifth@allowfreeze \th@allowfreezetrue
+\DeclareOptionX{usebatch}{\th@allowfreezefalse
+ \ExecuteOptionsX{useclass}}
+% \end{macrocode}
+% \leavevmode\IndexOpt{batchdistr} This option declares the instructor's intention
+% of using \app{Acrobat} to apply security using `\textsf{Thor distributes.sequ}' or `\textsf{Thor protects and distributes.sequ}'
+% to apply security and to distribute the files to the students's folders. This option simply
+% expands \cs{distrToStudentsOff}, and redefines the two commands so the author can't use them. This option
+% has no effect on writing quizzes to the instructor's folder.
+% \begin{macrocode}
+\DeclareOptionX{batchdistr}{\ExecuteOptionsX{usebatch}%
+ \AtEndOfPackage{\distrToStudentsOff
+ \let\distrToStudentsOff\relax\let\distrToStudentsOff\relax}}
+% \end{macrocode}
+% Process the options
+% \begin{macrocode}
+\ProcessOptionsX
+\edef\thOrdQz{\ifthordinary true\else false\fi}
+% \end{macrocode}
+% \subsection{Required packages}
+% \begin{macrocode}
+\RequirePackage{insdljs}[2019/08/06]
+% \end{macrocode}
+% We use the \opt{usealtadobe} option of \pkg{insdljs}, but not directly. If \cs{inputAltAdbFncs}
+% is \cs{relax} than the functions have not already been input above \pkg{thorshammer}.
+% \changes{v1.3.5}{2019/08/06}{Use \string\cs{usedAdbFuncs} to detect \string\opt{usealtadobe} option}
+% \begin{macrocode}
+\ifx\usedAdbFuncs\dl@NO
+ \def\inputAltAdbFncs{\InputIfFileExists{altadbfncs.def}%
+ {\PackageInfo{insdljs}{Inputting code for usealtadobe option}}%
+ {\PackageWarning{insdljs}{Cannot find altadbfncs.def.\MessageBreak
+ Reinstall or refresh your file name database.}}}%
+ \let\usedAdbFuncs\dl@YES
+\else
+ \let\inputAltAdbFncs\relax
+\fi
+\inputAltAdbFncs
+\RequirePackage{exerquiz}[2019/08/13]
+\RequirePackage{eq-save}[2019/08/07]
+\let\execjs\dl@YES
+\@ifundefined{CommentStream}{\newwrite\CommentStream}{}
+\def\csarg#1#2{\expandafter#1\csname#2\endcsname}
+\providecommand{\eqSP}{\string\040}
+\def\thPageOne{\setcounter{page}{1}}
+% \end{macrocode}
+% \section{Setting the initial view}
+% We require the document to be opened on the first page, but the initial magnification
+% is under the control of the document author.\medskip\par
+% \noindent
+% \DescribeMacro\setInitMag\nmpsep{\darg{fitpage\string|actualsize\string|fitwidth\string|fitheight\string|fitvisible\string|inheritzoom}}\\
+% This command determines the initial magnification. There are a choice of six values for the argument; the default is \texttt{fitpage}
+% \begin{macrocode}
+\def\setInitMag#1{\setkeys{thim}{mag=#1}}
+\define@choicekey+{thim}{mag}[\val\nr]%
+ {fitpage,actualsize,fitwidth,fitheight,%
+ fitvisible,inheritzoom}[fitpage]%
+ {\edef\th@initmag{\@nameuse{dl@\val}}}
+ {\PackageWarning{thorshammer}{%
+ Bad choice for initial magnification,\MessageBreak
+ permissible values are fitpage, actualsize,\MessageBreak
+ fitwidth, fitheight, fitvisible, and\MessageBreak
+ inheritzoom. Try again}}
+\def\th@initmag{\dl@fitpage}
+% \end{macrocode}
+% The \cs{addToDocOpen} is a command from \pkg{insdljs}. We turn off calculations as the student
+% does not need to see the calculation icon each time s/he enters a response. When the instructor
+% presses the \textsf{Mark It} button, calculations are turned on again. In the second line
+% below, we set the initial view to page~1 and the magnification set by the \cs{setInitMag} command above.
+% \begin{macrocode}
+\addToDocOpen{\JS{%
+ var stmot=app.setTimeOut("this.calculate=false;",100);}}
+\addToDocOpen{\GoToD[\Page{1}\th@initmag]}
+% \end{macrocode}
+% \section{Declaring instructor and class information}
+%
+% \DescribeMacro\instrPath\nmpsep{*\darg{\ameta{path}}} The path to the
+% instructor's folder. It is assumed that this \ameta{path} is an
+% absolute path. If the star option is taken, then the path is relative
+% to the current folder. The \DescribeMacro\instrPathIsCHTTP\cmd{\instrPathIsCHTTP}
+% declaration is available if the path to the instructor is a WebDAV address. This
+% info is passed on the a JavaScript method.
+% \begin{macrocode}
+\def\instrPathIsCHTTP{\def\thInstrFS{CHTTP}}
+\let\thInstrFS\@empty
+\newcommand\instrPath{\@ifstar
+ {\gdef\InstrPathFull{false}\instrPath@i}
+ {\gdef\InstrPathFull{true}\instrPath@i}}
+\def\instrPath@i#1{\gdef\InstrPath{"#1"}}
+\def\InstrPathFull{true}
+%\let\InstrPath\@empty
+\def\InstrPath{this.path.replace(reRmFn,"")}
+% \end{macrocode}
+% \DescribeMacro\classPath\nmpsep{*\darg{\ameta{path}}} The path to the class folder.
+% It is assumed that this \ameta{path} is an absolute path. If
+% the star option is taken, then the path is relative to the current folder.
+% The \DescribeMacro\classPathIsCHTTP\cmd{\instrPathIsCHTTP}
+% declaration is available if the path to the class folders is a WebDAV address. This
+% info is passed on the a JavaScript method.
+% \begin{macrocode}
+\def\classPathIsCHTTP{\def\thClassFS{CHTTP}}
+\let\thClassFS\@empty
+\newcommand\classPath{\@ifstar
+ {\gdef\ClassPathFull{false}\classPath@i}
+ {\gdef\ClassPathFull{true}\classPath@i}}
+\def\classPath@i#1{\gdef\ClassPath{"#1"}}
+\def\ClassPath{this.path.replace(reRmFn,"")}
+\def\ClassPathFull{true}
+% \end{macrocode}
+%
+% \section{Running headers}
+% The scheme used here assumes no other {\LaTeX} package has been used to take over the running
+% headers (and footers). If that is the case, use the values of the commands below to design
+% your own.
+% \DescribeMacro\thQzHeaderL\nmpsep{\darg{\ameta{text}}} This is inserted into the left running header
+% for the quiz pages.
+% \begin{macrocode}
+\def\thQzHeaderL#1{\def\th@QzHeaderLQ{\makebox[0pt][l]{#1}}}
+\def\th@QzHeaderL{\th@QzHeaderLQ}
+\thQzHeaderL{Thor's Class}
+\def\th@QzHeaderLS{\th@HeaderOffset\th@QzHeaderLQ}
+% \end{macrocode}
+% \DescribeMacro\thQzHeaderCQ\nmpsep{\darg{\ameta{text}}} This is inserted into the center running header
+% for the \emph{quiz} pages.
+% \begin{macrocode}
+\def\thQzHeaderCQ#1{\def\th@QzHeaderCQ{\makebox[0pt][c]{#1}}}
+\thQzHeaderCQ{Quiz \thQuizName}
+\def\th@QzHeaderC{\th@QzHeaderCQ}
+% \end{macrocode}
+% \DescribeMacro\thQzHeaderCS\nmpsep{\darg{\ameta{text}}} This is inserted into the center running header
+% for the \emph{solution} pages.
+% \begin{macrocode}
+\def\thQzHeaderCS#1{\def\th@QzHeaderCS{\makebox[0pt][c]{#1}}}
+\thQzHeaderCS{Solutions: \thQuizName}
+% \end{macrocode}
+% \DescribeMacro\thQzHeaderR\nmpsep{\darg{\ameta{text}}} This is inserted into the right running header
+% for the solution pages.
+% \begin{macrocode}
+\def\thQzHeaderR#1{\def\t@hQzHeaderR{\makebox[0pt][r]{#1}}}
+\thQzHeaderR{\thepage}
+% \end{macrocode}
+% We apply the running headings, depending on whether \pkg{web} loaded by testing for the
+% \texttt{webheadings} page style.
+% \begin{macrocode}
+\@ifundefined{ps@webheadings}{%
+ \def\th@setHeaders{%
+ \renewcommand{\@oddhead}{\th@QzHeaderL\hfil\th@QzHeaderC\hfil
+ \t@hQzHeaderR}\renewcommand{\@evenhead}{\@oddhead}}%
+}{%
+ \def\th@setHeaders{%
+ \lheader{\th@QzHeaderL}%
+ \cheader{\th@QzHeaderC}%
+ \rheader{\t@hQzHeaderR}}%
+}
+% \end{macrocode}
+% Change the header for the solution section
+% \begin{macrocode}
+\def\eq@normallheader{%
+ \@ifundefined{ps@webheadings}{%
+ \def\th@QzHeaderL{\th@QzHeaderLS}%
+ \def\th@QzHeaderC{\th@QzHeaderCS}%
+ }{%
+ \lheader{\th@QzHeaderLS}%
+ \cheader{\th@QzHeaderCS}%
+ }
+}
+% \end{macrocode}
+% \DescribeMacro\rhPgNumsOnly Originally, this package only exhibited page numbers
+% in the running header, expanding \cs{rhPgNumsOnly} in the preamble restores that
+% original experience.
+% \begin{macrocode}
+\def\rhPgNumsOnly{\thQzHeaderL{}\thQzHeaderCQ{}\thQzHeaderCS{}}
+\AtBeginDocument{\th@setHeaders}
+% \end{macrocode}
+% \section{Declaring a cover page}
+% \DescribeMacro\DeclareCoverPage\nmpsep{\darg{\ameta{pgNum}}}
+% A cover page, if declared, is appended to the beginning of the quiz. The page
+% specified by \ameta{pgNum} is the cover page. The cover page is a single page
+% and must occur prior to any quiz. Valid in the \emph{preamble only}.
+% \changes{v1.4.1}{2019/08/16}{Implement the concept of a cover page.}
+% \begin{macrocode}
+\newif\ifthCoverPage \thCoverPagefalse
+\newcommand{\DeclareCoverPage}[1]{\thCoverPagetrue
+ \def\thIsCP{true}\def\thCvrPg{#1}}
+\def\thIsCP{false}\def\thCvrPg{0}
+\@onlypreamble\DeclareCoverPage
+% \end{macrocode}
+% \section{Basic methods}
+%
+% Thor is tormenting me with the basic methods option. The basic methods option is
+% no options other than perhaps \opt{nocfgs}. As a consequence, the student names are
+% not pre-filled into the name fields. When multiple quizzes are produced, they are named
+% differently, \cs{jobname-1.pdf}, \cs{jobname-2.pdf}, and so on. A lot of work has gone
+% in to the basic methods so it works link the non-basic methods (option \opt{useclass} or higher).
+% The commands \cs{instrPath} and \cs{classPath} are supported; to use the \cs{classMember}
+% command, use \opt{useclass} or higher. In addition to \cs{instrPath} and \cs{classPath}, we
+% define special basic method commands, as describe in the next section.
+%
+% \subsection{Configuring the basic methods experience}
+%
+% \DescribeMacro\useNameToCustomize\nmpsep{ \normalfont(Basic methods)}
+% \cs{useNameToCustomize}
+% can be used to modify the file name of the quiz to include student name; the default is to
+% use the original quiz file name. This command is implemented through the \textsf{Freeze Quiz} button.
+% This command has no effect in the non-basic setting.
+% \changes{v1.3.6}{2019/08/07}{freezeQuizMU: Cannot freeze unless grade given and added suffix
+% \string\texttt{"-g"} to document name on saving.}
+% \changes{v1.4.8}{2019/09/05}{Added \string\cs{useNameToCustomize}}
+% \begin{macrocode}
+\def\useNameToCustomize{\def\thUseNameToCustomize{true}}
+\def\thUseNameToCustomize{false}
+% \end{macrocode}
+% \DescribeMacro\enumQuizzes\nmpsep{\darg{\ameta{num}}} (Basic methods) This file specifies that
+% the quizzes should be replicated \ameta{num} times and named \cs{jobname-1},
+% \cs{jobname-2}, ..., \cs{jobname-\ameta{num}}. The default is not to enumerate.
+% \changes{v1.4.8}{2019/09/05}{Added \string\cs{enumQuizzes}}
+% \begin{macrocode}
+\def\enumQuizzes#1{\def\bUseClass{true}\basicmethodsfalse
+ \ClassEntriestrue\def\ClassPathFull{true}\def\InstrPathFull{true}%
+ \def\ClassPath{this.path.replace(reRmFn,"")}%
+ \def\InstrPath{this.path.replace(reRmFn,"")}%
+ \bgroup\@tempcnta#1\relax
+ \@whilenum\@tempcnta>\z@\do{\classMember{}{}{}%
+ \advance\@tempcnta\m@ne}\egroup
+ \def\thEnumQuizzes{#1}\def\bEnumQuizzes{true}}
+\def\thEnumQuizzes{0}\def\bEnumQuizzes{false}
+% \end{macrocode}
+% \DescribeMacro\distrQuizzes\nmpsep{\darg{\darg{\ameta{folder\SUB1}}\darg{\ameta{folder\SUB2}}...\darg{\ameta{folder\SUB{n}}}}}
+% (Basic methods) If \cs{distrQuizzes} is used, \cs{enumQuizzes} command is ignored. The quizzes are enumerated,
+% as described above, but the number of quizzes created is the number of folders declared. The script
+% |\sadQuizzes| also distributes the individual quizzes to the appropriate folder, on the path
+% determined by the |\classPath| command.
+% \changes{v1.4.8}{2019/09/05}{Added \string\cs{distrQuizzes}}
+% \changes{v1.5.4}{2019/11/30}{Reworked \string\cs{distrQuizzes} to account for
+% second star option of \string\cs{classMember}}
+% \begin{macrocode}
+\newcommand{\distrQuizzes}{%
+ \ifuseclassOpt
+ \def\th@next{\PackageWarning{thorshammer}
+ {Use have specified the useclass option or higher\MessageBreak
+ yet you employ \string\distrQuizzes, these are\MessageBreak
+ incompatible. Assuming the specified package option}}%
+ \else
+ \let\th@next\th@distrQuizzes
+ \fi\th@next
+}
+\def\th@distrQuizzes{\def\bUseClass{true}\basicmethodsfalse
+ \ClassEntriestrue\bgroup\@makeother\_\th@distrQuizzes@i}
+\def\rmSTAR#1*\@nil{\def\@folder{#1}}
+%\def\tstForSTAR#1{\tstForSTAR@i#1**\@nil}
+\def\tstForSTAR#1*#2*\@nil{\def\@rgi{#1}\ifx\@rgi\@empty
+ \def\ISSTAR{*}\rmSTAR#2\@nil\else\let\ISSTAR\@empty\fi}%
+\def\th@distrQuizzes@i#1{\@tempcnta\z@
+ \@tfor\@folder:=#1\do{\advance\@tempcnta\@ne
+% \end{macrocode}
+% Determine if \cs{@folder} begin with \texttt*, remove it and return
+% the path as \cs{@folder}
+% \begin{macrocode}
+ \expandafter\tstForSTAR\@folder**\@nil
+ \edef\x{\noexpand\classMember{}{}\ISSTAR{\@folder}}\x
+ }\xdef\enumQuizzes{\the\@tempcnta}%
+ \gdef\bDistrQuizzes{true}\egroup
+}
+\def\bDistrQuizzes{false}
+% \end{macrocode}
+%
+% \paragraph*{Just auto-save the document - not recommended}
+% The \cs{executeSave()} command previously figured in importantly,
+% as this package developed, use of \cs{executeSave()} cannot be
+% recommended. This command was implemented early in the development process
+% \begin{macrocode}
+\@ifundefined{executeSave}
+ {\def\executeSave(){%
+ console.println("automatically saving this file...");^^J%
+ var retn=aebTrustedFunctions(this,aebDocSaveAs,%
+ {cPath:this.path,bCopy:false})}}{}
+% \end{macrocode}
+% The \DescribeEnv{docassembly}\env{docassembly} environment was created early
+% in development and was meant to be used with \cs{executSave()}. The environment
+% definition was updated to be equivalent to the \env{makeClassFiles} environment.
+% An environment by the same name, and the same functionality, is defined in \pkg{aeb\_pro}.
+% \changes{v1.4.14}{2019/09/13}{Inserted \string\cs{mkClFlsSpcls} as optional
+% argument of \string\env{docassembly}}
+% \begin{macrocode}
+\@ifundefined{docassembly}
+ {\newenvironment{docassembly}{%
+ \execJS[\mkClFlsSpcls]{docassembly}}{\endexecJS}}
+ {\renewenvironment{docassembly}{%
+ \execJS[\mkClFlsSpcls]{docassembly}}{\endexecJS}}
+% \end{macrocode}
+%
+% \subsection{Post creation document assembly}
+% The \DescribeMacro\rasSolns\cmd\sadQuizzes{} command is placed within the
+% \env{docassembly} or \env{makeClassFiles} environment,
+% \cs{sadQuizzes} in the body of the environment.
+%\begin{verbatim}
+%\begin{docassembly}
+%\sadQuizzes
+%\end{docassembly}
+%\begin{document}
+%\end{verbatim}
+%Originally, we defined a command \cs{rasSolns}, this command has been \cs{let} to
+%\cs{sadQuizzes}, which now performs its duties.
+% \begin{macrocode}
+% \end{macrocode}
+%
+% \section{Form field commands}
+%
+% We define two types of controls: (1) those placed outside the quiz; (2) those placed within the quiz.
+%
+% \subsection{Controls above the \tops{\protect\env{quiz}}{quiz} environment}
+%
+% \paragraph*{Commands that occur above the \tops{\protect\env{quiz}}{quiz} environment}\leavevmode\par\medskip\noindent
+% The student needs to sign in with his/her first and last name. The commands
+% \DescribeMacro\FirstName\cmd\FirstName{} and \DescribeMacro\LastName\cmd\LastName{} are
+% defined for that purpose.
+% \begin{macrocode}
+\ifbasicmethods\let\th@namePresets\@empty\else
+% \end{macrocode}
+% If the option \opt{useclass}, or higher, is taken, we make these fields read only and the
+% JavaScript code of \cs{sadQuizzes} will fill name field in for the student.
+% \begin{macrocode}
+\def\th@namePresets{\Ff\FfReadOnly\BC{}}\fi
+\newcommand\FirstName[3][]{\th@bMrkQz\textField[%
+ \presets{\th@namePresets}#1]{Name.first}{#2}{#3}}
+\newcommand\LastName[3][]{\textField[%
+ \presets{\th@namePresets}#1]{Name.last}{#2}{#3}}
+% \end{macrocode}
+% The \cs{sadQuizzes} command uses the name fields to identify on which page a quiz begins. This worries
+% me a little if a document designer places more than one name field for a quiz. We attempt to make
+% the first use of the name field per quiz. We define \cs{th@bMrkQz}. These fields are place exactly once
+% for each quiz and is attached to the name fields.
+% \changes{v1.4.7}{2019/08/27}{Added marker field attached to name field}
+% \begin{macrocode}
+\def\th@bMrkQz{\@ifundefined{bMrkQz\currQuiz}
+ {\rlap{\textField[\Ff\FfReadOnly\BC{}\BG{}]{bMrkQz}{0pt}{0pt}}%
+ \@namedef{bMrkQz\currQuiz}{}}{}}
+% \end{macrocode}
+% \DescribeMacro{\FullName}\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}} The first and
+% last name fields are required; however, when \opt{useclass} or higher is used, they are automatically
+% filled in. The \cs{FullName} field uses the calculate event to extract the first and last names
+% and displays them together in one field. The format for the this name field can be changed
+% through the declaration \DescribeMacro\thfullnameFmt\cmd{\thfullnameFmt}.
+% \begin{macrocode}
+\def\th@fullnamePresets{\Ff\FfReadOnly\BG{}\BC{}}
+\def\thfullnameFmt#1{\def\th@fullnameFmt##1##2{#1}}
+\thfullnameFmt{#1+" "+#2}
+\newcommand{\FullName}[3][]{\textField[%
+ \presets{\th@fullnamePresets}#1\AAcalculate{%
+ var fName=this.getField("Name.first").value;\r
+ var lName=this.getField("Name.last").value;\r
+ event.value=\th@fullnameFmt{fName}{lName};}]{FullName}{#2}{#3}}
+% \end{macrocode}
+% \leavevmode\DescribeMacro\pwdInstrFld\nmpsep{[\ameta{options}]\darg{\ameta{pwd}}\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% In this workflow, when the instructor opens a quiz file, he/she enters a password. On success, the
+% non-extended response questions of the student's quiz is marked, and various hidden form elements are
+% made visible.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\pwdInstrFldTU\nmpsep{\darg{\ameta{pdfstr}}}
+% can be redefined to provide a tool tip
+% for this field.
+% \begin{macrocode}
+\def\pwdInstrFldTU#1{\def\pwdInstrFld@TU{#1}}
+\pwdInstrFldTU{Enter password to mark this quiz}
+% \end{macrocode}
+% The definition of \cmd\pwdInstrFld
+% \begin{macrocode}
+\newcommand{\pwdInstrFld}[4][]{% opts, pwd, wd, ht
+ \@ifundefined{\currQuiz-nQs}{\def\nQs{0}}
+ {\edef\nQs{\@nameuse{\currQuiz-nQs}}}%
+ \textField[\cmd{\bParams{\currQuiz}{\nQs}{"#2"}\eParams}
+ \Ff\FfPassword\AAkeystroke{\pwdKeyJS}
+ \protect\AA\protect\Ff\TU{\pwdInstrFld@TU}#1%
+]{pwdtxt}{#3}{#4}}
+% \end{macrocode}
+% \DescribeMacro\markQz\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}} Loki
+% suggested another idea to have the password field hidden until the instructor opens the file.
+% Well if you are doing that, why have a password field? Instead, a push button is provided.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\markQzFldCA\nmpsep{\ameta{jsstr}} The caption for this button
+% \begin{macrocode}
+\def\markQzFldCA#1{\def\markQzFld@CA{#1}}
+\markQzFldCA{Mark It}
+% \end{macrocode}
+% \DescribeMacro\markQzFldTU\nmpsep{\ameta{jsstr}} The tool tip for this button
+% \begin{macrocode}
+\def\markQzFldTU#1{\def\markQzFld@TU{#1}}
+\markQzFldTU{Press to mark this quiz}
+% \end{macrocode}
+% The code for \cmd\markQz. \textbf{Important!}\marginpar{\raggedleft\textbf{Important!}} For obvious
+% reasons, we don't want the push button to be seen by the students. As a result, it is initially hidden.
+% The key to having the push button visible when the instructor is the private JavaScript variable
+% \texttt{\_thorshammer}\marginpar{\raggedleft\texttt{\_thorshammer}} (this can be changed). The following
+% code is placed in the \texttt{config.js}\marginpar{\raggedleft\texttt{config.js}} file of the instructor's \app{Acrobat} installation:
+% \begin{quote}\ttfamily
+% var \_thorshammer=true;
+% \end{quote}
+% \app{Acrobat} reads this file only once when it's opened.
+% When the instructor opens the student's quiz PDF in \app{Acrobat}\marginpar{\raggedleft\app{Acrobat}},
+% some underlying JavaScript code tests whether the \texttt{\_thorshammer} variable is defined and is
+% \texttt{true}. If these conditions are met, JavaScript makes the \cs{markQuizFld} and
+% \cs{freezeQz} fields visible.
+% \begin{macrocode}
+\newcommand{\markQz}[3][]{%
+ \@ifundefined{\currQuiz-nQs}{\def\nQs{0}}%
+ {\edef\nQs{\@nameuse{\currQuiz-nQs}}}%
+% \end{macrocode}
+% This text field is placed underneath the push button. It is the one that
+% causes the \cs{markQz} field to be visible.
+% \begin{macrocode}
+ \makebox[0pt][l]{\textField[\BC{}\BG{}\H{S}\AAformat{%
+ var f=this.getField("MarkIt");\r
+ var g=this.getField("freezeQz");\r
+ if(typeof _thorshammer!="undefined" && _thorshammer){\r\t
+ if(f!=null)f.display=display.visible;\r\t
+} else{\r\t
+ if(f!=null)f.display=display.hidden;\r\t
+ if(g!=null)g.display=display.hidden;\r
+}}]{hideTxtFldMI}{0pt}{0pt}}%
+% \end{macrocode}
+% The push button seen by the instructor to mark the quiz.
+% \begin{macrocode}
+ \pushButton[\cmd{\bParams{\currQuiz}{\nQs}\eParams}\F\FHidden
+ \AAmouseup{\commonPassKey}\CA{\markQzFld@CA}
+ \TU{\markQzFld@TU}\protect\AA\protect\F#1%
+ ]{MarkIt}{#2}{#3}}
+% \end{macrocode}
+% \DescribeMacro\freezeQuiz\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% The \cs{freezeQuiz} makes all form fields readonly. After the instructor finishes marking
+% the quiz, he/she presses the freeze quiz button before he moves it to the student's folder
+% for review. This is done so the student cannot modify the quiz in any case and beg for more
+% points. (They never beg for fewer points). The freeze quiz button makes itself hidden as well.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\freezeQuizFldTU\nmpsep{\darg{\ameta{pdfstr}}}
+% can be redefined to provide a tool tip for this field.
+% \begin{macrocode}
+\def\freezeQuizFldTU#1{\def\freezeQuizFld@TU{#1}}
+\freezeQuizFldTU{Make all fields readonly, cannot be undone}
+% \end{macrocode}
+% \DescribeMacro\freezeQuizFldCA\nmpsep{\darg{\ameta{pdfstr}}}
+% can be redefined to provide a button caption for this field.
+% \begin{macrocode}
+\def\freezeQuizFldCA#1{\def\freezeQuizFld@CA{#1}}
+\freezeQuizFldCA{Freeze Quiz}
+% \end{macrocode}
+% The definition of \cmd\freezeQuiz. If the \opt{usebatch} option is taken,
+% we do not create the push button.
+% \begin{macrocode}
+\newcommand\freezeQuiz[3][]{\pushButton[\cmd{\let\%\defjsLB}
+ \CA{\freezeQuizFld@CA}\F\FHidden
+ \TU{\freezeQuizFld@TU}\AAmouseup{freezeQuizMU()}
+ \protect\AA\protect\F
+ #1]{freezeQz}{}{11bp}}
+% \end{macrocode}
+% \DescribeMacro\instrSave\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% A companion macro to \cs{freezeQuiz}. This macro is substituted for \cs{freezeQuiz}
+% when the \opt{usebatch} option is taken. The \cs{instrSave} and \cs{freezeQuiz}
+% should not appear in the same document; we give them the same field name
+% so the JavaScript treats them them the same, in terms of making them hidden
+% and visible. |\ifth@allowfreeze|
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\instrSaveFldTU\nmpsep{\darg{\ameta{pdfstr}}}
+% can be redefined to provide a tool tip for this field.
+% \begin{macrocode}
+\def\instrSaveFldTU#1{\def\instrSaveFld@TU{#1}}
+\instrSaveFldTU{Save and close this file to the current folder}
+% \end{macrocode}
+% \DescribeMacro\instrSaveFldCA\nmpsep{\darg{\ameta{pdfstr}}}
+% can be redefined to provide a button caption for this field.
+% \begin{macrocode}
+\def\instrSaveFldCA#1{\def\instrSaveFld@CA{#1}}
+\instrSaveFldCA{Save \string& Close}
+% \end{macrocode}
+% The definition of \cmd\instrSave. If the \opt{usebatch} option is taken,
+% we do not create the push button.
+% \begin{macrocode}
+\newcommand\instrSave[3][]{\pushButton[%
+ \CA{\instrSaveFld@CA}\F\FHidden
+ \TU{\instrSaveFld@TU}\AAmouseup{%
+ var f=this.getField("studentenGrade");\r
+ var str=""+f.value;\r
+ str=str.replace(/\string\s/g,"");\r
+ if (str=="")\r\t
+ app.alert("You did not award the student a final mark."
+ +"\\n\\nAward the mark and then save.");\r
+ else {\r\t
+ aebTrustedFunctions(this,aebSaveAs);\r\t
+ this.closeDoc(true);\r
+ }}\protect\AA\protect\F
+ #1]{freezeQz}{}{11bp}}
+% \end{macrocode}
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\freezeOrSave\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% is the recommended way of inserting \cs{freezeQuiz} or \cs{instrSave}. If \opt{usebatch}
+% is taken, \c{freezeOrSave} expands to \cs{instrSave}; otherwise it expands to \cs{freezeQuiz}.
+%\changes{v1.2}{2019/07/16}{Added \string\cs{freezeOrSave}}
+% \begin{macrocode}
+\AtEndOfPackage{\ifth@allowfreeze\let\freezeOrSave\freezeQuiz
+ \else\let\freezeOrSave\instrSave\fi}
+% \end{macrocode}
+% \DescribeMacro\studentReport\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}} In Thor's
+% way of things, a summary report is placed at the top of the document. This readonly field
+% shows the number of points awarded and the total points.
+% \changes{v1.1.8}{2019/07/08}{make studentenReport initially hidden}
+% \begin{macrocode}
+\newcommand{\studentReport}[3][]{%
+ \textField[\BC{}\BG{}\F\FHidden\Ff\FfReadOnly\protect\Ff#1%
+ ]{studentenReport}{#2}{#3}}
+% \end{macrocode}
+% \DescribeMacro\studentGrade\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% Again, in Thor's way of things, a text field is available to assign grade. This field
+% is initially hidden, but becomes visible when instructor signs in.
+% \begin{macrocode}
+\newcommand{\studentGrade}[3][]{\textField[\F\FHidden\protect\F
+ \BC{red}\BG{}\Q1\textSize{12}\textColor{blue}
+ \AAkeystroke{event.change=event.change.toUpperCase()}#1%
+ ]{studentenGrade}{#2}{#3}}
+% \end{macrocode}
+% \DescribeMacro\thQHFirstName\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% The first name of the student
+% \begin{macrocode}
+\def\thQHFirstName#1{\def\th@QHFirstName{\textbf{#1}\space}}
+\thQHFirstName{First name:}
+% \end{macrocode}
+% \DescribeMacro\thQHLastName\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% The last name of the student
+% \begin{macrocode}
+\def\thQHLastName#1{\def\th@QHLastName{\textbf{#1}\space}}
+\thQHLastName{Last name:}
+% \end{macrocode}
+% \DescribeMacro\thQHPoints\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% Number of points, displayed in the form `10 / 20'.
+% \begin{macrocode}
+\def\thQHPoints#1{\def\th@QHPoints{\textbf{#1}\space}}
+\thQHPoints{Points:}
+% \end{macrocode}
+% \DescribeMacro\thQHGrade\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% Some grade mark (A, B, C, etc., or 1, 2, 3, etc.)
+% \begin{macrocode}
+\def\thQHGrade#1{\def\th@QHGrade{\textbf{#1}\space}}
+\thQHGrade{Grade:}
+% \end{macrocode}
+% \DescribeMacro\thQuizHeader\nmpsep{*}
+% The above commands typically appear above the quiz and placed in some beautiful way.
+% We bundle these commands into a single one, according to my own happiness, but you may
+% seek happiness some other way by redefining \cs{thQuizHeaderLayout}.
+% (The command \cs{thQuizHeader} just picks up on the \texttt*-option, then expands \cs{thQuizHeaderLayout}.)
+% The command is placed beneath the \cs{DeclareQuiz} command and above the \env{quiz}
+% environment. The command automatically emits a \cs{newpage}, unless the \texttt*-option is taken.\par\medskip\noindent
+%\begin{minipage}[t]{\widthof{\cs{DeclareQuiz\darg{\ameta{qz-name}}}}}
+%\begin{flushleft}
+%\textbf{Preferred Placement}\\[3pt]
+%\ttfamily
+%\cs{DeclareQuiz\darg{\ameta{qz-name}}}\\
+%...\\
+%\string\begin\darg{document}\\
+%...\\
+%\cs{thQuizHeader}\\
+%...\\
+%\ameta{\textsf{quiz-begins}}
+%\end{flushleft}
+%\end{minipage}\qquad
+%\begin{minipage}[t]{\widthof{\cs{DeclareQuiz\darg{\ameta{qz-name}}}}}
+%\begin{flushleft}
+%\textbf{Alternate Placement}\\[3pt]
+%\ttfamily
+%\string\begin\darg{document}\\
+%\cs{DeclareQuiz\darg{\ameta{qz-name}}}\\
+%\cs{thQuizHeader}\\
+%...\\
+%\ameta{\textsf{quiz-begins}}
+%\end{flushleft}
+%\changes{v1.4.3}{2019/08/22}{let \string\cs{Hy@EveryPageAnchor} to \string\cs{relax}}
+%\end{minipage}\medskip
+% \begin{macrocode}
+\newcommand{\thQuizHeader}{\let\Hy@EveryPageAnchor\relax
+ \@ifstar{\thPageOne\thQuizHeaderLayout}
+ {\newpage\thPageOne\thQuizHeaderLayout}%
+}
+% \end{macrocode}
+% \DescribeMacro\thQuizHeaderLayout The body of this command contains the arraignment of
+% the above defined commands. It is this command that may be redefined.
+% \begin{macrocode}
+\newcommand\thQuizHeaderLayout{\noindent
+ \th@QHFirstName\FirstName{1.5in}{13bp}\vcgBdry[3pt]
+ \th@QHLastName\LastName{1.5in}{13bp}\vcgBdry[6pt]
+ \begin{minipage}[t]{1.2in}\kern0pt
+ \makebox[0pt][r]{\raggedleft\markQz{}{11bp}%
+ \hspace{\marginparsep}}%
+ \th@QHPoints\studentReport{\widthof{000/000}}{11bp}\vcgBdry[6pt]
+ \makebox[0pt][r]{\raggedleft\freezeOrSave{}{11bp}%
+ \hspace{\marginparsep}}%
+ \th@QHGrade\studentGrade{14bp}{14bp}\vcgBdry[6pt]
+ \end{minipage}\hfill
+ \begin{minipage}[t]{\linewidth-1em-1.2in}\kern0pt
+ \begin{sumryTblAux}{\currQuiz}
+ \displaySumryTbl[ntables=1,showmarkup]{\currQuiz}
+ \end{sumryTblAux}
+ \end{minipage}}
+% \end{macrocode}
+% This assumes the English language and the \opt{usesumrytbls} option of \pkg{exerquiz}.
+% \subsection{Commands that usually follow the quiz} %\leavevmode\par\medskip\noindent
+% \DescribeMacro\completeMsgFldV\nmpsep{\darg{\ameta{pdfstr}}} is the message
+% that is displayed in this multi-line text field.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\completeMsgFld\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% When the student completes the quiz, a hidden text field appears and reminds
+% the student to save the document.
+% \begin{macrocode}
+\def\completeMsgFldV#1{\def\completeMsgFld@V{#1}}
+\completeMsgFldV{Congratulations, you have completed the quiz,
+ before doing anything else, you need to save this document.}
+% \end{macrocode}
+% The definition of \cmd\completeMsgFld
+% \begin{macrocode}
+\newcommand{\completeMsgFld}[3][]{\textField[\F\FHidden\Ff\FfMultiline
+ \Ff\FfReadOnly\V{\completeMsgFld@V}
+ \DV{\completeMsgFld@V}]{postQzMsg}{#2}{#3}}
+% \end{macrocode}
+% \DescribeMacro\ShrtPtsFld\nmpsep{\darg{\ameta{options}}\darg{\ameta{quiz-name}}}
+% This is \pkg{exerquiz}s \cs{PointsField}, but with special format script.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\ShrtPtsFldFmt\nmpsep{\darg{\ameta{js-str}}} is the formatting string
+% used; \ameta{js-str} should incorporate the event property \texttt{event.value}
+% in its definition. See default definition below.
+% \changes{v1.4.17}{2019/10/03}{Rewrote \string\cs{ShrtPtsFldFmt} to produce pdf spaces}
+% \begin{macrocode}
+\def\ShrtPtsFldFmt{\bgroup\obeyspaces\ShrtPtsFldFmt@i}
+\def\ShrtPtsFldFmt@i#1{\egroup\flJSStr[noquotes]{\ShrtPtsFld@Fmt}{#1}}
+\ShrtPtsFldFmt{"Short Pts: "+event.value}
+% \end{macrocode}
+% The definition of \cmd\ShrtPtsFld
+% \begin{macrocode}
+\newcommand{\ShrtPtsFld}[2][]{%
+ \PointsField[\AAformat{if(event.value!="")
+ event.value=\ShrtPtsFld@Fmt}\F\FHidden\protect\AA
+ \protect\F#1]{#2}}
+% \end{macrocode}
+% \DescribeMacro\LngPtsFld\nmpsep{\darg{\ameta{options}}\darg{\ameta{quiz-name}}}
+% This field will hold the total points for the essay or extended response
+% questions. It is modeled after \cs{PointsField}, having the same defaults
+% and width and height.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\LngPtsFldFmt\nmpsep{\darg{\ameta{js-str}}} is the formatting string
+% used; \ameta{js-str} should incorporate the event property \texttt{event.value}
+% in its definition. See default definition below.
+% \changes{v1.4.17}{2019/10/03}{Rewrote \string\cs{LngPtsFldFmt} to produce pdf spaces}
+% \begin{macrocode}
+\def\LngPtsFldFmt{\bgroup\obeyspaces\LngPtsFldFmt@i}
+\def\LngPtsFldFmt@i#1{\egroup\flJSStr[noquotes]{\LngPtsFld@Fmt}{#1}}
+\LngPtsFldFmt{"Long Pts: "+event.value}
+% \end{macrocode}
+% The definition of \cmd\LngPtsFld
+% \changes{v1.1.3}{2019/07/03}{Make \string\cs{LngPtsFld} a calculation field}
+% \changes{v1.4.10}{2019/09/11}{Fixed a bug in calculation when there are no
+% essay questions}
+% \begin{macrocode}
+\newcommand{\LngPtsFld}[2][]{%
+ \textField[\presets{\PointsFieldDefaults}\F\FHidden
+ \AAformat{if(event.value!="") event.value=\LngPtsFld@Fmt}
+ \AAcalculate{var f=this.getField("essayMrkUp");\r
+ if(f!=null)EFSimple_Calculate("SUM",%
+new Array("essayMrkUp.\currQuiz"));}
+ ]{EssayField.\currQuiz}{\PtFW}{\DefaultHeightOfWidget}}
+% \end{macrocode}
+% \DescribeMacro\TotalsFld\nmpsep{\darg{\ameta{options}}\darg{\ameta{quiz-name}}}
+% This is modeled after \pkg{exerquiz}s \cs{PointsField}, but with special format script.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\TotalsFldFmt\nmpsep{\darg{\ameta{js-str}}} is the formatting string
+% used; \ameta{js-str} should incorporate the event property \texttt{event.value}
+% in its definition. See default definition below.
+% \changes{v1.4.17}{2019/10/03}{Rewrote \string\cs{TotalsFldFmt} to produce pdf spaces}
+% \begin{macrocode}
+\def\TotalsFldFmt{\bgroup\obeyspaces\TotalsFldFmt@i}
+\def\TotalsFldFmt@i#1{\egroup\flJSStr[noquotes]{\TotalsFld@Fmt}{#1}}
+\TotalsFldFmt{"Total: "+event.value+"\space\eqOutOf\space"%
++NPointTotal}
+% \end{macrocode}
+% The definition of \cmd\TotalsFld
+% \changes{v1.1.2}{2019/07/02}{Added try/catch in \string\cs{AAformat} to avoid
+% exceptions thrown in the case of distiller; added pdf space in the \string\cs{TotalsFld}
+% JS to avoid unexpected wraps in the case of dvips/distiller worflow.}
+% \begin{macrocode}
+\newcommand{\TotalsFld}[2][]{%
+ \textField[\presets{\PointsFieldDefaults}\F\FHidden
+ \AAformat{try{event.value=(\TotalsFld@Fmt)}catch(e){}}
+ \AAcalculate{EFSimple_Calculate("SUM",%
+new Array("PointsField.\currQuiz","EssayField.\currQuiz"));\r
+ var\eqSP f=this.getField("studentenReport");\r
+ f.value=(1*event.value)+"\eqSP/\eqSP"+\theeqpointvalue;
+ }]{TotalsField.\currQuiz}{\PtFW}{\DefaultHeightOfWidget}}
+% \end{macrocode}
+% \leavevmode\DescribeMacro\thQuizTrailer
+% The above commands can be arranged in some way following the quiz; one such arrangement
+% is found in the command \cmd\thQuizTrailer.
+% \begin{macrocode}
+\newcommand{\thQuizTrailer}{\raisebox{\baselineskip-\fboxsep}%
+ {\makebox[0pt][l]{\parbox[t]{3in}{\kern0pt
+ \completeMsgFld{3in}{3\baselineskip}}}}%
+ \makebox[0pt][l]{\hspace{3in}\quad
+ \ifthtestmode\CorrButton{\currQuiz}\else
+ \stuSaveBtn{}{11bp}\fi}\parbox[t]{3in}
+ {\ShrtPtsFld{\currQuiz}\vcgBdry[6pt]
+ \LngPtsFld{\currQuiz}\vcgBdry[6pt]
+ \TotalsFld{\currQuiz}}}
+% \end{macrocode}
+%
+% \subsection{Controls inside the \tops{\protect\env{quiz}}{quiz} environment}
+%
+% \DescribeMacro{\essayQ}\nmpsep{\darg{\ameta{nPts}}}
+% When we have an essay type question we need to mark it prior to the \cs{item}.
+% In order to test whether the instructor has put in more credit than specified
+% by the \cs{PTs} command, we need to pass the number of points for this question.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\essayQFldTU\nmpsep{\darg{\ameta{pdfstr}}} is the tool tip
+% for this field.
+% \begin{macrocode}
+\def\essayQFldTU#1{\def\essayQFld@TU{#1}}
+\essayQFldTU{Assign points to extended responses}
+% \end{macrocode}
+% We fix the width \DescribeMacro\EsW\cmd\EsW{} and the height \DescribeMacro\EsH\cmd\EsH{}
+% of \cs{essayQ} using commands, these can be redefined.
+% \begin{macrocode}
+\def\EsW{33bp}\def\EsH{14bp}
+% \end{macrocode}
+% Now for the definition of \cmd\essayQ
+% \begin{macrocode}
+\def\essayQ#1{\let\qMark@HookSave\qMark@Hook
+ \def\qMark@Hook{\makebox[0pt][r]{\smash
+ {\raisebox{-7bp+\fboxsep}{\stepcounter{questionno}\textField[%
+ \cmd{\bParams{#1}\eParams}\F\FHidden\Q{1}
+ \AAkeystroke{\essayQKey}
+% \AAonfocus{var essayPtsAssigned=(1*event.value);}
+ \AAformat{if(event.value!="") event.value=event.value
+ +((event.value==1)?" \eqptLabel":" \eqptsLabel")}
+ \TU{\essayQFld@TU}
+ ]{essayMrkUp.\currQuiz.\thequestionno}{\EsW}{\EsH}%
+ \addtocounter{questionno}{-1}}}}\global
+ \let\qMark@Hook\qMark@HookSave}}
+% \end{macrocode}
+% The way you pose an essay question is as follows:
+%\begin{verbatim}
+% \essayQ{5}
+% \item\PTs{5} The question ...\\[3pt]
+% \RespBoxEssay{4in}{4\baselineskip}
+%\end{verbatim}
+%\leavevmode\DescribeMacro\essayitem\nmpsep{\darg{\ameta{num}}}
+% We simply this workflow a little, define \cs{essayitem}:
+% \begin{macrocode}
+\def\essayitem#1{\essayQ{#1}\item\PTs{#1}}
+% \end{macrocode}
+%Thus, we can now type,
+%\begin{verbatim}
+% \essayitem{5} The question ...\\[3pt]
+% \RespBoxEssay{4in}{4\baselineskip}
+%\end{verbatim}
+%
+% \section{Field level JavaScript for form field commands}
+%
+% JS\DescribeMacro\pwdInstrFld{} Keystroke action for \cmd\pwdInstrFld. This script
+% uses three parameters passed to it through {\cmd\pwdInstrFld}: \texttt{@p(1)} is the quiz
+% name (\cmd\currQuiz); \texttt{@p(2)} is the number of questions; and \texttt{@p(3)} is
+% the password.
+% \begin{macrocode}
+\begin{defineJS}[\catcode`\@=0\relax]{\pwdKeyJS}
+if (event.willCommit) {
+ if (event.value==@p(3)) {
+ @commonPassKey
+ }
+}
+\end{defineJS}
+\begin{defineJS}[\catcode`\@=0\relax]{\commonPassKey}
+% \end{macrocode}
+% Added code from \cs{qz@IDTxtField} to avoid the dreaded `q1 is undefined'
+% JavaScript error message. This happends when the \textsf{Mark It} control
+% and the \textsf{Begin Quiz} controls are on different pages. When \textsf{Mark It}
+% is pressed, `q1' has not been defined yet, not until the next page.
+% \changes{v1.4.7}{2019/08/27}{Added format code from \string\cs{qz@IDTxtField}}
+% \begin{macrocode}
+if(typeof aQuizzesInDoc=="undefined")
+ var aQuizzesInDoc=new Array();
+if (aQuizzesInDoc.indexOf("@oField"))
+ aQuizzesInDoc.push("@oField");
+if (typeof @oField=="undefined")
+ var @oField=new Object;
+restoreQuizData();
+this.calculate=true;
+var f=this.getField("postQzMsg");
+if (f!=null) f.display=display.hidden;
+var f=this.getField("pbStuSvCl");
+if (f!=null) f.display=display.hidden;
+var f=this.getField("ScoreField.@p(1)");
+if (f!=null) f.display=display.visible;
+var f=this.getField("PointsField.@p(1)");
+if (f!=null) f.display=display.visible;
+var f=this.getField("EssayField.@p(1)");
+if (f!=null) f.display=display.visible;
+var f=this.getField("TotalsField.@p(1)");
+if (f!=null) f.display=display.visible;
+var f=this.getField("essayMrkUp");
+if (f!=null) f.display=display.visible;
+correctQuiz("@p(1)",@p(2));
+var f=this.getField("qzreset");
+if (f!=null) f.display=display.visible;
+var f=this.getField("freezeQz");
+if (f!=null) f.display=display.visible;
+var f=this.getField("studentenReport");
+if (f!=null) f.display=display.visible;
+var f=this.getField("studentenGrade");
+if (f!=null) f.display=display.visible;
+if (typeof correctSumryTbl == "function")
+ correctSumryTbl("@p(1)",@p(2));
+\end{defineJS}
+% \end{macrocode}
+% Keystroke JS\DescribeMacro\essayQKey{} action for \cmd\essayQ. The
+% \texttt{@p(1)} parameter is the weight of this essay question, it is passed to
+% this script by \cmd\essayQ.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\NoNumEnteredMsg\nmpsep{\darg{\ameta{jsstr}}} When you enter a non-number,
+% and an alert box pops up with this as its message.
+% \begin{macrocode}
+\def\NoNumEnteredMsg#1{\flJSStr*[noquotes]{\cNoNumEnteredMsg}{#1}}
+\NoNumEnteredMsg{"You did not enter a number, %
+enter a nonnegative number only"}
+% \end{macrocode}
+% \DescribeMacro\TooMuchCreditMsg\nmpsep{\darg{\ameta{jsstr}}} When you assign too
+% much credit for the problem, an alert box appears containing this message.
+% \begin{macrocode}
+\def\TooMuchCreditMsg#1{\flJSStr*[noquotes]{\cTooMuchCredit}{#1}}
+\TooMuchCreditMsg{"You've assigned too much credit for this %
+problem, assigning the maximum instead"}
+% \end{macrocode}
+% Now the definition of \cmd\essayQKey
+% \changes{v1.1.1}{2019/06/30}{Corrected a bug in \string\cs{essayQKey} that caused
+% a miscalculation.}
+% \changes{v1.1.3}{2019/07/03}{Remove lines not needed since \string\cs{LngPtsFld} became
+% a calculation field}
+% \begin{macrocode}
+\begin{defineJS}[\makeesc\@\catcode`\%=14\relax]{\essayQKey}
+if (event.willCommit) {
+ var qpts=(1*event.value);
+ if (isNaN(qpts)) {
+ app.alert(@cNoNumEnteredMsg);
+ event.rc=false;
+ } else if (qpts<0) {
+ event.value=-1*event.value;
+ qpts=1*event.value;
+ }
+ if (event.rc) {
+ if (qpts > @p(1) ) {
+ app.alert(@cTooMuchCredit);
+ qpts=@p(1);
+ }
+ // update ProbDist array
+ ProbDist[@thequestionno]=qpts;
+ // see if table is present
+ if (typeof correctSumryTbl == "function") {
+ f=this.getField("%
+@dlcombine(@currQuiz)(SanityCheckPts).@thequestionno");
+ var thesePts= qpts + (( qpts == 1 )?%
+" @eqptLabel":" @eqptsLabel");
+ f.value=thesePts;
+ // add color
+ var cb=this.getField("%
+@dlcombine(@currQuiz)(SanityCheck).@thequestionno");
+ if (qpts==@p(1)) cb.strokeColor=@rghtColorJS;
+ else if (qpts>0) cb.strokeColor=@partialColorJS;
+ else cb.strokeColor=@wrngColorJS;
+ }
+ event.value=qpts;
+ }
+}
+\end{defineJS}
+% \end{macrocode}
+% \DescribeMacro\instrAutoSaveOn When the instructor presses the freeze quiz control, there is an option
+% to automatically save the document or not. \cmd\instrAutoSaveOn{} saves the document; however, if
+% \DescribeMacro\instrAutoSaveOff\cmd{\instrAutoSaveOff} is expanded in the preamble, no automatic
+% save is performed. The default is \cmd\instrAutoSaveOn.
+% \begin{macrocode}
+\def\instrAutoSaveOn{\def\instrAutoSave{true}}
+\def\instrAutoSaveOff{\def\instrAutoSave{false}}
+\instrAutoSaveOn
+% \end{macrocode}
+% \DescribeMacro\instrAutoCloseOn When the instructor presses the freeze quiz control, there is an option
+% to silently close the document or not. \cmd\instrAutoCloseOn{} closes the document; however, if
+% \DescribeMacro\instrAutoCloseOff\cmd{\instrAutoCloseOff} is expanded in the preamble, no automatic
+% closing occurs. The default is \cmd{\instrAutoCloseOn}.
+% \begin{macrocode}
+\def\instrAutoCloseOn{\def\instrAutoClose{true}}
+\instrAutoCloseOn
+\def\instrAutoCloseOff{\def\instrAutoClose{false}}
+% \end{macrocode}
+% The mouse up\IndexJS{freezeQuizMU()}{} JavaScript for \texttt{freezeQuiz()}. It makes all form fields
+% \emph{in the entire document} readonly. \emph{Use only} after all markups are finished and document is ready
+% to be moved into the student's folder.
+% \changes{v1.4.12}{2019/09/11}{Correction a problem with \string\cs{MarkWarningMsg}
+% in the dvips/distiller workflow}
+% \begin{macrocode}
+\def\MarkWarningMsg#1{\dlJSStr*[noquotes]{\MarkWarning@Msg}{#1}}
+\MarkWarningMsg{"You did not award the student a final mark.\
+ \\n\\nAward the mark and then save."}
+% \end{macrocode}
+% The \DescribeMacro\flattenOn\cs{flattenOn} turns on flattening, while
+% \DescribeMacro\flattenOff\cs{flattenOff} turns flattening off. The reason
+% you would turn flattening off is to use \textsf{Thor's way} for basic methods
+% and for the \opt{useclass} option. The default is \cs{flattenOff} for basic methods
+% and \cs{flattenOn} for \opt{usebatch}. Applies only when the \texttt{Freeze Quiz}
+% button is present.
+% \changes{v1.4.13}{2019/09/12}{Added \string\cs{flattenOn} and \string\cs{flattenOff}}
+% \begin{macrocode}
+\def\flattenOn{\def\bFlattenState{false}}
+\def\flattenOff{\def\bFlattenState{true}}
+\ifbasicmethods\flattenOff\else\flattenOn\fi
+% \end{macrocode}
+% The definition of \texttt{freezeMU()}.
+% \begin{macrocode}
+\begin{insDLJS}{jsforthor}{thorshammer: Freeze/Save Doc}
+var sndSaveWarning=\SecondSave@Msg;
+var isthereCvrPg=\thIsCP;
+var cvrPgNum="\thCvrPg";
+function freezeQuizMU() {
+var f, fname;
+var bOK=true;
+var f=this.getField("studentenGrade");
+var str=""+f.value;
+str=str.replace(/\s/g,"");
+if (str=="") {
+ app.alert(\MarkWarning@Msg);
+ bOK=false;
+}
+% \end{macrocode}
+% Determine if there are solution pages, and if so, re-insert them.
+% \changes{v1.4.8}{2019/09/05}{Append solution pages if there is one}
+% \begin{macrocode}
+var SolnSet=this.info.SolnSet;
+if (bOK&&SolnSet!=""){
+ var SolnPath=this.info.SolnPath;
+// var SolnSet=this.info.SolnSet;
+ var qzbasename=this.info.qzBaseName;
+ aebTrustedFunctions(this,aebInsertPages,{
+ nPage: (this.numPages-1),
+ cPath: SolnPath+"/"+qzbasename+"-"+SolnSet+".pdf"
+ })
+};
+% \end{macrocode}
+% If \cs{thUseNameToCustomize} is true, we use the current file name; otherwise
+% we use the original file name (\cs{jobname})
+% \begin{macrocode}
+if(\instrAutoSave&&bOK) {
+// var cSave="\jobname";
+ var docFN=this.documentFileName;
+ docFN=docFN.substring(0,docFN.length-4);
+ var cSave=(\thUseNameToCustomize)?"\jobname":docFN;
+% \end{macrocode}
+% If \cs{thUseNameToCustomize} is true, we append student and \texttt{"-g"}
+% to signal that this file has been graded.
+% \begin{macrocode}
+ if(\thUseNameToCustomize) {
+ var f=this.getField("Name.first");
+ if(f!=null)cSave+=("-"+f.value+"_");
+ f=this.getField("Name.last");
+ if(f!=null)cSave+=(f.value);
+ cSave+=("-g");
+ }
+ var oRetn=aebTrustedFunctions(this,aebBrowseForDoc,{bSave:true,%
+cFilenameInit: cSave });
+ bOK=(typeof oRetn=="object");
+ if(bOK) {
+% \end{macrocode}
+% If the file name and path are chosen, we make all files readonly
+% \begin{macrocode}
+ for (var i=0; i<this.numFields; i++) {
+ fname=this.getNthFieldName(i);
+ f=this.getField(fname);
+ f.readonly=true;
+ }
+% \end{macrocode}
+% After making all fields readonly, we hide the freeze quiz button itself.
+% \begin{macrocode}
+ var f=this.getField("MarkIt");
+ if (f!=null)f.display=display.hidden;
+ f=this.getField("freezeQz");
+ if (f!=null)f.display=display.hidden;
+% \end{macrocode}
+% (2019/06/30) J\"{u}rgen suggested to flatten the document to add more security.
+% \changes{v1.1}{2019/06/30}{Added flattening}
+% \changes{v1.1.6}{2019/07/06}{Added save as requiring acrobat}
+% \changes{v1.2.1}{2019/07/19}{Inserted test for \string\texttt{oRecordOfQuizData} before saving,
+% this avoids the message that appears in the console that 'f is null'}
+% \begin{macrocode}
+ if(typeof _flattenThisDoc=="undefined")this.flattenPages();
+% \end{macrocode}
+% Now we are ready to save the file
+% \begin{macrocode}
+ oRecordOfQuizData=undefined;
+% \end{macrocode}
+% If instructor uses \textsf{Thor's way}, we don't want to reattach
+% the solution page as it has already been reattached in this
+% workflow.
+% \begin{macrocode}
+ this.info.SolnSet="";
+ var retn=aebTrustedFunctions(this,aebDocSaveAs,%
+{cPath:oRetn.cPath,cFS:oRetn.cFS});
+ }
+}
+if(\instrAutoClose&&bOK) this.closeDoc(true);
+}
+\end{insDLJS}
+\begin{defineJS}[\catcode`\@=0\relax]{\freezeQuizMU}
+var f, fname;
+var bOK=true;
+if(@instrAutoSave) {
+ var cSave="@jobname";
+ var f=this.getField("Name.first");
+ if(f!=null)cSave+=("-"+f.value+"_");
+ f=this.getField("Name.last");
+ if(f!=null)cSave+=(f.value);
+ var oRetn=aebTrustedFunctions(this,aebBrowseForDoc,{bSave:true,@%
+cFilenameInit: cSave });
+ bOK=(typeof oRetn=="object");
+ if(bOK) {
+% \end{macrocode}
+% If the file name and path are chosen, we make all files readonly
+% \begin{macrocode}
+ for (var i=0; i<this.numFields; i++) {
+ fname=this.getNthFieldName(i);
+ f=this.getField(fname);
+ f.readonly=true;
+ }
+% \end{macrocode}
+% After making all fields readonly, we hide the freeze quiz button itself.
+% \begin{macrocode}
+ var f=this.getField("MarkIt");
+ if (f!=null)f.display=display.hidden;
+ f=this.getField("freezeQz");
+ if (f!=null)f.display=display.hidden;
+% \end{macrocode}
+% (2019/06/30) J\"{u}rgen suggested to flatten the document to add more security.
+% \changes{v1.1}{2019/06/30}{Added flattening}
+% \changes{v1.1.6}{2019/07/06}{Added save as requiring acrobat}
+% \begin{macrocode}
+ this.flattenPages();
+% \end{macrocode}
+% Now we are ready to save the file
+% \changes{v1.4.1}{2019/08/16}{Added cFS to aebDocSaveAs}
+% \begin{macrocode}
+ var retn=aebTrustedFunctions(this,aebDocSaveAs,@%
+{cFS:oRetn.cFS,cPath: oRetn.cPath });
+ }
+}
+if(@instrAutoClose&&bOK) this.closeDoc(true);
+\end{defineJS}
+% \end{macrocode}
+% \section{Modifications and redefinitions of AeB}
+% We modify various commands of \pkg{exerquiz} to conform the goals
+% of the mighty Thor.
+%
+% \subsection{Quiz components modified}
+% We begin by modifying the \cs{RespBoxEssay} action.
+% \begin{macrocode}
+\def\@@RespBoxEssayActions{%
+ \AA{\if\eqQuizType\isQZ
+ \AAKeystroke{%
+ if(event.willCommit){\jsR\jsT
+ RecordPointValue(\eqPTs,\thequestionno);\jsR\jsT
+ RecordProblemType("\eqQT",\thequestionno);\jsR
+% \end{macrocode}
+% The next three lines are inserted. After user has left the
+% text field, we determine if he/she did anything. If \texttt{event.value},
+% stripped of all white space, is empty, nothing was done and we mark
+% the response as \texttt{undefined}; otherwise we mark it as
+% \texttt{"<essay>"}. The fact that the \texttt{Responses} array
+% is nonempty for this question will cause a check mark to appear
+% in the summary table.
+% \begin{macrocode}
+ var stripResp=stripWhiteSpace(event.value);\jsR\jsT
+ if(stripResp=="")Responses[\thequestionno]=undefined;\jsR\jsT
+ else Responses[\thequestionno]="<essay>";\jsR\jsT
+ if ( typeof fieldPopTbl == "function" ) fieldPopTbl("\currQuiz");
+ }\jsR
+ if (!isQuizInitialized("\curr@quiz")) {\jsR\jsT
+ \eqObjAlert\space eqAppAlert(%
+ InitMsg("\bqlabelISO"),3);\jsR\jsT
+ event.rc = false;\jsR
+ }%
+ }%
+ \fi
+ }
+}
+% \end{macrocode}
+% We redefine \cs{@initQuiz} from \pkg{exerquiz} to first test whether
+% name fields have been entered.
+% \changes{v1.1.6}{2019/07/06}{Check on name fields}
+% \begin{macrocode}
+\def\InitQzMsg#1{\flJSStr*[noquotes]{\InitQzMsg@Msg}{#1}}
+\InitQzMsg{"You cannot begin the quiz before entering
+ your first and last names in the fields provided.\n\n
+ Enter the name as you are known in the class; otherwise,
+ you will receive no credit for your work."}
+\def\IfbQzChkSnippet{%
+this.calculate=false;\jsR
+if(\thOrdQz) bOk=true\jsR
+else {\jsR\jsT
+ var f=this.getField("Name.first");\jsR\jsT
+ var str1=stripWhiteSpace(f.value);\jsR\jsT
+ var f=this.getField("Name.last");\jsR\jsT
+ var str2=stripWhiteSpace(f.value);\jsR\jsT
+ bOk=(str1!=""&&str2!="");\jsR
+}
+if(bOk)}
+\expandafter\def\expandafter\@initQuiz\expandafter
+ {\expandafter\IfbQzChkSnippet\expandafter{\@initQuiz}
+ else app.alert({cMsg:\InitQzMsg@Msg,cTitle:\ThorsAlert@Title});
+}
+% \end{macrocode}
+% Modify \DescribeMacro\postSubmitQuiz\cmd\postSubmitQuiz.
+% When the \textsf{End Quiz} control is pressed, we make visible the post
+% quiz message, placed in the document by the \cmd\completeMsgFld{} command.
+% \begin{macrocode}
+\toks@=\expandafter{\postSubmitQuiz\t\t
+ oRecordOfQuizData["ProbDist.\oField"]=ProbDist;\r\t\t
+ oRecordOfQuizData["RightWrong.\oField"]=RightWrong;\r\t\t
+ var f=this.getField("postQzMsg");\r\t\t
+ if (f!=null) f.display=display.visible;\r\t\t
+ var f=this.getField("pbStuSvCl");\r\t\t
+ if (\stuAutoSave&&f!=null)f.display=display.visible;} %\r\t\t
+\edef\postSubmitQuiz{\the\toks@}
+% \end{macrocode}
+% The action for the End Quiz button, we modify it to give the student a chance to reconsider
+% his decision to end the quiz.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\EndQzWarningMsg\nmpsep{\darg{\ameta{jsstr}}} The message that appears
+% on the alert box asking to student to verify ending the quiz.
+% \changes{v1.1.6}{2019/07/06}{Added end quiz warning}
+% \begin{macrocode}
+\def\EndQzWarningMsg#1{\flJSStr*[noquotes]{\EndQzWarning@Msg}{#1}}
+\EndQzWarningMsg{"When you end the quiz, you cannot change
+any of your answers without starting the quiz over from the
+beginning.\n\n Press \\"Yes\\" to end the quiz."}
+\def\ThorsAlertTitle#1{\flJSStr*[noquotes]{\ThorsAlert@Title}{#1}}
+\ThorsAlertTitle{"Thor's Hammer"}
+% \end{macrocode}
+% \DescribeMacro\eq@EndQzBtnScript The modified script for the end of the
+% quiz button. We rework the script of \cs{eq@@EndQuizButtonActions}, taken from \pkg{exerquiz}.
+% \begin{macrocode}
+\begin{defineJS}[\makeesc\*\catcode`\%=14\relax]{\eq@EndQzBtnScript}
+if (!isQuizInitialized("*currQuiz"))
+ eqAppAlert(InitMsg("*bqlabelISO"),3);
+else {
+ var retn=app.alert({cMsg: *EndQzWarning@Msg,%
+cTitle: *ThorsAlert@Title, nIcon: 2, nType: 2});
+ if (retn==4) {
+ if (*minQuizResp(*thequestionno)&&_ModalNotOn){
+ *currQuiz.PtValues=(new %
+Array(*pointValuesArray));
+ ProbType=[*ptypeArray];
+*if@inclkey%
+ *currQuiz.CorrAns=(new %
+Array(*corrAnsArray));
+*fi%
+ DisplayQuizResults("*currQuiz",*theeqpointvalue,%
+*thequestionno);
+ var h=this.getField("ScoreData.*currQuiz");
+ h.value=Score+";"+NQuestions+";"%
++ptScore+";"+NPointTotal;
+% *eq@submitURL
+ *postSubmitQuiz
+ resetQuiz("*currQuiz");
+ }
+ }
+}
+\end{defineJS}
+% \end{macrocode}
+% Now, we redefine \cs{eq@@EndQuizButtonActions} of \pkg{exerquiz}.
+% \begin{macrocode}
+\def\eq@@EndQuizButtonActions{\A{\JS{\eq@EndQzBtnScript}}}
+% \end{macrocode}
+% Add a \textsf{SaveAs} menu item to end of the quiz
+% \changes{v1.1.4}{2019/07/04}{Add a SaveAs menu item to end of the quiz}
+% \changes{v1.1.5}{2019/07/06}{If document is dirty, do not save}
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\stuAutoSaveOn When expanded in the preamble, a save button will appear (\cmd\stuSaveBtn)
+% when the \textsf{End Quiz} control is pressed. A dialog appears to save the file, the student can choose
+% the file location and the file name at that time. When \DescribeMacro\stuAutoSaveOff\cmd\stuAutoSaveOff{}
+% is in effect, the save button does not appear, and the student must press the save button the on
+% \app{Adobe Reader} toolbar. The default is \cmd\stuAutoSaveOn.
+% \begin{macrocode}
+\let\stuASOn\ef@YES
+\def\stuAutoSaveOn{\let\stuASOn\ef@YES
+ \def\stuAutoSaveScript{\t app.execMenuItem("SaveAs");\r}%
+ \def\stuAutoSave{true}}
+\def\stuAutoSaveOff{\let\stuASOn\ef@NO
+ \let\stuAutoSaveScript\@empty
+ \def\stuAutoSave{false}}
+\stuAutoSaveOn
+% \end{macrocode}
+% \DescribeMacro\stuAutoCloseOn This command is obeyed only if \cmd{\stuAutoSaveOn}
+% is in effect. After the student presses the save button (\cmd\stuSaveBtn), the
+% document is closed after the student save the document. Note that if the student
+% cancels saving the document and if the document still needs saving, the document
+% is not closed. The default is \cmd\stuAutoCloseOn.
+% \begin{macrocode}
+\def\stuAutoCloseOn{\def\stuAutoCloseScript{\t
+ if(!this.dirty)this.closeDoc(true);\r}%
+ \def\stuAutoClose{true}}
+\stuAutoCloseOn
+\def\stuAutoCloseOff{\let\stuAutoCloseScript\@empty
+ \def\stuAutoClose{false}}
+% \end{macrocode}
+% \DescribeMacro\stuSaveBtnCA\nmpsep{\darg{\ameta{jsstr}}} The caption for this button
+% \begin{macrocode}
+\def\stuSaveBtnCA#1{\def\stuSaveBtn@CA{#1}}
+\stuSaveBtnCA{Save}
+% \end{macrocode}
+% \DescribeMacro\stuSaveBtnTU\nmpsep{\darg{\ameta{jsstr}}} The tool tip for this button
+% \begin{macrocode}
+\def\stuSaveBtnTU#1{\def\stuSaveBtn@TU{#1}}
+\stuSaveBtnTU{Press to save and close the document}
+% \end{macrocode}
+% \DescribeMacro\stuSaveBtn\nmpsep{[\ameta{options}]\darg{\ameta{wd}}\darg{\ameta{ht}}}
+% This button is initially hidden and becomes visible within the student presses
+% the \textsf{End Quiz} control; provided \cs{stuAutoSaveOn} is in effect. The button
+% saves and optionally closes the document.
+% \begin{macrocode}
+% \end{macrocode}
+% \leavevmode\DescribeMacro\autoSaveStuJS is a revised version of the JavaScript action
+% for \cs{stuSaveBtn}. If the JavaScript method \texttt{aebTrustedFunctions} is undefined, we use the old code;
+% otherwise, we use the new code.
+% \changes{v1.5.5}{2019/12/08}{Use \string\texttt{aebTrustedFunctions} if present}
+%
+% \medskip\noindent\DescribeMacro\SecondSaveMsg\nmpsep{\darg{\ameta{msg}}} is an alert dialog message stating
+% the the document was not saved. This declaration mush occur on the preamble of in the CFG file, or is has no effect.
+% \begin{macrocode}
+\def\SecondSaveMsg#1{\dlJSStr*[noquotes]{\SecondSave@Msg}{#1}}
+\SecondSaveMsg{"Alert! This document has not been saved, do not
+ exit before saving!"}
+% \end{macrocode}
+% When \texttt{aebTrustedFunctions} is defined for \app{AR}, we offer two methods for the student
+% to save the document: (1) \DescribeMacro\useStuSaveAsDialogOff\cs{useStuSaveAsDialogOff} (the default)
+% is the most seamless method, no save-as dialog is offered, the student asked to confirm the save; (2)
+% \DescribeMacro\useStuSaveAsDialogOn\cs{useStuSaveAsDialogOn} offers the save-as dialog (but streamlined).
+% These two commands must appear on the preamble or CFG file, or they have no effect.
+% \begin{macrocode}
+\newif\ifUseStuSaveAsDialog\UseStuSaveAsDialogfalse
+\def\useStuSaveAsDialogOn{\UseStuSaveAsDialogtrue}
+\def\useStuSaveAsDialogOff{\UseStuSaveAsDialogfalse}
+\begin{defineJS}[\makeesc\*\catcode`\%=14\relax]{\autoSaveStuJS}
+ var bOK=true;
+ global.bOkClose=true;
+ var _path=this.path;
+ var pos=_path.lastIndexOf("/");
+ var currentFolder=_path.substring(0,pos+1);
+ var docFN=this.documentFileName;
+ docFN=docFN.substring(0,docFN.length-4);
+ var cSave=(*thUseNameToCustomize)?"*jobname":docFN;
+ currentFolder=currentFolder+cSave+".pdf";
+ if (typeof aebTrustedFunctions=="undefined")
+ app.execMenuItem("SaveAs");
+ else {
+% \end{macrocode}
+% In this controlled environment of taking PDF quizzes at an institution,
+% the AeB special function \texttt{aebTrustedFunctions} is defined,
+% along with supporting functions.
+% \begin{macrocode}
+*ifUseStuSaveAsDialog%
+ var oRetn=aebTrustedFunctions(this,aebBrowseForDoc,%
+{bSave:true,cFilenameInit: cSave });
+ bOK=(typeof oRetn=="object");
+*fi%
+% \end{macrocode}
+% If the user dismisses the browse-for-doc dialog, the return value (\texttt{oRetn}) is undefined;
+% in this case, we do not save or close the document. The user must initiate the action
+% again.
+% \changes{v1.5.7}{2020/01/13}{Added delete global.bOkClose}
+% \begin{macrocode}
+ aebDocSaveAs.msg="";
+ aebDocSaveAs.action=%
+'global.bOkClose=false;app.alert("'+sndSaveWarning+'")';
+ if (bOK) var retn=aebTrustedFunctions(this,aebDocSaveAs,%
+{cPath:*ifUseStuSaveAsDialog oRetn.cPath*else currentFolder*fi });
+ else app.alert(sndSaveWarning);
+ }
+ if(*stuAutoClose&&bOK&&global.bOkClose&&!this.dirty)
+ delete global.bOkClose;
+ this.closeDoc(true);
+\end{defineJS}
+% \end{macrocode}
+% We finally reach the definition of \cs{stuSaveBtn}
+% \begin{macrocode}
+\newcommand\stuSaveBtn[3][]{\pushButton[\F\FHidden
+ \CA{\stuSaveBtn@CA}\TU{\stuSaveBtn@TU}
+% \end{macrocode}
+% Here, we leverage the new \cs{cmd} command to test if auto save is on, if not
+% we gobble the \cs{AAmouseup} action.
+% \begin{macrocode}
+ \cmd{\ifx\stuASOn\ef@NO\let\@eqAAmouseup\@gobble\fi}
+ \AAmouseup{if(\stuAutoSave){\r
+ \autoSaveStuJS
+% \stuAutoSaveScript\stuAutoCloseScript
+ }}\protect\AA\protect\F#1
+]{pbStuSvCl}{#2}{#3}}
+% \end{macrocode}
+% \DescribeMacro\DeclareQuiz\nmpsep{\darg{\ameta{qz-name}}}
+% We modify the \cs{DeclareQuiz} command of \pkg{exerquiz}, by appending
+% some code that defines \cs{eq@prior@endQuiz} to write the number of questions
+% and the number of points to the AUX file.
+% This command \emph{must appear}\marginpar{\raggedleft Required in preamble or at top of file} at the top of the source file, just after
+% \verb|\begin{document}| or in the \emph{preamble}, it defines \cs{currQuiz} for the rest of the document,
+% and write to AUX file. When using multi-quizzes in one source file, this package redefines the \cs{currQuiz}; for example,
+% if originally, you declared \cs{DeclareQuiz\darg{Quiz1}}, the first renditions uses the quiz name
+% \texttt{Quiz1a}, the second \texttt{Quiz1b}, and so on. (Limit of 26 renditions). To preserve the original
+% quiz name, we define \DescribeMacro\thQuizName\cs{thQuizName}, this command expands to \cs{Quiz1} within all
+% renditions; consequently, can be used in the running head to consistently display the quiz name.
+% \begin{macrocode}
+\let\DeclareQuizSAVE\DeclareQuiz
+\def\DeclareQuiz#1{\def\thQuizName{#1}\th@DeclareQuiz{#1}}
+\def\th@DeclareQuiz#1{\DeclareQuizSAVE{#1}%
+ \expandafter\gdef\expandafter
+ \eq@prior@endQuiz\expandafter{\eq@prior@endQuiz\wrtQzInfo}}
+% \end{macrocode}
+% \DescribeMacro\thQzName\nmpsep{\darg{\ameta{friendly-qz-name}}} This is the friendly (human readable)
+% quiz name, suitable for use in the running header and elsewhere.
+% \begin{macrocode}
+\def\thQzName#1{\def\thqzname{#1}}
+\thQzName{\thQuizName}
+% \end{macrocode}
+% \begin{macrocode}
+\def\wrtQzInfo{\eq@IWAuxOut{\string
+ \csarg\string\gdef{\currQuiz-nQs}{\thequestionno}^^J\string
+ \csarg\string\gdef{\currQuiz-nPts}{\theeqpointvalue}}}
+% \end{macrocode}
+% We modify \DescribeMacro\eqQuizPointsMsg\cmd\eqQuizPointsMsg{}, its default definition
+% is the string \begin{quote}\ttfamily"\string\eqptScore\string\space"+ptScore+"
+% \string\eqOutOf\string\space"+nPointTotal\end{quote}but for Thor's way, we simplify to \texttt{ptScore}.
+% \begin{macrocode}
+\renewcommand\eqQuizPointsMsg{ptScore}
+% \end{macrocode}
+% \subsection{Modify margin points markup}
+% Make the markup boxes in the margins larger.
+% \begin{macrocode}
+\renewcommand{\aeb@creditmarkup}{\bgroup
+ \edef\markupWidth{\EsW}\edef\markupHeight{\EsH}%
+ \textField[\Ff\FfReadOnly\BC{}\F\FHidden
+ \textColor{\pcMarkupColor}\textSize{\markupTextSize}\autoCenter{y}%
+ \DV{0 \eqptsLabel}\V{0 \eqptsLabel}]%
+ {qMark.\currQuiz.\thequestionno.\arabic{qMarkCnt}}%
+ {\markupWidth}{\markupHeight}\egroup}
+% \end{macrocode}
+%
+% \subsection{Modifications to the summary table}
+% We modify the summary table to make the markup points larger and
+% left align the second column. Thor may come down on me with his mighty hammer, but
+% I'll take the chance.
+% \begin{macrocode}
+\def\eq@begintab{% second column left aligned
+ \begin{tabular}[t]{llc}\sumryTblQ&\sumryTblR&\sumryTblP\\\sthline
+ {\Large\strut}}%
+\let\st@scndclmnSAVE\st@scndclmn
+% \end{macrocode}
+% Offset the check boxes by 2bp to better align with the heading
+% \begin{macrocode}
+\def\st@scndclmn{\kern2bp\st@scndclmnSAVE}
+% \end{macrocode}
+% Increase the width of the markup boxes (from 12bp to 20bp, and change to a fixed text size
+% \begin{macrocode}
+\def\stmarkupWidth{20bp} % normally 12bp
+\def\stmarkupHeight{9bp} % unchanged
+\def\stmarkupTextSize{8} % normally 0pt
+% \end{macrocode}
+% Offset the check boxes by 2bp to better align with the heading
+% \begin{macrocode}
+\def\stmarkupbox{\mbox} % normally {\makebox[0pt][l]}
+%\def\sumrytbllinkHook#1{\the\value{page}}
+\def\st@thrdclmn#1{\setLink[\linktxtcolor{black}
+ \A{\JS{this.pageNum=(this.pageNum+#1-1)}}]{\sumrytbllinkHook{#1}}}
+% \end{macrocode}
+%
+% \subsection{Boom! Thor's thunders: ``Thor needs solutions!''}
+%
+% The package was complete, then it wasn't. \cs{RespBoxEssay} never supported
+% solutions, so that needed to be fixed, now requiring \pkg{exerquiz} dated
+% 2019/08/13 or later.\par\medskip
+%
+% The first issue addressed here is the labeling of the solutions to the quiz.
+% We try a simple enumeration of the solutions. For that, the \cs{fancyQuizHeaders}
+% is used from \pkg{exerquiz}.
+% \begin{macrocode}
+\fancyQuizHeaders
+\setsolnspace{}
+\let\FncyHdrsFmtNoTitleQuiz\@empty
+% \end{macrocode}
+% The question numbers protrude into the left margin, to disguise this, wes
+% shift the running header over a little
+% \changes{v1.4.5}{2019/08/25}{Added command to remove shift for solns headers}
+% \begin{macrocode}
+\setlength{\eflength}{\widthof{\textbf{00.}\space}}
+\edef\th@leftShiftHdr{\the\eflength}
+\def\th@HeaderOffset{\hskip-\th@leftShiftHdr\relax}
+\def\doNotShirtSonsHdrs{\let\th@HeaderOffset\relax}
+% \end{macrocode}
+% \DescribeMacro\thQzSolnMrkr\cmd{\thQzSolnMrkr} is a small text field that is inserted under the
+% section title. This is used to identify on what page the solutions begin.
+% Later used by \cs{sadQuizzes}.
+% \begin{macrocode}
+\def\thQzSolnMrkr{\textField[\BC{}]{thsolns4.\currQuiz}{1bp}{1bp}}
+% \end{macrocode}
+% The quiz numbers will go in the left margin, so we'll shift
+% the section title over a little to disguise this.
+% \begin{macrocode}
+\def\quizSolnsHeadnToc{\section*
+ {\makebox[0pt][l]{\th@HeaderOffset
+ \thQzSolnMrkr\sqslsectitle}}%
+ \addcontentsline{toc}{section}{%
+ \@ifundefined{web@latextoc}{}{%
+ \ifx\web@latextoc\eq@YES\else
+ \protect\numberline{}\fi}\sqslsectitle}}
+\renewcommand\eq@sqslsectitle{Solutions to the Quiz}
+% \end{macrocode}
+% \DescribeMacro\myFQHFmt describes the numbering scheme
+% for the solutions.
+% \begin{macrocode}
+\newcommand\myFQHFmt{%
+ \string\bfseries\string\color{\fncyQHdrsColor}%
+ \ifx\aebTitleQuiz\@empty
+ \ifnum\@eqquestiondepth>0\relax
+ \FncyHdrsFmtNoTitleQuiz\fi\else
+ \aebTitleQuiz\protect\
+ \ifnum\@eqquestiondepth=0\else\\\relax
+ \FncyHdrsFmtQuestion\fi
+ \fi %\space
+ \ifcase\@eqquestiondepth
+ \ifx\aebTitleQuiz\@empty\FncyHdrsFmtNoTitleQuiz\fi
+ \or
+ \string\llap{\arabic{eqquestionnoi}.\space}%
+ \or
+ \string\llap{\arabic{eqquestionnoi}.\space}%
+ (\alph{eqquestionnoii})\space
+ \or
+ \string\llap{\arabic{eqquestionnoi}.\space}%
+ (\alph{eqquestionnoii})%
+ (\roman{eqquestionnoiii})\space
+ \fi
+}
+\dclrFncyQzHdrsFmt{\myFQHFmt}
+% \end{macrocode}
+% No return symbol or link to the question.
+% \begin{macrocode}
+\let\ReturnTo\@gobbletwo
+% \end{macrocode}
+%
+% \subsection{Modifications to the \texorpdfstring{\protect\pkg{web}}{web} package}
+%
+% The TEX template file (\texttt{tex-template.tex}, generated by \texttt{thmclass.ps1})
+% specifies the \pkg{web} package
+% and uses many command particular to that package. Here, we create a special command
+% to input customization commands that are specified in the \texttt{web.cfg} file. Place
+% \DescribeMacro\inputWebCfg\cs{inputWebCfg} in the preamble to input the \texttt{web.cfg};
+% any \cs{ExecuteOptions} commands are ignored. Customization commands are placed between
+% the two marks \cs{bWebCustomize} and \cs{eWebCustomize}.
+% \changes{v1.5.1}{2019/10/23}{Allow \string\texttt{web.cfg} to be imported in the preamble.}
+%
+% \begin{macrocode}
+\let\bWebCustomize\endinput
+\let\eWebCustomize\relax
+\providecommand{\inputWebCfg}{%
+ \let\bWebCustomize\relax
+ \let\eWebCustomize\endinput
+ \let\ExecuteOptions@SAVE\ExecuteOptions
+ \let\ExecuteOptions\@gobble
+ \makeatletter
+ \InputIfFileExists{web.cfg}{}{}\makeatother
+ \let\ExecuteOptions\ExecuteOptions@SAVE
+ \let\bWebCustomize\endinput
+ \let\eWebCustomize\relax
+}
+% \end{macrocode}
+%
+% \section{The \texttt{useclass} option and above}
+%
+% These options (\opt{useclass}, \opt{usebatch}, and \opt{batchdistr}) are designed for the mass production of the quizzes, one for each student
+% in the class. The quiz is built and saved (for each student), saved to the instructor's
+% designated folder, as declared by \cs{instrPath}, and to the student's personal folder
+% as declared within the \cs{classMember} entry and \cs{classEntries} array.
+%
+% \subsection{Declaring class members}\label{s:ICInfo}
+% In conjunction with \cs{instrPath} and \cs{classPath}, use \cs{classMember} to declare
+% the identity of each member of the class.
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\classMember\nmpsep{*\darg{\ameta{first-name}}\darg{\ameta{last-name}}*\darg{\ameta{folder{\upshape\string|}path}}}
+% Enter the first name, last name, and folder name of each student in the class. When the star
+% form is used, \ameta{first-name} and \ameta{last-name} are first passed through
+% \cs{pdfstringdef}. If the second star-open is specified between the second and third arguments, the third argument
+% should be the absolute path to the (exceptional) student.\medskip
+%
+% \noindent There are several ways of producing characters in the Latin-1 character set:
+%\begin{itemize}
+% \item unicode method\DescribeMacro\u: |\classMember{J\u00FCrgen}{Loki}{B}|
+%
+% \item using \cs{pdfstringdef}\DescribeMacro{\classMember*}, in this case use the star version of \cs{classMember}
+% |\classMember*{J\"{u}rgen}{Loki}{B}|
+%
+% \item octal method\DescribeMacro\oct: |\classMember{J\oct374rgen}{Loki}{B}| or\\
+% \phantom{octal method:} |\classMember{J\string\374rgen}{Loki}{B}|
+%\end{itemize}
+% \begin{macrocode}
+\def\classEntriesDef{["","","",false]}
+\newif\ifClassEntries\ClassEntriesfalse
+\let\classEntries\@gobble
+\def\classMember{\ClassEntriestrue\@ifstar
+ {\let\th@star\ef@YES\classMember@i}
+ {\let\th@star\ef@NO\classMember@i}}
+\newcommand\classMember@i[2]{%
+ \@ifstar{\let\th@exstar\ef@YES\classMember@ii{#1}{#2}}
+ {\let\th@exstar\ef@NO\classMember@ii{#1}{#2}}}
+\newcommand\classMember@ii[3]{%
+ \ifx\th@exstar\ef@YES\def\AbsPth{true}\else
+ \def\AbsPth{false}\fi
+ \ifx\th@star\ef@NO
+ \ifx\th@exstar\ef@YES
+ \g@addto@macro\classEntries{,["#1","#2","#3",true]}\else
+ \g@addto@macro\classEntries{,["#1","#2","#3",false]}\fi
+ \else
+ \g@addto@macro\classEntries{,["}%
+ \pdfstringdef\x{#1}\expandafter
+ \g@addto@macro\expandafter\classEntries\expandafter{\x}%
+ \g@addto@macro\classEntries{","}%
+ \pdfstringdef\x{#2}\expandafter
+ \g@addto@macro\expandafter\classEntries\expandafter{\x}%
+ \g@addto@macro\classEntries{","}%
+ \pdfstringdef\x{#3}\expandafter
+ \g@addto@macro\expandafter\classEntries\expandafter{\x}%
+ \ifx\th@exstar\ef@YES
+ \g@addto@macro\classEntries{",true]}\else
+ \g@addto@macro\classEntries{",false]}\fi
+ \fi}
+% \end{macrocode}
+%
+% \subsection{Some process controls}
+%
+% During document development, you don't want to copy the files each time you build and review the document.
+% Set \DescribeMacro\autoCopyOff\cs{autoCopyOff} during quiz development, and declare
+% \DescribeMacro\autoCopyOn\cs{autoCopyOn}. The default is \cs{autoCopyOn}.
+% \begin{macrocode}
+\def\autoCopyOn{\def\autoCopy{true}}
+\def\autoCopyOff{\def\autoCopy{false}}
+\autoCopyOn
+% \end{macrocode}
+% \DescribeMacro\cFS\nmpsep{\darg{empty\string|CHTTP}} (This command is obsolete, and should be removed. Its functionality
+% is accessed through the optional arguments of \cs{instrPath} and \cs{classPath}.)
+% The \texttt{Doc.saveAs()} method has a
+% \texttt{cFS} key for determining the file system, the value of the key is either empty
+% or the string \texttt{CHTTP}. We offer this option. This key is recognized for the \cs{classPath}, we
+% assume the \cs{instrPath} is in his local file system; however, it is easy to incorporate the \texttt{cFS}
+% key here as well.
+% \begin{macrocode}
+\newcommand{\cFS}[1]{\def\@rgi{#1}\ifx\@rgi\@empty
+ \let\cFSth\@empty\else\def\cFSth{CHTTP}\fi}
+\let\cFSth\@empty
+% \end{macrocode}
+% \DescribeMacro\distrToStudentsOff
+% Allow the instructor to turn off the distribution of the quizzes to the students'
+% folders using \cs{distrToStudentsOff}, the default
+% is \DescribeMacro\distrToStudentsOn\cs{distrToStudentsOn}.
+% \begin{macrocode}
+\def\distrToStudentsOn{\def\distrToStudents{true}}\distrToStudentsOn
+\def\distrToStudentsOff{\def\distrToStudents{false}}
+% \end{macrocode}
+% \DescribeMacro\distrToInstrOff
+% Allow the instructor to turn off the distribution of the quizzes to himself
+% by using \cs{distrToInstrOff}, the default
+% is \DescribeMacro\distrToStudentsOn\cs{distrToInstrOn}.
+% \begin{macrocode}
+\def\distrToInstrOn{\def\distrToInstr{true}}\distrToInstrOn
+\def\distrToInstrOff{\def\distrToInstr{false}}
+% \end{macrocode}
+% (2019/08/26) Combined \cs{sadMultQuizzes} with \cs{sadQuizzes}
+% \changes{v1.4.6}{2019/08/26}{Combined \string\cs{sadMultQuizzes} with
+% \string\cs{sadQuizzes}}
+% \begin{macrocode}
+% \end{macrocode}
+% \subsection{Working with multiple quizzes in one source}
+% This section we develop some ideas of creating a single source file with multiple quizzes,
+% these quizzes should be roughly equivalent. One such approach is to have a single quiz,
+% and randomly permute the questions as well as randomly permute any MC or MS choice fields.
+% \changes{v1.3}{2019/07/20}{Added multiple quizzes in one source}
+% \begin{macrocode}
+% \end{macrocode}
+% \DescribeMacro\declareQuizBody\nmpsep{\darg{\ameta{name}}} This macro defines a
+% verbatim environment with \ameta{name}. Such an environment cuts and saves its contents
+% under the name of \texttt{\ameta{name}.cut}. It typically is designed to enclose
+% the `body of a quiz,' the `quiz body' can then be input later using \cs{InputQuizBody}, define
+% below. Associated with the declaration is a version number, \DescribeMacro\QzVer\cs{QzVer}, which
+% may be used in the titles, refer to \texttt{thexrt.tex} in the \texttt{examples/misc} folder.
+% \changes{v1.4.7}{2019/08/27}{Added version support for quiz bodies}
+% \begin{macrocode}
+\def\th@QzVer{0}
+\def\QzVer{1}
+\newcommand{\declareQuizBody}[1]{%
+ \bgroup\@tempcnta\th@QzVer\relax
+ \advance\@tempcnta\@ne
+ \edef\th@qbCnt{\the\@tempcnta}%
+ \csarg\xdef{#1-QzVer}{\th@qbCnt}\egroup
+ \csarg\def{#1}{\immediate\openout\CommentStream #1.cut
+ \let\verbatim@out\CommentStream
+ \immediate\write\verbatim@out{\string
+ \def\string\QzVer{\@nameuse{#1-QzVer}}}%
+ \verbatimwrite}%
+ \csarg\def{end#1}{\endverbatimwrite
+ \immediate\closeout\CommentStream}}
+% \end{macrocode}
+% \DescribeMacro\InputQuizBody\nmpsep{\darg{\ameta{name}}}
+% We input a `quiz body' that has been earlier CUT and saved
+% under the name of \texttt{\ameta{name}.cut}.
+% \changes{v1.4}{2019/08/11}{Changes to \string\cs{InputBodyQuiz}
+% to support solution sets}
+% \begin{macrocode}
+\newcounter{th@qzCnt}
+\def\theth@qzCnt{\alph{th@qzCnt}}
+\newcommand{\InputQuizBody}[1]{\newpage %\thPageOne
+ \@ifundefined{thisQuizOrig}{\edef\thisQuizOrig{\thisQuiz}
+ \let\Hy@EveryPageAnchor\relax}{}\stepcounter{th@qzCnt}%
+ \edef\x{\thisQuizOrig\theth@qzCnt}\expandafter
+ \th@DeclareQuiz\expandafter{\x}%
+ \renewcommand\sqslsecrunhead{}%
+ \InputIfFileExists{#1.cut}{}{}
+% \end{macrocode}
+% Before we include quiz solutions, we close the \cs{quiz@solns} stream.
+% \begin{macrocode}
+ \immediate\closeout\quiz@solns %\th@QzHeaderLS
+ \let\eq@normallheader\relax
+ \newpage
+ \@ifundefined{ps@webheadings}{%
+ \def\th@QzHeaderL{\th@QzHeaderLS}%
+ \def\th@QzHeaderC{\th@QzHeaderCS}%
+ }{%
+ \lheader{\th@QzHeaderLS}%
+ \cheader{\th@QzHeaderCS}%
+ }
+ \includequizsolutions*\relax
+ \global\therearequizsolutionsfalse
+ \renewcommand\sqslsecrunhead{\eq@sqslsecrunhead}%
+ \eq@noformstrue
+% \end{macrocode}
+% Putting \cs{eq@noformtrue} assures us that the solution file will not be
+% input a |\end{document}|. Next, we open a new quiz solution file stream
+% so the another rendition to write solutions to a fresh file.
+% \begin{macrocode}
+ \immediate\openout \quiz@solns \jobname.qsl
+ \@ifundefined{ps@webheadings}{%
+ \def\th@QzHeaderL{\th@QzHeaderLQ}%
+ \def\th@QzHeaderC{\th@QzHeaderCQ}%
+ }{%
+ \lheader{\th@QzHeaderLQ}%
+ \cheader{\th@QzHeaderCQ}%
+ }%
+}
+% \end{macrocode}
+% \subsection{Building quizzes with \tops{\protect\env}{}{makeClassFiles} \& \tops{\protect\cs}{\textbackslash}{sadQuizzes}}
+% Central to this whole process is building customized quizzes. This done by the
+% \cs{sadQuizzes} expanded within the \env{makeClassFiles} environment.\medskip
+%
+% \noindent\DescribeEnv{makeClassFiles} is an \env{execJS} environment, the base name has been
+% preset to be \texttt{mcfthor}. The contents of this environment is \cs{sadQuizzes}.
+% Beginning the 2019/07/15 of \pkg{insdljs}, \env{execJS} has an option argument
+% that is used to pass a command to the \texttt{.djs} file. We use this to make
+% special definitions to support \DescribeMacro\oct\cs{oct} and \DescribeMacro\u\cs{u}.
+% \changes{v1.1.9}{2019/07/15}{Added optional argument \string\cs{mkClFlsSpcls}}
+%
+% \begin{macrocode}
+\def\mkClFlsSpcls{\let\oct\eqbs\let\u\relax}
+\newenvironment{makeClassFiles}{%
+\execJS[\mkClFlsSpcls]{mcfthor}}{\endexecJS}
+% \end{macrocode}
+% \DescribeMacro\sadQuizzes (save and distribute quizzes)
+% is a script for the \env{makeClassFiles} environment.
+% \changes{v1.4.6}{2019/08/26}{Renamed \string\cs{sadMultQuizzes} to
+% \string\cs{sadQuizzes}, removed old \string\cs{sadQuizzes}.}
+%\begin{verbatim}
+%\begin{makeClassFiles}
+%\sadQuizzes
+%\end{makeClassFiles}
+%\begin{document}
+%...
+%\end{verbatim}
+%The above is placed just above |\begin{document}|. The script populates, for each entry in the
+%\cs{classEntries} array, the \texttt{Name.first} and \texttt{Name.last} fields with the student's
+%first and last name. It then saves a copy of the document to the instructor's folder under the name
+%\texttt{\string\jobname-\ameta{first-name}\_\ameta{last-name}}. It does the same thing for the
+%student's private folder. Finally, it clears the \texttt{Name} fields, and saves itself to the
+%source folder. The script may be redefined in the preamble of the document using the
+%\env{defineJS*} environment. The script also deals with solution and cover pages.
+% \begin{macrocode}
+\def\setClassArray{\ifClassEntries
+ \classEntries\else\classEntriesDef\fi}
+\def\setArrayLength{\ifbasicmethods0\else lst.length\fi}
+\def\setfilesuffix{\ifuseclassOpt"-"+fN+"_"+lN\else
+ \ifbasicmethods""\else"-"+(i+1)\fi\fi+".pdf"}
+\begin{defineJS}[\def\defineJSjsR{^^J}\let\u\relax
+ \catcode`\@=0\relax]{\sadQuizzes}
+% \end{macrocode}
+% If \cs{autoCopyOff}, then this script does nothing
+% \begin{macrocode}
+if(@bFlattenState)
+ this.addScript({
+ cName: "thorshammer: Do not flatten",
+ cScript:"var _flattenThisDoc=false;"
+ });
+if (@autoCopy) {
+% \end{macrocode}
+% \textbf{JavaScript variables common to building quizzes}
+% \begin{macrocode}
+ var bUseClass=@bUseClass;
+ var reRmFn=new RegExp(this.documentFileName,"i");
+ var instrPath=@InstrPath;
+ var cLast=instrPath[instrPath.length-1];
+ if (cLast=="/")
+ instrPath=instrPath.substring(0,instrPath.length-1);
+ var classPath=@ClassPath;
+ cLast=classPath[classPath.length-1];
+ if (cLast=="/")
+ classPath=classPath.substring(0,classPath.length-1);
+ var thInstrFS="@thInstrFS";
+ var thClassFS="@thClassFS";
+ var isthereCvrPg=@thIsCP;
+ var cvrPgNum="@thCvrPg";
+ console.println("autocopy "+((@autoCopy)?"on":"off"));
+ var retn;
+ var solnSuffix="";
+ var oSolnSuffix=new Object;
+ var parentoDoc=this;
+ var workingFolder=this.path;
+ var pos=workingFolder.lastIndexOf("/");
+ workingFolder=workingFolder.substring(0,pos+1);
+ var _workingFolder="";
+ // console.println("working folder: " + workingFolder);
+ var willSaveScript='isAQuizUnfinishedAtSave();\r'
+ +'if (oRecordOfQuizData !=undefined) collectQuizData();';
+ var oHSD=this.getField("holdScoreData");
+ var Rect=oHSD.rect;
+ this.removeField("holdScoreData");
+ var hsdFmt='if(typeof oRecordOfQuizData=="undefined")\r\t\
+ oRecordOfQuizData=new Object;';
+ var restQD='@restoreQD';
+% \end{macrocode}
+% \textbf{Cover page or pages.} Determine if there are cover pages, if yes, extract it and save it
+% to the instructor's folder. Cover pages are declared in the preamble with
+% the command \cs{DeclareCoverPage}, the argument of which is either a single number (usually 0)
+% of a range of zero-based page numbers.
+% \begin{macrocode}
+ if(isthereCvrPg) {// -------- extract cover pages ------------
+ var aCvrPgRng=cvrPgNum.split("-");
+ if (aCvrPgRng[0]=="") {
+ console.println("Start Range not specified, using 0 instead");
+ var bPg=0;
+ } else var bPg=aCvrPgRng[0];
+ var ePg=(aCvrPgRng.length>1)?aCvrPgRng[1]:aCvrPgRng[0];
+ var oDoc=aebTrustedFunctions(this,aebExtractPages,
+ {nStart: bPg, nEnd: ePg});
+ // save cover page(s) to the instructor folder
+ _workingFolder=(@InstrPathFull)?"":workingFolder;
+ aebDocSaveAs.msg="Cannot access the local folder "
+ + _workingFolder+instrPath+"/@jobname-cvrpg.pdf";
+ var retn=aebTrustedFunctions(oDoc,aebDocSaveAs,
+ {cFS:thInstrFS,cPath: _workingFolder+instrPath+"/@jobname-"
+ +"cvrpg.pdf",bCopy:false});
+ oDoc.dirty=false;
+ oDoc.closeDoc(true);
+ // delete cover page before continuing, will reinsert it later
+ this.deletePages({nStart: bPg, nEnd: ePg});
+ this.dirty=false;
+ }
+// ------- end cover page code --------------
+ var nQz=aQuizzesInDoc.length; // number of quizzes this doc
+% \end{macrocode}
+% \textbf{Solution pages.} Before getting into generating the customized quizzes for the class, we must
+% first see if there are any solutions in this document, if so, we separate
+% the solution page(e) from the quiz.
+% \begin{macrocode}
+ var bOkBasicSolns=false;
+ var f=this.getField("thsolns4");
+ if (f != null ) {
+ console.println("There are solutions");
+ bOkBasicSolns=true;
+% \end{macrocode}
+% Save the solution suffixes for later use
+% \begin{macrocode}
+ var g=f.getArray();
+ for (var i=0; i<g.length; i++) {
+ var solnSuffix=g[i].name; // eg solns4.q1a
+ var pos=solnSuffix.indexOf(".");
+ var qzName=solnSuffix.substring(pos+1); // eg q1a
+ solnSuffix=solnSuffix.replace(/\./g,"-"); // eg solns4-q1a
+ // oSolnSuffix records whether a quiz has solution pages
+ oSolnSuffix[qzName]=solnSuffix;
+ }
+% \end{macrocode}
+% Extract the solution page save it, close it, delete the page from master document
+% \begin{macrocode}
+ // ------------- extraction--------------
+// console.println("aQuizzesInDoc: " + aQuizzesInDoc.toSource());
+// console.println("nQz="+nQz);
+ for (var i=0; i< nQz; i++) {
+ var f=this.getField("thsolns4");
+ var g=f.getArray();
+ var qzName=aQuizzesInDoc[i];
+ var bOk2Extract=(typeof oSolnSuffix[qzName]!="undefined");
+ if (bOk2Extract) {
+// console.println(g[0].name + ", begins on page "+g[0].page);
+ var bPg=g[0].page;
+// console.println("bPg= " + bPg);
+// var f=this.getField("Name.first."+(i+1));
+ var f=this.getField("bMrkQz."+(i+1));
+ var ePg=(f==null)?(this.numPages-1):(f.page-1);
+// console.println("ePg= " + ePg);
+ var solnSuffix=g[0].name; // solns4.<qzName>
+ solnSuffix=solnSuffix.replace(/\./g,"-"); // solns4-<qzName>
+ var oDoc=aebTrustedFunctions(this,aebExtractPages,
+ {nStart: bPg, nEnd: ePg});
+ // save
+ _workingFolder=(@InstrPathFull)?"":workingFolder;
+ aebDocSaveAs.msg="Cannot access the local folder "
+ + _workingFolder+instrPath+"/@jobname-"+solnSuffix+".pdf";
+ var retn=aebTrustedFunctions(oDoc,aebDocSaveAs,
+ {cFS:thInstrFS,cPath: _workingFolder+instrPath+"/@jobname-"
+ +solnSuffix+".pdf",bCopy:false});
+ // close
+ oDoc.dirty=false;
+ oDoc.closeDoc(true);
+ // delete solution page before continuing
+ this.deletePages({
+ nStart: bPg,
+ nEnd: ePg});
+ this.dirty=false;
+ }
+ }
+ }
+// ------ begin creating custom quizzes for class members ------
+ var cnt=0; // determines which quiz to generate
+ var lst=new Array(@setClassArray);
+ var l=(bUseClass)?@setArrayLength:1; // dps
+ for (var i=0; i < l; i++) {
+ var qzName=aQuizzesInDoc[cnt];
+// console.println("Working on " + qzName);
+ var fN=lst[i][0];
+ var lN=lst[i][1];
+ var folder=lst[i][2];
+ var isAbsPth=lst[i][3]; // dps
+ if (folder!="")folder+="/";
+ // pre-populate with the student's name
+ this.getField("Name.first").value=fN;
+ this.getField("Name.last").value=lN;
+ // extract quiz
+// var f=this.getField("Name.first."+cnt);
+ var f=this.getField("bMrkQz."+cnt);
+ var bPg=f.page;
+// var f=this.getField("Name.first."+(cnt+1));
+ var f=this.getField("bMrkQz."+(cnt+1));
+ var ePg=(f==null)?(this.numPages-1):(f.page-1);
+% \end{macrocode}
+% \textbf{Extraction:} We extract a quiz from the master document. Extracting
+% causes some problems: the restore quiz data is lost, the WillSave event is
+% lost, and the \texttt{holdScoreData} field is lost. We try to overcome this
+% problems.
+% \begin{macrocode}
+ // ------------- extraction of quiz pages --------------
+ if(bUseClass)var oDoc=aebTrustedFunctions(this,aebExtractPages,
+ {nStart: bPg, nEnd: ePg});
+ else oDoc=this; // dps
+% \end{macrocode}
+% Restore the \textsf{WillSave} event.
+% \begin{macrocode}
+ // extracting preserves doc JS but not doc actions
+ oDoc.setAction({cTrigger: "WillSave", cScript: willSaveScript});
+% \end{macrocode}
+% We have had problems with \texttt{oRecordOfQuizData} is \texttt{undefined},
+% to (finally) overcome this, we place some code at the document level.
+% \begin{macrocode}
+ oDoc.addScript({
+ cName: "oRecordOfQuizData Obj Declaration", cScript: hsdFmt});
+% \end{macrocode}
+% The \texttt{holdScoreData} is on the first page of the document, this first
+% page may not survive on the extracted pages, so we place this text field
+% and the top of each of the first pages of the extracted quizzes.
+% \begin{macrocode}
+ var oDocHSD=oDoc.addField({
+ cName: "holdScoreData",
+ cFieldType: "text",
+ nPageNum: 0,
+ oCoords: Rect
+ });
+% \end{macrocode}
+% Create a page open action to execute the restore quiz data
+% \begin{macrocode}
+ oDoc.setPageAction({
+ nPage: 0,
+ cTrigger: "Open",
+ cScript: restQD
+ });
+% \end{macrocode}
+% We save custom info to each of the files being saved: \texttt{StudentPath}
+% has the path to the students' folders and \texttt{cFS} is the file system.
+% These two are used by `protect and distribute'.
+% \begin{macrocode}
+ oDoc.info.qzBaseName="@jobname";
+ if(isAbsPth) // dps
+ oDoc.info.StudentPath=folder;
+ else
+ oDoc.info.StudentPath=classPath+"/"+folder;
+ var bOkSolns=(typeof oSolnSuffix[qzName]!="undefined");
+ if(bOkSolns) oDoc.info.SolnSet=oSolnSuffix[qzName];
+ oDoc.info.SolnPath=_workingFolder+instrPath+"/";
+ if(isthereCvrPg) oDoc.info.CvrPg="cvrpg";
+ oDoc.info.cFS=thInstrFS;
+% \end{macrocode}
+% \textbf{Insert cover page, if any}
+% \changes{v1.4.2}{2019/08/22}{Insert cover page in \string\cs{sadQuizzes}}
+% \changes{v1.4.17}{2019/10/03}{Saved path to cover page}
+% \begin{macrocode}
+ // Insert cover page, if any.
+ if (isthereCvrPg) {
+ if (typeof bCVMsg == "undefined") {
+ console.println("Inserting cover page from "
+ + _workingFolder+instrPath+"/@jobname-cvrpg.pdf");
+ var bCVMsg=true;
+ }
+ if (cnt==0) var _cvrPath=_workingFolder+instrPath;
+ aebTrustedFunctions(oDoc,aebInsertPages,
+ {nPage: -1,
+ cPath: _cvrPath+"/@jobname-cvrpg.pdf"});
+ }
+ var filesuffix=@setfilesuffix;
+ // Now save this as a copy
+% \end{macrocode}
+% \textbf{Instructor's folder:} Save a copy to the instructor's folder
+% \begin{macrocode}
+ if(bUseClass) {
+ _workingFolder=(@InstrPathFull)?"":workingFolder;
+ aebDocSaveAs.msg="Cannot access the local folder "
+ + _workingFolder+instrPath+"/@jobname-"+fN+"_"+lN+".pdf";
+ if(@distrToInstr) retn=aebTrustedFunctions(oDoc,aebDocSaveAs,
+ {cFS:thInstrFS,
+ cPath: _workingFolder+instrPath+"/@jobname"+filesuffix,
+ bCopy:true});
+% \end{macrocode}
+% \textbf{Student's folder:} Save a copy to the student's folder
+% \changes{v1.4.17}{2019/10/03}{Defined \string\texttt{\_workingFolderC} to avoid
+% redefinition of \string\texttt{\_workingFolder}}
+% \begin{macrocode}
+ var _workingFolderC=(@ClassPathFull)?"":workingFolder;
+ if(isAbsPth)
+ var cPath=folder+"@jobname"+filesuffix;
+ else
+ var cPath=_workingFolderC+classPath+"/"+folder
+ +"@jobname"+filesuffix
+ aebDocSaveAs.msg="Cannot access the path "+ cPath;
+ if(@distrToStudents) retn=aebTrustedFunctions(oDoc,aebDocSaveAs,
+ {cFS:thClassFS,
+ cPath: cPath,
+ bCopy:true});
+ oDoc.dirty=false;
+ oDoc.closeDoc(true);
+ }
+ cnt=++cnt % nQz
+ }
+}
+this.resetForm(["Name"]);
+console.println("automatically saving this file...");
+% \end{macrocode}
+% Remove the following line\\
+%|// this.oRecordOfQuizData=undefined;|
+% \begin{macrocode}
+% \end{macrocode}
+% \textbf{Save the source document:} Finally, save any changes
+% that have occurred source document. Before saving, we make
+% some adjustments in the case this is the basic method case.
+% \begin{macrocode}
+var toSa=app.setTimeOut("aebTrustedFunctions(this,aebSaveAs);\
+app.clearTimeOut(toSa);",50);
+\end{defineJS}
+\let\sadMultQuizzes\sadQuizzes
+\let\rasSolns\sadQuizzes
+% \end{macrocode}
+% \begin{macrocode}
+%</package>
+%<*container>
+% \end{macrocode}
+% \section{Batch support files}
+% These files are designed for a workflow wherein the \opt{usebatch}
+% option is taken. This option, though largely symbolic, declares the instructor
+% is going to use a batch sequence to process the students' quizzes, after they
+% have taken the quiz and returned to the instructor.
+% A custom batch file \texttt{Thor's way} was written for this purpose.
+%
+% \paragraph*{\textsf{Thor's way}.}\hskip-\lastskip\space
+% This batch sequence is run after the instructor has
+% has a final look at each quiz (additional markup needed in the case of essay questions
+% and assigning a final mark. the batch sequence performs a number of actions,
+% for each quiz file selected, it acquires minimal quiz data (first name, last name,
+% number of points awarded, total points, and final mark.
+%\changes{v1.2}{2019/07/16}{Added batch support files}
+% \subsection{The container file for Thor's way}
+% This file should be brought into \app{Acrobat}, its fields filled, and the button pushed. It sets
+% global JavaScript variables \texttt{global.qzName} and \texttt{global.gradedPath}.
+% \changes{v1.3.1}{2019/07/20}{container: Push now closes the container}
+% \begin{macrocode}
+\documentclass{article}
+\usepackage[designi]{web}
+\usepackage{eforms}
+\hypersetup{pdfpagemode=UseAttachments}
+%% \previewOn\pmpvOn
+\parindent0pt \parskip6pt
+\begin{defineJS}{\pbContainer}
+var f=this.getField("qzName");
+if(typeof global.RcrdData=="undefined")
+ global.RcrdData=1;
+% \end{macrocode}
+% If the `\textsf{Record class data}' box is checked we create a new attachment to receive the data;
+% otherwise, no new attachment file is created.
+% \begin{macrocode}
+if(global.RcrdData) {
+ global.qzName=f.value;
+ if (global.qzName=="") {
+ f.value="qzData";
+ global.qzName="qzData.txt";
+ } else global.qzName=f.value+".txt";
+ var d=this.dataObjects;
+ if (d!=null) {
+ for(var i=0; i< d.length; i++)
+ this.removeDataObject(d[i].name);
+ }
+ this.createDataObject({
+ cName: global.qzName,
+ cValue: "First\\tSecond\\tPoints\\tTotal\\tGrade"
+ });
+}
+var _path=this.path;
+var pos=_path.lastIndexOf("/");
+global.containerPath=_path.substring(0,pos+1);
+var f=this.getField("gradedPath");
+var v=f.value;
+var pos=v.indexOf(":");
+if(pos!=-1||v[0]=="/") global.gradedPath=v;
+else global.gradedPath=global.containerPath+v;
+aebTrustedFunctions(this,aebSaveAs);
+this.closeDoc(true);
+\end{defineJS}
+% \end{macrocode}
+% (2019/11/21) Put JS for Clear Btn in \env{defineJS} environment
+% \changes{v1.5.2}{2019/11/21}{Put JS for Clear Btn in \string\env{defineJS}}
+% \begin{macrocode}
+\begin{defineJS}{\clrContainer}
+this.resetForm(["qzName","gradedPath"]);
+try{
+% \end{macrocode}
+% (2019/11/21) Fixed a bug with exception thrown
+% \changes{v1.5.2}{2019/11/21}{Fixed a bug with exception thrown}
+% \begin{macrocode}
+ if (typeof global.qzName!="undefined")
+ delete global.qzName; global.qzName="";
+ if (typeof global.gradedPath!="undefined")
+ delete global.gradedPath; global.gradedPath="";
+ if (typeof global.appndSolns!="undefined")
+ delete global.appndSolns; global.appndSolns=true;
+ if (typeof global.RcrdDat!="undefined")
+ delete global.RcrdDat; global.RcrdDat=true;
+} catch(e){}
+\end{defineJS}
+\begin{document}
+This file contains the quiz data as an attachment. Before you
+start the batch action \textsf{Thor's way}, build and
+\emph{place this file in the class folder of the instructor}.
+\begin{center}
+\begin{tabular}{rl}
+\pushButton[\TU{Fill in the two fields then push this button
+before starting the batch sequence}\CA{Push}\AAmouseup{\pbContainer}
+]{pbContainer}{}{13bp}&%
+\parbox[c]{1.5in}{\textField[\TU{Enter base name of the file that
+stores quiz results}]{qzName}{1.5in}{13bp}\vcgBdry[3bp]
+\textField[\TU{The path to the folder that will hold the graded
+quizzes, it may be a relative or an absolute path}
+]{gradedPath}{1.5in}{13bp}}\cgBdry[\columnsep]%\makebox[0pt][l]
+{\pushButton[\CA{Clear}
+ \AAmouseup{\clrContainer}]{clear}{}{13bp}}\\[12pt]
+ \checkBox[\V{Yes}\DV{Yes}\AAmouseup{%
+ global.appndSolns=(event.target.isBoxChecked(0));
+}]{AppdSolns}{11bp}{11bp}{Yes}&%
+\rlap{Append solutions, if they exist}\\[6pt]
+\checkBox[\V{Yes}\DV{Yes}\AAmouseup{%
+ global.RcrdData=(event.target.isBoxChecked(0));
+}]{RecordData}{11bp}{11bp}{Yes}&%
+\rlap{Record class data}
+\end{tabular}
+\end{center}
+Fill in the base name of the file in the text field above. After
+you push the button, the file is saved, then start
+\textsf{Thor's way} action. After the batch sequence finishes,
+this file is opened again. Open the attachments panel and save
+the attached file. The file just saved is a tab delimited text
+file that can be opened in Microsoft Excel.
+\end{document}
+%</container>
+%<*bterminate>
+% \end{macrocode}
+% \subsection{The batch termination file}
+% When running \pkg{Thor's way}, it is important that \texttt{terminate-batch.pdf} is the last
+% file processed by the batch. The batch test each file initially, if the current file being process,
+% the batch exits `gracefully', otherwise, the batch processes the current file. The role
+% \texttt{terminate-batch.pdf} plays it that it is detected by the batch, it performs no actions.
+% \begin{macrocode}
+\documentclass{article}
+\usepackage[designi]{web}
+\parindent0pt\parskip6pt
+\begin{document}
+\null\vfil
+\begin{center}
+\fbox{\begin{minipage}{.67\linewidth}
+This file is the last to be processed by \textsf{Thor's way},
+the batch action identifies it and gracefully terminates.
+\end{minipage}}
+\end{center}
+\vfil
+\end{document}
+%</bterminate>
+% \end{macrocode}
+% \begin{macrocode}
+%<*package>
+% \end{macrocode}
+% \section{Configuration files}
+% \subsection{Class configureation}
+% It was suggested by Loki that we should be able to have a configuration file
+% for the class. In the case an instructor has several classes, this is a great
+% convenience.\medskip\par\noindent
+% \DescribeMacro\InputClassData\nmpsep{\darg{\ameta{base-name}}} Input the class file
+% with name \texttt{\ameta{base-name}.cfg}. The class configuration file (\texttt{\ameta{base-name}.cfg}) consists
+% of a series of declarations of the form,
+% \begin{quote}\ttfamily
+% \string\instrPath\darg{\ameta{path}}\\
+% \string\classPath\darg{\ameta{path}}\\
+% \string\classMember*\darg{\ameta{first-name}}\darg{\ameta{last-name}}\darg{\ameta{folder}}\\
+% ...
+% \end{quote}
+% where the \texttt* is optionally included.
+% \begin{macrocode}
+\def\InputClassData#1{\def\InputCl@ssData{#1}\mkClFlsSpcls
+ \InputIfFileExists{#1.cfg}
+ {\PackageInfo{thorshammer}{Inputting class file #1.cfg}}
+ {\PackageWarning{thorshammer}
+ {Cannot find the class file #1.cfg}}}
+% \end{macrocode}
+% \DescribeMacro\InputFormattedClass\nmpsep{[\ameta{\cs{cmd}}]\darg{\ameta{base-name}}}
+% We define a more general input method.
+% The format for the class configuration file is as follows:
+% \begin{quote}\ttfamily
+% \string\instrPath\darg{\ameta{path}}\\
+% \string\classPath\darg{\ameta{path}}\\
+% \string\bClassData\\
+% \ameta{entry1}\\
+% \ameta{entry2}\\
+% ...
+% \end{quote}
+% Prior to \cs{bClassData}, the entries are passed through, so you can, for example,
+% set the \cs{instrPath} and \cs{classPath} here. After \cs{bClassData} comes a series
+% of lines, one each student. Each line (\ameta{entry}) should be marked up so it can be parsed and information
+% extracted; at the minimum, each line should contain \ameta{first-name}, \ameta{last-name},
+% and \ameta{folder}, with possibly more. The default for \ameta{\cs{cmd}} is \cs{classMember}.
+% For each line following \cs{bClassData}, \ameta{\cs{cmd}} is placed in front of each entry
+% like so, \ameta{\cs{cmd}}\ameta{entry}.
+%
+% The first optional argument is the command (\ameta{\cs{cmd}}) that parses each line.
+% The end purpose of the command is to construct a data structure,
+% \begin{quote}\ttfamily
+% \string\classMember*\darg{\ameta{first-name}}\darg{\ameta{last-name}}\darg{\ameta{folder}}
+% \end{quote}
+% A simple example is the following (filename is \texttt{myclassroll.cfg}):
+%\begin{verbatim}
+% \instrPath{myClass}
+% \classPath{/z/Users/thor/myClass}
+% \bClassData
+% {Peter}{Pan}{A}
+% *{J\"{u}rgen}{Loki}{B}
+% {Thors}{Hammer}{C}
+%\end{verbatim}
+%We can then input this CFG file with \cs{InputFormattedClass\darg{myclassroll}}.
+% For each line after \cs{bClassData}, the default \ameta{\cs{cmd}} is placed in front;
+% for example, the first two lines of class data become |\classMember{Peter}{Pan}{A}|
+% and |\classMember*{J\"{u}rgen}{Loki}{B}|, and so on.
+% \begin{macrocode}
+\newcommand\InputFormattedClass[2][\classMember]{\ClassEntriestrue
+ \begingroup
+ \mkClFlsSpcls
+ \endlinechar=-1
+ \let\procThisLine\relax
+ \let\bClassData\relax
+ \let\re@dOK\dl@YES
+ \newread\fmtclass
+ \immediate\openin\fmtclass=#2.cfg
+ \loop
+ \read\fmtclass to \classmember
+ \ifeof\fmtclass\let\re@dOK\dl@NO
+ \else
+ \expandafter
+ \ifx\classmember\endinput\let\re@dOK\dl@NO
+ \else
+ \ifx\classmember\@empty %\let\procThisLine\relax
+ \else
+ \expandafter\procThisLine\classmember
+ \expandafter\ifx\classmember\bClassData
+% \end{macrocode}
+% After we process the current line, if this line is \cs{bClassData},
+% we switch over to \texttt{\#1} as the definition of
+% \cs{procThisLine}.
+% \begin{macrocode}
+ \def\procThisLine{#1}\fi
+ \fi
+ \fi
+ \fi
+ \ifx\re@dOK\dl@YES\repeat
+ \immediate\closein\fmtclass
+ \endgroup
+}
+% \end{macrocode}
+% \subsection{Load the configuration file}
+% \changes{v1.3.7}{2019/08/11}{fixed typo in loading cfg}
+% \begin{macrocode}
+\def\th@InputCFG{\InputIfFileExists{thorshammer.cfg}
+ {\PackageInfo{thorshammer}
+ {Inputting the configuration file}}
+ {\PackageInfo{thorshammer}
+ {No configuration file found}}}
+\ifx\th@loadCFG\dl@YES\expandafter\th@InputCFG\fi
+% \end{macrocode}
+% \begin{macrocode}
+% \end{macrocode}
+% \begin{macrocode}
+\catcode`\"=\th@dquoteCat
+%</package>
+% \end{macrocode}
+%\Finale
diff --git a/macros/latex/contrib/thorshammer/thorshammer.ins b/macros/latex/contrib/thorshammer/thorshammer.ins
new file mode 100644
index 0000000000..06434d0d60
--- /dev/null
+++ b/macros/latex/contrib/thorshammer/thorshammer.ins
@@ -0,0 +1,62 @@
+%%
+%% This file will generate fast loadable files and documentation
+%% driver files from the doc files in this package when run through
+%% LaTeX or TeX.
+%%
+%% Copyright 1999-2012 D. P. Story
+%%
+%% This file is part of the `AcroTeX eDucation Bundle'.
+%% -------------------------------------------
+%%
+%% It may be distributed under the conditions of the LaTeX Project Public
+%% License, either version 1.2 of this license or (at your option) any
+%% later version. The latest version of this license is in
+%% http://www.latex-project.org/lppl.txt
+%% and version 1.2 or later is part of all distributions of LaTeX
+%% version 1999/12/01 or later.
+%%
+%% --------------- start of docstrip commands ------------------
+%%
+\def\filedate{2020/01/13}
+\def\batchfile{thorshammer.ins}
+
+\input docstrip
+\ifx\generate\undefined
+ \Msg{**********************************************}
+ \Msg{*}
+ \Msg{* This installation requires docstrip}
+ \Msg{* version 2.4 or later.}
+ \Msg{*}
+ \Msg{* An older version of docstrip has been input}
+ \Msg{*}
+ \Msg{**********************************************}
+ \errhelp{Move or rename old docstrip.tex and get a newer one.}
+ \errmessage{Old docstrip in input path}
+ \batchmode
+ \csname @@end\endcsname\end
+\fi
+
+\keepsilent
+\askforoverwritefalse
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\preamble
+\endpreamble
+
+\generate
+{%
+ \file{thorshammer.sty}{\from{thorshammer.dtx}{copyright,package}}
+ \file{container.tex}{\from{thorshammer.dtx}{container}}
+ \file{terminate-batch.tex}{\from{thorshammer.dtx}{bterminate}}
+}
+
+\Msg{***************************************************************}
+\Msg{*}
+\Msg{* \space To finish the installation you have to copy the files }
+\Msg{*}
+\Msg{* \space *.sty, *.cfg and *.def into a directory searched by TeX}
+\Msg{*}
+\Msg{***************************************************************}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput