前言

要做这种东西:
在这里插入图片描述
Listings这个库是没提供这种功能的。我找了它的手册,只提供了个breaklines勉强和箭头有点关联,不过那个长这样:

在这里插入图片描述
问了 GPT,他说要用 Tikz 库。

注意事项

1 Tikz 的调用方法:newcommand

Tikz 库调用的时候不能直接扔 List 的代码里面,需要新定义一个command,然后你在哪里插入command哪里就是箭头的起点:
在这里插入图片描述

新定义的command是纯字母,不要添加任何数字,不然会报错如下(这个报错你绝对联想不到到底是什么原因导致的):
在这里插入图片描述

你可以定义多个command,并且给他们命不同的名字。

2 标号圆圈数字的添加方式:\large{\textcircled{\small{1}}}\normalsize

参考:怎样在LaTeX中方便输入带圆圈的数字

如果直接输入标号①,那么将解析不出来。

需要输入这个公式\large{\textcircled{\small{1}}}\normalsize,才可以完美的解析一个带圆圈的数字序号。

在这里插入图片描述

3 快速掌握 Tikz 箭头写法:插入点+相对位移+标号node

想要掌握写法,我觉得可以通过以下两张图掌握。我标了一些关键要素。

3.1 第一张图:插入点+相对位移

看了底下那张图和我的图片说明,你们应该能明白,它需要确定一个插入点以及知道每条边是怎么做出来的。

  1. 橙色的箭头代表新定义的 command,以及它的引用方式。可以看到,我们首先定义了一个 command,叫做 DrawArrow,然后在下面的 list 代码段中引用了它,并用特殊符号{**}框起来。
  2. 蓝色的箭头代表箭头的位置信息。可以看到代码中的(0,0)意味着实际渲染结果中的坐标原点,坐标原点就等同于在代码中的插入点。
  3. 绿色的数字(在pdf里面)代表了相对位移,可以看到我这个代码里面是从(0,0)点要求向右移动4个单位作第一条边,然后向下移动一个单位,再向左移动一个单位做第二、三条边。
    在这里插入图片描述
3.2 第二张图:标号node

看到这张图,你们应该能明白这个标号是怎么标在这个图片上的。

  1. node的参数:下图中绿色的圆圈圈出来了 node 的两个参数,xshift 和 yshift 是可以用来偏移标号的位置的,它可以让标号处于一个更加合适的位置,免得挡住了什么。

  2. node的添加方式:node 是添加在一个节点的后面的,只要加一个空格就能加上去。对比第一张图和第二张图,你们应该能看到我把 node 的位置移动了:在第一张图中,node 的位置是在第三条边的起点,而在这一张图中,node 的位置变成了第一条边的上方。总之,当你们想要加在不同的边上时可以把它放在其他的节点的后面,它的位置和这个边的真正的对应关系,没必要琢磨的那么清楚,反正代码能用就行。

在这里插入图片描述

4 警惕莫名其妙的GPT代码:pic cs:start#1-start

我让 GPT 来生成代码的时候,它生成的不太对劲,如下图所示,包含了这种([yshift=0.5ex]#1-1-1.west)代码,让我误以为我可以指定代码行。虽然确实是我先提问,让他在第一行到第三行加箭头的。但是他的代码中的这个标号实际上毫无用处,我也不知道他是怎么使用的。这个地方用坐标可以用,但是用行标好像是用不了的,而且也和插入点毫无关系。

在这里插入图片描述

完整代码

这里贴出能够实现前言里面贴出来的那张图的代码。

\documentclass{article}
\usepackage{listings}
\usepackage{tikz}
\usetikzlibrary{arrows.meta}

% Define a new command to draw an arrow from the first line to the third line with a label ①
\newcommand{\DrawArrow}[1]{
  \begin{tikzpicture}[remember picture, overlay]
    \draw[->, thick, red, >=Stealth] 
        ([yshift=0.5em](0,0) -- ++(4,0) node[midway, left, xshift=2em,yshift=1em]{\large{\textcircled{\small{1}}}\normalsize} -- ++(0,-1)
        -- ++(-1,0) ;
  \end{tikzpicture}
}

% Define another command to draw an arrow from the first line to the third line with a label ②
\newcommand{\DrawArrowTwo}[1]{
  \begin{tikzpicture}[remember picture, overlay]
    \draw[->, thick, blue, >=Stealth] 
        ([yshift=0.5em](0,0) -- ++(4,0) node[midway, left, xshift=2em,yshift=1em]{\large{\textcircled{\small{2}}}\normalsize} -- ++(0,-1)
        -- ++(-1,0) ;
  \end{tikzpicture}
}

\begin{document}

\begin{lstlisting}[escapeinside={(*}{*)}]
int main() {(*\DrawArrow{lstlisting}*)
    printf("Hello, World!\n");(*\DrawArrowTwo{lstlisting}*)
    return 0;
}
\end{lstlisting}

\end{document}

效果如下:
在这里插入图片描述

本账号所有文章均为原创,欢迎转载,请注明文章出处:https://blog.csdn.net/qq_46106285/article/details/140330868。百度和各类采集站皆不可信,搜索请谨慎鉴别。技术类文章一般都有时效性,本人习惯不定期对自己的博文进行修正和更新,因此请访问出处以查看本文的最新版本。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