I use algorithmicx
with vertical lines. And the code is working good:
\documentclass{article}
\usepackage{algorithm}
\usepackage{algpseudocode}
% Vertical line
\makeatletter
\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{Examples}\label{alg:Examples}
\begin{algorithmic}[1]
\LState $X=45$
\For{\textbf{от} $i=0$ \textbf{до} 5}
\LState $X=X-2$
\LState \Call {Find}{$X$}
\While{$Y_2<5$}
\If{$quality\ge 9$}
\LState $a\gets perfect$
\ElsIf{$quality\ge 7$}
\LState $a\gets good$
\ElsIf{$quality\ge 5$}
\LState $a\gets medium$
\ElsIf{$quality\ge 3$}
\LState $a\gets bad$
\Else
\LState $a\gets unusable$
\EndIf
\EndWhile
\LState \Return $X$
\EndFor
\end{algorithmic}
\end{algorithm}
\end{document}
a busy cat http://harrix.org/2013-04-24_151430.png
-
I want to translate commands to my language. For common commands the translation does not break the vertical line.
\algrenewcommand\algorithmicwhile{\textbf{BlaBlaWhile}} \algrenewcommand\algorithmicif{\textbf{BlaBlaIf}}
But when I translate the end of the team structures, broken vertical line.
\algrenewtext{EndWhile}{\textbf{BlaBlaEndWhile}}
\algrenewtext{ElsIf}{\textbf{BlaBlaElsIf }}
Code:
\documentclass{article}
\usepackage{algorithm}
\usepackage{algpseudocode}
% Vertical line
\makeatletter
\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}
\algrenewcommand\algorithmicwhile{\textbf{BlaBlaWhile}}
\algrenewcommand\algorithmicif{\textbf{BlaBlaIf}}
\algrenewtext{EndWhile}{\textbf{BlaBlaEndWhile}}
\algrenewtext{ElsIf}{\textbf{BlaBlaElsIf }}
\begin{algorithm}
\caption{Examples}\label{alg:Examples}
\begin{algorithmic}[1]
\LState $X=45$
\For{\textbf{от} $i=0$ \textbf{до} 5}
\LState $X=X-2$
\LState \Call {Find}{$X$}
\While{$Y_2<5$}
\If{$quality\ge 9$}
\LState $a\gets perfect$
\ElsIf{$quality\ge 7$}
\LState $a\gets good$
\ElsIf{$quality\ge 5$}
\LState $a\gets medium$
\ElsIf{$quality\ge 3$}
\LState $a\gets bad$
\Else
\LState $a\gets unusable$
\EndIf
\EndWhile
\LState \Return $X$
\EndFor
\end{algorithmic}
\end{algorithm}
\end{document}
a busy cat http://harrix.org/2013-04-24_153318.png
How to fix it?
-
When I use a big formula with a height greater than the height line, vertical line breaks.
\documentclass{article} \usepackage{algorithm} \usepackage{algpseudocode} \usepackage{amsthm,amsfonts,amsmath,amssymb,amscd} % Vertical line \makeatletter \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{Examples}\label{alg:Examples} \begin{algorithmic}[1] \LState $X=45$ \For{\textbf{от} $i=0$ \textbf{до} 5} \LState $X=X-2$ \LState \Call {Find}{$X$} \While{$Y_2<5$} \If{$quality\ge 9$} \LState $a\gets perfect$ \ElsIf{$quality\ge 7$} \LState Try \begin{flalign*} &\left( \begin{array}{c} X_{B} \\ f_B\left( \bar{x}_{B}\right) \\ {g_i}_B\left( \bar{x}_B\right) \\ {h_j}_B\left( \bar{x}_B\right) \\ ParametersOfBinaryGA\end{array}\right)\\ &=ConvertingIntoBinaryGA\left( \begin{array}{c} X \\ f\left( \bar{x}\right) \\ g_i\left( \bar{x}\right) \\ h_j\left( \bar{x}\right) \\ ParametersOfBinaryGA \\ ParametersOfConvertingIntoBinaryGA \end{array}\right) \end{flalign*} \ElsIf{$quality\ge 5$} \LState $a\gets medium$ \ElsIf{$quality\ge 3$} \LState $a\gets bad$ \Else \LState $\left( \begin{array}{c} X_{B} \\ f_B\left( \bar{x}_{B}\right) \\ {g_i}_B\left( \bar{x}_B\right) \\ {h_j}_B\left( \bar{x}_B\right) \\ ParametersOfBinaryGA\end{array}\right)$ \EndIf \EndWhile \LState \Return $X$ \EndFor \end{algorithmic} \end{algorithm} \end{document}
a busy cat http://harrix.org/2013-04-24_155014.png
How to fix it?
Best Answer
The indentation issues are answered by a simple extension to the solution to Forced indentation in algorithmicx.
The vertical lines pose a harder problem. One cannot introduce any solution that creates a group where the vertical line should start and ends the group where the vertical line should end, because this breaks
algorithmicx
. Therefore, the only solution that comes to mind involvestikz
andzpos
. I have adapted code from marking conditional versions with line in margin foralgorithmicx
, to cope with nested blocks and being the right distance from the margin. Of course, this needs a few runs to stabilise as it essentially usestikzmark
. However, my solution does not currently work well with matrices (or other lines that are taller), and I cannot see how to fix it (note: based on the answer to Determine height of the line you are in, this is either not easy or impossible, at least without LuaTeX). It also doesn't currently work when the algorithm spans more than one column (some lines are in the wrong place or not drawn at all).Lastly, instead of working with your code example, I have based this on the one at How to automatically keep the indentation level when a line has to be broken instead, for simplicity.
I have removed floating structure, to show that the lines still look reasonable when the algorithm takes up multiple pages (uncomment the
\lipsum
line to see).The output demonstrates the issues with the tall lines such as those with matrices: