% ALGORITHMIC STYLE -- Released 18 MAR 2004 % for LaTeX version 2e % % Copyright Szasz Janos % E-mail szaszjanos@users.sourceforge.net % Based on Peter Williams's algorithmic.sty % % % *** INITIALISING *** % % \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{algorithmicx}[2004/03/18 v1.1 Algorithmicx] \RequirePackage{ifthen} \typeout{Document Style algorithmicx 1.1 - a greatly improved `algorithmic' style} % \newcounter{ALG@line} \newcounter{ALG@rem} \newlength{\ALG@tlm} \newlength{\ALG@ctlm} \newlength{\algorithmicindent} \setlength{\algorithmicindent}{1.5em} \newcounter{ALG@blocknr}% the number of defined blocks \setcounter{ALG@blocknr}{0} \newcounter{ALG@tmpcounter}% only to decrement things \def\algorithmicnoindent{-\ALG@tlm} \def\algbackskipbegin{\hskip\ALG@ctlm} \def\algbackskip{\hskip\ALG@ctlm\hskip-\ALG@tlm} \def\algbackskipend{\hskip-\ALG@tlm} \def\ALG@defaultindent{\algorithmicindent} % % % *** ALGORITHMIC *** % % \newenvironment{ALG@g}[1]% a list for the iner loops {% \begin{list}% {\ALG@step}% {% \itemsep\z@% \itemindent\z@% \listparindent2em% the indent given to multiline lines... \rightmargin\z@% \topsep\z@% \partopsep\z@% \parskip\z@% \parsep\z@% \leftmargin#1% \ALG@ctlm#1% \addtolength{\ALG@tlm}{\leftmargin}% \labelsep\ALG@tlm% \addtolength{\labelsep}{0.5em}% }% \global\@newlistfalse% give no error, if the list is empty }% {\end{list}}% % % algorithmic environment % \let\ALG@beginalgorithmic\relax% for user overrides \let\ALG@endalgorithmic\relax% for user overrides \newenvironment{algorithmic}[1][0]% {% \def\@currentlabel{\theALG@line}% \newcommand{\ALG@step}% {% \addtocounter{ALG@line}{1}% \addtocounter{ALG@rem}{1}% \ifthenelse{\equal{\arabic{ALG@rem}}{#1}}% {\setcounter{ALG@rem}{0}{\footnotesize \arabic{ALG@line}:}}% {}% }% % \setcounter{ALG@line}{0}% \setcounter{ALG@rem}{0}% % \let\@listii\@listi% \let\@listiii\@listi% \let\@listiv\@listi% \let\@listv\@listi% \let\@listvi\@listi% \let\@listvii\@listi% \renewcommand{\@toodeep}{}% % \renewcommand{\\}% for multiline parameters !!! needs fix {% \item% \hskip\ALG@parindent%!!! not yet implemented % \hskip-\algorithmicindent% }% % \edef\ALG@currentitem{0}% \let\ALG@currentvalue\relax% % \begin{list}% {\ALG@step}% {% \rightmargin\z@% \itemsep\z@ \itemindent\z@ \listparindent2em% \partopsep\z@ \parskip\z@ \parsep\z@% \labelsep 0.5em \topsep 0.0em%\skip 1.2em \ifthenelse{\equal{#1}{0}}% {\labelwidth 0.5em}% {\labelwidth 1.2em}% \leftmargin\labelwidth \addtolength{\leftmargin}{\labelsep}% Ok. the perfect leftmargin :-)) \ALG@tlm 0em% \ALG@ctlm\ALG@tlm% }% \ALG@beginalgorithmic% }% {% end{algorithmic} % \global\@newlistfalse% protects against empty algorithms, not needed % check if all blocks are closed \ALG@closeloops% \ifnum0=\ALG@currentitem\relax% \else% \PackageError{algorithmicx}{Some blocks are not closed!!!}{Yes, you have some open blocks.}% \fi% \ALG@endalgorithmic% \end{list}% }% % % % *** Functional core *** % % \def\ALG@makeentitie#1% execute the entitie (#1) {% \expandafter\ifx\csname ALG@b@#1@0\endcsname\relax% \ALG@makenobegin{#1}% this entitie ends or continues blocks \else% \ALG@makebegin{#1}% this entitie can open blocks \fi% \ALG@entitiecommand% }% % \def\ALG@makebegin#1% executes an entitie (#1) that can open blocks {% \ifx\ALG@currentvalue\relax% \ALG@openblock{0}{#1}% in infinite block I can open my block \else% \ifnum0<\ALG@currentvalue\relax% \ifnum\ALG@currentvalue>65534\else% \setcounter{ALG@tmpcounter}{\ALG@currentvalue}% the block has 'space' for another included block \addtocounter{ALG@tmpcounter}{-1}% \edef\ALG@currentvalue{\arabic{ALG@tmpcounter}}% \fi% \ALG@openblock{0}{#1}% \else% the block needs to be closed \expandafter\ifx\csname ALG@b@#1@\ALG@currentitem\endcsname\relax% \end{ALG@g}% I can not close this block, continue after it is closed by force \ALG@makebegin{#1}% \else% \ALG@changeblock{#1}% close this block \fi% \fi% \fi% }% % \def\ALG@makenobegin#1% executes an entitie (#1) that can not open blocks {% \ifx\ALG@currentvalue\relax% \ALG@changeblock{#1}% an infinite block must be broken \else% \expandafter\ifx\csname ALG@b@#1@\ALG@currentitem\endcsname\relax% \end{ALG@g}% the block must be ended by force, \ALG@makenobegin{#1}% the command still runs \else% \ALG@changeblock{#1}% i can continue / end this block, let's do it \fi% \fi% }% % \def\ALG@ifnotrelax#1#2#3% #1 - the number of the closed block, #2 - the entitie, #3 - things to be done {% \edef\ALG@tmpcmd{\expandafter\noexpand\csname algorithmic#2\endcsname}% \expandafter\ifx\csname ALG@t@#1@#2\endcsname\relax\else% \expandafter\ifx\csname ALG@t@#1@#2\endcsname\ALG@tmpcmd% \expandafter\ifx\csname algorithmic#2\endcsname\relax\else% #3% \fi% \else% #3% \fi% \fi% }% % \def\ALG@closeblock#1#2% #1 - the number of the closed block, #2 - the entitie {% \ALG@ifnotrelax{#1}{#2}{\item}% \expandafter\let\expandafter\ALG@entitiecommand\csname ALG@t@#1@#2\endcsname% }% % \def\ALG@openblock#1#2% #1 - the number of the closed block, #2 - the entitie {% \item[]% \begin{ALG@g}{\csname ALG@i@#2@#1\endcsname}% \edef\ALG@currentitem{\csname ALG@b@#2@#1\endcsname}% \expandafter\ifx\csname ALG@c@#2@#1\endcsname\relax% \let\ALG@currentvalue\relax% \else% \edef\ALG@currentvalue{\csname ALG@c@#2@#1\endcsname}% \fi% \ALG@ifnotrelax{#1}{#2}% {% \item\hskip-\ALG@ctlm% default spacing }% \expandafter\let\expandafter\ALG@entitiecommand\csname ALG@t@#1@#2\endcsname% }% % \def\ALG@changeblock#1% #1 - the entitie {% \setcounter{ALG@tmpcounter}{\ALG@currentitem}% \expandafter\ifnum0=\csname ALG@b@#1@\ALG@currentitem\endcsname\relax% \end{ALG@g}% \ALG@closeblock{\arabic{ALG@tmpcounter}}{#1}% \else% \end{ALG@g}% \ALG@openblock{\arabic{ALG@tmpcounter}}{#1}% \fi% }% % \def\ALG@closeloops% closes all finite blocks {% \ifx\ALG@currentvalue\relax% \else% only if it is finite \end{ALG@g}% the block must be ended by force, \ALG@closeloops% the command still runs \fi% }% % % % *** Low level block/entitie defining commands *** % % \def\ALG@bl@{0}% the BIG block \let\ALG@bl@@\ALG@bl@% the BIG block % % Create a block % \def\ALG@createblock#1% create the block #1, if it does not exists {% \@ifundefined{ALG@bl@#1}% needs to be created? {% \addtocounter{ALG@blocknr}{1}% increment the block counter \expandafter\edef\csname ALG@bl@#1\endcsname{\arabic{ALG@blocknr}}% set the block number }% {}% }% % % Get the block number % \def\ALG@getblocknumber#1{\csname ALG@bl@#1\endcsname}% % % Create an entitie % \def\ALG@createentitie#1% create the entitie #1, if it does not exists {% \@ifundefined{#1}% needs to be created? {% \expandafter\edef\csname #1\endcsname{\noexpand\ALG@makeentitie{#1}}% \@ifundefined{algorithmic#1}% \algorithmic#1 exists? {% \expandafter\edef\csname algorithmic#1\endcsname{\noexpand\textbf{#1}}% }% {}% }% {}% }% % \def\ALG@createtext#1#2% #1 = closed block; #2 = entitie; creates \ALG@t@#1@#2 {% \expandafter\edef\csname ALG@t@#1@#2\endcsname% {% \expandafter\noexpand\csname algorithmic#2\endcsname% }% }% % % End and Continue block % \def\ALG@endandcontinueblock#1#2#3#4#5% #1 = new block; #2 = old block; #3 = entitie; #4 = credits; #5 = indent {% \ifthenelse{\equal{#3}{}}{}% execute only if the entity is not empty {% \ALG@createentitie{#3}% create the entitie \ALG@createblock{#2}% create the old block, if needed \ifthenelse{\equal{#1}{}}% whe need to open a new block? {\expandafter\edef\csname ALG@b@#3@\ALG@getblocknumber{#2}\endcsname{0}}% no, just close the old one {% yes, \ALG@createblock{#1}% create the block \expandafter\edef\csname ALG@b@#3@\ALG@getblocknumber{#2}\endcsname{\ALG@getblocknumber{#1}}% ending the old block opens a new one \ifthenelse{\equal{#4}{}}% infinite or finite credits? {\expandafter\let\csname ALG@c@#3@\ALG@getblocknumber{#2}\endcsname\relax}% infinite credits {\expandafter\edef\csname ALG@c@#3@\ALG@getblocknumber{#2}\endcsname{#4}}% finite credits \ifthenelse{\equal{#5}{}}% default or specified indentation {\expandafter\let\csname ALG@i@#3@\ALG@getblocknumber{#2}\endcsname\ALG@defaultindent}% default indentation {\expandafter\edef\csname ALG@i@#3@\ALG@getblocknumber{#2}\endcsname{#5}}% indentation is specified }% \ALG@createtext{\ALG@getblocknumber{#2}}{#3}% }% }% % % % *** NEW VERSION *** % % % used macros % \def\ALG@p@endtext@E{\algrenewtext{\ALG@v@end}}% \def\ALG@p@endtext@xE{\algrenewtext[\ALG@v@newblock]{\ALG@v@end}}% \def\ALG@p@endtext@N{\algnotext{\ALG@v@end}}% \def\ALG@p@endtext@xN{\algnotext[\ALG@v@newblock]{\ALG@v@end}}% \def\ALG@p@endtext@{}% % starttext defines are more compex -- care must be taken for the optional parameters \def\ALG@p@starttext@S{\ALG@p@s@process{\algrenewtext}}% \def\ALG@p@starttext@C{\ALG@p@s@process{\algrenewtext}}% \def\ALG@p@starttext@xC{\ALG@p@s@process{\algrenewtext[\ALG@v@oldblock]}}% \def\ALG@p@s@process#1% {% \ifthenelse{\equal{\ALG@v@start}{}}% {\ALG@p@endtext}% {\@ifnextchar{[}{\ALG@p@s@getparamcount{#1}}{\ALG@p@s@simple{#1}}}% }% \def\ALG@p@s@getparamcount#1[#2]% {% \@ifnextchar{[}{\ALG@p@s@getdefparam{#1}{#2}}{\ALG@p@s@param{#1}{#2}}% }% \def\ALG@p@s@getdefparam#1#2[#3]% {% \ALG@p@s@defparam{#1}{#2}{#3}% }% \def\ALG@p@s@simple#1#2{#1{\ALG@v@start}{#2}\ALG@p@endtext}% \def\ALG@p@s@param#1#2#3{#1{\ALG@v@start}[#2]{#3}\ALG@p@endtext}% \def\ALG@p@s@defparam#1#2#3#4{#1{\ALG@v@start}[#2][#3]{#4}\ALG@p@endtext}% % the rest of the crew \def\ALG@p@starttext@{\ALG@p@endtext}% \def\ALG@p@indent@def#1{\def\ALG@v@indent{#1}\ALG@p@setup}% \def\ALG@p@indent@{\def\ALG@v@indent{}\ALG@p@setup}% \def\ALG@p@credits@def#1{\def\ALG@v@credits{#1}\ALG@p@indent}% \def\ALG@p@credits@{\ALG@p@indent}% \def\ALG@p@end@def#1{\def\ALG@v@end{#1}\ALG@p@credits}% \def\ALG@p@end@{\def\ALG@v@end{}\ALG@p@credits}% \def\ALG@p@start@def#1{\def\ALG@v@start{#1}\ALG@p@end}% \def\ALG@p@start@{\def\ALG@v@start{}\ALG@p@end}% \def\ALG@p@oldblock@def#1{\def\ALG@v@oldblock{#1}\ALG@p@start}% \def\ALG@p@oldblock@{\def\ALG@v@oldblock{}\ALG@p@start}% \newcommand\ALG@p@newblock[1][]{\def\ALG@v@newblock{#1}\ALG@p@oldblock}% \def\ALG@p@setup% {% \ifthenelse{\equal{\ALG@v@newblock}{}}% {% \ifthenelse{\equal{\ALG@v@start}{}}% {% \PackageError{algorithmicx}{Block or starting entitie must be specified!!!}{}% }% {% \let\ALG@v@newblock\ALG@v@start% }% }% {% }% \ALG@endandcontinueblock% {\ALG@v@newblock}{\ALG@v@oldblock}{\ALG@v@start}% {\ALG@v@credits}{\ALG@v@indent}% \ALG@endandcontinueblock% {}{\ALG@v@newblock}{\ALG@v@end}% {}{}% \ALG@p@starttext% }% % % param handling % \newcommand\ALG@p@def[2][def]% {% \expandafter\let\csname ALG@p@#2\expandafter\endcsname\csname ALG@p@#2@#1\endcsname% }% \def\ALG@p@undef{\ALG@p@def[]}% % \def\ALG@p@ons{\ALG@p@def{start}}% \def\ALG@p@onS{\ALG@p@def{start}\ALG@p@def[S]{starttext}}% \def\ALG@p@onc{\ALG@p@def{oldblock}\ALG@p@def{start}}% \def\ALG@p@onC{\ALG@p@def{oldblock}\ALG@p@def{start}\ALG@p@def[C]{starttext}}% \def\ALG@p@onxC{\ALG@p@def{oldblock}\ALG@p@def{start}\ALG@p@def[xC]{starttext}}% \def\ALG@p@one{\ALG@p@def{end}}% \def\ALG@p@onE{\ALG@p@def{end}\ALG@p@def[E]{endtext}}% \def\ALG@p@onxE{\ALG@p@def{end}\ALG@p@def[xE]{endtext}}% \def\ALG@p@onN{\ALG@p@def{end}\ALG@p@def[N]{endtext}}% \def\ALG@p@onxN{\ALG@p@def{end}\ALG@p@def[xN]{endtext}}% \def\ALG@p@onb{\def\ALG@v@credits{}}% \def\ALG@p@onl{\def\ALG@v@credits{1}}% \def\ALG@p@onL{\ALG@p@def{credits}}% \def\ALG@p@oni{\ALG@p@def{indent}}% \expandafter\def\csname ALG@p@on]\endcsname{\let\ALG@p@rec\relax}% % % param processing % \def\ALG@p@process#1% {% \@ifundefined{ALG@p@on#1}% {\typeout{algdef: Ignoring unknown token #1}}% {\csname ALG@p@on#1\endcsname}% \ALG@p@rec% }% % \def\ALG@p@onx{\let\ALG@p@rec\ALG@p@processx}% % \def\ALG@p@processx#1% {% \@ifundefined{ALG@p@onx#1}% {% \typeout{algdef: Ignoring sole x}% \def\ALG@p@rec{\let\ALG@p@rec\ALG@p@process\ALG@p@process#1}% }% {\csname ALG@p@onx#1\endcsname\let\ALG@p@rec\ALG@p@process}% \ALG@p@rec% }% % % % *** User level block/entitie commands *** % % % % algdef{switches}... -- the king of all definitions in the algorithmicx package % \newcommand\algdef[1]% {% \ALG@p@undef{oldblock}% \ALG@p@undef{start}% \ALG@p@undef{end}% \def\ALG@v@credits{}% \ALG@p@undef{credits}% \ALG@p@undef{indent}% \ALG@p@undef{starttext}% \ALG@p@undef{endtext}% \let\ALG@p@rec\ALG@p@process% \ALG@p@rec#1]% \ALG@p@newblock% }% % % a lot of other macros are provided for convenience % \def\algblock{\algdef{se}}% \def\algcblock{\algdef{ce}}% \def\algloop{\algdef{sl}}% \def\algcloop{\algdef{cl}}% \def\algsetblock{\algdef{seLi}}% \def\algsetcblock{\algdef{ceLi}}% \def\algblockx{\algdef{SxE}}% \def\algblockdefx{\algdef{SE}}% \def\algcblockx{\algdef{CxE}}% \def\algcblockdefx{\algdef{CE}}% \def\algsetblockx{\algdef{SxELi}}% \def\algsetblockdefx{\algdef{SELi}}% \def\algsetcblockx{\algdef{CxELi}}% \def\algsetcblockdefx{\algdef{CELi}}% \def\algloopdefx{\algdef{Sl}}% \def\algcloopx{\algdef{xCl}}% \def\algcloopdefx{\algdef{Cl}}% % algloopx is not correct, use algloopdefx % % Text output commands % \newcommand\algrenewtext[2][]% [block]{entity} {% \ifthenelse{\equal{#2}{}}{}% {% \algnotext[#1]{#2}% \ifthenelse{\equal{#1}{}}% {% \expandafter\newcommand\csname algorithmic#2\endcsname% }% {% \expandafter\newcommand\csname ALG@t@\ALG@getblocknumber{#1}@#2\endcsname% }% }% }% % \newcommand\algnotext[2][]% [block]{entity} {% \ifthenelse{\equal{#2}{}}{}% {% \ifthenelse{\equal{#1}{}}% {% \expandafter\let\csname algorithmic#2\endcsname\relax% }% {% \expandafter\let\csname ALG@t@\ALG@getblocknumber{#1}@#2\endcsname\relax% }% }% }% % \newcommand\algdefaulttext[2][]% [block]{entity} {% \ifthenelse{\equal{#1}{}}% {% \expandafter\def\csname algorithmic#2\endcsname{\textbf{#2}}% }% {% \ALG@createtext{\ALG@getblocknumber{#1}}{#2}% }% }% % \def\ALG@notext*{\algnotext}% \def\algtext{\@ifnextchar{*}{\ALG@notext}{\algrenewtext}}% % % % *** OTHERS *** % % \algdef{SL}[STATE]{State}{0}{}% \def\BState{\State \algbackskip}% \def\Statex{\item[]}% an empty line \newcommand\algorithmiccomment[1]{\hfill\(\triangleright\) #1}% \def\Comment{\algorithmiccomment}% \def\algref#1#2{\ref{#1}.\ref{#2}}% % % % *** LANGUAGE SWITCHING *** % % \newcommand\ALG@deflanguage[3]%#1#2#3% {% \ifthenelse{\equal{#2}{}}% {\expandafter\def\csname ALG@setlanguage@#1\endcsname{#3}}% {\def\ALG@tmp{\let\ALG@tmp\relax#3}\ALG@tmp}% }% % \def\algsetlanguage#1% {% \csname ALG@setlanguage@#1\endcsname% }% % %