我想给你看一个本书采用了很好的技巧描述代码清单(参见PDF的第6和7页——本书的116和117),其中相关语句用特殊的“标记”标记。
你能告诉我如何在 Latex 中复制这种技术吗?
我知道数据包listings
允许转义(因此可以在代码列表中插入 Latex 代码),但我无法弄清楚如何排版标记(希望在列表本身内自动编号)——在书中,标记的编号在每个列表处环绕。
我在想类似以下的事情:
% preamble
\lstset{
(...)
escapechar=§,
}
% Definition for the command `mycoderef`
(...)
% begin document
% Marked listing
\begin{lstlisting}[language=c,label=src-hello-c]
#include <stdio.h>
int
main(int argc, char *argv[])
{
§\mycoderef{mylabel1}§printf("Hello, World!\n");
return 0;
}
\end{lstlisting}
% The text refers to the marked statement
The hello message is printed with the statement printf\autoref{mylabel1}.
谢谢,
乔治奥
答案1
您可以这样做。我没有费心打印与您书中完全相同的标记,但我认为这会相当容易。请注意,计数器已初始化一次;如果您有更多列表,它将保留先前的值。这也应该得到修复。
\documentclass[11pt]{article}
\usepackage{listings}
\lstset{basicstyle=\normalsize\ttfamily,
showstringspaces=false,
basewidth=1.2ex,
fontadjust=true,
escapechar=§}
\newcount\mymark
\makeatletter
\def\mycoderef#1{%
\global\advance\mymark by 1%
\protected@write \@auxout {}{\string \newlabel {#1}{{\the\mymark}{}}}%
\makebox[0pt][r]{{\scriptsize\bfseries \the\mymark~}}%
}
\makeatother
\begin{document}
\begin{lstlisting}[language=c,label=src-hello-c]
#include <stdio.h>
int main(int argc, char *argv[])
{
§\mycoderef{mylabel1}§printf("Hello world!\n");
printf("Love, peace and harmony!\n");
§\mycoderef{mylabel2}§return 0;
}
\end{lstlisting}
The hello message is printed with the statement printf at \ref{mylabel1}.
Yet another message is printed similarly.
Then, the program returns with \ref{mylabel2}.
\end{document}
附录
这是使用 TikZ 重新创建盒装数字的一种非常基本的方法。
\documentclass[11pt]{article}
\usepackage{tikz}
\usepackage{listings}
\lstset{basicstyle=\normalsize\ttfamily,
showstringspaces=false,
basewidth=1.2ex,
fontadjust=true,
escapechar=§}
\newcommand{\roundbox}[1]{%
\tikz[baseline=-1ex]%
\node[%
inner sep=1.5pt,
draw=black,
fill=black,
text=white,
rounded corners=2.5pt]{#1};}
\newcommand{\boxref}[1]{%
\begingroup%
\scriptsize\ttfamily%
\roundbox{\ref{#1}}%
\endgroup%
}
\newcount\mymark
\makeatletter
\def\mycoderef#1{%
\global\advance\mymark by 1%
\protected@write \@auxout {}{\string \newlabel {#1}{{\the\mymark}{}}}%
\makebox[0pt][r]{{\scriptsize\roundbox{\the\mymark}~}}%
}
\makeatother
\begin{document}
\begin{lstlisting}[language=c,label=src-hello-c]
#include <stdio.h>
int main(int argc, char *argv[])
{
§\mycoderef{mylabel1}§printf("Hello world!\n");
printf("Love, peace and harmony!\n");
§\mycoderef{mylabel2}§return 0;
}
\end{lstlisting}
The hello message is printed with the statement printf at \boxref{mylabel1}.
Yet another message is printed similarly.
Then, the program returns with \boxref{mylabel2}.
\end{document}