0

I'm writing a very long algorithm which can't stand on one page, I have to split it using \algstore and \algrestore commands provided by the algorithmicx package. Moreover, I'm using code from this post to obtain vertical indentation rules.

minimal (not) working exemple

As shown in this screenshot, indentation and rules are not restored in the second algorithm. My compiler returns:

   Argument of \@gobble has an extra }.

There is probably a compatibility problem between the indentation rules code and \algstore. Does anyone have an idea about how to fix it? I give you the MWE corresponding to the screen shot.

\documentclass{article}
\usepackage{algorithm}% http://ctan.org/pkg/algorithm
\usepackage{algpseudocode}% http://ctan.org/pkg/algorithmicx

\makeatletter
% This is the vertical rule that is inserted
\def\therule{\makebox[\algorithmicindent][l]{\hspace*{.5em}\vrule height .75\baselineskip depth .25\baselineskip}}%

\newtoks\therules% Contains rules
\therules={}% Start with empty token list
\def\appendto#1#2{\expandafter#1\expandafter{\the#1#2}}% Append to token list
\def\gobblefirst#1{% Remove (first) from token list
    #1\expandafter\expandafter\expandafter{\expandafter\@gobble\the#1}}%
\def\LState{\State\unskip\the\therules}% New line-state
\def\pushindent{\appendto\therules\therule}%
\def\popindent{\gobblefirst\therules}%
\def\printindent{\unskip\the\therules}%
\def\printandpush{\printindent\pushindent}%
\def\popandprint{\popindent\printindent}%

