diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/getitems')
-rw-r--r-- | Master/texmf-dist/source/latex/getitems/getitems.dtx | 460 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/getitems/getitems.ins | 57 |
2 files changed, 517 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/getitems/getitems.dtx b/Master/texmf-dist/source/latex/getitems/getitems.dtx new file mode 100644 index 00000000000..f5dc7c12bac --- /dev/null +++ b/Master/texmf-dist/source/latex/getitems/getitems.dtx @@ -0,0 +1,460 @@ +% \iffalse meta-comment +% +% getitems.dtx +% Copyright 2016 by Anders O.F. Hendrickson (anders.hendrickson@snc.edu) +% +% This work may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3 +% 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.3 or later is part of all distributions of LaTeX +% version 2005/12/01 or later. +% +% This work has the LPPL maintenance status `maintained'. +% +% The Current Maintainer of this work is Anders O.F. Hendrickson. +% +% This work consists of the files moodle.dtx and moodle.ins +% and the derived files moodle.sty and getitems.sty. +% +% \fi +% +% \iffalse +%<*driver> +\ProvidesFile{getitems.dtx} +%</driver> +%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01] +%<package>\ProvidesPackage{getitems} +%<*package> + [2016/01/11 v1.0 gather items from a list] +%</package> +% +%<*driver> +\documentclass{ltxdoc} +\usepackage{getitems} +\usepackage{fancyvrb} +\usepackage{amssymb} +\usepackage{xcolor} +\EnableCrossrefs +\CodelineIndex +\RecordChanges +\begin{document} + \DocInput{getitems.dtx} + \PrintChanges + %\PrintIndex +\end{document} +%</driver> +% \fi +% +% \CheckSum{212} +% +% \CharacterTable +% {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +% Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +% Digits \0\1\2\3\4\5\6\7\8\9 +% Exclamation \! Double quote \" Hash (number) \# +% Dollar \$ Percent \% Ampersand \& +% Acute accent \' Left paren \( Right paren \) +% Asterisk \* Plus \+ Comma \, +% Minus \- Point \. Solidus \/ +% Colon \: Semicolon \; Less than \< +% Equals \= Greater than \> Question mark \? +% Commercial at \@ Left bracket \[ Backslash \\ +% Right bracket \] Circumflex \^ Underscore \_ +% Grave accent \` Left brace \{ Vertical bar \| +% Right brace \} Tilde \~} +% +% +% \changes{v1.0}{2016/01/11}{Initial version} +% +% \GetFileInfo{getitems.sty} +% +% \DoNotIndex{\newcommand,\newenvironment,\def} +% +% +% \title{The \textsf{getitems} package: \\ +% gathering {\tt\string\item}'s from a list-like environment\thanks{This document +% corresponds to \textsf{getitems.sty}~\fileversion, dated \filedate.}} +% \author{Anders Hendrickson\\ St.~Norbert College, De~Pere, WI, USA \\ \texttt{anders.hendrickson@snc.edu}} +% +% +% \maketitle +% +% \section{Overview} +% +% The |enumerate| and |itemize| environments of \LaTeX\ organize their contents +% through the use of the |\item| command. Each entry in these lists is prefaced +% with the command |\item|, making for very compact and easily readable source +% code. Package designers may find it useful to use the same syntax for +% their custom environments. The \textsf{getitems} package makes +% it easy to code such environments by parsing a string of tokens, separating them +% by the occurrence of |\item|'s, and saving the contents as macros. +% Nested environments are handled correctly. +% +% Moreover, some typesetting tasks naturally consist of a ``header'' followed by +% several related items; one example would be a multiple-choice question on a +% school examination. This package saves any \TeX\ tokens appearing before the +% first |\item| as the zeroth item for special handling. +% +% \section{Usage} +% +% \DescribeMacro{\gatheritems} +% To parse a string of text, such as the body of an environment, +% call +% \begin{center} +% |\gatheritems|\marg{text to parse}. +% \end{center} +% This will scan through the \meta{text to parse}, dividing it at each |\item| +% while respecting \TeX\ groupings and nested environments, +% and store the divided portions of text into memory. +% +% \DescribeMacro{numgathereditems} +% The total number of items in the parsed text is stored in the \LaTeX\ counter +% |numgathereditems|. +% +% \DescribeMacro{\gathereditem} +% To retrieve a stored item, you may call |\gathereditem|\marg{item number}; +% the \meta{item number} should expand to an arabic representation of a nonnegative integer. +% Any tokens occurring before the first |\item| may be retrieved with +% |\gathereditem{0}|. +% +% \DescribeMacro{\loopthroughitemswithcommand} +% Once the items are gathered, it will probably be necessary to loop through +% all of them. +% Of course a package author can do so manually, but |getitems| provides a +% built-in way to do so by calling |\loopthroughitemswithcommand|\marg{macro}. +% The \meta{macro} must be a control sequence taking exactly one argument; +% it will be called successively with the item text. +% For example, +% \begin{quote} +% \begin{tabular}{p{3in}p{1.5in}} +% \begin{minipage}{3in} +% \begin{Verbatim}[gobble=6] +% \gatheritems{% +% Zero +% \item One +% \item Two +% \item Three +% } +% \loopthroughitemswithcommand{\fbox} +% \end{Verbatim} +% \end{minipage} +% & +% \begin{minipage}{1.5in} +% \gatheritems{% +% Zero +% \item One +% \item Two +% \item Three +% } +% \loopthroughitemswithcommand{\fbox} +% \end{minipage} +% \end{tabular} +% \end{quote} +% The result is the same as processing |\fbox{One}|, then |\fbox{Two}|, and finally |\fbox{Three}|. +% Note that |\loopthroughitemswithcommand| deliberately ignores the zeroth entry, which occurs +% before the first |\item|. +% +% \DescribeMacro{currentitemnumber} +% Typically the package author will create a custom macro to process each item. +% This macro may make use of the index of the loop, which is stored in the +% \LaTeX\ counter |currentitemnumber|. +% \DescribeMacro{\ifgatherbeginningofloop} +% A conditional |\ifgatherbeginningofloop| is also available, +% which only evaluates as true when +% processing the first item; it is thus functionally equivalent to +% |\ifnum1=\c@currentitemnumber|. +% The custom macro may take advantage of this to run special code for the first item only. +% +% +% \section{Example} +% An example using |getitems| to create a custom environment may be informative. +% We use the |\NewEnviron| command from the |environ| package +% (automatically loaded by |getitems|) to define a |question| environment; +% the body between the |\begin{question}| and |\end{question}| is available as |\BODY|. +% \medskip +% +% \par \noindent +% \begin{tabular}{p{3in}p{1.5in}} +% \begin{minipage}{3in} +% \small +% \begin{Verbatim}[gobble=6] +% \def\doitem#1{\item #1\hfill $\Box$}% +% \NewEnviron{question}{% +% \expandafter\gatheritems\expandafter{\BODY}% +% \gathereditem{0}% +% \begin{itemize} +% \loopthroughitemswithcommand{\doitem} +% \end{itemize} +% } +% \begin{question} +% Who proved the unsolvability of the quintic? +% \item Abel +% \item Galois +% \item Lie +% \end{question} +% \end{Verbatim} +% \end{minipage} +% & +% \begin{minipage}{1.5in} +% \def\doitem#1{\item #1\hfill $\Box$}% +% \NewEnviron{question}{% +% \expandafter\gatheritems\expandafter{\BODY}% +% \gathereditem{0}% +% \begin{itemize} +% \loopthroughitemswithcommand{\doitem} +% \end{itemize} +% } +% \begin{question} +% Who proved the unsolvability of the quintic? +% Check the appropriate box. +% \item Abel +% \item Galois +% \item Lie +% \end{question} +% \end{minipage} +% \end{tabular} +% \medskip +% +% +% This second example shows that nested environments are handled as expected. +% \medskip +% +% \par \noindent +% \begin{tabular}{p{3in}p{2in}} +% \begin{minipage}{3in} +% \small +% \begin{Verbatim}[gobble=6] +% \def\doitem#1{\item[$\Box$] +% \fbox{\parbox[t]{1.75in}{#1}}}% +% \NewEnviron{question}{% +% \expandafter\gatheritems\expandafter{\BODY}% +% \gathereditem{0}% +% \begin{itemize} +% \loopthroughitemswithcommand{\doitem} +% \end{itemize} +% } +% \begin{question} +% Who proved the unsolvability of the quintic? +% Check the appropriate box. +% \item Abel +% \begin{itemize} +% \item Born August 5, 1802 +% \item Died April 6, 1829 +% \end{itemize} +% \item Galois +% \begin{itemize} +% \item Born October 25, 1811 +% \item Died May 31, 1832 +% \end{itemize} +% \item Lie +% \begin{itemize} +% \item Born December 17, 1842 +% \item Died February 18, 1899 +% \end{itemize} +% \end{question} +% \end{Verbatim} +% \end{minipage} +% & +% \begin{minipage}{2.5in} +% \def\doitem#1{\item[$\Box$] \fbox{\parbox[t]{1.75in}{#1}}}% +% \NewEnviron{question}{% +% \expandafter\gatheritems\expandafter{\BODY}% +% \gathereditem{0}% +% \begin{itemize} +% \loopthroughitemswithcommand{\doitem} +% \end{itemize} +% } +% \begin{question} +% Who proved the unsolvability of the quintic? +% Check the appropriate box. +% \item Abel +% \begin{itemize} +% \item Born August 5, 1802 +% \item Died April 6, 1829 +% \end{itemize} +% \item Galois +% \begin{itemize} +% \item Born October 25, 1811 +% \item Died May 31, 1832 +% \end{itemize} +% \item Lie +% \begin{itemize} +% \item Born December 17, 1842 +% \item Died February 18, 1899 +% \end{itemize} +% \end{question} +% \end{minipage} +% \end{tabular} +% +% +% \StopEventually{} +% +% \section{Implementation} +% +% We need the |trimspaces| package to remove excess spaces +% from the items we find. +% Although the |environ| package is not used by |getitems| itself, +% it will almost certainly be needed. +% \begin{macrocode} +\RequirePackage{environ} +\RequirePackage{trimspaces} +\let\xa=\expandafter +% \end{macrocode} +% \begin{macro}{\gathereditem} +% The $k$th item found will be stored in the macro |\getitems@item@|\meta{k}; +% the user can access it through the |\gathereditem| macro. +% \begin{macrocode} +\def\gathereditem#1{\csname getitems@item@#1\endcsname} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{numgathereditems} +% We define the \LaTeX\ counter |numgathereditems|. +% \begin{macrocode} +\newcounter{numgathereditems} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\gatheritems} +% The main control sequence of this package is |\gatheritems|. +% The na\"ive strategy is to use the delimiter mechanism of \TeX\ to +% split the text at the first occurrence of the token ``|\item|.'' +% We add |\getitems@relax| before, +% and ``|\item\getitems@terminalitem|'' after, the text to help us +% detect empty items and prevent +% errors after we have found all the genuine |\item|'s. +% \begin{macrocode} +\long\def\gatheritems#1{% + \setcounter{getitems@begindepth}{0}% + \setcounter{numgathereditems}{0}% + \xa\long\xa\gdef\csname getitems@item@0\endcsname{}% + \gatheritems@int\getitems@relax#1\item\getitems@terminalitem\getitems@endgatheritems + \xa\let\xa\gatheredheader\xa=\csname getitems@item@0\endcsname +} +% \end{macrocode} +% \end{macro} +% The trouble with the na\"ive strategy is that it won't handle nested +% environments correctly. To do that, we need to keep track of how deeply +% nested we are with the macro |\getitems@trackbegindepth|, defined below. +% That macro stores its results in the \LaTeX\ counter |getitems@begindepth|; +% a value of 0 indicates the top-level within the argument of |\gatheritems|. +% \begin{macrocode} +\def\@getitems@terminalitem{\getitems@terminalitem}% +\def\@dummy@relax{\getitems@relax}% +\long\def\gatheritems@int#1\item#2\getitems@endgatheritems{% + \getitems@trackbegindepth{#1}% + \ifnum\c@getitems@begindepth=0\relax +% \end{macrocode} +% At this point we have gathered a complete |\item|; we have not stopped +% accidentally at a sub|\item|. The original |\item| might have had no content, +% in which case |#1| will be simply ``|\getitems@relax|'', and we do nothing; +% otherwise we strip off the |\getitems@relax| and store those tokens in +% |\getitems@item@|\meta{numgathereditems}. +% \begin{macrocode} + \def\getitems@test@i{#1}% + \ifx\getitems@test@i\@dummy@relax + \relax + \else + \xa\xa\xa\g@addto@macro + \xa\xa\csname getitems@item@\the\c@numgathereditems\endcsname + \xa{\getitems@stripfirsttokenfrom#1\getitems@endstrip}% + \fi +% \end{macrocode} +% Now we test whether we have reached the end of the text to be parsed. +% This is the case if |#2| is simply |\getitems@terminalitem|, +% and we stop the recursion. +% Otherwise there is at least one more |\item| to process, so we increment |numgathereditems|, +% prepare |\getitems@item@|\meta{k+1}, +% and prepare to recurse. +% \begin{macrocode} + \def\getitems@test@ii{#2}% + \ifx\getitems@test@ii\@getitems@terminalitem + \let\getitems@next=\relax + \else + \stepcounter{numgathereditems}% + \xa\gdef\csname getitems@item@\the\c@numgathereditems\endcsname{}% + \def\getitems@next{\gatheritems@int\getitems@relax#2\getitems@endgatheritems}% + \fi + \else +% \end{macrocode} +% We are now in the case where |getitems@begindepth|${}\neq 0$. +% This essentially means that the text in |#1| has more |\begin|'s than |\end|'s, +% so we have not read a complete |\item|; we stopped at an ``|\item|'' token +% within a sub-environment. +% We save the text gathered so far to |\getitems@item@|\meta{k}, +% including the |\item| we parsed by mistake, +% and then call |\gatheritems@int| again to sweep up more tokens. +% \begin{macrocode} + \xa\xa\xa\g@addto@macro + \xa\xa\csname getitems@item@\the\c@numgathereditems\endcsname + \xa{\getitems@stripfirsttokenfrom#1\getitems@endstrip}% + \xa\g@addto@macro\csname getitems@item@\the\c@numgathereditems\endcsname{\item}% + \def\getitems@next{\gatheritems@int\getitems@relax#2\getitems@endgatheritems}% + \fi + \getitems@next +} +% \end{macrocode} +% This next macro is used by |\gatheritems@int| to strip off a +% dummy |\getitems@relax| token from the beginning of its first parameter. +% \begin{macrocode} +\long\def\getitems@stripfirsttokenfrom#1#2\getitems@endstrip{#2} +% \end{macrocode} +% Here is the code used to track the depth of nesting of |\begin|'s in a text. +% \begin{macrocode} +\newcounter{getitems@begindepth} +\long\def\getitems@trackbegindepth#1{% + \getitems@trackbegindepth@int#1\getitems@terminalbegindepth\getitems@endtrackbegindepth +} +\def\@getitems@begin{\begin}% +\def\@getitems@end{\end}% +\def\@getitems@terminalbegindepth{\getitems@terminalbegindepth}% +\long\def\getitems@trackbegindepth@int#1#2\getitems@endtrackbegindepth{% + \def\getitems@test@i{#1}% + \ifx\getitems@test@i\@getitems@begin + \advance\c@getitems@begindepth by 1\relax + \else + \ifx\getitems@test@i\@getitems@end + \advance\c@getitems@begindepth by -1\relax + \fi + \fi + \def\getitems@test@ii{#2}% + \trim@spaces@in\getitems@test@ii + \ifx\getitems@test@ii\@getitems@terminalbegindepth + \let\getitems@trackbegindepth@next=\relax + \else + \def\getitems@trackbegindepth@next{% + \getitems@trackbegindepth@int#2\getitems@endtrackbegindepth}% + \fi + \getitems@trackbegindepth@next +} +% \end{macrocode} +% \begin{macro}{\loopthroughitemswithcommand} +% Finally, we define the user-level command to loop through +% the gathered items from 1 through |numgathereditems|. +% \begin{macrocode} +\newif\ifgatherbeginningofloop +\newcounter{currentitemnumber} +\def\loopthroughitemswithcommand#1{% + \setcounter{currentitemnumber}{1}% + \gatherbeginningoflooptrue + \loopthroughitemswithcommand@int{#1}% +} + +\def\loopthroughitemswithcommand@int#1{% + \ifnum\c@currentitemnumber>\c@numgathereditems\relax + \let\getitems@loop@next=\relax% + \else + \xa\xa\xa#1\xa\xa\xa{\csname getitems@item@\the\c@currentitemnumber\endcsname}% + \def\getitems@loop@next{\loopthroughitemswithcommand@int{#1}}% + \stepcounter{currentitemnumber}% + \fi + \gatherbeginningofloopfalse + \getitems@loop@next +} +% \end{macrocode} +% \end{macro} +% +% \Finale +\endinput diff --git a/Master/texmf-dist/source/latex/getitems/getitems.ins b/Master/texmf-dist/source/latex/getitems/getitems.ins new file mode 100644 index 00000000000..a6e527bf3f1 --- /dev/null +++ b/Master/texmf-dist/source/latex/getitems/getitems.ins @@ -0,0 +1,57 @@ +%% getitems.ins +%% Copyright 2016 by Anders O.F. Hendrickson +%% +%% This work may be distributed and/or modified under the +%% conditions of the LaTeX Project Public License, either version 1.3 +%% 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.3 or later is part of all distributions of LaTeX +%% version 2005/12/01 or later. +%% +%% This work has the LPPL maintenance status `maintained'. +%% +%% The Current Maintainer of this work is Anders O.F. Hendrickson. +%% +%% This work consists of the files getitems.dtx and getitems.ins +%% and the derived file getitems.sty. + +\input docstrip.tex +\keepsilent + +\usedir{tex/latex/getitems} + +\preamble + +This is a generated file. + +Copyright (C) 2016 by Anders Hendrickson <anders.hendrickson@snc.edu> + +This work may be distributed and/or modified under the +conditions of the LaTeX Project Public License, either version 1.3 +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.3 or later is part of all distributions of LaTeX +version 2005/12/01 or later. + +\endpreamble + +\generate{\file{getitems.sty}{\from{getitems.dtx}{package}}} + +\obeyspaces +\Msg{*************************************************************} +\Msg{* *} +\Msg{* To finish the installation you have to move the following *} +\Msg{* file into a directory searched by TeX: *} +\Msg{* *} +\Msg{* getitems.sty *} +\Msg{* *} +\Msg{* To produce the documentation run the file getitems.dtx *} +\Msg{* through LaTeX. *} +\Msg{* *} +\Msg{* Happy TeXing! *} +\Msg{* *} +\Msg{*************************************************************} + +\endbatchfile |