[Tex/LaTex] pgf error: No shape named … is known, but only at 1st run

beamerlistingstikz-pgftikzmark

(This question extend this one.)

The following MCE:

  1. at its 1st compilation, leads to a:

    Package pgf Error: No shape named comment is known.

  2. if the 1st compilation is run without stopping, works like a charm at the subsequent ones (at its 3rd one, all the cross-references are right and the resulting PDF file is as expected).

Do you know how to make this example run smoothly at 1st compilation?

\documentclass{beamer}

\usepackage{listings}

\lstset{basicstyle=\ttfamily}

\usepackage{tikz}

\usetikzlibrary{%
  tikzmark,fit,calc,%
  positioning
}

\usetikzmarklibrary{listings}

\makeatletter
\renewcommand\iftikzmark[3]{%
  \@ifundefined{save@pt@#1-\the\beamer@slideinframe}{%
    #3%
  }{%
    #2%
  }%
}%
\newcommand{\@balloon}[4]{%
  \pgfmathtruncatemacro\@firstline{%
    #3-1%
  }%
  \iftikzmark{line-#2-\@firstline-start}{%
    \iftikzmark{line-#2-#3-first}{%
      \xdef\@blines{%
        ($ ({pic cs:line-#2-\@firstline-start} -| {pic
          cs:line-#2-#3-first})!.5!({pic cs:line-#2-#3-first}) $)%
      }%
    }{%
      \iftikzmark{line-#2-#3-start}{%
        \xdef\@blines{%
          ({pic cs:line-#2-\@firstline-start} -| {pic cs:line-#2-#3-start})%
        }%
      }{%
        \xdef\@blines{(pic cs:line-#2-\@firstline-start)}%
      }%
    }%
  }{%
    \xdef\@blines{}%
  }%
  \foreach \k in {#3,...,#4} {%
    \iftikzmark{line-#2-\k-first}{%
      \xdef\@blines{%
        \@blines (pic cs:line-#2-\k-first)%
      }%
    }{}%
    \iftikzmark{line-#2-\k-end}{%
      \xdef\@blines{%
        \@blines (pic cs:line-#2-\k-end)%
      }%
    }{}%
  }%
  \ifx\@blines\empty%
  \else%
  \edef\temp{%
    \noexpand\tikz[remember picture,overlay]%
    \noexpand\node[fit={\@blines},draw] (#1) {};%
  }%
  \temp%
  \fi%
}
%
\newcommand<>{\balloon}[4][code\the\beamer@slideinframe]{%
  \alt#5{\@balloon{#2}{#1}{#3}{#4}}{\tikz[overlay,remember picture]\path (0,0);}%
}
%
\lstnewenvironment{hllisting}[1][]{%
  \lstset{name=code\the\beamer@slideinframe,#1}%
}{%
  \lstset{name=}%
}
\makeatother
%
\begin{document}
\begin{frame}[fragile]
\begin{hllisting}
1st line of code
2nd line of code
3rd line of code
4th line of code
5th line of code
6th line of code
\end{hllisting}
\balloon{comment}{2}{3}%
\tikz[overlay,remember picture] {
  \node[right=of comment] () {Foo};%
}
\end{frame}
\end{document}

Best Answer

You should add suitable nodes in the alternative pathes, that means after

 \ifx@blines\empty 

there should be a

 \tikz[remember picture,overlay]\node(#1){}; 

and in the balloon definition also in the branch with the \tikz command (in this case with #2 instead of #1).