代码列表跨越多页,顶部有标题

代码列表跨越多页,顶部有标题

是否可以跨越一个lstlisting环境或lstlistinginput多个页面,使得标题在每个页面上重复(列表计数器保持不变),以及能够在以下页面上自定义它?

与 longtable 包提供的内容类似。

最小示例,其中标题仅在顶部显示一次,但应该显示两次。

\documentclass[12pt,a4paper]{article}
\usepackage[utf8x]{inputenc}
\usepackage{listings}
\usepackage{caption}

\begin{document}

\lstset{
breaklines=true,
breakatwhitespace=false,
xleftmargin=1em,
frame=single,
numbers=left,
numbersep=5pt
}

\begin{lstlisting}[language=C, caption=Example listing of code, label=lst:c1]

struct safe_buffer {
struct list_head node;

/* original request */
void    *ptr;
size_t  size;
int direction;

/* safe buffer info */
struct dmabounce_pool *pool;
void    *safe;
dma_addr_t  safe_dma_addr;
};

struct dmabounce_pool {
unsigned long   size;
struct dma_pool *pool;
#ifdef STATS
unsigned long   allocs;
#endif
};

struct dmabounce_device_info {
struct device *dev;
struct list_head safe_buffers;
#ifdef STATS
unsigned long total_allocs;
unsigned long map_op_count;
unsigned long bounce_count;
int attr_res;
#endif
struct dmabounce_pool   small;
struct dmabounce_pool   large;

rwlock_t lock;

int (*needs_bounce)(struct device *, dma_addr_t, size_t);
};

#ifdef STATS
static ssize_t dmabounce_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
return sprintf(buf, "%lu %lu %lu %lu %lu %lu\n",
device_info->small.allocs,
device_info->large.allocs,
device_info->total_allocs - device_info->small.allocs -
device_info->large.allocs,
device_info->total_allocs,
device_info->map_op_count,
device_info->bounce_count);
}

static DEVICE_ATTR(dmabounce_stats, 0400, dmabounce_show, NULL);
#endif

\end{lstlisting}
\end{document}

答案1

一个想法是使用mdframed包及其middleextra,secondextra键来添加连续的标题:

\documentclass[12pt,a4paper]{article}
\usepackage[a5paper]{geometry}% just for the example
\usepackage[utf8x]{inputenc}
\usepackage{listings}
\usepackage{caption}
\usepackage[framemethod=tikz]{mdframed}

\lstset{
breaklines=true,
breakatwhitespace=false,
xleftmargin=1em,
frame=single,
numbers=left,
numbersep=5pt,
}

\newcommand\mylstcaption{}

\surroundwithmdframed[
hidealllines=true,
middleextra={
  \node[anchor=west] at (O|-P)
    {\lstlistingname~\thelstlisting\  (Cont.):~\mylstcaption};},
secondextra={
  \node[anchor=west] at (O|-P)
    {\lstlistingname~\thelstlisting\  (Cont.):~\mylstcaption};},
splittopskip=2\baselineskip
]{lstlisting}

\begin{document}

\renewcommand\mylstcaption{Example listing of code}
\begin{lstlisting}[language=C, caption=\mylstcaption, label=lst:c1]

struct safe_buffer {
struct list_head node;

/* original request */
void    *ptr;
size_t  size;
int direction;

/* safe buffer info */
struct dmabounce_pool *pool;
void    *safe;
dma_addr_t  safe_dma_addr;
};

struct dmabounce_pool {
unsigned long   size;
struct dma_pool *pool;
#ifdef STATS
unsigned long   allocs;
#endif
};

struct dmabounce_device_info {
struct device *dev;
struct list_head safe_buffers;
#ifdef STATS
unsigned long total_allocs;
unsigned long map_op_count;
unsigned long bounce_count;
int attr_res;
#endif
struct dmabounce_pool   small;
struct dmabounce_pool   large;

rwlock_t lock;

int (*needs_bounce)(struct device *, dma_addr_t, size_t);
};

#ifdef STATS
static ssize_t dmabounce_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
return sprintf(buf, "%lu %lu %lu %lu %lu %lu\n",
device_info->small.allocs,
device_info->large.allocs,
device_info->total_allocs - device_info->small.allocs -
device_info->large.allocs,
device_info->total_allocs,
device_info->map_op_count,
device_info->bounce_count);
}

static DEVICE_ATTR(dmabounce_stats, 0400, dmabounce_show, NULL);
#endif

\end{lstlisting}

\end{document}

在此处输入图片描述

在每个lstlisting环境之前你都要\mylstcaption用标题文本重新定义。

对于\lstinpulisting,总体思路是相同的,但是这次使用\newmdenv;为了避免不必要的代码重复,定义了一种样式:

\documentclass[12pt,a4paper]{article}
\usepackage[a5paper]{geometry}% just for the example
\usepackage[utf8x]{inputenc}
\usepackage{listings}
\usepackage{caption}
\usepackage[framemethod=tikz]{mdframed}

