texlive[63424] Master/texmf-dist: gamebooklib (28may22)

commits+karl at tug.org commits+karl at tug.org
Sat May 28 22:18:12 CEST 2022


Revision: 63424
          http://tug.org/svn/texlive?view=revision&revision=63424
Author:   karl
Date:     2022-05-28 22:18:12 +0200 (Sat, 28 May 2022)
Log Message:
-----------
gamebooklib (28may22)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/gamebooklib/gamebooklib.pdf
    trunk/Master/texmf-dist/doc/latex/gamebooklib/gamebooklib_test.pdf
    trunk/Master/texmf-dist/doc/latex/gamebooklib/gamebooklib_test.tex
    trunk/Master/texmf-dist/source/latex/gamebooklib/Makefile
    trunk/Master/texmf-dist/source/latex/gamebooklib/gamebooklib.dtx
    trunk/Master/texmf-dist/tex/latex/gamebooklib/gamebooklib.sty

Modified: trunk/Master/texmf-dist/doc/latex/gamebooklib/gamebooklib.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/gamebooklib/gamebooklib_test.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/gamebooklib/gamebooklib_test.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/gamebooklib/gamebooklib_test.tex	2022-05-28 20:17:50 UTC (rev 63423)
+++ trunk/Master/texmf-dist/doc/latex/gamebooklib/gamebooklib_test.tex	2022-05-28 20:18:12 UTC (rev 63424)
@@ -27,7 +27,7 @@
 Please see the \texttt{gamebooklib\_test.tex} file alongside the PDF
 to see how the package behaves.
 
-
+\tracingmacros=1
 \begin{gentry}{codea}
   This is the first gentry!
 

Modified: trunk/Master/texmf-dist/source/latex/gamebooklib/Makefile
===================================================================
--- trunk/Master/texmf-dist/source/latex/gamebooklib/Makefile	2022-05-28 20:17:50 UTC (rev 63423)
+++ trunk/Master/texmf-dist/source/latex/gamebooklib/Makefile	2022-05-28 20:18:12 UTC (rev 63424)
@@ -1,4 +1,4 @@
-default: gamebooklib_test.pdf gamebooklib.pdf tidy
+default: gamebooklib_test.pdf gamebooklib.pdf gamebooklib.zip tidy
 
 gamebooklib_test.pdf : gamebooklib_test.tex gamebooklib.sty
 	pdflatex \\nonstopmode\\input gamebooklib_test.tex && \
@@ -13,6 +13,14 @@
 	makeindex -s gind.ist -o gamebooklib.ind gamebooklib.idx && \
 	pdflatex \\nonstopmode\\input gamebooklib.dtx
 
+gamebooklib.zip : gamebooklib_countpagesperseed.sh gamebooklib.dtx gamebooklib.ins gamebooklib.pdf gamebooklib_test.pdf gamebooklib_test.tex Makefile README
+	cd ..; zip gamebooklib/gamebooklib.zip \
+	gamebooklib/gamebooklib_countpagesperseed.sh \
+	gamebooklib/gamebooklib.dtx gamebooklib/gamebooklib.ins \
+	gamebooklib/gamebooklib.pdf gamebooklib/gamebooklib_test.pdf \
+	gamebooklib/gamebooklib_test.tex gamebooklib/Makefile \
+	gamebooklib/README; cd gamebooklib
+
 tidy:
 	rm -f *.log *.ind *.idx *.glo *.gls *.aux *.ilg
 # TODO: should we really be deleting the .sty? Check CTAN rules.

Modified: trunk/Master/texmf-dist/source/latex/gamebooklib/gamebooklib.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/gamebooklib/gamebooklib.dtx	2022-05-28 20:17:50 UTC (rev 63423)
+++ trunk/Master/texmf-dist/source/latex/gamebooklib/gamebooklib.dtx	2022-05-28 20:18:12 UTC (rev 63424)
@@ -17,7 +17,7 @@
 % \iffalse
 % <package>\NeedsTeXFormat{LaTeX2e}[2005/12/01]
 % <package>\ProvidesPackage{gamebooklib}
-% <package>   [2021/08/24 v1.1 gamebooklib typesetting]
+% <package>   [2022/05/26 v1.3 gamebooklib typesetting]
 %
 %<*driver>
 \documentclass{ltxdoc}
