Use
\Function{foo}{\null}
and
\Call{foo}{\null}
This way you're passing these macros a non-empty, non-printing argument. Here is a mock example taken from the algorithmicx
documentation:
\documentclass{article}
\usepackage{algorithm}% http://ctan.org/pkg/algorithms
\usepackage{algpseudocode}% http://ctan.org/pkg/algorithmicx
\begin{document}
\begin{algorithm}
\caption{Euclid’s algorithm}\label{euclid}
\begin{algorithmic}[1]
\Function{Euclid}{\null}\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$
\State $r\gets a\bmod b$
\EndWhile\label{euclidendwhile}
\State \textbf{return} $b$\Comment{The gcd is b}
\State \Call{foo}{\null}
\EndFunction
\end{algorithmic}
\end{algorithm}
\end{document}
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 involves tikz
and zpos
. I have adapted code from marking conditional versions with line in margin for algorithmicx
, 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 uses tikzmark
. 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.
\documentclass[twocolumn]{article}
\usepackage[paperheight=10cm]{geometry}% to help test the twocolumn behaviour
\usepackage{algpseudocode}
\errorcontextlines\maxdimen
% begin vertical rule patch for algorithmicx
% borrowing from https://tex.stackexchange.com/questions/41956/marking-conditional-versions-with-line-in-margin
\RequirePackage{tikz}
\RequirePackage{zref-abspage}
\RequirePackage{zref-user}
\RequirePackage{tikz}
\RequirePackage{atbegshi}
\usetikzlibrary{calc}
\RequirePackage{tikzpagenodes}
\RequirePackage{etoolbox}
\makeatletter
\newcommand*\ALG@lastblockb{b}
\newcommand*\ALG@lastblocke{e}
\apptocmd{\ALG@beginblock}{%
%\typeout{beginning block, nesting level \theALG@nested, line \arabic{ALG@line}}%
\ifx\ALG@lastblock\ALG@lastblockb
\ifnum\theALG@nested>1\relax\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi{\ALG@tikzborder}{}%
\fi
\let\ALG@lastblock\ALG@lastblockb%
}{}{\errmessage{failed to patch}}
\pretocmd{\ALG@endblock}{%
%\typeout{ending block, nesting level \theALG@nested, line \arabic{ALG@line}}%
\ifx\ALG@lastblock\ALG@lastblocke
\addtocounter{ALG@nested}{1}%
\addtolength\ALG@tlm{\csname ALG@ind@\theALG@nested\endcsname}%
\ifnum\theALG@nested>1\relax\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi{\endALG@tikzborder}{}%
\addtolength\ALG@tlm{-\csname ALG@ind@\theALG@nested\endcsname}%
\addtocounter{ALG@nested}{-1}%
\fi
\let\ALG@lastblock\ALG@lastblocke%
}{}{\errmessage{failed to patch}}
\tikzset{ALG@tikzborder/.style={line width=0.5pt,black}}
\newcommand*\currenttextarea{current page text area}
\newcommand*{\updatecurrenttextarea}{%
\if@twocolumn
\if@firstcolumn
\renewcommand*{\currenttextarea}{current page column 1 area}%
\else
\renewcommand*{\currenttextarea}{current page column 2 area}%
\fi
\else
\renewcommand*\currenttextarea{current page text area}%
\fi
}
\newcounter{ALG@tikzborder}
\newcounter{ALG@totaltikzborder}
\newenvironment{ALG@tikzborder}[1][]{%
% Allow user to overwrite the used style locally
\ifx&\else
\tikzset{ALG@tikzborder/.style={#1}}%
\fi
\stepcounter{ALG@totaltikzborder}%
\expandafter\edef\csname ALG@ind@border@\theALG@nested\endcsname{\theALG@totaltikzborder}%
\setcounter{ALG@tikzborder}{\csname ALG@ind@border@\theALG@nested\endcsname}%
%\typeout{begin ALG border nesting level=\theALG@nested, tikzborder=\theALG@tikzborder, tlm=\the\ALG@tlm}%
\tikz[overlay,remember picture] \coordinate (ALG@tikzborder-\theALG@tikzborder);% node {\theALG@tikzborder};% Modified \tikzmark macro
\zlabel{ALG@tikzborder-begin-\theALG@tikzborder}%
% Test if end-label is at the same page and draw first half of border if not, from start place to the end of the page
\ifnum\zref@extract{ALG@tikzborder-begin-\theALG@tikzborder}{abspage}=\zref@extract{ALG@tikzborder-end-\theALG@tikzborder}{abspage} \else
\updatecurrenttextarea
\ALG@drawvline{[shift={(0pt,.5\ht\strutbox)}]ALG@tikzborder-\theALG@tikzborder}{\currenttextarea.south east}{\ALG@thistlm}%
% If it spreads over more than two pages:
\newcounter{ALG@tikzborderpages\theALG@tikzborder}%
\setcounter{ALG@tikzborderpages\theALG@tikzborder}{\numexpr-\zref@extract{ALG@tikzborder-begin-\theALG@tikzborder}{abspage}+\zref@extract{ALG@tikzborder-end-\theALG@tikzborder}{abspage}}%
\ifnum\value{ALG@tikzborderpages\theALG@tikzborder}>1
\edef\nextcmd{\noexpand\AtBeginShipoutNext{\noexpand\ALG@tikzborderpage{\theALG@tikzborder}{\the\ALG@thistlm}}}%some pages need a border on the whole page
\nextcmd
\fi
\fi
}{%
\setcounter{ALG@tikzborder}{\csname ALG@ind@border@\theALG@nested\endcsname}%
%\typeout{end ALG border nesting level=\theALG@nested, tikzborder=\theALG@tikzborder, tlm=\the\ALG@tlm}%
\tikz[overlay,remember picture] \coordinate (ALG@tikzborder-end-\theALG@tikzborder);% node {\theALG@tikzborder};% Modified \tikzmark macro
\zlabel{ALG@tikzborder-end-\theALG@tikzborder}%
% Test if begin-label is at the same page and draw whole border if so, from start place to end place
\updatecurrenttextarea
\ifnum\zref@extract{ALG@tikzborder-begin-\theALG@tikzborder}{abspage}=\zref@extract{ALG@tikzborder-end-\theALG@tikzborder}{abspage}\relax
\ALG@drawvline{[shift={(0pt,.5\ht\strutbox)}]ALG@tikzborder-\theALG@tikzborder}{ALG@tikzborder-end-\theALG@tikzborder}{\ALG@thistlm}%
% Otherwise draw second half of border, from the top of the page to the end place
\else
%\settextarea
\ALG@drawvline{\currenttextarea.north west}{ALG@tikzborder-end-\theALG@tikzborder}{\ALG@thistlm}%
\fi
}
\newcommand*{\ALG@drawvline}[3]{%#1=from, #2=to, #3=value of \ALG@tlm/\ALG@thisthm
\begin{tikzpicture}[overlay,remember picture]
\draw [ALG@tikzborder]
let \p0 = (\currenttextarea.north west), \p1=(#1), \p2 = (#2)
in
(#3+\fboxsep+.5\pgflinewidth+\x0,\y1+\fboxsep+.5\pgflinewidth)%-\fboxsep-.5\pgflinewidth
--
(#3+\fboxsep+.5\pgflinewidth+\x0,\y2-\fboxsep-.5\pgflinewidth)
%node[midway,anchor=east] {\ALG@tikzbordertext}
;
\end{tikzpicture}%
}
\newcommand{\ALG@tikzborderpage}[2]{%the whole page gets a border, #1=value of \theALG@tikzborder, #2=value of \ALG@tlm/\ALG@thistlm
\updatecurrenttextarea
\setcounter{ALG@tikzborder}{#1}%
\ALG@drawvline{\currenttextarea.north west}{\currenttextarea.south east}{#2}%
\addtocounter{ALG@tikzborderpages\theALG@tikzborder}{-1}%
\ifnum\value{ALG@tikzborderpages\theALG@tikzborder}>1
\AtBeginShipoutNext{\ALG@tikzborderpage{#1}{#2}}%
\fi
\vspace{-0.5\baselineskip}% Compensate for the generated extra space at begin of the page. No idea why exactly this happens.
}
\def\ALG@tikzbordertext{\the\ALG@tlm}
\makeatother
% end vertical rule patch for algorithmicx
% continuation indent patch, slightly extended from https://tex.stackexchange.com/questions/78776/forced-indentation-in-algorithmicx to support multiple paragraphs in one block
\RequirePackage{etoolbox}
\makeatletter
\newlength{\ALG@continueindent}
\setlength{\ALG@continueindent}{2em}
\newcommand*{\ALG@customparshape}{\parshape 2 \leftmargin \linewidth \dimexpr\ALG@tlm+\ALG@continueindent\relax \dimexpr\linewidth+\leftmargin-\ALG@tlm-\ALG@continueindent\relax}
\newcommand*{\ALG@customparshapex}{\parshape 1 \dimexpr\ALG@tlm+\ALG@continueindent\relax \dimexpr\linewidth+\leftmargin-\ALG@tlm-\ALG@continueindent\relax}
\apptocmd{\ALG@beginblock}{\ALG@customparshape\everypar{\ALG@customparshapex}}{}{\errmessage{failed to patch}}
\makeatother
% end continuation indent patch
% user level stuff
\usepackage{amsmath}
\usepackage{lipsum}
% example copied from https://tex.stackexchange.com/questions/130199/how-to-automatically-keep-the-indentation-level-when-a-line-has-to-be-broken
% A command for defining assignments within the algorithmic environment
\newcommand{\Let}[2]{\State #1 $\gets$ #2}
\begin{document}
test in second column
\newpage
\begin{algorithmic}[1]
\Function{test}{$(x, y)$}%
% \State Some lines extend \raisebox{1ex}{higher} but we don't like that at the beginning of a block (leaves space above the vertical line).
\Let{$a$}{some math expression}
\Let{$b$}{some very very long expression that doesn't fit on one line and is
even longer and longer \par\noindent and a new paragraph with another very very long expression that doesn't fit on one line}
\For{each $e$ in a list}
\Let{$l(e)$}{the length of element $e$}
\If{some condition on $l(e)$}
\State{run some complex sub-routine and get the result and this
description is very very long, long indeed...}
\Let{$a$}{some math expression}
\Let{$b$}{some very very long expression that doesn't fit on one
line and is even longer and longer}
\If{some other condition}
\Let{$c$}{another math expression}
\State \(\begin{bmatrix} 1 & 0 & 0 \\ 0 & 1 & 0 \\ 0 & 0 & 1 \end{bmatrix}\)
\EndIf
\EndIf
% \State \lipsum*[1-9]
\EndFor
\EndFunction
\end{algorithmic}
\end{document}
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:
Best Answer
The solution is very simple: it's enough add a space between commas.
I'm sorry for such a (stupid) question. However I hope this answer will save someone else's time.