summaryrefslogtreecommitdiff
path: root/macros/latex/contrib
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-08-25 03:00:45 +0000
committerNorbert Preining <norbert@preining.info>2021-08-25 03:00:45 +0000
commit960421b0bcd1af561be3f2eb9468224969a7bd34 (patch)
tree5a044ffc102d87d8ffdf2396ee6ee9fc3faa98f9 /macros/latex/contrib
parent3e6c1d9e0f4a3f6852f41547738a6b62086fda9d (diff)
CTAN sync 202108250300
Diffstat (limited to 'macros/latex/contrib')
-rw-r--r--macros/latex/contrib/gamebooklib/Makefile2
-rw-r--r--macros/latex/contrib/gamebooklib/gamebooklib.dtx156
-rw-r--r--macros/latex/contrib/gamebooklib/gamebooklib.pdfbin265430 -> 263005 bytes
-rw-r--r--[-rwxr-xr-x]macros/latex/contrib/gamebooklib/gamebooklib_countpagesperseed.sh0
-rw-r--r--macros/latex/contrib/gamebooklib/gamebooklib_test.pdfbin117057 -> 117057 bytes
5 files changed, 107 insertions, 51 deletions
diff --git a/macros/latex/contrib/gamebooklib/Makefile b/macros/latex/contrib/gamebooklib/Makefile
index eae8922072..6925b402bd 100644
--- a/macros/latex/contrib/gamebooklib/Makefile
+++ b/macros/latex/contrib/gamebooklib/Makefile
@@ -15,6 +15,6 @@ gamebooklib.pdf : gamebooklib.sty gamebooklib.dtx
tidy:
rm -f *.log *.ind *.idx *.glo *.gls *.aux *.ilg
-
+# TODO: should we really be deleting the .sty? Check CTAN rules.
clean: tidy
rm -f *~ *.sty
diff --git a/macros/latex/contrib/gamebooklib/gamebooklib.dtx b/macros/latex/contrib/gamebooklib/gamebooklib.dtx
index eed4fc64c6..0251127fb0 100644
--- a/macros/latex/contrib/gamebooklib/gamebooklib.dtx
+++ b/macros/latex/contrib/gamebooklib/gamebooklib.dtx
@@ -17,7 +17,7 @@
% \iffalse
% <package>\NeedsTeXFormat{LaTeX2e}[2005/12/01]
% <package>\ProvidesPackage{gamebooklib}
-% <package> [2021/08/10 v1.0 gamebooklib typesetting]
+% <package> [2021/08/24 v1.1 gamebooklib typesetting]
%
%<*driver>
\documentclass{ltxdoc}
@@ -51,9 +51,10 @@
% Grave accent \` Left brace \{ Vertical bar \|
% Right brace \} Tilde \~}
%
-% \CheckSum{507}
+% \CheckSum{539}
%
% \changes{v1.0}{2021/08/10}{Initial Release}
+% \changes{v1.1}{2021/08/24}{Bugfix: edge case with clashing fixed-index entries}
%
% \GetFileInfo{gamebooklib.sty}
%
@@ -77,7 +78,7 @@
% \DoNotIndex{\vbox, \unvbox, \vfill, \vspace, \vsize}
% \DoNotIndex{\WarningFilter, \whiledo, \Collect@Body, \CurrentOption}
% \DoNotIndex{\DeclareOption, \g@addto@macro, \the, \noindent}
-% \DoNotIndex{\interfootnotelinepenalty, \marginpar, \myidx}
+% \DoNotIndex{\interfootnotelinepenalty, \marginpar}
% \DoNotIndex{\addtocounter, \refstepcounter, \label}
% \DoNotIndex{\iffalse, \iftrue, \outputpenalty, \renewcommand}
% \DoNotIndex{\noshuffle, \verbose, \endpage, \footnote}
@@ -332,7 +333,7 @@
%\StopEventually{\PrintChanges \pagebreak[4] \PrintIndex}
%
% \begin{macrocode}
-\ProvidesPackage{gamebooklib}[2021/08/10 Gamebook by R Lee latex@rjlee.homelinux.org]
+\ProvidesPackage{gamebooklib}[2021/08/24 Gamebook by R Lee latex@rjlee.homelinux.org]
% \end{macrocode}
% We need \LaTeXe, for the extra token registers.
% \begin{macrocode}
@@ -396,7 +397,6 @@
% |\usepackage[seed=123]{lcg}|
% \begin{macrocode}
\DeclareOption*{%
- \typeout{Current option: \CurrentOption}%
\PassOptionsToClass{\CurrentOption}{lcg}%
}%
\ProcessOptions\relax%
@@ -446,20 +446,33 @@
% \end{macrocode}
% \cs{gentry} just makes the first argument mandatory.
%
-% \cs{@gentry} defines \cs{gentryidx} and \cs{gentrycode}, which can be used in
-% the body of the \cs{gentry} environment to supply the unsorted index
-% number and the current entry's unique code.
-%
% NB: If you define two entries with the same code, \LaTeX\ will print
% out a "multiply defined" label warning.
% \begin{macrocode}
\newenvironment{@gentry}[2]{%
- \def\gentryidx{#1}%
- \def\gentrycode{#2}%
+ \xdef\gentryidx{#1}%
+ \xdef\gentrycode{#2}%
\@@gentry%
}{\ignorespacesandallpars%
+ \global\let\gentryidx\@undefined%
+ \global\let\gentrycode\@undefined%
+ \global\let\gentryidxu\@undefined%
+ \global\let\gentryidxs\@undefined%
}%
% \end{macrocode}
+% \begin{macro}{gentryidx}
+% This can be used inside a |gentry|; it expands to the first optional
+% argument of the |gentry| environment, which is either blank or the
+% requested fixed index of the entry.
+% To get the actual shuffled index, use \cs{gentryidxu}.
+% \end{macro}
+%
+% \begin{macro}{gentrycode}
+% This can be used inside a |gentry|; it expands to the first mandatory
+% argument of the |gentry| environment, which is the code for this
+% entry (without the |gentry:| prefix).
+% \end{macro}
+%
% \cs{@@gentry} then reads in the optional title argument, storing it in the \cs{gentrytitle}
% macro to supply the unsorted index number and the current entry's code respectively.
% \begin{macrocode}
@@ -590,13 +603,30 @@
}\fi%
% \end{macrocode}
%
-% \subsection*{The shuffling algorithm}
+% \subsection*{The Shuffling Algorithm}
+%
+% The basic shuffling algorithm is to first shuffle all entries,
+% except for those marked with a fixed index, then to ge through the
+% fixed-index entries in order and swap them into their final place.
+%
+% The original version of this package had a bug relating to multiple
+% fixed-index entries.
+% In short, let $A$, $B$, and $C$ be indices; if $A<B$ and
+% (unshuffled) entry number $A$ was fixed at (shuffled)
+% location $B$, while (unshuffled) entry number $B$ was fixed at
+% (shuffled) location $C$, so during the ``shuffle,'' $A$ would be
+% swapped with $B$, then $B$ would be swapped with $C$, resulting in
+% $A$ appearing at $C$ in the text, not $B$ as requested. Because the
+% unshuffled index doesn't appear in either the source or output
+% document, this could be difficult to diagnose; the author simply saw
+% one of their entries ending up in the wrong place.
%
% \TeX\ has well beyond 255 token registers these days, so don't
% bother to check that limit.
%
% The LCG package provides a suitable pseudo-random number generator.
-% What we want is a repeatable series of numbers.
+% What we want is a repeatable series of dispirate numbers, not an
+% especially random one.
%
%\begin{enumerate}
% \item Work out how many entries there are~($N$). Provided \cs{thegentries} is
@@ -604,7 +634,7 @@
% \item Declare a set of token registers named \cs{paratoks}$n$, where $n$ is
% each integer 1\dots$N$ inclusive. These will hold the contents of the entry.
% \item Declare a set of macros named \cs{paraidx}$n$, where $n$ is
-% each integer 1\dots$N$ inclusive, initialised to $n$. These will hold the number of the entry.
+% each integer 1\dots$N$ inclusive, each initialised to $n$. These will hold the number of the entry.
% \item Shuffle elements $\{2:N-1\}$, in that array. For $i=2$ through $N-2$
% \begin{enumerate}
% \item Let $R$ be a random number between $i$ and $N-1$ inclusive
@@ -614,8 +644,8 @@
% \item For $i=1:n$, output token reg $i$
%\end{enumerate}
%
-% Define macros \cs{csname}~|paraIdx|$N'$\cs{endcsname} containing the arabic
-% original page number to be put out on the $N'$th output ``page''
+% Define macros \cs{csname}~|paraIdx|$n$\cs{endcsname} containing the arabic
+% original page number to be put out on the $n$th output ``page''
% \begin{macrocode}
\xdef\gentrycount{\arabic{gentryctr}}%
% \end{macrocode}
@@ -628,64 +658,90 @@
% \begin{macrocode}
\ifthenelse{\gentrycount<3}{}{%SHUFFLE START
\whiledo{\not{\value{gentryctr}>\gentrycount}}{%
- \edef\myidx{\arabic{gentryctr}}%
- \expandafter\xdef\csname paraIdx\myidx\endcsname{\myidx}%
+ \edef\gentryidxu{\arabic{gentryctr}}%
+ \expandafter\xdef\csname paraIdx\gentryidxu\endcsname{\gentryidxu}%
\stepcounter{gentryctr}%
}%
% \end{macrocode}
-% Don't renumber para~1 or \cs{gentrycount}; Knuth-shuffle the rest
-% NB: we stop at \cs{gentrycount}$-2$, because \cs{gentrycount}$-1$ would only shuffle
-% with itself.
+% \begin{macro}{gentryidxu}
+% \changes{v1.1}{2021/08/24}{Access shuffled index}
+% The \cs{gentryidxu} macro can be used inside a |gentry| to obtain the
+% current arabic shuffled index of the entry.
+% \end{macro}
+% \begin{macro}{gentryidxs}
+% \changes{v1.1}{2021/08/24}{Access original index}
+% The \cs{gentryidxs} macro can be used inside a |gentry| to obtain the
+% arabic original unshuffled index of the entry (the first |gentry| is
+% 1, and this counter resets after each expansion of \cs{thegentries}).
+% \end{macro}
% \begin{macrocode}
\if@gamebook@shuffle
- \setcounter{gentryctr}{2}%
\setcounter{rand}{\gentrycount}%
\addtocounter{rand}{-1}\edef%
\stoppoint{\arabic{rand}}%
+% \end{macrocode}
+% First, shuffle everything that isn't fixed down.
+% Don't renumber para~1 or \cs{gentrycount}; Knuth-shuffle the rest
+% NB: we stop at \cs{gentrycount}$-2$, because \cs{gentrycount}$-1$ would only shuffle
+% with itself.
+% \begin{macrocode}
+ \setcounter{gentryctr}{2}%
\chgrand[last=\stoppoint]%
\whiledo{\value{gentryctr}<\stoppoint}{%
% \end{macrocode}
% If this is to be swapped with a fixed position, skip it
% \begin{macrocode}
- \edef\myidx{\arabic{gentryctr}}%
- \expandafter\ifcsname fixedat\myidx\endcsname%
- \gamebook@info{Not shuffling \myidx; fixed pos}%
+ \edef\gentryidxu{\arabic{gentryctr}}%
+ \expandafter\ifcsname fixedat\gentryidxu\endcsname%
+ \gamebook@info{Not shuffling \gentryidxu; fixed pos}%
\stepcounter{gentryctr}%
\else%
- \gamebook@info{Shuffling \myidx}%
+ \gamebook@info{Shuffling \gentryidxu}%
\stepcounter{gentryctr}%
\edef\nextidx{\arabic{gentryctr}}%
% \end{macrocode}
-% If we've hit an entry with fixed position, we may as well skip it
+% Roll the dice. If we've hit an entry with fixed position, we must
+% skip it, or it would end up being swapped out into
+% |fixedat\arabic{rand}| instead.
% \begin{macrocode}
- \expandafter\ifcsname fixedto\arabic{rand}\endcsname\else%
\chgrand[first=\nextidx]%
\rand%
- \gamebook@info{Shuffling \myidx to \arabic{rand}}%
- \macroswap{paraIdx\myidx}{paraIdx\arabic{rand}}%
+ \expandafter\ifcsname fixedat\arabic{rand}\endcsname\else%
+ \gamebook@info{Shuffling \gentryidxu to \arabic{rand}}%
+ \macroswap{paraIdx\gentryidxu}{paraIdx\arabic{rand}}%
\fi%
\fi%
}%
% \end{macrocode}
-% Now move fixed entries into their final place:
+% Now move fixed entries into their final place:
% \begin{macrocode}
\setcounter{gentryctr}{2}%
- \whiledo{\value{gentryctr}<\stoppoint}{%
- \edef\myidx{\arabic{gentryctr}}%
- \expandafter\ifcsname fixedat\myidx\endcsname%
- \expandafter\edef\expandafter\mydest\expandafter%
- {\expandafter\csname fixedat\myidx\endcsname}%
- \gamebook@info{MOVING FIXED GAMEBOOK ENTRY INTO PLACE: \myidx -> \mydest}%
- \macroswap{paraIdx\myidx}%
- {paraIdx\expandafter\csname fixedat\myidx\endcsname}%
+ \whiledo{\not{\value{gentryctr}>\stoppoint}}{%
+ \edef\gentryidxu{\arabic{gentryctr}}%
+ \expandafter\ifcsname fixedat\gentryidxu\endcsname%
+ \expandafter\edef\expandafter\mydest\expandafter%
+ {\expandafter\csname fixedat\gentryidxu\endcsname}%
+ \gamebook@info{MOVING FIXED GAMEBOOK ENTRY INTO PLACE: \gentryidxu -> \mydest}%
+ \macroswap{paraIdx\gentryidxu}%
+ {paraIdx\expandafter\csname fixedat\gentryidxu\endcsname}%
+% \end{macrocode}
+% Edge case: It's possible that we also have |fixedat\mydest|; in which case that
+% would be messed up with the reshuffling. So we need to rename that
+% to |fixedat\gentryidxu| as well, then reprocess this index
+% \begin{macrocode}
+ \expandafter\ifcsname fixedat\mydest\endcsname%
+ \macroswap{fixedat\gentryidxu}{fixedat\mydest}%
+ \expandafter\global\expandafter\let\csname fixedat\mydest\endcsname\@undefined%
+ \addtocounter{gentryctr}{-1}%
+ \fi%
\fi%
\stepcounter{gentryctr}%
}}\fi%SHUFFLE END
\gamebook@info{Shuffled! Gentry order:}%
\setcounter{gentryctr}{1}%
\whiledo{\not{\value{gentryctr}>\gentrycount}}{%
- \edef\myidx{\arabic{gentryctr}}%
- \gamebook@info{\myidx -> \csname paraIdx\myidx\endcsname}%
+ \edef\gentryidxu{\arabic{gentryctr}}%
+ \gamebook@info{\gentryidxu -> \csname paraIdx\gentryidxu\endcsname}%
\stepcounter{gentryctr}%
}%
% \end{macrocode}
@@ -705,14 +761,14 @@
\ifthenelse{\value{gentryctr}=\gentrycount}{%
\gamebook@beforelast%
}{}%
- \edef\myidx{\arabic{gentryctr}}%
- \xdef\youridx{\csname paraIdx\myidx\endcsname}%
- \gamebook@info{Output gentry \myidx\ of \gentrycount,%
- original idx \youridx}%
+ \edef\gentryidxu{\arabic{gentryctr}}%
+ \xdef\gentryidxs{\csname paraIdx\gentryidxu\endcsname}%
+ \gamebook@info{Output gentry \gentryidxu\ of \gentrycount,%
+ original idx \gentryidxs}%
% \end{macrocode}
% Output the stored entry body, stripping any extraneous space:
% \begin{macrocode}
- \the\csname paratok\youridx\endcsname%
+ \the\csname paratok\gentryidxs\endcsname%
}%
% \end{macrocode}
% Finally, we clear the registers and reset the counter in case we want to start again
@@ -720,12 +776,12 @@
\gamebook@info{All gamebook entries added to main vertical list}%
\setcounter{gentryctr}{1}%
\whiledo{\not{\value{gentryctr}>\gentrycount}}{%
- \edef\myidx{\arabic{gentryctr}}%
+ \edef\gentryidxu{\arabic{gentryctr}}%
\expandafter\global\expandafter\let%
- \csname paratok\myidx\endcsname\@undefined%
- \expandafter\ifcsname fixedat\myidx\endcsname%
+ \csname paratok\gentryidxu\endcsname\@undefined%
+ \expandafter\ifcsname fixedat\gentryidxu\endcsname%
\expandafter\global\expandafter\let%
- \csname fixedat\myidx\endcsname\@undefined%
+ \csname fixedat\gentryidxu\endcsname\@undefined%
\fi%
\stepcounter{gentryctr}%
}%
diff --git a/macros/latex/contrib/gamebooklib/gamebooklib.pdf b/macros/latex/contrib/gamebooklib/gamebooklib.pdf
index 991b237de3..43657233fe 100644
--- a/macros/latex/contrib/gamebooklib/gamebooklib.pdf
+++ b/macros/latex/contrib/gamebooklib/gamebooklib.pdf
Binary files differ
diff --git a/macros/latex/contrib/gamebooklib/gamebooklib_countpagesperseed.sh b/macros/latex/contrib/gamebooklib/gamebooklib_countpagesperseed.sh
index 926e7d152e..926e7d152e 100755..100644
--- a/macros/latex/contrib/gamebooklib/gamebooklib_countpagesperseed.sh
+++ b/macros/latex/contrib/gamebooklib/gamebooklib_countpagesperseed.sh
diff --git a/macros/latex/contrib/gamebooklib/gamebooklib_test.pdf b/macros/latex/contrib/gamebooklib/gamebooklib_test.pdf
index ceac9a9eb7..ae56f8e953 100644
--- a/macros/latex/contrib/gamebooklib/gamebooklib_test.pdf
+++ b/macros/latex/contrib/gamebooklib/gamebooklib_test.pdf
Binary files differ