1

(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}
3
  • 2
    Imho it should work if you 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 (with #2). Mar 26, 2017 at 14:49
  • @UlrikeFischer Indeed, though the 1st addition seems to be enough (I must admit I don't understand the 2nd one you suggested :) Would you mind make this comment an answer? Mar 26, 2017 at 15:45
  • In your example the first is enough. But there must exist a case where the second argument of \alt is used (or you wouldn't need it at all) and so it is safer to add the node there too. Mar 26, 2017 at 15:55

1 Answer 1

3

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).

2
  • For the 2nd part, do you mean to replace \tikz[overlay,remember picture]\path (0,0); by \tikz[remember picture,overlay]\node(#2){}; in \alt#5{\@balloon{#2}{#1}{#3}{#4}}{\tikz[overlay,remember picture]\path (0,0);}? Mar 26, 2017 at 16:02
  • 1
    I don't remember why there is a zero path, but imho an empty node there should work too. Mar 26, 2017 at 16:09

You must log in to answer this question.

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