我正在为我的班级制作一些讲座幻灯片,有时我需要标记 C/C++ 程序的不同组件。为此,我参考了这篇文章如何在列表中画箭头来解释位置关联?但还是没能搞清楚。
\documentclass{beamer}
\usepackage{listings}
\usepackage{fancybox}
\usepackage{tikz}
\usetikzlibrary{decorations.text,calc}
\mode<presentation> {
\usetheme{Madrid}
}
%% This is to put the lstlisting in the center but horizontally
\makeatletter
\newenvironment{CenteredBox}{%
\begin{Sbox}}{% Save the content in a box
\end{Sbox}\centerline{\parbox{\wd\@Sbox}{\TheSbox}}}% And output it centered
\makeatother
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand{\tikzmark}[2]{%
\tikz[overlay,remember picture] \node[text=black,
inner sep=2pt] (#1) {#2};}
\newcommand{\VerticalShiftForArrows}{0.0em,+2.75ex}%
\newcommand{\VerticalShiftForBar}{0.0em,+2.0ex}%
\newcommand{\Stub}{0.0em,-0.6ex}%
\newcommand{\DrawOverBar}[3][]{%
\coordinate (top left) at ($(#2) +(\VerticalShiftForBar)$);
\coordinate (start) at ($(top left) +(\Stub)$);
\coordinate (top right) at ($(#3) +(\VerticalShiftForBar)$);
\coordinate (end) at ($(top right)+(\Stub)$);
\draw [#1] (start) -- (top left) -- (top right) -- (end);
}%
\newcommand{\DrawArrows}[3][]{%
\coordinate (Start Mid) at ($(#2Left)!0.5!(#2Right) + (\VerticalShiftForArrows)$);
\coordinate (End Mid) at ($(#3Left)!0.5!(#3Right) + (\VerticalShiftForArrows)$);
\draw[-stealth, thick, #1] (Start Mid) to (End Mid);
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\begin{frame}[fragile]
\frametitle{Functions}
\lstset{language=C,
basicstyle=\fontsize{11pt}{9.2}\selectfont\ttfamily,
keywordstyle=\color{blue}\ttfamily,
stringstyle=\color{red}\ttfamily,
commentstyle=\color{green}\ttfamily,
morecomment=[l][\color{magenta}]{\#},
emph={raise_to_power},emphstyle=\textbf
}
\begin{itemize}
\item \tikzmark{bLeft}{}Function name\tikzmark{bRight}{}
\end{itemize}
\begin{figure}[thp]
\begin{CenteredBox}
\begin{lstlisting}[language=c,escapeinside={(*@}{@*)},basicstyle=\ttfamily]
int (*@\tikzmark{aLeft}{}@*)raise_to_power(*@\tikzmark{aRight}{}@*) (int base, int exponent)
{
int result = 1;
for (i=0; i<exponent; i=i+1)
{
result = result * base;
}
return result;
}
\end{lstlisting}
\end{CenteredBox}
\end{figure}
\begin{tikzpicture}[overlay,remember picture]
\renewcommand{\VerticalShiftForBar}{0.0em,-0.8ex}%
\renewcommand{\Stub}{0.0em,+0.6ex}%
\DrawOverBar[-, red, thick]{aLeft.south}{aRight.south}
\renewcommand{\VerticalShiftForArrows}{0.0em,0ex}
\DrawArrows[red,in=20,out=160]{b}{a}
\end{tikzpicture}
\end{frame}
\end{document}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:
可以看出,箭头确实在正确的中点开始和结束,但看起来有点丑。我该如何微调坐标。请提出是否有其他好的解决方案。