10

Problematic algorithm

I have an algorithm dealing with some very large parameter names, messing up the readability. What I've done so far is break the lines of the problematic statement (lines 4-5) manually into two separate statements. Without it the statement will go outside the page margins. The procedure signature wraps itself.

What I want to do is to indent the overflowing lines in both the procedure name and the long statement to the location of the arrows in the figure above.

How should I do this? I am open for suggestions to other packages for algorithms as well.

\documentclass[12pt,a4paper,english,twoside,titlepage]{report}
\usepackage{algorithm}
\usepackage{algpseudocode}
\begin{document}
    \begin{algorithm}
        \caption{This procedure calculates the \texttt{response} value}
        \begin{algorithmic}[1]
            \Procedure {CalculateResponse}{$pszMethod$, $pszDigestUri$, $pszQop$, $pszUsername$, $pszRealm$, $pszPassword$, $pszNonce$, $pszCNonce$, $pszNonceCount$}
                \State $ha1 \gets DigestCalcHA1(pszUsername, pszRealm, pszPassword)$
                \State $ha2 \gets DigestCalcHA2(pszMethod, pszDigestUri, pszQop)$
                \State $response \gets calculateResponse(ha1, ha2,pszMethod, pszDigestUri,$
                \State $pszQop,pszNonce, pszNonceCount, pszCNonce)$
        \EndProcedure
            \Statex
        \end{algorithmic}
    \end{algorithm}
\end{document}

3 Answers 3

11
+50

One can modify the algorithmic enviornment so that continuation lines are indented.

Sample output

\documentclass[12pt,a4paper]{report}
\usepackage{algorithm}
\usepackage{algpseudocode}

\makeatletter
\newlength{\continueindent}
\setlength{\continueindent}{6em}

