[Tex/LaTex] new clause in algorithmic package

algorithms

I want to define a new clause in algorithmic package (sync in my case), so that the code inside that clause would be indented as it was inside a while clause for example.

So far I made things work by adding those lines in different places of 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}
}

Is there a simpler way to do the job without editing algorithmic.sty file?

Best Answer

As Werner says in his comment, it is not advisable to modify the .sty files directly. You can include your definitions in the document preamble (after loading the required packages); since your commands use the @ character, you will need to use \makeatletter before the definitions and \makeatother after them.

However, I would suggest you to use the algorithmicx package instead; this package offers you many possibilities to customize the layout of algorithms and gives you an easy way to define a completely new layout for your specific needs. For example (algpseudocode internally loads 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}

enter image description here

EDIT: if changing to algorithmicx is not an option at the present time, you can still make your definitions in the preamble of your document instead of modifying the .sty file directly; simply use \renewenvironment to redefine the algorithmic environment and include your new definitions:

\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}

If you don't want your preamble to look too crowded, you can put the code that goes between \makeatletter and \makeatother in a new document and save this new document as, for example, algorithmic-modified.sty in your current working directory (or in your local TDS tree). Now this file can be loaded in the standard way in the preamble of your document, after having loaded algorithmic (you'll have to be careful, since other users working with the document will also have to have access to this new file):

\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}

And here's the contents of 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}}