% lollipop-lists.tex copyright 1992/3 Victor Eijkhout % copyright 2014--2016 Vafa Khalighi % % % This program is free software: you can redistribute it and/or modify % it under the terms of the GNU General Public License as published by % the Free Software Foundation, either version 3 of the License, or % (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program. If not, see . % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%% L I S T S \@GenericConstruct{List} \newif\if@initem \@initemyes \newif\if@alitem \newbox\@labelbox \def\item{\Emessage{Item command outside list}} % Breakpoints around a list % % first redefine generic defaults: % try not to break before, maybe not after, % \add@List@default{\def\@beforepenalty{\penalty1000 }} \add@List@default{\def\@afterpenalty{\penalty200 }} % between items is okay % \add@List@default{\def\@betweenpenalty{\penalty-50 }} \@ListOption{breakbetween}{ \switch {\if\EqualString{#1}} {no} {\def\@betweenpenalty{\penalty\@M}} {yes} {\def\@betweenpenalty{\CSname{\h@or@v fil}\penalty-\@M}} {0} {\def\@betweenpenalty{}} {default} {\edef\cs@e{\def\nxp\@betweenpenalty{\penalty\@w@w{#1}\relax}} \cs@e} \endswitch } \newtoks\indent@depth \add@List@default{\indent@depth={}} \noeol \def\@DefineList{ \@DefineStopCommand{\nxp\xx@label \the\item@e@coms\@gen@close} \csarg\edef{\@name}{\@gen@open \ifitem@list \nxp\step@counter{itemlevel}\fi \ifenum@list \nxp\step@counter{enumlevel} \nxp\represent@counter{item} {\nxp\enum@repr{\counter@@name{enumlevel}}}\fi \ifleft@embedded@construct \previousindent\z@ \else \nxp\PushIndentLevel \ifauto@indent \else \levelindent\the\indent@depth \fi \parindent\levelindent \fi \nxp\@alitemno \nxp\start@counter{item}% \the\item@b@coms \def\nxp\item@label{ \nxp\ifdim\wd\@labelbox>\tempdima \ifitem@tab \advance\tempdima20pt\relax {\nxp\item@label} \else \iflabel@flow@right \ifleft@embedded@construct \else\hskip-\previousindent\fi \box\@labelbox \else \nxp\llap{\box\@labelbox}\fi\fi \nxp\else \llap{\hbox to \tempdima {\ifleft@item\else\hfil\fi \box\@labelbox \ifleft@item\hfil\fi}} \nxp\fi}% \def\nxp\num@item {\setbox\@labelbox=\hbox{\the\item@coms} \tempdima\previousindent \nxp\item@label %\nxp\Indent:no \the\item@a@coms \nxp\xx@label} \def\nxp\item {\ifleft@embedded@construct \else \nxp\if@alitem\@par%\CSname{@itembreek}% \nxp\hold@parskip \nxp\fi \fi \nxp\if\nxp\TestCounter:item >0 \@betweenpenalty \nxp\fi \CSname{@\h@or@v white}{\white@between} \nxp\@initemno \nxp\@alitemyes \nxp\noindent \nxp\step@counter{item}\relax \iflabel@defined\else\nxp\define@reference{item}\fi \CSname{\@name @item}} } \csarg\edef{\@name @item}{ \iflist@has@description \nxp\desc@item \else \nxp\num@item\fi} \@Labelize{\@name @item} } \normaleol % Inside a list Foo \item is defined as % % \item = all sorts of skips and switches % step item counter, define reference % \Foo@item % % \Foo@item[opt.lab.] = \desc@item or \num@item % % \desc@item = % { \aftergroup\num@item \@description} % % \num@item = \item@label \item@a@coms \xx@label % % Item % start with start/left/right % indicating alignment, start = left % \newif\ifleft@item \newif\ifitem@tab \add@List@default{\left@itemyes \item@tabno} \newtoks\item@coms % content of the item label \newtoks\item@b@coms % start of the list? \newtoks\item@a@coms % immediately after the item \newtoks\item@e@coms % after the whole list \add@List@default{\item@coms{}\item@b@coms{}\item@a@coms{} \item@e@coms{}\def\@current@options@list{item@b@coms}} \@ListOption{item}{ \switch {\if\EqualString{#1}} {stop} {\@add@toks{\egroup}\e@group \def\@current@options@list{item@a@coms}} {tabstop} {\item@tabyes \@add@toks{\egroup}\e@group \def\@current@options@list{item@a@coms}} {left} {\global\left@itemyes \b@group\def\@current@options@list{item@coms}% \@add@toks{\bgroup}} {start}{\global\left@itemyes \b@group\def\@current@options@list{item@coms}% \@add@toks{\bgroup}} {right}{\global\left@itemno \b@group\def\@current@options@list{item@coms}% \@add@toks{\bgroup}} {default} {\Emessage{Unknown option #1 for List, item}} \endswitch} % Label overflow % \newif\iflabel@flow@right \add@List@default{\label@flow@rightyes} \@ListOption{labeloverflow}{ \if\EqualString{#1}{left}\label@flow@rightno \else\label@flow@rightyes\fi} % Description % the line after \item gets picked up, % and becomes available as `description' % \newif\iflist@has@description \add@List@default{\list@has@descriptionno} \@ListOption{description}{ \global\list@has@descriptionyes \@add@toks{\description@text}} {\noeol \othercr \gdef\@description{\bgroup\othercr \@@description} \gdef\@@description#1^^M {\gdef\description@text{#1}% \egroup % balance the \bgroup in \@description % which kept the \othercr local \egroup % balance the \bgroup in \desc@item % which enabled the \aftergroup\num@item } } \def\desc@item{\bgroup \aftergroup\num@item \@description} % White between items % \add@List@default{\def\white@between{0pt}} \@ListOption{whitebetween}{\def\white@between{#1}} % \edef\white@between{\@w@w{#1}}} % Indentation % is automatic (default) and level dependent % or explicit % \newif\ifauto@indent \add@List@default{\auto@indentyes} \@ListOption{indentation}{ \if\EqualString{#1}{automatic}\auto@indentyes \else\auto@indentno \edef\cs@e{\nxp\indent@depth={\@w@w{#1}}}\cs@e \fi} % Tail of the list: % everything after the keyword 'text' is tail % \@ListOption{text}{\at@breakpointyes \def\@current@options@list{item@e@coms}} %%%%%%%%%%%%%%%% List Nesting Counters % % Item sign % gives the default, level dependent marker % \new@@counter{itemlevel} \set@counter{itemlevel}0 \newif\ifitem@list \add@List@default{\item@listno} \@ListOption{itemsign}{ \global\item@listyes \edef\cs@e{\nxp\@add@toks {\nxp\ifcustom@label\nxp\the\current@label \nxp\else\nxp\item@sign\counter@@name{itemlevel}% \nxp\fi}} \cs@e} \def\@item@sign#1{itemsign\romannumeral#1} \def\item@sign#1{\if\UndefinedCS{\@item@sign{#1}}\@@item@sign{#1}% \else \csname \@item@sign{#1}\endcsname \fi} \def\@@item@sign#1{\ifcase#1\relax\or $\bullet$\or $\circ$ \or --\else $\cdot$\fi} \def\SetItemSign:#1=#2{\csarg\edef{\@item@sign{#1}}% {\cswitch \ifx#2 in: b $\bullet$; c $\circ$; d $\diamond$; m ---; n --; . $\cdot$; default $\cdot$; \endswitch}} % Item Counter % % Allocate a bare bones counter \new@@counter{item}\represent@counter{item}1 \newtoks\item@RL \item@RL{} % Keep track of enumerate list level % \new@@counter{enumlevel} \set@counter{enumlevel}0 \newif\ifenum@list \add@List@default{\enum@listno} \@ListOption{itemCounter}{ \global\enum@listyes \@add@toks{\pad@clear\ifcustom@label\the\current@label \else\itemCounter\fi} } \def\@enum@repr#1{enumrepr\romannumeral#1} \def\enum@repr#1{\if\UndefinedCS{\@enum@repr{#1}}\@@enum@repr{#1}% \else \csname \@enum@repr{#1}\endcsname \fi} \def\@@enum@repr#1{\ifcase#1\relax\or 1\or A\or I\or a\or i\else 1\fi} \def\SetItemCounterRepresentation:#1=#2{\csarg\edef{\@enum@repr{#1}}{#2}} % \def\@itembreek{\if@initem\par\fi} % Clear items for Widest. % this is rather susceptible for improvement. % \def\ClearFor:#1 {\def\widest@pad{#1}} \def\widest@pad{\m@ne} \def\pad@clear{\ifnum\widest@pad=\m@ne\else \tempcounta\widest@pad \advance\tempcounta-\LogTen{\cs@counter@name{item}}\relax \hphantom{\ifcase\tempcounta \or 9\or 99 \or 999 \or 9999 \else 99999\fi }% \fi} %%%%%%%%%%%%%%%% Stripped Lists % % for use in external files % \@GenericConstruct{ExternalItem}%stripped list \add@ExternalItem@default{\extra@args\tw@} \noeol \def\@DefineExternalItem{ \@DefineStopCommand{\@gen@close} \ifx\pre@fix\@empty \Wmessage{No file for external item: \@name}\fi \edef\cs@e{\nxp\append@to@list {\pre@fix @local@defs} {\nxp\if\nxp\UndefinedCS{\@command} \nxp\Wmessage{Item `\@name' not defined for `\pre@fix'} \nxp\else \let\CSname{\@name}\CSname{\@command} \nxp\fi}} \cs@e \csarg\edef{\@command}##1##2{ \def\CSname{\@name Label}{##1} \@gen@open\def\nxp\Page{##2} \nxp\PushIndentLevel \let\nxp\nl\relax \the\item@b@coms \def\nxp\item{\ifleft@embedded@construct\else\noindent\fi \setbox\@labelbox=\hbox{\the\item@coms} \nxp\ifdim\wd\@labelbox>\previousindent \iflabel@flow@right \hskip-\previousindent\box\@labelbox \else \nxp\llap{\box\@labelbox}\fi \nxp\else \llap{\hbox to \previousindent {\ifleft@item\else\hfil\fi \box\@labelbox \ifleft@item\hfil\fi}} \nxp\fi}% \ifexternal@item@has@item\nxp\item\the\item@a@coms\fi \ifright@embedded@construct\else\@par\fi \iflong@external\else\nxp\>\fi } } \normaleol \add@ExternalItem@default{\@whitebefore\z@toks} \add@ExternalItem@default{\@whiteafter\z@toks} \add@ExternalItem@default{\let\Page\@space \csarg\let{\@name Label}\@space} % Specify for what external file this is meant % \@ExternalItemOption{file}{ \if\UndefinedCS{\file@ext@name{#1}} \Emessage{File <#1> has not been defined yet}\fi \def\pre@fix{#1}} \newif\iflong@external \add@ExternalItem@default{\long@externalno} \@ExternalItemOption{long}{ \csname long@external#1\endcsname} % Commands before and after % option 'title' is dummy % %\@ExternalItemOption{title}{} % dangerous: better rely on automatic titelization % Item % start with start/left/right % indicating alignment, start = left % \add@ExternalItem@default{\left@itemyes} \add@ExternalItem@default{\item@coms{}\item@b@coms{}\item@e@coms{} \item@a@coms{}\def\@current@options@list{item@b@coms}} \newif\ifexternal@item@has@item \adds@ExternalItem@default{\external@item@has@itemno} \def\ExternalItem@item{\external@item@has@itemyes \List@item} % Label overflow % \add@ExternalItem@default{\label@flow@rightyes} \let\ExternalItem@labeloverflow\List@labeloverflow \endinput % 92/11/26 itemsign / itemCounter changed to handle custom@label % 93/01/03 item call in ExternalItem made conditional