\renewenvironment{algorithmic}[1][0]%
   {%
   \edef\ALG@numberfreq{#1}%
   \def\@currentlabel{\theALG@line}%
   %
   \setcounter{ALG@line}{0}%
   \setcounter{ALG@rem}{0}%
   %
   \let\\\algbreak%
   %
   \expandafter\edef\csname ALG@currentblock@\theALG@nested\endcsname{0}%
   \expandafter\let\csname ALG@currentlifetime@\theALG@nested\endcsname\relax%
   %
   \begin{list}%
      {\ALG@step}%
      {%
      \rightmargin\z@%
      \itemsep\z@ \itemindent\z@ \listparindent2em%
      \partopsep\z@ \parskip\z@ \parsep\z@%
      \labelsep 0.5em \topsep 0.2em%\skip 1.2em 
      \ifthenelse{\equal{#1}{0}}%
         {\labelwidth 0.5em}%
         {\labelwidth 1.2em}%
       \leftmargin\labelwidth \addtolength{\leftmargin}{\labelsep}
      \ALG@tlm\z@%
      }%
      \parshape 2 \leftmargin \linewidth \continueindent \dimexpr\linewidth-\continueindent\relax
   \setcounter{ALG@nested}{0}%
   \ALG@beginalgorithmic%
   }%
   {% end{algorithmic}
   % check if all blocks are closed
   \ALG@closeloops%
   \expandafter\ifnum\csname ALG@currentblock@\theALG@nested\endcsname=0\relax%
   \else%
      \PackageError{algorithmicx}{Some blocks are not closed!!!}{}%
   \fi%
   \ALG@endalgorithmic%
   \end{list}%
   }%
\makeatother


\begin{document}

\begin{algorithm}
  \caption{This procedure calculates the \texttt{response} value}
  \begin{algorithmic}[1]
      \Procedure {CalculateResponse}{$pszMethod$,
        $pszDigestUri$, $pszQop$, $pszUsername$, $pszRealm$,
        $pszPassword$, $pszNonce$, $pszCNonce$, $pszNonceCount$} 
        \State $ha1 \gets DigestCalcHA1(pszUsername, pszRealm,
          pszPassword)$ 
        \State $ha2 \gets DigestCalcHA2(pszMethod, pszDigestUri,
          pszQop)$ 
        \State $response \gets calculateResponse(ha1,
          ha2,pszMethod, pszDigestUri,\break pszQop,pszNonce,
          pszNonceCount, pszCNonce)$ 
      \EndProcedure
      \Statex
  \end{algorithmic}
\end{algorithm}

\end{document}

The change to the standard definition of the environment is that a \parshape command has been added to the items. The amount of indentation is controlled by a new length \continueindent. Now you can either let latex break lines for you automatically, and so may wish to look at the question Allowing line break at ',' in inline math mode? to make this go more smoothly, or you can manually add \break commands in the formulae. I have included an example of each in the above code.

For breaks in text use \newline.

Should you need extra indentation on a single line you can use \break\hspace*{2em} and \newline\hspace*{2em}.

Also consider using @JLDiaz suggestion of \raggedright to avoid lines being stretched too much.

1
  • This should be the standard definition in the package...
    – Gus
    Jan 12, 2022 at 6:23
2

This is just one tiny addition to Andrew Swann's answer, namely that nested algorithm block levels get appropriate hanging indents too (so community wiki). The setting of the \parshape now has to be done every time the indent changes (\ALG@beginblock) instead of just at the start of the algorithmic environment.

\documentclass[12pt,a4paper]{report}
\usepackage{algorithm}
\usepackage{algpseudocode}


% continuation indent patch http://tex.stackexchange.com/questions/78776/forced-indentation-in-algorithmicx
\newlength{\continueindent}
\setlength{\continueindent}{2em}
\usepackage{etoolbox}
\makeatletter
\newcommand*{\ALG@customparshape}{\parshape 2 \leftmargin \linewidth \dimexpr\ALG@tlm+\continueindent\relax \dimexpr\linewidth+\leftmargin-\ALG@tlm-\continueindent\relax}
\apptocmd{\ALG@beginblock}{\ALG@customparshape}{}{\errmessage{failed to patch}}
\makeatother
% end continuation indent patch

\begin{document}

\begin{algorithm}
  \caption{This procedure is filler text, extracted from lipsum package}
  \begin{algorithmic}[1]
    \Procedure{Lipsum}{r}
      \State Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. 
      \While{$r\not=0$}
        \State Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
        \State Mauris ut leo. Cras viverra metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices.
        \State $r \gets r - 1$
      \EndWhile\label{euclidendwhile}
      \State Phasellus eu tellus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium quis, viverra ac, nunc.
    \EndProcedure
  \end{algorithmic}
\end{algorithm}

\end{document}

Output

1
  • This is a nice addition. Dec 1, 2013 at 19:23
1

EDIT: The following answer uses version 1.1 of algorithtmicx package. With version 1.2, continuation lines are not indented. Since there is a better answer, there is no point in finding the causes and remedies.

Old answer:

algorithmicx package does the job right indeed, provided that you give it the correct input. In your case, you are using a single formula to enclose all the parameter list. TeX does not allow line breaks in that formula, and thus it is printed in a single (overfull) line. If you instead separate the argument list in a comma separated list of independent formulae (one per variable), line breaks are allowed, and the output is what you wanted.

\documentclass[12pt,a4paper,english,twoside,titlepage]{report}
\usepackage{algorithm}
\usepackage{algpseudocode}
\begin{document}
\begin{algorithm}
  \caption{This procedure calculates the \texttt{response} value}
  \begin{algorithmic}[1]
  \Procedure {CalculateResponse}{$pszMethod$, $pszDigestUri$, $pszQop$,
        $pszUsername$, $pszRealm$, $pszPassword$, $pszNonce$,
        $pszCNonce$, $pszNonceCount$}
        \State $ha1 \gets DigestCalcHA1$ ($pszUsername$, $pszRealm$, $pszPassword$)
        \State $ha2 \gets DigestCalcHA2$ ($pszMethod$, $pszDigestUri$, $pszQop$)
        \State $response \gets calculateResponse$ ($ha1$, $ha2$,
            $pszMethod$, $pszDigestUri$, $pszQop$ , $pszNonce$,
            $pszNonceCount$, $pszCNonce$)
    \EndProcedure
    \Statex
  \end{algorithmic}
\end{algorithm}
\end{document}

Algorithm

Note however that there are still problems with the result, which is plenty of underfull boxes and badly spaced. You can fix this using \raggedright inside algorithmic environment:

\begin{algorithmic}[1]\raggedright

Better formatted

1
  • With your MWE I don't get the same output as in the first image; the procedure line results in the same output as Henning Klevjer's.
    – egreg
    Dec 10, 2012 at 10:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .