我正在使用列表来显示源代码。我想标记/括起此源代码的某些行,以便我可以调出每个部分并描述它们的作用。
下面是我想要做的一个例子:
这里有一些包含示例代码的乳胶。代码中的 /**** SECTION X ****/ 注释只是为了表示我希望在此特定列表中的各个部分的位置。
\documentclass{article}
\usepackage{listings}
\begin{document}
\begin{lstlisting}
List<Point2D> data = // ...
/**** SECTION A ****/
val x = scaleBand<Int> {
rangeRound(listOf(0.0, width))
domain(data.indices.toList())
padding(0.1)
}
/**** SECTION B ****/
val y = scaleLinear<Double> {
domain(listOf(height, 0))
range(listOf(0, data.maxBy { it.y })
}
/**** SECTION C ****/
val bar = rect<Point2D> {
width(x.bandwidth)
height { d, _ -> height - y(d.y) }
fill(Color.STEELBLUE)
}
/**** SECTION D ****/
val root = Group()
root.selectAll<Point2D>(".bar")
.data(data)
.enter()
.append { d, _, _ -> bar(d) }
.translateX { _, i, _ -> x(i) }
.translateY { d, _, _ -> y(d.y) }
\end{lstlisting}
\end{document}
答案1
基于休斯评论建议使用tikzmark
,并找到多行括号解决方案这里,我得出了以下结论:
\documentclass{article}
\usepackage{enumitem}
\usepackage{tikz}
\usepackage{listings}
\usepackage{xparse}
\usetikzlibrary{calc,decorations.pathreplacing}
\newcommand{\tikzmark}[1]{%
\tikz[overlay,remember picture,baseline] \node [anchor=base] (#1) {};}
\newcommand*{\BracektStubSize}{0.5em}%
\NewDocumentCommand\LeftBracket{%
O{}% #1 = draw options
O{0pt}% #2 = shift to be applied (optional, for use with nested braces)
m% #3 = top \tikzmark name
m% #4 = bottom \tikzmark name
m% #5 = node text
}{%
\begin{tikzpicture}[overlay,remember picture,baseline]
\coordinate (Top Start of Bracket) at ([shift={(#2-15pt,5pt)}]#3.north east);
\coordinate (Bottom Start of Bracket) at ([shift={(#2-15pt,2pt)}]#4.south east);
\draw[thick, #1]
(Top Start of Bracket) --++(-\BracektStubSize,0)
|-(Bottom Start of Bracket) ;
\node[xshift=-5pt, align=left, anchor=east, #1]
at ($(Bottom Start of Bracket)!0.5!(Top Start of Bracket)$) {#5};
\end{tikzpicture}
}
\begin{document}
\begin{lstlisting}[escapechar=\&]
List<Point2D> data = // ...
&\tikzmark{Mark A}&val x = scaleBand<Int> {
rangeRound(listOf(0.0, width))
domain(data.indices.toList())
padding(0.1)
&\tikzmark{End A}&}
&\tikzmark{Mark B}&val y = scaleLinear<Double> {
domain(listOf(height, 0))
range(listOf(0, data.maxBy { it.y })
&\tikzmark{End B}&}
&\tikzmark{Mark C}&val bar = rect<Point2D> {
width(x.bandwidth)
height { d, _ -> height - y(d.y) }
fill(Color.STEELBLUE)
&\tikzmark{End C}&}
&\tikzmark{Mark D}&val root = Group()
root.selectAll<Point2D>(".bar")
.data(data)
.enter()
.append { d, _, _ -> bar(d) }
.translateX { _, i, _ -> x(i) }
&\tikzmark{End D}& .translateY { d, _, _ -> y(d.y) }
\end{lstlisting}
\LeftBracket[black][0pt]{Mark A}{End A}{a}
\LeftBracket[black][0pt]{Mark B}{End B}{b}
\LeftBracket[black][0pt]{Mark C}{End C}{c}
\LeftBracket[black][0pt]{Mark D}{End D}{d}
\end{document}
其结果为: