Algorithmicx - 使用 \algstore 的缩进规则

Algorithmicx - 使用 \algstore 的缩进规则

我正在编写一个很长的算法,无法放在一页纸上,我必须使用包提供的命令\algstore将其拆分。此外,我使用的代码来自\algrestorealgorithmicx这个帖子获得垂直缩进规则。

最小(非)工作示例

如该屏幕截图所示,第二个算法中未恢复缩进和规则。我的编译器返回:

   Argument of \@gobble has an extra }.

缩进规则代码和 之间可能存在兼容性问题\algstore。有人知道如何修复它吗?我给你与屏幕截图相对应的 MWE。

\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

我从algpseudocode添加法语关键字(包选项frenchenglish)以及vruled允许缩进规则的包选项开始创建了自己的包,这些规则来自上面给出的代码。我\algrestore通过在后面手动添加三个规则解决了我的问题:

 \therules={\therule \therule \therule}

有新的.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}

这使 : pdf 结果

我给你我改进的版本的包algpseudocode

% PSEUDOCODE ALGORITHMIC STYLE -- Released 27 APR 2005
%    for LaTeX version 2e
%
% Copyright Szasz Janos
% E-mail [email protected]
% 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}%
       }%
    }{}%

关键是要找到一种保存标记 \therules 的方法\algstore。我尝试查看将保存过程放入algorithmicx包中的过程,我甚至确定了一些相关的段落,但我并不真正理解它是如何工作的。如果了解 TeX 的人可以帮助我理解它的\algstore工作原理,我会用优雅的方式完成包以拆分规则算法。

相关内容