@@ -51,10 +51,11 @@
 %   Grave accent  \`     Left brace    \{     Vertical bar  \|
 %   Right brace   \}     Tilde         \~}
 %
-% \CheckSum{539}
+% \CheckSum{708}
 %
 % \changes{v1.0}{2021/08/10}{Initial Release}
 % \changes{v1.1}{2021/08/24}{Bugfix: edge case with clashing fixed-index entries}
+% \changes{v1.2}{2021/09/11}{Bugfix: footnotes set justified on last line}
 %
 % \GetFileInfo{gamebooklib.sty}
 %
@@ -67,6 +68,7 @@
 % \DoNotIndex{\endgroup, \equal, \expandafter, \fi}
 % \DoNotIndex{\gdef, \global, \head, \hspace, \Huge, \if}
 % \DoNotIndex{\ifcsname, \ifhmode, \ifnum, \ifthenelse, \ifvmode}
+% \DoNotIndex{\numexpr}
 % \DoNotIndex{\interlinepenalty, \interlinefootnotepenalty}
 % \DoNotIndex{\large, \leftskip, \mark, \NeedsTeXFormat}
 % \DoNotIndex{\newcounter, \newenvironment, \newtoks, \noexpand}
@@ -74,7 +76,7 @@
 % \DoNotIndex{\par, \PassOptionsToClass, \penalty, \ProcessOptions}
 % \DoNotIndex{\protected at xdef, \ProvidesPackage, \rand, \requirecommand}
 % \DoNotIndex{\RequirePackage, \rightskip, \rule, \setbox}
-% \DoNotIndex{\setcounter, \stepcounter, \textbf, \typeout, \value}
+% \DoNotIndex{\setcounter, \stepcounter, \textbf, \value}
 % \DoNotIndex{\vbox, \unvbox, \vfill, \vspace, \vsize}
 % \DoNotIndex{\WarningFilter, \whiledo, \Collect at Body, \CurrentOption}
 % \DoNotIndex{\DeclareOption, \g at addto@macro, \the, \noindent}
@@ -82,6 +84,7 @@
 % \DoNotIndex{\addtocounter, \refstepcounter, \label}
 % \DoNotIndex{\iffalse, \iftrue, \outputpenalty, \renewcommand}
 % \DoNotIndex{\noshuffle, \verbose, \endpage, \footnote}
+% \DoNotIndex{\if\dots}
 %
 % \title{The Gamebooklib Package\thanks{This document corresponds to \textsf{Gamebooklib}~\fileversion, dated \filedate.}}
 % \author{Robert J Lee \\ latex at rjlee.homelinux.org}
@@ -104,7 +107,7 @@
 % paragraph or longer), each with a sequentially numbered value. At
 % the end of each entry, a link to one or more other numbered
 % entries is given; the reader selects one and they follow through
-% the story in this order. gamebooks traditionally start at the
+% the story in this order. Gamebooks traditionally start at the
 % entry numbered~``1'' and some gamebooks have multiple endings,
 % with the final section representing a success or victory for the
 % reader.
@@ -138,8 +141,8 @@
 %
 % To load the class, use |\usepackage[|\textit{options}|]{gamebook}|
 %
-% The class options are described below; |[footnotes]| is normally a
-% good choice, although there are some limitations.
+% The class options are described below; |[footnotes,jukebox]| is
+% normally a good choice, although there are some limitations.
 %
 % The user simply writes entries like this inside the document:
 % \begin{verbatim}
@@ -239,6 +242,26 @@
 % to avoid broken links.
 % \end{macro}
 %
+%
+% \begin{macro}{jukebox}
+% \changes{v1.3}{2022/05/26}{Feature: "jukebox" shuffle}
+% Use the Jukebox Index shuffling
+% algorithm\footnote{\texttt{https://github.com/robertjlee/jukeboxshuffle}}.
+% This is slightly slower, but tends to reduce the number of times you
+% get a  ``turn to~'' instrution referencing the next (or previous)
+% entry in the original order, by modifying the shuffle to ensure that
+% adjacent gentries in the input have much less chance of being
+% adjacent in the final document. |jukebox| requires a \LaTeXe that
+% supports \cs{numexpr}, and a minimum of 6 gentries. If fewer than
+% 6~|gentry| environments are supplied before \cs{thegentries}, this
+% option will only log a warning in verbose mode.
+%
+% The |jukebox| option guarantees no more adjacent entries than
+% without the option, for a given |seed| value; it may not eliminate
+% them completely unless the number of entries is large. The
+% performance is linear to the number of entries.
+% \end{macro}
+%
 % \begin{macro}{noshuffle}
 % \changes{v1.0}{2021/08/10}{Noshuffle option}
 % In general, it's easier to write gamebooks in a more linear fashion,
@@ -269,7 +292,11 @@
 % each way and see which works better for your text.
 % \end{macro}
 %
-%
+% \begin{macro}{seed}
+% It's suggested that users specify a value for ``seed'' for stable
+% builds, by adding the following before including this package:
+% |\usepackage[seed=123]{lcg}|
+% \end{macro}
 % \section*{Footnotes}
 %
 % When typesetting a gamebook with footnotes, it is confusing if they
@@ -295,7 +322,7 @@
 % page. \TeX\ is asked not to break the page there, but this influence
 % is limited. It may be possible for the author to avoid this, eg by
 % adding a rubber length to the interline spacing (it may be easier to
-% simply choose a different seed value for the |lcg| package to
+% simply choose a different |seed| value for the |lcg| package to
 % reshuffle).
 % \item If you have a lot of rubber space in the text, or
 % variably-sized items, \LaTeX\ may expand the footnote at the end of
@@ -333,7 +360,7 @@
 %\StopEventually{\PrintChanges \pagebreak[4] \PrintIndex}
 %
 %    \begin{macrocode}
-\ProvidesPackage{gamebooklib}[2021/08/24 Gamebook by R Lee latex at rjlee.homelinux.org]
+\ProvidesPackage{gamebooklib}[2022/05/25 Gamebook by R Lee latex at rjlee.homelinux.org]
 %    \end{macrocode}
 % We need \LaTeXe, for the extra token registers.
 %    \begin{macrocode}
@@ -353,7 +380,7 @@
 %
 % \begin{macro}{endpage}
 % The |endpage| option puts the last entry on its own page. This can
-% work better when the last entryraph is about a page long, and also
+% work better when the last entry is about a page long, and also
 % the final ``winning'' entry of the gamebook.
 %    \begin{macrocode}
 \newcommand\gamebook at beforelast{}
@@ -363,6 +390,19 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{jukebox}
+% The |jukebox| option defines the \cs{gamebox at jukebox} macro;
+% while the macro does nothing, \cs{ifcsname} can then be used to
+% determine if the option was set.
+%    \begin{macrocode}
+\DeclareOption{jukebox}{%
+  \newcommand\gamebook at jukebox{}%
+  \gamebook at info{Gamebook Library to perform jukebox index reshuffle
+    pass}%
+}%
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{footnote}
 % The |footnote| option enables our footnote processing, to throw out
 % footnotes at the end of each |gentry| so that they don't appear to be
@@ -370,7 +410,7 @@
 %
 % This is genearlly recommended, unless you have a reason to turn it
 % off (such as a conflicting package). It's disabled by default
-% because it could cause unexpected errors.
+% because it could cause unexpected faults.
 %    \begin{macrocode}
 \def\if at gamebook@footnotes{\iffalse}
 \DeclareOption{footnote}{%
@@ -390,11 +430,8 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{seed}
 % All unknown options are passed to |lcg|, as it's our only dependency with options.
-% It's suggested that users specify a value for ``seed'' for stable
-% builds, by adding the following before including this package:
-%
-% |\usepackage[seed=123]{lcg}|
 %    \begin{macrocode}
 \DeclareOption*{%
   \PassOptionsToClass{\CurrentOption}{lcg}%
@@ -401,7 +438,7 @@
 }%
 \ProcessOptions\relax%
 %    \end{macrocode}
-% We need to capture environment contents
+% \end{macro}% We need to capture environment contents
 %    \begin{macrocode}
 \RequirePackage{environ}%
 %    \end{macrocode}
@@ -504,7 +541,7 @@
 % Later, we'll change the values of the $N$ bit of \cs{gentry$N$}
 % macros when we shuffle (the underlying token registers stay the same).
 %
-% This relies on \cs{refstepcounter}\marg{gentryctr} before expanded
+% This relies on \cs{refstepcounter}\marg{gentryctr} being expanded
 % before this macro. The label |gentry:\gentrycode| is thus set to the
 % current index of the final output entry.
 %    \begin{macrocode}
@@ -546,7 +583,7 @@
 % |footnote| option was given; it sets up the output routine while the
 % gamebook is running.
 %    \begin{macrocode}
-\begingroup%  
+\begingroup%
   \if at gamebook@footnotes\gentry at footnotespergentry\fi%
 %    \end{macrocode}
 % To begin, let's record the number of entries. This may come in
@@ -561,7 +598,7 @@
 % than replacing the definition of \cs{p at stkeysr@nd}.
 % The warning is simply that this package doesn't waste another
 % counter every time it changes the random limits (which happens a lot
-% during Knuth shuffle):
+% during the Fisher-Yates shuffle):
 %    \begin{macrocode}
   \WarningFilter{lcg}{Using an already existing counter rand}%
 %    \end{macrocode}
@@ -587,6 +624,7 @@
 % bottom of \cs{box255}.
 %    \begin{macrocode}
 \if at gamebook@footnotes\output={%
+  \def\gentry at deferoutput{\the\gentry at oldoutput}%
 %    \end{macrocode}
 % The \cs{outputpenalty} tells us why the output routine was called; generally, it's invoked whenever
 % a new floatable environment is generated, or when a page is full. Anything less than -1000 means that
@@ -593,16 +631,22 @@
 % the page was filled, so we should add any footnotes only in this case.
 %    \begin{macrocode}
   \ifnum\outputpenalty<-\@M\else%
-    \edef\tmp@{footnotetoks\botmark}
-    \expandafter\ifcsname footnotetoks\botmark\endcsname%
-    \global\setbox255=\vbox to \vsize{%
-      \unvbox255\vfill\outputfootnotes at endpage}%
-    \fi%
-  \fi%
-  \the\gentry at oldoutput
+    \if\gentryshouldoutput0%
+      \unvbox255\def\gentry at deferoutput{}%
+    \else%
+      \expandafter\ifcsname footnotetoks\botmark\endcsname%
+      \expandafter\if\expandafter\relax\expandafter%
+      \detokenize\expandafter{\csname footnotetoks\botmark\endcsname}\relax\else%
+      \global\setbox255=\vbox to \vsize{%
+        \unvbox255\vfill\outputfootnotes at endpage}%
+    \fi\fi%
+  \fi\fi%
+  \gentry at deferoutput%
+%  \the\gentry at oldoutput
 }\fi%
 %    \end{macrocode}
 %
+%
 % \subsection*{The Shuffling Algorithm}
 %
 % The basic shuffling algorithm is to first shuffle all entries,
@@ -610,7 +654,7 @@
 % 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.
+% fixed-index entries (now fixed).
 % 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
@@ -624,8 +668,8 @@
 % \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 dispirate numbers, not an
+% The |LCG| package provides a suitable pseudo-random number generator.
+% What we want is a repeatable series of disparate numbers, not an
 % especially random one.
 %
 %\begin{enumerate}  
@@ -641,14 +685,18 @@
 % \item If $R\ne i$ then swap macros \cs{gentrytoks}$R$ and \cs{gentrytoks}$i$
 % \item If $R\ne i$ then swap macros \cs{paraIdx}$R$ and \cs{gentryidx}$i$
 % \end{enumerate}
+% \item If a jukebox index sort is requested, perform an optimisation
+% pass (see below)
 % \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''
+% original gentry number to be put out on the $n$th output gentry.
+% \begin{macro}{gentrycount}
 %    \begin{macrocode}
   \xdef\gentrycount{\arabic{gentryctr}}%
 %    \end{macrocode}
+% \end{macro}  
 % we can reuse |gentryctr|; we've finished this set of paras and
 % kept the total count.
 %    \begin{macrocode}
@@ -660,6 +708,7 @@
   \whiledo{\not{\value{gentryctr}>\gentrycount}}{%
     \edef\gentryidxu{\arabic{gentryctr}}%
     \expandafter\xdef\csname paraIdx\gentryidxu\endcsname{\gentryidxu}%
+    \typeout{DEFINED paraIdx\gentryidxu}%
     \stepcounter{gentryctr}%
   }%
 %    \end{macrocode}
@@ -675,13 +724,13 @@
 % 1, and this counter resets after each expansion of \cs{thegentries}).
 % \end{macro}
 %    \begin{macrocode}
-  \if at gamebook@shuffle
+  \if at gamebook@shuffle%
   \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
+% Don't renumber para~1 or \cs{gentrycount}; Fisher-Yates-shuffle the rest
 % NB: we stop at \cs{gentrycount}$-2$, because \cs{gentrycount}$-1$ would only shuffle
 % with itself.
 %    \begin{macrocode}
@@ -734,9 +783,77 @@
         \expandafter\global\expandafter\let\csname fixedat\mydest\endcsname\@undefined%
         \addtocounter{gentryctr}{-1}%
       \fi%
+%    \end{macrocode}
+% if we are doing a jukebox shuffle, remember which final entries are fixed, so
+% they don't get moved.
+%    \begin{macrocode}
+      \ifcsname gamebook at jukebox\endcsname%
+        \expandafter\def\csname fixedto\mydest\endcsname{}%
+      \fi%
     \fi%
     \stepcounter{gentryctr}%
-  }}\fi%SHUFFLE END
+  }%
+%    \end{macrocode}
+% The jukebox shuffle requires an extra pass. This must come after
+% moving fixed entries into their final place, to allow us to compare
+% the initial indicies.
+% We make a reasonable effort:\begin{itemize}
+% \item $t$ is the current index
+% \item $u$ is the next index
+% \item $r$ is a random index after $u$ (make 3 attempts to find a
+% non-fixed $r$)
+% \item if abs$(t-u)=1$ and $r$ is not fixed, then swap $u$ and $r$
+% \textbf{if} $u$ is not fixed; otherwise:
+% \item if abs$(t-u)=1$ and $r$ is not fixed, then swap $t$ and $r$
+% \textbf{if} $t$ is not fixed;
+% \item otherwise, give up.  
+% \end{itemize}
+%    \begin{macrocode}
+  \ifcsname gamebook at jukebox\endcsname%
+  \ifnum\gentrycount<6%
+    \gamebook at info{Jukebox pass skipped; too few entries}%
+  \else%
+  \setcounter{gentryctr}{2}%
+  \whiledo{\not{\value{gentryctr}=\stoppoint}}{%
+    \edef\gentryidxt{\arabic{gentryctr}}%
+    \edef\curpos{\csname paraIdx\gentryidxt\endcsname}%
+    \stepcounter{gentryctr}%
+    \edef\gentryidxu{\arabic{gentryctr}}%
+    \edef\nextpos{\csname paraIdx\gentryidxu\endcsname}%
+    \edef\pdiff{\the\numexpr\curpos+\nextpos}%
+    \ifnum\pdiff<0\edef\pdiff{\the\numexpr-\pdiff}\fi%
+    \edef\sdiff{\the\numexpr\curpos-\nextpos}%
+    \ifnum\sdiff<0\edef\sdiff{\the\numexpr-\sdiff}\fi%
+    \ifnum\pdiff<\sdiff\relax\def\thediff{\pdiff}\else\def\thediff{\sdiff}\fi%
+    \ifnum\thediff=1%
+      \gamebook at info{Jukebox: entries are too close: %
+        \gentryidxt,\gentryidxu\space (original \curpos,\nextpos)}%
+      \chgrand[first=\numexpr\gentryidxu+1]%
+      \rand%
+      \expandafter\ifcsname fixedto\arabic{rand}\endcsname\rand\fi%
+      \expandafter\ifcsname fixedto\arabic{rand}\endcsname\rand\fi%
+      \expandafter\ifcsname fixedto\arabic{rand}\endcsname%
+        \gamebook at info{Can't reshuffle: failed to find non-fixed index}%
+      \else%
+        \ifcsname fixedto\gentryidxu\endcsname%
+          \ifcsname fixedto\gentryidxt\endcsname%
+          \gamebook at info{Can't reshuffle: \curpos\space and %
+            \nextpos\space are both fixed.}%
+          \else%
+            \gamebook at info{Reshuffling \gentryidxt\space to \arabic{rand}}%
+            \macroswap{paraIdx\gentryidxt}{paraIdx\arabic{rand}}%
+          \fi%
+        \else%
+          \gamebook at info{Reshuffling \gentryidxu\space to%
+            \arabic{rand} (alt)}%
+          \macroswap{paraIdx\gentryidxu}{paraIdx\arabic{rand}}%
+    \fi\fi\fi%
+  }%
+  \fi\fi%
+  }\fi%SHUFFLE END
+%    \end{macrocode}
+% Now we can output the |gentry| token registers to let \LaTeX\ do its thing:
+%    \begin{macrocode}
   \gamebook at info{Shuffled! Gentry order:}%
   \setcounter{gentryctr}{1}%
   \whiledo{\not{\value{gentryctr}>\gentrycount}}{%
@@ -749,7 +866,7 @@
 % We can reuse the same counter again to output
 %    \begin{macrocode}
   \setcounter{gentryctr}{0}%
-  \gamebook at info{Outputting \gentrycount\ gamebook entries}%
+  \gamebook at info{Outputting \gentrycount\space gamebook entries}%
   \whiledo{\value{gentryctr}<\gentrycount}{%
 %    \end{macrocode}
 % Use refstepcounter in the loop to allow \cs{label} to work as expected.
@@ -772,6 +889,7 @@
   }%
 %    \end{macrocode}
 % Finally, we clear the registers and reset the counter in case we want to start again
+% (NB: fixedto is scope to the current block only, so no need to clear that)
 %    \begin{macrocode}
   \gamebook at info{All gamebook entries added to main vertical list}%
   \setcounter{gentryctr}{1}%
@@ -786,7 +904,7 @@
     \stepcounter{gentryctr}%
   }%
   \setcounter{gentryctr}{0}%
-  \eject
+  \eject%
   \endgroup%
 }%
 %    \end{macrocode}
@@ -820,6 +938,30 @@
 }%
 %    \end{macrocode}
 %
+% \begin{macro}{gentryshouldoutput}
+% \changes{v1.3}{2022/05/26}{Suppress short pages option}
+% This macro \textbf{may} be called from the output routine, and can
+% be used to suppress page breaks. It was added because it proves
+% fairly easy to write custom divider routines that can produce blank
+% pages. If it expands to the number 1, then the page will be output;
+% if it expands to 0, it will not be.
+%
+% For example, the following will prevent pages that are less than 80\% full.
+%
+% \verb!\renewcommand{\gentryshouldoutput}{%!
+%
+% \verb!   \ifdim\pagetotal>0.8\pagegoal\relax1\else 0\fi}!
+%
+% \textbf{Caution:} if this macro continually tests false, then
+% material will eventually be discarded from the main vertical list to
+% ensure that \TeX\ can complete the output of the document. If you
+% redefine this macro, make sure to check out output carefully for
+% missing text.
+%    \begin{macrocode}
+\newcommand{\gentryshouldoutput}{1}
+%    \end{macrocode}
+% \end{macro}
+%
 % \DescribeMacro{\gentryfooter}
 % This takes no arguments and is simply expanded after the entry is typeset. The default adds some vertical
 % space and a simple separator.
@@ -831,10 +973,8 @@
 %    \end{macrocode}
 %
 % \DescribeMacro{\ignorespacesandallpars@}
-% This is a technique described on StackExchange:
+% This is a technique described on StackExchange\footnote{\small https://tex.stackexchange.com/questions/179016/\\\mbox{~}\hspace{1in}ignore-spaces-and-pars-after-an-environment\#179034}.
 %
-% {\small https://tex.stackexchange.com/questions/179016/\\ignore-spaces-and-pars-after-an-environment\#179034}
-%
 % This is used to ensure that extra space at the start and end of the |gentry|
 % environment is ignored.
 %
@@ -916,7 +1056,7 @@
 %
 % This macro takes one argument, being the maximum index of footnotes to output, inclusive.
 % Footnotes after this index will be excluded. If not provided, the
-% value provided by the counter \cs{@mfpn}, which in the default
+% value provided by the counter \cs{@mfpn}, which is the default
 % \LaTeX\ counter, will be used.
 %    \begin{macrocode}
 \newcounter{fncounter}%
@@ -923,7 +1063,7 @@
 \newcommand{\outputfootnotes}[1]{%
   \begingroup%
   \def\in at out{}% flag that footnotes are outputting; suppresses marks
-  \setcounter{fncounter}{1}
+  \setcounter{fncounter}{1}%
 %    \end{macrocode}
 % Called in vertical mode, and don't want to throw a page break.
 %
@@ -931,7 +1071,7 @@
 %    \begin{macrocode}
   \def\footnote at rule{%
 %    \end{macrocode}
-% The next  line comess from the TUGboat suggestions, and protect against various user changes
+% The next line comes from the TUGboat suggestions, and protect against various user changes
 %    \begin{macrocode}
     \leftskip=0pt\rightskip=0pt\interlinepenalty=1000%
     \penalty-1000%
@@ -971,9 +1111,7 @@
         \edef\tmp@@{\csname footnotetoks\arabic{fncounter}\endcsname}%
 %    \end{macrocode}
 % This \cs{detokenize} black magic tests if a token reg is actually
-% empty:
-%        
-% https://tex.stackexchange.com/questions/263733/\\whats-the-best-practice-way-to-test-whether-parameter-is-empty
+% empty\footnote{\texttt{https://tex.stackexchange.com/questions/263733/\\\mbox{~}\hspace{1in}whats-the-best-practice-way-to-test-whether-parameter-is-empty}}
 %    \begin{macrocode}
         \expandafter\if\expandafter\relax\expandafter%
           \detokenize\expandafter{\the\tmp@@}\relax\else%
@@ -1042,7 +1180,7 @@
 % \cs{botmark} has a value, then we can output all footnotes up to
 % that index.
 %    \begin{macrocode}
-\g at addto@macro{\gentry at footnotespergentry}{
+\g at addto@macro{\gentry at footnotespergentry}{%
 \newcommand{\outputfootnotes at endpage}{%
   \expandafter\if\expandafter\relax\expandafter%
   \detokenize\expandafter{\botmark}\relax\else%

Modified: trunk/Master/texmf-dist/tex/latex/gamebooklib/gamebooklib.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/gamebooklib/gamebooklib.sty	2022-05-28 20:17:50 UTC (rev 63423)
+++ trunk/Master/texmf-dist/tex/latex/gamebooklib/gamebooklib.sty	2022-05-28 20:18:12 UTC (rev 63424)
@@ -20,7 +20,7 @@
 %% and version 1.3 or later is part of all distributions of
 %% LaTeX version 2005/12/01 or later.
 %% 
-\ProvidesPackage{gamebooklib}[2021/08/24 Gamebook by R Lee latex at rjlee.homelinux.org]
+\ProvidesPackage{gamebooklib}[2022/05/25 Gamebook by R Lee latex at rjlee.homelinux.org]
 \NeedsTeXFormat{LaTeX2e}[1994/06/01]
 \newcommand{\gamebook at info}[1]{}%
 \DeclareOption{verbose}{%
@@ -30,6 +30,11 @@
 \DeclareOption{endpage}{%
   \renewcommand\gamebook at beforelast{\eject}%
 }%
+\DeclareOption{jukebox}{%
+  \newcommand\gamebook at jukebox{}%
+  \gamebook at info{Gamebook Library to perform jukebox index reshuffle
+    pass}%
+}%
 \def\if at gamebook@footnotes{\iffalse}
 \DeclareOption{footnote}{%
   \gdef\if at gamebook@footnotes{\iftrue}%
@@ -92,14 +97,19 @@
 \newtoks\gentry at oldoutput{}%
 \edef\mytmp@{\noexpand\gentry at oldoutput={\the\output}}\mytmp@%
 \if at gamebook@footnotes\output={%
+  \def\gentry at deferoutput{\the\gentry at oldoutput}%
   \ifnum\outputpenalty<-\@M\else%
-    \edef\tmp@{footnotetoks\botmark}
-    \expandafter\ifcsname footnotetoks\botmark\endcsname%
-    \global\setbox255=\vbox to \vsize{%
-      \unvbox255\vfill\outputfootnotes at endpage}%
-    \fi%
-  \fi%
-  \the\gentry at oldoutput
+    \if\gentryshouldoutput0%
+      \unvbox255\def\gentry at deferoutput{}%
+    \else%
+      \expandafter\ifcsname footnotetoks\botmark\endcsname%
+      \expandafter\if\expandafter\relax\expandafter%
+      \detokenize\expandafter{\csname footnotetoks\botmark\endcsname}\relax\else%
+      \global\setbox255=\vbox to \vsize{%
+        \unvbox255\vfill\outputfootnotes at endpage}%
+    \fi\fi%
+  \fi\fi%
+  \gentry at deferoutput%
 }\fi%
   \xdef\gentrycount{\arabic{gentryctr}}%
   \setcounter{gentryctr}{0}%
@@ -107,9 +117,10 @@
   \whiledo{\not{\value{gentryctr}>\gentrycount}}{%
     \edef\gentryidxu{\arabic{gentryctr}}%
     \expandafter\xdef\csname paraIdx\gentryidxu\endcsname{\gentryidxu}%
+    \typeout{DEFINED paraIdx\gentryidxu}%
     \stepcounter{gentryctr}%
   }%
-  \if at gamebook@shuffle
+  \if at gamebook@shuffle%
   \setcounter{rand}{\gentrycount}%
   \addtocounter{rand}{-1}\edef%
   \stoppoint{\arabic{rand}}%
@@ -146,9 +157,54 @@
         \expandafter\global\expandafter\let\csname fixedat\mydest\endcsname\@undefined%
         \addtocounter{gentryctr}{-1}%
       \fi%
+      \ifcsname gamebook at jukebox\endcsname%
+        \expandafter\def\csname fixedto\mydest\endcsname{}%
+      \fi%
     \fi%
     \stepcounter{gentryctr}%
-  }}\fi%SHUFFLE END
+  }%
+  \ifcsname gamebook at jukebox\endcsname%
+  \ifnum\gentrycount<6%
+    \gamebook at info{Jukebox pass skipped; too few entries}%
+  \else%
+  \setcounter{gentryctr}{2}%
+  \whiledo{\not{\value{gentryctr}=\stoppoint}}{%
+    \edef\gentryidxt{\arabic{gentryctr}}%
+    \edef\curpos{\csname paraIdx\gentryidxt\endcsname}%
+    \stepcounter{gentryctr}%
+    \edef\gentryidxu{\arabic{gentryctr}}%
+    \edef\nextpos{\csname paraIdx\gentryidxu\endcsname}%
+    \edef\pdiff{\the\numexpr\curpos+\nextpos}%
+    \ifnum\pdiff<0\edef\pdiff{\the\numexpr-\pdiff}\fi%
+    \edef\sdiff{\the\numexpr\curpos-\nextpos}%
+    \ifnum\sdiff<0\edef\sdiff{\the\numexpr-\sdiff}\fi%
+    \ifnum\pdiff<\sdiff\relax\def\thediff{\pdiff}\else\def\thediff{\sdiff}\fi%
+    \ifnum\thediff=1%
+      \gamebook at info{Jukebox: entries are too close: %
+        \gentryidxt,\gentryidxu\space (original \curpos,\nextpos)}%
+      \chgrand[first=\numexpr\gentryidxu+1]%
+      \rand%
+      \expandafter\ifcsname fixedto\arabic{rand}\endcsname\rand\fi%
+      \expandafter\ifcsname fixedto\arabic{rand}\endcsname\rand\fi%
+      \expandafter\ifcsname fixedto\arabic{rand}\endcsname%
+        \gamebook at info{Can't reshuffle: failed to find non-fixed index}%
+      \else%
+        \ifcsname fixedto\gentryidxu\endcsname%
+          \ifcsname fixedto\gentryidxt\endcsname%
+          \gamebook at info{Can't reshuffle: \curpos\space and %
+            \nextpos\space are both fixed.}%
+          \else%
+            \gamebook at info{Reshuffling \gentryidxt\space to \arabic{rand}}%
+            \macroswap{paraIdx\gentryidxt}{paraIdx\arabic{rand}}%
+          \fi%
+        \else%
+          \gamebook at info{Reshuffling \gentryidxu\space to%
+            \arabic{rand} (alt)}%
+          \macroswap{paraIdx\gentryidxu}{paraIdx\arabic{rand}}%
+    \fi\fi\fi%
+  }%
+  \fi\fi%
+  }\fi%SHUFFLE END
   \gamebook at info{Shuffled! Gentry order:}%
   \setcounter{gentryctr}{1}%
   \whiledo{\not{\value{gentryctr}>\gentrycount}}{%
@@ -157,7 +213,7 @@
     \stepcounter{gentryctr}%
   }%
   \setcounter{gentryctr}{0}%
-  \gamebook at info{Outputting \gentrycount\ gamebook entries}%
+  \gamebook at info{Outputting \gentrycount\space gamebook entries}%
   \whiledo{\value{gentryctr}<\gentrycount}{%
     \refstepcounter{gentryctr}%
     \ifthenelse{\value{gentryctr}=\gentrycount}{%
@@ -182,7 +238,7 @@
     \stepcounter{gentryctr}%
   }%
   \setcounter{gentryctr}{0}%
-  \eject
+  \eject%
   \endgroup%
 }%
 \newcommand{\gentryheader}[4]{%
@@ -193,6 +249,7 @@
   \par%
   \marginpar{#3}%
 }%
+\newcommand{\gentryshouldoutput}{1}
 \newcommand{\gentryfooter}{%
   \par\vspace{2em}\centerline{---}\vspace{2em plus 1in}\par%
 }%
@@ -230,7 +287,7 @@
 \newcommand{\outputfootnotes}[1]{%
   \begingroup%
   \def\in at out{}% flag that footnotes are outputting; suppresses marks
-  \setcounter{fncounter}{1}
+  \setcounter{fncounter}{1}%
   \def\footnote at rule{%
     \leftskip=0pt\rightskip=0pt\interlinepenalty=1000%
     \penalty-1000%
@@ -262,7 +319,7 @@
   \fi%
 }%
 \newcommand{\noentryfoot}{\def\outputfootnotes at endgentry{}}
-\g at addto@macro{\gentry at footnotespergentry}{
+\g at addto@macro{\gentry at footnotespergentry}{%
 \newcommand{\outputfootnotes at endpage}{%
   \expandafter\if\expandafter\relax\expandafter%
   \detokenize\expandafter{\botmark}\relax\else%



More information about the tex-live-commits mailing list.