是否可以跨越一个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 中一样。