我想在算法包中定义一个新子句(sync
在我的情况下),以便该子句内的代码可以像在while
子句内部一样缩进。
到目前为止,我通过在不同的地方添加这些行来使事情正常进行algorithmic.sty
\newcommand{\algorithmicsync}{\textbf{sync}}
\newcommand{\algorithmicendsync}{\algorithmicend\ \algorithmicsync}
\newenvironment{ALC@syn}{\begin{ALC@g}}{\end{ALC@g}}
\newcommand{\SYNC}[2][default]{\ALC@it\algorithmicsync\ ##2\ %
\ALC@com{##1}\begin{ALC@syn}}
\ifthenelse{\boolean{ALC@noend}}{
\newcommand{\ENDSYNC}{\end{ALC@syn}}
}{
\newcommand{\ENDSYNC}{\end{ALC@syn}\ALC@it\algorithmicendsync}
}
有没有更简单的方法来完成这项工作而无需编辑algorithmic.sty
文件?
答案1
正如 Werner 在他的评论中所说,不建议.sty
直接修改文件。您可以在文档序言中包含您的定义(在加载所需的包之后);由于您的命令使用了字符@
,因此您需要\makeatletter
在定义之前和\makeatother
之后使用。
不过,我建议你使用算法包;这个包为您提供了许多自定义算法布局的可能性,并为您提供了一种简单的方法来根据您的特定需求定义一个全新的布局。例如(algpseudocode
内部加载algorithmicx
):
\documentclass{article}
\usepackage{algpseudocode}
\algblockdefx{Sync}{EndSync}[1]{\textbf{sync} #1}{\textbf{end sync}}
\begin{document}
\begin{algorithmic}
\Require$n \geq 0$
\Ensure $y = x^n$
\State $y \leftarrow 1$
\While{$N \neq 0$}
\State $X \leftarrow X$
\EndWhile
\Sync{$N$ id odd}
\State $N \leftarrow n$
\EndSync
\end{algorithmic}
\end{document}
编辑:如果algorithmicx
目前无法更改为,您仍然可以在文档的序言中进行定义,而不是.sty
直接修改文件;只需使用\renewenvironment
重新定义algorithmic
环境并包含新定义:
\documentclass{article}
\usepackage{algorithmic}
\makeatletter
\newcommand{\algorithmicsync}{\textbf{sync}}
\newcommand{\algorithmicendsync}{\algorithmicend\ \algorithmicsync}
\renewenvironment{algorithmic}[1][0]{
\let\@item\ALC@item
\newcommand{\ALC@lno}{%
\ifthenelse{\equal{\arabic{ALC@rem}}{0}}
{{\footnotesize \arabic{ALC@line}:}}{}%
}
\let\@listii\@listi
\let\@listiii\@listi
\let\@listiv\@listi
\let\@listv\@listi
\let\@listvi\@listi
\let\@listvii\@listi
\newenvironment{ALC@g}{
\begin{list}{\ALC@lno}{ \itemsep\z@ \itemindent\z@
\listparindent\z@ \rightmargin\z@
\topsep\z@ \partopsep\z@ \parskip\z@\parsep\z@
\leftmargin 1em
\addtolength{\ALC@tlm}{\leftmargin}
}
}
{\end{list}}
\newcommand{\ALC@it}{\addtocounter{ALC@line}{1}\addtocounter{ALC@rem}{1}\ifthenelse{\equal{\arabic{ALC@rem}}{#1}}{\setcounter{ALC@rem}{0}}{}\item}
\newcommand{\ALC@com}[1]{\ifthenelse{\equal{##1}{default}}%
{}{\ \algorithmiccomment{##1}}}
\newcommand{\REQUIRE}{\item[\algorithmicrequire]}
\newcommand{\ENSURE}{\item[\algorithmicensure]}
\newcommand{\STATE}{\ALC@it}
\newcommand{\COMMENT}[1]{\algorithmiccomment{##1}}
\newenvironment{ALC@if}{\begin{ALC@g}}{\end{ALC@g}}
\newenvironment{ALC@for}{\begin{ALC@g}}{\end{ALC@g}}
\newenvironment{ALC@whl}{\begin{ALC@g}}{\end{ALC@g}}
\newenvironment{ALC@loop}{\begin{ALC@g}}{\end{ALC@g}}
\newenvironment{ALC@rpt}{\begin{ALC@g}}{\end{ALC@g}}
\newenvironment{ALC@syn}{\begin{ALC@g}}{\end{ALC@g}}% new
\renewcommand{\\}{\@centercr}
\newcommand{\IF}[2][default]{\ALC@it\algorithmicif\ ##2\ \algorithmicthen%
\ALC@com{##1}\begin{ALC@if}}
\newcommand{\ELSE}[1][default]{\end{ALC@if}\ALC@it\algorithmicelse%
\ALC@com{##1}\begin{ALC@if}}
\newcommand{\ELSIF}[2][default]%
{\end{ALC@if}\ALC@it\algorithmicelsif\ ##2\ \algorithmicthen%
\ALC@com{##1}\begin{ALC@if}}
\newcommand{\FOR}[2][default]{\ALC@it\algorithmicfor\ ##2\ \algorithmicdo%
\ALC@com{##1}\begin{ALC@for}}
\newcommand{\FORALL}[2][default]{\ALC@it\algorithmicforall\ ##2\ %
\algorithmicdo%
\ALC@com{##1}\begin{ALC@for}}
\newcommand{\WHILE}[2][default]{\ALC@it\algorithmicwhile\ ##2\ %
\algorithmicdo%
\ALC@com{##1}\begin{ALC@whl}}
\newcommand{\LOOP}[1][default]{\ALC@it\algorithmicloop%
\ALC@com{##1}\begin{ALC@loop}}
\newcommand{\REPEAT}[1][default]{\ALC@it\algorithmicrepeat%
\ALC@com{##1}\begin{ALC@rpt}}
\newcommand{\UNTIL}[1]{\end{ALC@rpt}\ALC@it\algorithmicuntil\ ##1}
\newcommand{\SYNC}[2][default]{\ALC@it\algorithmicsync\ ##2\ % new
\ALC@com{##1}\begin{ALC@syn}} %new
\ifthenelse{\boolean{ALC@noend}}{
\newcommand{\ENDIF}{\end{ALC@if}}
\newcommand{\ENDFOR}{\end{ALC@for}}
\newcommand{\ENDWHILE}{\end{ALC@whl}}
\newcommand{\ENDLOOP}{\end{ALC@loop}}
\newcommand{\ENDSYNC}{\end{ALC@syn}} % new
}{
\newcommand{\ENDIF}{\end{ALC@if}\ALC@it\algorithmicendif}
\newcommand{\ENDFOR}{\end{ALC@for}\ALC@it\algorithmicendfor}
\newcommand{\ENDWHILE}{\end{ALC@whl}\ALC@it\algorithmicendwhile}
\newcommand{\ENDLOOP}{\end{ALC@loop}\ALC@it\algorithmicendloop}
\newcommand{\ENDSYNC}{\end{ALC@syn}\ALC@it\algorithmicendsync}% new
}
\renewcommand{\@toodeep}{}
\begin{list}{\ALC@lno}{\setcounter{ALC@line}{0}\setcounter{ALC@rem}{0}%
\itemsep\z@ \itemindent\z@ \listparindent\z@%
\partopsep\z@ \parskip\z@ \parsep\z@%
\labelsep 0.5em \topsep 0.2em%
\ifthenelse{\equal{#1}{0}}
{\labelwidth 0.5em }
{\labelwidth 1.2em }
\leftmargin\labelwidth \addtolength{\leftmargin}{\labelsep}
\ALC@tlm\labelsep
}
}
{\end{list}}
\makeatother
\begin{document}
\begin{algorithmic}
\REQUIRE $n \geq 0$
\ENSURE $y = x^n$
\STATE $y \leftarrow 1$
\WHILE{$N \neq 0$}
\STATE $X \leftarrow X$
\ENDWHILE
\SYNC{$N$ id odd}
\STATE $N \leftarrow n$
\ENDSYNC
\end{algorithmic}
\end{document}
如果您不想让序言看起来太拥挤,您可以将\makeatletter
和之间的代码放在\makeatother
一个新文档中,并将此新文档保存为,例如,保存algorithmic-modified.sty
在当前工作目录中(或保存在本地 TDS 树中)。现在,可以在加载后以标准方式将此文件加载到文档的序言中algorithmic
(您必须小心,因为使用该文档的其他用户也必须有权访问此新文件):
\documentclass{article}
\usepackage{algorithmic}
\usepackage{algorithmic-modified}
\begin{document}
\begin{algorithmic}
\REQUIRE $n \geq 0$
\ENSURE $y = x^n$
\STATE $y \leftarrow 1$
\WHILE{$N \neq 0$}
\STATE $X \leftarrow X$
\ENDWHILE
\SYNC{$N$ id odd}
\STATE $N \leftarrow n$
\ENDSYNC
\end{algorithmic}
\end{document}
以下是的内容algorithmic-modified.sty
:
% redefinition of the algorithmic environment
\newcommand{\algorithmicsync}{\textbf{sync}}
\newcommand{\algorithmicendsync}{\textbf{end sync}}
\renewenvironment{algorithmic}[1][0]{
\let\@item\ALC@item
\newcommand{\ALC@lno}{%
\ifthenelse{\equal{\arabic{ALC@rem}}{0}}
{{\footnotesize \arabic{ALC@line}:}}{}%
}
\let\@listii\@listi
\let\@listiii\@listi
\let\@listiv\@listi
\let\@listv\@listi
\let\@listvi\@listi
\let\@listvii\@listi
\newenvironment{ALC@g}{
\begin{list}{\ALC@lno}{ \itemsep\z@ \itemindent\z@
\listparindent\z@ \rightmargin\z@
\topsep\z@ \partopsep\z@ \parskip\z@\parsep\z@
\leftmargin 1em
\addtolength{\ALC@tlm}{\leftmargin}
}
}
{\end{list}}
\newcommand{\ALC@it}{\addtocounter{ALC@line}{1}\addtocounter{ALC@rem}{1}\ifthenelse{\equal{\arabic{ALC@rem}}{#1}}{\setcounter{ALC@rem}{0}}{}\item}
\newcommand{\ALC@com}[1]{\ifthenelse{\equal{##1}{default}}%
{}{\ \algorithmiccomment{##1}}}
\newcommand{\REQUIRE}{\item[\algorithmicrequire]}
\newcommand{\ENSURE}{\item[\algorithmicensure]}
\newcommand{\STATE}{\ALC@it}
\newcommand{\COMMENT}[1]{\algorithmiccomment{##1}}
\newenvironment{ALC@if}{\begin{ALC@g}}{\end{ALC@g}}
\newenvironment{ALC@for}{\begin{ALC@g}}{\end{ALC@g}}
\newenvironment{ALC@whl}{\begin{ALC@g}}{\end{ALC@g}}
\newenvironment{ALC@loop}{\begin{ALC@g}}{\end{ALC@g}}
\newenvironment{ALC@rpt}{\begin{ALC@g}}{\end{ALC@g}}
\newenvironment{ALC@syn}{\begin{ALC@g}}{\end{ALC@g}}% new
\renewcommand{\\}{\@centercr}
\newcommand{\IF}[2][default]{\ALC@it\algorithmicif\ ##2\ \algorithmicthen%
\ALC@com{##1}\begin{ALC@if}}
\newcommand{\ELSE}[1][default]{\end{ALC@if}\ALC@it\algorithmicelse%
\ALC@com{##1}\begin{ALC@if}}
\newcommand{\ELSIF}[2][default]%
{\end{ALC@if}\ALC@it\algorithmicelsif\ ##2\ \algorithmicthen%
\ALC@com{##1}\begin{ALC@if}}
\newcommand{\FOR}[2][default]{\ALC@it\algorithmicfor\ ##2\ \algorithmicdo%
\ALC@com{##1}\begin{ALC@for}}
\newcommand{\FORALL}[2][default]{\ALC@it\algorithmicforall\ ##2\ %
\algorithmicdo%
\ALC@com{##1}\begin{ALC@for}}
\newcommand{\WHILE}[2][default]{\ALC@it\algorithmicwhile\ ##2\ %
\algorithmicdo%
\ALC@com{##1}\begin{ALC@whl}}
\newcommand{\LOOP}[1][default]{\ALC@it\algorithmicloop%
\ALC@com{##1}\begin{ALC@loop}}
\newcommand{\REPEAT}[1][default]{\ALC@it\algorithmicrepeat%
\ALC@com{##1}\begin{ALC@rpt}}
\newcommand{\UNTIL}[1]{\end{ALC@rpt}\ALC@it\algorithmicuntil\ ##1}
\newcommand{\SYNC}[2][default]{\ALC@it\algorithmicsync\ ##2\ % new
\ALC@com{##1}\begin{ALC@syn}} %new
\ifthenelse{\boolean{ALC@noend}}{
\newcommand{\ENDIF}{\end{ALC@if}}
\newcommand{\ENDFOR}{\end{ALC@for}}
\newcommand{\ENDWHILE}{\end{ALC@whl}}
\newcommand{\ENDLOOP}{\end{ALC@loop}}
\newcommand{\ENDSYNC}{\end{ALC@syn}} % new
}{
\newcommand{\ENDIF}{\end{ALC@if}\ALC@it\algorithmicendif}
\newcommand{\ENDFOR}{\end{ALC@for}\ALC@it\algorithmicendfor}
\newcommand{\ENDWHILE}{\end{ALC@whl}\ALC@it\algorithmicendwhile}
\newcommand{\ENDLOOP}{\end{ALC@loop}\ALC@it\algorithmicendloop}
\newcommand{\ENDSYNC}{\end{ALC@syn}\ALC@it\algorithmicendsync}% new
}
\renewcommand{\@toodeep}{}
\begin{list}{\ALC@lno}{\setcounter{ALC@line}{0}\setcounter{ALC@rem}{0}%
\itemsep\z@ \itemindent\z@ \listparindent\z@%
\partopsep\z@ \parskip\z@ \parsep\z@%
\labelsep 0.5em \topsep 0.2em%
\ifthenelse{\equal{#1}{0}}
{\labelwidth 0.5em }
{\labelwidth 1.2em }
\leftmargin\labelwidth \addtolength{\leftmargin}{\labelsep}
\ALC@tlm\labelsep
}
}
{\end{list}}