
Ich versuche mir eine Frage zu beantworten, die ich in meinem Kommentar gestellt habediese Antwort, ich habe den folgenden Code erstellt, der auf dem von Ulrike basiert, aber das \balloon
Makro überlagerungsfähig macht. Wenn dieses Makro jedoch vor Auflistungen verwendet wird, führt es einen falschen vertikalen Abstand ein. Sehen Sie, woher das kommen kann?
Aktualisieren
Der Code wurde leicht geändert und eine Animation hinzugefügt, um den störenden vertikalen Raum deutlicher zu machen.
Aktualisierung 2
Um Probleme durch Duplikate bei \balloon
der Overlay-Erkennung zu vermeiden, ist es tatsächlich notwendig, dass die Einträge eindeutige Namen haben. Die Verwendung der Foliennummern ( \the\beamer@slideinframe
) reicht dazu innerhalb eines bestimmten Rahmens aus, aber nicht im gesamten Dokument. Das Hinzufügen der Rahmennummern ( \insertframenumber
) erledigt den Trick.
\documentclass{beamer}
%
\setbeamertemplate{footline}[page number]
%
\usepackage{listings}
\usepackage[foreground]{pagegrid}
\usepackage{tikz}
\usetikzlibrary{tikzmark,fit,calc}
\usetikzmarklibrary{listings}
\lstset{basicstyle=\ttfamily}
\tikzset{%
balloon/.style={%
draw,%
fill=blue!20,%
opacity=0.4,%
inner sep=4pt,%
rounded corners=2pt%
},%
}
%
\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},balloon] (#1) {};}%
\temp%
\fi%
}
%
\newcommand<>{\balloon}[4][code\insertframenumber\the\beamer@slideinframe]{%
\only#5{\@balloon{#2}{#1}{#3}{#4}}%
}
%
\lstnewenvironment{hllisting}[1][]{%
\lstset{name=code\insertframenumber\the\beamer@slideinframe,#1}%
}{%
\lstset{name=}%
}
\makeatother
%
\begin{document}
\begin{frame}[fragile]
\balloon<3>{comment}{5}{6}%
\balloon<4>{comment}{1}{3}%
\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}
\end{frame}
\end{document}
Antwort1
Hier gibt es keine Zauberei: Sie fügen \tikz[overlay]
in einigen Frames ein ein und in anderen nicht. Ein A \tikz[overlay]
hat zwar keine Größe, ist aber trotzdem eine Box und \mbox{}
kann wie ein Leerzeichen einfügen. Das bedeutet, dass es wichtig ist, entweder das \tikz[overlay]
an Stellen zu verwenden, an denen eine solche Box keinen Schaden anrichtet. Oder eine ähnliche Box in allen Frames zu verwenden, z. B. indem Sie wie von David vorgeschlagen ein \mbox
oder z. B. \alt
anstelle von \only
in der Definition von verwenden \balloon
:
\documentclass{beamer}
%
\setbeamertemplate{footline}[page number]
%
\usepackage{listings}
\usepackage[foreground]{pagegrid}
\usepackage{tikz}
\usetikzlibrary{tikzmark,fit,calc}
\usetikzmarklibrary{listings}
\lstset{basicstyle=\ttfamily}
\tikzset{%
balloon/.style={%
draw,%
fill=blue!20,%
opacity=0.4,%
inner sep=4pt,%
rounded corners=2pt%
},%
}
%
\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},balloon] (#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}
\tikz[overlay]\node{a};
blblb
\end{frame}
\begin{frame}
blblb
\end{frame}
\begin{frame}[fragile]
\balloon<3>{comment}{5}{6}%
\balloon<4>{comment}{1}{3}%
\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}
\end{frame}
\end{document}
Antwort2
Seltsamerweise habe ich nicht ganz genau nachvollzogen, was Beamer und Tikzmark hier machen, aber das Hinzufügen von unsichtbarenwas istim vertikalen Modus, egal ob \color
oder \label
oder, \tikzmark
ist immer knifflig und hat schwer kontrollierbare Nebenwirkungen. Die Lösung besteht in allen Fällen darin, sicher in den horizontalen Modus zu gelangen, bevor Sie etwas Schwieriges tun.
Wenn Sie tun
\mbox{\balloon<3>{comment}{5}{6}%
\balloon<4>{comment}{1}{3}}%
dann erscheint die Auflistung auf allen vier Folien an derselben Position. Die leere Mbox erzeugt einen unechten Absatz, der die Dinge ein wenig nach unten verschiebt, aber da es sich um einen festen Punkt handelt und auf allen Folien gleich ist, können Sie bei Bedarf eine Leerzeile und ein negatives Leerzeichen nach der Box verwenden.