\lstset{
breaklines=true,
breakatwhitespace=false,
xleftmargin=1em,
frame=single,
numbers=left,
numbersep=5pt,
}

\newcommand\mylstcaption{}

\mdfdefinestyle{mymdstyle}{
hidealllines=true,
middleextra={
  \node[anchor=west] at (O|-P)
    {\lstlistingname~\thelstlisting\  (Cont.):~\mylstcaption};},
secondextra={
  \node[anchor=west] at (O|-P)
    {\lstlistingname~\thelstlisting\  (Cont.):~\mylstcaption};},
splittopskip=2\baselineskip
}

\surroundwithmdframed[style=mymdstyle]{lstlisting}
\newmdenv[style=mymdstyle]{mdlisting}

\begin{document}

\renewcommand\mylstcaption{Example listing of code}
\begin{mdlisting}
\lstinputlisting[language=C, caption=\mylstcaption, label=lst:c1]{file}
\end{mdlisting}

\end{document}

更新

这是同样的想法,但是使用现在tcolorbox

\documentclass[12pt,a4paper]{article}
\usepackage[utf8x]{inputenc}
\usepackage[many]{tcolorbox}
\tcbuselibrary{listings}

\lstset{
  breaklines=true,
  breakatwhitespace=false,
  xleftmargin=1em,
  frame=single,
  numbers=left,
  numbersep=5pt,
}

\newtcblisting{TCBlisting}[1][]{
  breakable,
  enhanced,
  arc=0pt,
  outer arc=0pt,
  boxrule=0pt,
  colback=white,
  listing only,
  listing remove caption=false,
  listing options={#1},
  overlay middle and last={
  \node[anchor=south west,text width=\columnwidth] at (frame.north west)
    {\lstlistingname~\thelstlisting\  (Cont.):~\mylstcaption};
  }
}

\newcommand\mylstcaption{}

\begin{document}

\renewcommand\mylstcaption{Example listing of code with a long caption spanning several lines in a two-column document. this is just a test for the example.}
\begin{TCBlisting}[language=C,caption={\mylstcaption}]
struct safe_buffer {
struct list_head node;

/* original request */
void    *ptr;
size_t  size;
int direction;

/* safe buffer info */
struct dmabounce_pool *pool;
void    *safe;
dma_addr_t  safe_dma_addr;
};

struct dmabounce_pool {
unsigned long   size;
struct dma_pool *pool;
#ifdef STATS
unsigned long   allocs;
#endif
};

struct dmabounce_device_info {
struct device *dev;
struct list_head safe_buffers;
#ifdef STATS
unsigned long total_allocs;
unsigned long map_op_count;
unsigned long bounce_count;
int attr_res;
#endif
struct dmabounce_pool   small;
struct dmabounce_pool   large;

rwlock_t lock;

int (*needs_bounce)(struct device *, dma_addr_t, size_t);
};

#ifdef STATS
static ssize_t dmabounce_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
return sprintf(buf, "%lu %lu %lu %lu %lu %lu\n",
device_info->small.allocs,
device_info->large.allocs,
device_info->total_allocs - device_info->small.allocs -
device_info->large.allocs,
device_info->total_allocs,
device_info->map_op_count,
device_info->bounce_count);
}

static DEVICE_ATTR(dmabounce_stats, 0400, dmabounce_show, NULL);
#endif

\end{TCBlisting}
\end{document}
\begin{lstlisting}[language=C, caption=\mylstcaption, label=lst:c1]

struct safe_buffer {
struct list_head node;

/* original request */
void    *ptr;
size_t  size;
int direction;

/* safe buffer info */
struct dmabounce_pool *pool;
void    *safe;
dma_addr_t  safe_dma_addr;
};

struct dmabounce_pool {
unsigned long   size;
struct dma_pool *pool;
#ifdef STATS
unsigned long   allocs;
#endif
};

struct dmabounce_device_info {
struct device *dev;
struct list_head safe_buffers;
#ifdef STATS
unsigned long total_allocs;
unsigned long map_op_count;
unsigned long bounce_count;
int attr_res;
#endif
struct dmabounce_pool   small;
struct dmabounce_pool   large;

rwlock_t lock;

int (*needs_bounce)(struct device *, dma_addr_t, size_t);
};

#ifdef STATS
static ssize_t dmabounce_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
return sprintf(buf, "%lu %lu %lu %lu %lu %lu\n",
device_info->small.allocs,
device_info->large.allocs,
device_info->total_allocs - device_info->small.allocs -
device_info->large.allocs,
device_info->total_allocs,
device_info->map_op_count,
device_info->bounce_count);
}

static DEVICE_ATTR(dmabounce_stats, 0400, dmabounce_show, NULL);
#endif

\end{lstlisting}

\end{document}

在此处输入图片描述

答案2

您可以直接输入文件,即:

\lstinputlisting[language=C]{./Code/nameofthefile}

当然,您可以使用 在序言中设置所有内容\lstset,就像在 MWE 中一样。

相关内容