Latex 和代码块:如何以这种方式标记语句?

Latex 和代码块:如何以这种方式标记语句?

我想给你看一个本书采用了很好的技巧描述代码清单(参见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} 

enter image description here

相关内容