為什麼在列表之前有如此虛假的垂直空間?

為什麼在列表之前有如此虛假的垂直空間?

試圖回答自己在評論中提出的問題這個答案,我最終得到了下面基於 Ulrike 的程式碼,但它使\balloon巨集覆蓋感知。但是,當在列表之前使用時,該巨集會引入虛假的垂直空間。你知道它來自哪裡嗎?

更新

程式碼已略有更改,並添加了動畫,以使虛假的垂直空間更加明顯。

更新2

事實上,為了避免在\balloon意識到覆蓋時由於重複而造成的麻煩,清單有必要具有不同的名稱。為此,\the\beamer@slideinframe在給定框架內使用幻燈片編號 ( ) 就足夠了,但在整個文件中還不夠。加幀數 ( \insertframenumber) 就可以了。

\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}

在此輸入影像描述

答案1

這裡沒有魔法:您\tikz[overlay]在某些幀中插入 a 而在其他幀中則不插入。 A\tikz[overlay]可能沒有大小,但它仍然是一個盒子,並且像 an 一樣,\mbox{}它可以引入空間。這意味著重要的是要\tikz[overlay]在這樣的盒子不會造成傷害的地方使用。或在所有框架中使用類似的框,例如按照 David 的建議使用\mbox或例如 \alt而不是\only在定義中\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}

答案2

奇怪的是,我還沒有完全追蹤 beamer 和 tikzmark 在這裡所做的事情,但是添加了無形的什麼事在垂直模式下,無論是\color\label\tikzmark總是比較棘手且難以控制副作用。在所有情況下,解決方案都是在執行任何棘手的操作之前安全地進入水平模式。

如果你這樣做

\mbox{\balloon<3>{comment}{5}{6}%
\balloon<4>{comment}{1}{3}}%

然後該清單將出現在所有四張投影片的相同位置。空的 mbox 會產生一個虛假段落,將內容向下移動一點,但由於它是一個固定點並且在所有幻燈片上都相同,因此您可以根據需要在框後面使用空行和負 vspace。

相關內容