我想注释代码列表如下:
以下是我迄今为止尝试过的方法。我有点担心必须使用 raisebox,这样箭头尖端就不会指向线的底部。我该如何避免这种硬编码?我也很感激任何有关改进的建议,以便更容易处理屏幕截图中所示的几种注释。
如果我能指定以下内容,就能获得所需的结果,那就太好了:
源线末端与箭头尖端之间的距离
箭头的水平线长度和垂直线长度(以及垂直线是向上还是向下)
以及文本节点的位置(垂直线的右侧或左侧以及文本节点与顶部或底部的垂直对齐。
\documentclass[twoside, openright, 10pt]{book}
\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{arrows.meta, tikzmark}
\begin{document}
\chapter{TiKz}
\begin{lstlisting}[caption={[MeetKarel]{MeetKarel}}, label={lst:meet_karel}, escapechar=ß]
import stanford.karel.Karel;
public class MeetKarel extends Karel {
public void run() {
move();
move();
move();
ß\tikzmark{b}ßpickBeeper();ß\raisebox{2.6pt}{\tikzmark{a}}ß
turnLeft();
move();
move();
turnLeft();
turnLeft();
turnLeft();ß\raisebox{2.6pt}{\tikzmark{c}}ß
move();
putBeeper();
move();
}
}
\end{lstlisting}
\begin{tikzpicture}[remember picture,overlay]
\draw([shift={(12ex,10ex)}] pic cs:a) ++ (0.05, 0) % shift just a little to the right
% set inner and outer to 0 so that text is alighed with the beginning of the vertical line
node[inner sep=0,outer sep=0, fill=yellow!80!black,text width=5cm, anchor= north west]
{Shifted a little above so that the arrow head points to the middle of the line.};
\draw[thin, gray, arrows = {-Stealth[inset=0pt, angle=45:7pt]}]
([shift={(12ex,10ex)}] pic cs:a) --
([shift={(12ex,0ex)}] pic cs:a) --
([shift={(0ex,0ex)}] pic cs:a);
\draw([shift={(12ex,-10ex)}] pic cs:c) ++ (0.05, -0.05) % shift just a little to the right and down
% set inner and outer to 0 so that text is alighed with the beginning of the vertical line
node[inner sep=0,outer sep=0, fill=yellow!80!black,text width=5cm, anchor= south west]
{I want to align base line of this text to the `c` node nicely. };
\draw[thin, gray, arrows = {-Stealth[inset=0pt, angle=45:7pt]}]
([shift={(12ex,-10ex)}] pic cs:c) --
([shift={(12ex,0ex)}] pic cs:c) --
([shift={(0ex,0ex)}] pic cs:c);
\end{tikzpicture}
\end{document}
答案1
这是您的代码的稍微简化的版本。
- 通过使用 tikzmark 特殊列表库,您不需要在代码中指定 tikzmarks,它们都为您提供了。
- 箭头
(0.5,.5ex)
从相应的 tikzmarks 处开始。.5ex
的高度是 的一半x
,并且对我来说看起来垂直高度很好。 - 线条和节点一起绘制,并
-|
使用路径构造使线条很好地弯曲。 - 在标签节点上添加一点点
outer xsep
,使它们远离连接线。实现相同效果的其他方法似乎会导致箭头放置问题。
所有这些都是为了使代码更短。各种数字可以硬编码到样式中,使其更简单、更灵活。
\documentclass[twoside, openright, 10pt]{book}
%\url{https://tex.stackexchange.com/q/657375/86}
\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{
arrows.meta,
tikzmark,
calc,
positioning
}
\usetikzmarklibrary{listings}
\begin{document}
\chapter{Ti\emph{k}Z}
\begin{lstlisting}[
caption={[MeetKarel]{MeetKarel}},
label={lst:meet_karel},
name=karel,
escapechar=ß
]
import stanford.karel.Karel;
public class MeetKarel extends Karel {
public void run() {
move();
move();
move();
pickBeeper();
turnLeft();
move();
move();
turnLeft();
turnLeft();
turnLeft();
move();
putBeeper();
move();
}
}
\end{lstlisting}
\begin{tikzpicture}[
remember picture,
overlay,
annotation/.style={
inner sep=0pt,
outer sep=0pt,
outer xsep=1mm,
fill=yellow!80!black,
text width=5cm
},
>={Stealth[inset=0pt, angle=45:7pt]}
]
\draw[<-] (pic cs:line-karel-7-end) ++(.5,.5ex) -| ++(2,1.5)
node[annotation, below right]
{Shifted a little above so that the arrow head points to the middle of the line.};
\draw[<-] (pic cs:line-karel-13-end) ++(0.5,.5ex) -| ++(2,-1)
node[annotation, above right]
{I want to align base line of this text to the `c` node nicely. };
\end{tikzpicture}
\end{document}