%      ***      DECLARED LOOPS      ***
% (from algpseudocode.sty)
\algdef{SE}[WHILE]{While}{EndWhile}[1]
{\printandpush\algorithmicwhile\ #1\ \algorithmicdo}
{\popandprint\algorithmicend\ \algorithmicwhile}%
\algdef{SE}[FOR]{For}{EndFor}[1]
{\printandpush\algorithmicfor\ #1\ \algorithmicdo}
{\popandprint\algorithmicend\ \algorithmicfor}%
\algdef{S}[FOR]{ForAll}[1]
{\printindent\algorithmicforall\ #1\ \algorithmicdo}%
\algdef{SE}[LOOP]{Loop}{EndLoop}
{\printandpush\algorithmicloop}
{\popandprint\algorithmicend\ \algorithmicloop}%
\algdef{SE}[REPEAT]{Repeat}{Until}
{\printandpush\algorithmicrepeat}[1]
{\popandprint\algorithmicuntil\ #1}%
\algdef{SE}[IF]{If}{EndIf}[1]
{\printandpush\algorithmicif\ #1\ \algorithmicthen}
{\popandprint\algorithmicend\ \algorithmicif}%
\algdef{C}[IF]{IF}{ElsIf}[1]
{\popandprint\pushindent\algorithmicelse\ \algorithmicif\ #1\ \algorithmicthen}%
\algdef{Ce}[ELSE]{IF}{Else}{EndIf}
{\popandprint\pushindent\algorithmicelse}%
\algdef{SE}[PROCEDURE]{Procedure}{EndProcedure}[2]
{\printandpush\algorithmicprocedure\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
{\popandprint\algorithmicend\ \algorithmicprocedure}%
\algdef{SE}[FUNCTION]{Function}{EndFunction}[2]
{\printandpush\algorithmicfunction\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
{\popandprint\algorithmicend\ \algorithmicfunction}%
\makeatother

\begin{document}

\begin{algorithm}
 \caption{Euclid’s algorithm - Part.1}\label{euclid}
 \begin{algorithmic}[1]
  \Procedure{Euclid}{$a,b$}\Comment{The g.c.d. of a and b}
   \LState $r\gets a\bmod b$
   \While{$r\not=0$}\Comment{We have the answer if r is 0}
    \LState $a\gets b$
    \algstore{test}
 \end{algorithmic}
\end{algorithm}

\begin{algorithm}
 \caption{Euclid’s algorithm - Part.2}\label{euclid2}
 \begin{algorithmic}[1]
    \algrestore{test}
    \LState $b\gets r$
    \LState $r\gets a\bmod b$
   \EndWhile\label{euclidendwhile}
   \LState \textbf{return} $b$\Comment{The gcd is b}
  \EndProcedure
 \end{algorithmic}
\end{algorithm}

\end{document}
1

I created my own package starting from algpseudocode adding french keywords (package option french and english) and the vruled package option allowing indentation rules from the code given above. I solved my problem manually adding three rules after \algrestore with :

 \therules={\therule \therule \therule}

There the new .tex :

\documentclass{article}
\usepackage{algorithm}% http://ctan.org/pkg/algorithm
\usepackage[french,vruled]{./style/algopc}
\usepackage{amsmath}

\begin{document}

\begin{algorithm}
   \caption{Euclid’s algorithm - Part.1}\label{euclid1}
   \begin{algorithmic}[0]
      \Algo
         \Procedure{Euclid}{$a,b$}\Comment{The g.c.d. of a and b}
            \State $r\gets a\bmod b$
            \While{$r\not=0$}\Comment{We have the answer if r is 0}
               \State $a\gets b$
               \State $b\gets r$
      \algstore{savename}
   \end{algorithmic}
\end{algorithm}

\begin{algorithm}
   \begin{algorithmic}[0]
      \algrestore{savename}
      \therules={\therule \therule \therule}
               \State $r\gets a\bmod b$
            \EndWhile\label{euclidendwhile}
            \Return $b$\Comment{The gcd is b}
         \EndProcedure
      \EndAlgo
   \end{algorithmic}
\end{algorithm}

\end{document}

which gives : pdf result

I give you my improved version of package algpseudocode:

% PSEUDOCODE ALGORITHMIC STYLE -- Released 27 APR 2005
%    for LaTeX version 2e
%
% Copyright Szasz Janos
% E-mail szaszjanos@users.sourceforge.net
% Based on Szasz Janos's algpseudocode.sty
%
\NeedsTeXFormat{LaTeX2e}%
\ProvidesPackage{algopc}%
\RequirePackage{ifthen}%
\RequirePackage{algorithmicx}%
\typeout{Document Style - pseudocode environments for use with the `algorithmicx' style}%
%
\def\ALG@noend{f}%
\newboolean{ALG@compatible}%
\setboolean{ALG@compatible}{false}%
\newboolean{ALG@vruled}%
\setboolean{ALG@vruled}{false}%
%
\DeclareOption{noend}{\def\ALG@noend{t}}%
\DeclareOption{end}{\def\ALG@noend{f}}%
\DeclareOption{compatible}{%
   \typeout{For compatibility mode use algcompatible.sty!!!}%
   \setboolean{ALG@compatible}{true}%
   }%
\DeclareOption{noncompatible}{\setboolean{ALG@noncompatible}{false}}%
\DeclareOption{vruled}{\setboolean{ALG@vruled}{true}}%
\DeclareOption{english}{%
   \def\wordbegalgo{begin}%
   \def\wordendalgo{end}%
   \def\wordend{end}%
   \def\worddo{do}%
   \def\wordwhile{while}%
   \def\wordfor{for}%
   \def\wordforall{for all}%
   \def\wordloop{loop}%
   \def\wordrepeat{repeat}%
   \def\worduntil{until}%
   \def\wordprocedure{procedure}%
   \def\wordfunction{function}%
   \def\wordif{if}%
   \def\wordthen{then}%
   \def\wordelse{else}%
   \def\wordrequire{Require:}%
   \def\wordensure{Ensure:}%
   \def\wordreturn{return}%
   }%
\DeclareOption{french}{% FRENCH
   \def\wordbegalgo{d\'ebut}%
   \def\wordendalgo{fin}%
   \def\wordend{fin}%
   \def\worddo{faire}%
   \def\wordwhile{tant que}%
   \def\wordfor{pour}%
   \def\wordforall{pour tout}%
   \def\wordloop{boucle}%
   \def\wordrepeat{r\'ep\'eter}%
   \def\worduntil{jusqu'\`a}%
   \def\wordprocedure{proc\'edure}%
   \def\wordfunction{fonction}%
   \def\wordif{si}%
   \def\wordthen{alors}%
   \def\wordelse{sinon}%
   \def\wordrequire{demander :}%
   \def\wordensure{assurer :}%
   \def\wordreturn{retourner}%
   }%
\ProcessOptions%
%
%      ***      DECLARATIONS      ***
%
\algnewlanguage{pscde}%
\alglanguage{pscde}%
%
%      ***      KEYWORDS      ***
%
\algnewcommand\textkw{\textbf}
\algnewcommand\algorithmicbegalgo{\textkw{\wordbegalgo}}
\algnewcommand\algorithmicendalgo{\textkw{\wordendalgo}}
\algnewcommand\algorithmicend{\textkw{\wordend}}
\algnewcommand\algorithmicdo{\textkw{\worddo}}
\algnewcommand\algorithmicwhile{\textkw{\wordwhile}}
\algnewcommand\algorithmicfor{\textkw{\wordfor}}
\algnewcommand\algorithmicforall{\textkw{\wordforall}}
\algnewcommand\algorithmicloop{\textkw{\wordloop}}
\algnewcommand\algorithmicrepeat{\textkw{\wordrepeat}}
\algnewcommand\algorithmicuntil{\textkw{\worduntil}}
\algnewcommand\algorithmicprocedure{\textkw{\wordprocedure}}
\algnewcommand\algorithmicfunction{\textkw{\wordfunction}}
\algnewcommand\algorithmicif{\textkw{\wordif}}
\algnewcommand\algorithmicthen{\textkw{\wordthen}}
\algnewcommand\algorithmicelse{\textkw{\wordelse}}
\algnewcommand\algorithmicrequire{\textkw{\wordRequire:}}
\algnewcommand\algorithmicensure{\textkw{\wordEnsure:}}
\algnewcommand\algorithmicreturn{\textkw{\wordreturn}}
\algnewcommand\textproc{\textsc}
%
%      ***      DEFINE VRULED COMMAND      ***
%
\ifthenelse{\boolean{ALG@vruled}}{%
   % This is the vertical rule that is inserted
   \algnewcommand\therule{%
      \makebox[\algorithmicindent][l]{%
         \hspace*{.5em}\vrule height .75\baselineskip depth .25\baselineskip
         }%
      }%
   \newtoks\therules% Contains rules
   \therules={}% Start with empty token list
   \def\appendto#1#2{% Append to token list
      \expandafter#1\expandafter{\the#1#2}%
      }% 
   \def\gobblefirst#1{% Remove (first) from token list
      #1\expandafter\expandafter\expandafter{\expandafter\@gobble\the#1}%
      }%
   \algdef{SL}[STATE]{State}{0}{\unskip\the\therules}% New line-state
   %
   \def\pushindent{\appendto\therules\therule}%
   \def\popindent{\gobblefirst\therules}%
   \def\printindent{\unskip\the\therules}%
   \def\printandpush{\printindent\pushindent}%
   \def\popandprint{\popindent\printindent}%
   }{}%
%
%      ***      DECLARED LOOPS      ***
%
\ifthenelse{\boolean{ALG@vruled}}{%
   \algdef{SE}[ALGO]{Algo}{EndAlgo}%
      {\printandpush\algorithmicbegalgo}%
      {\popandprint\algorithmicendalgo}%
   \algdef{SE}[WHILE]{While}{EndWhile}%
      [1]{\printandpush\algorithmicwhile\ #1\ \algorithmicdo}%
      {\popandprint\algorithmicend\ \algorithmicwhile}%
   \algdef{SE}[FOR]{For}{EndFor}%
      [1]{\printandpush\algorithmicfor\ #1\ \algorithmicdo}%
      {\popandprint\algorithmicend\ \algorithmicfor}%
   \algdef{S}[FOR]{ForAll}%
      [1]{\printandpush\algorithmicforall\ #1\ \algorithmicdo}%
   \algdef{SE}[LOOP]{Loop}{EndLoop}%
      {\printandpush\algorithmicloop}%
      {\popandprint\algorithmicend\ \algorithmicloop}%
   \algdef{SE}[REPEAT]{Repeat}{Until}%
      {\printandpush\algorithmicrepeat}%
      [1]{\popandprint\algorithmicuntil\ #1}%
   \algdef{SE}[IF]{If}{EndIf}%
      [1]{\printandpush\algorithmicif\ #1\ \algorithmicthen}%
      {\popandprint\algorithmicend\ \algorithmicif}%
   \algdef{C}[IF]{IF}{ElsIf}%
      [1]{\popandprint\pushindent\algorithmicelse\ \algorithmicif\ #1\ \algorithmicthen}%
   \algdef{Ce}[ELSE]{IF}{Else}{EndIf}%
      {\popandprint\pushindent\algorithmicelse}%
   \algdef{SE}[PROCEDURE]{Procedure}{EndProcedure}%
      [2]{\printandpush\algorithmicprocedure\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
      {\popandprint\algorithmicend\ \algorithmicprocedure}%
   \algdef{SE}[FUNCTION]{Function}{EndFunction}%
      [2]{\printandpush\algorithmicfunction\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
      {\popandprint\algorithmicend\ \algorithmicfunction}%
   }{%
   \algdef{SE}[ALGO]{Algo}{EndAlgo}%
      {\algorithmicbegalgo}%
      {\algorithmicendalgo}%
   \algdef{SE}[WHILE]{While}{EndWhile}%
      [1]{\algorithmicwhile\ #1\ \algorithmicdo}%
      {\algorithmicend\ \algorithmicwhile}%
   \algdef{SE}[FOR]{For}{EndFor}%
      [1]{\algorithmicfor\ #1\ \algorithmicdo}%
      {\algorithmicend\ \algorithmicfor}%
   \algdef{S}[FOR]{ForAll}%
      [1]{\algorithmicforall\ #1\ \algorithmicdo}%
   \algdef{SE}[LOOP]{Loop}{EndLoop}%
      {\algorithmicloop}%
      {\algorithmicend\ \algorithmicloop}%
   \algdef{SE}[REPEAT]{Repeat}{Until}%
      {\algorithmicrepeat}%
      [1]{\algorithmicuntil\ #1}%
   \algdef{SE}[IF]{If}{EndIf}%
      [1]{\algorithmicif\ #1\ \algorithmicthen}
      {\algorithmicend\ \algorithmicif}%
   \algdef{C}[IF]{IF}{ElsIf}%
      [1]{\algorithmicelse\ \algorithmicif\ #1\ \algorithmicthen}%
   \algdef{Ce}[ELSE]{IF}{Else}{EndIf}%
      {\algorithmicelse}%
   \algdef{SE}[PROCEDURE]{Procedure}{EndProcedure}%
      [2]{\algorithmicprocedure\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
      {\algorithmicend\ \algorithmicprocedure}%
   \algdef{SE}[FUNCTION]{Function}{EndFunction}%
      [2]{\algorithmicfunction\ \textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
      {\algorithmicend\ \algorithmicfunction}%
   }%
%
\ifthenelse{\equal{\ALG@noend}{t}}{%
   \ifthenelse{\boolean{ALG@vruled}}{%
      \algtext{EndWhile}{\popindent\vspace{-.99\baselineskip}}%
      \algtext{EndFor}{\popindent\vspace{-.99\baselineskip}}%
      \algtext{EndLoop}{\popindent\vspace{-.99\baselineskip}}%
      \algtext{EndIf}{\popindent\vspace{-.99\baselineskip}}%
      \algtext{EndProcedure}{\popindent\vspace{-.99\baselineskip}}%
      \algtext{EndFunction}{\popindent\vspace{-.99\baselineskip}}%
      \algtext{EndAlgo}{\popindent\vspace{-.99\baselineskip}}%
      }{%
      \algtext*{EndWhile}%
      \algtext*{EndFor}%
      \algtext*{EndLoop}%
      \algtext*{EndIf}%
      \algtext*{EndProcedure}%
      \algtext*{EndFunction}%
      \algtext*{EndAlgo}%
      }%
   }{}%
%
%      ***      OTHER DECLARATIONS      ***
%
\algnewcommand\Require{\State\item[\algorithmicrequire]}%
\algnewcommand\Ensure{\State\item[\algorithmicensure]}%
\algnewcommand\Return{\State\algorithmicreturn{} }%
\algnewcommand\Call[2]{\textproc{#1}\ifthenelse{\equal{#2}{}}{}{(#2)}}%
%
\ifthenelse{\boolean{ALG@compatible}}{%
    \ifthenelse{\equal{\ALG@noend}{t}}{%
       \RequirePackage[noend]{algcompatible}%
       }{%
       \RequirePackage{algcompatible}%
       }%
    }{}%

The point is to find a way that \algstore save the token \therules. I tried to look after the saving process into the algorithmicx package, I even identified some passages related, but I not really understood how it works. If someone who knows TeX can help me to understand how \algstore works I would finish the package with elegant way to split a ruled algorithm.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.