我的最小示例如下:
\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{multicol}
\lstdefinelanguage{Cpp}{
keywords={auto, double, int, struct, break, else, long,
switch, case, enum, register, typedef, char, extern,
return, union, continue, for, signed, void, do, if, static,
while, default, goto, sizeof, volatile, const, float, short, unsigned, NULL, \#include, \#define},
sensitive=true,
alsoletter = {\#},
comment=[l]{//},
morecomment=[s]{/*}{*/},
morestring=[b]',
morestring=[b]"
}
\lstdefinestyle{mystyle}{
% Basic design
basicstyle=\ttfamily\linespread{1}\small,
frame=t,
multicols=2,
%framesep=5pt,
framerule=.5pt,
rulecolor=\color{violet},
abovecaptionskip=0pt,
belowcaptionskip=5pt,
% Code design
keywordstyle=\color{codecolorkeywords},
commentstyle=\color{codecolorcomments},
stringstyle=\color{codecolorstrings},
numberstyle=\small\color{gray},
breakatwhitespace=false,
breaklines=true,
captionpos=t,
keepspaces=true,
% Line numbers
numbers=left,
numbersep=2pt,
xleftmargin=.5em,
stepnumber=1,
firstnumber=1,
numberfirstline=true,
% Code
tabsize=4,
showspaces=false,
showstringspaces=false,
showtabs=false,
breaklines=true,
}
\lstset{style=mystyle}
\begin{document}
\lstset{language=Cpp}
\begin{lstlisting}[frame=tb, caption={caption}]
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void swap(int *q, int a, int b) {
int tmp = q[a];
q[a] = q[b];
q[b] = tmp;
}
void quick_sort(int *q, int l, int r)
{
if (l >= r) {
return;
}
int x = q[(l + r) >> 1];
int i = l - 1;
int j = r + 1;
while (i < j) {
do i++; while (q[i] < x);
do j--; while (q[j] > x);
if (i < j) {
swap(q, i, j);
}
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
\end{lstlisting}
\end{document}
但我希望得到从左到右的多列框架线,而不是文本宽度的一半。并且多列环境的第二列将向下移动,以避免与扩展框架线重叠。
任何答案都会有帮助。非常感谢。
答案1
环境multicols
被添加到 和Init
中DeInit
的钩子中listings
。标题和框架被添加到相同的钩子中,但在 multicol 代码之后,因此标题和框架最终位于列内。
您可以将 multicol 代码移至InitVars
和ExitVars
钩子,它们分别在 之后Init
和 之前执行DeInit
。参见清单开发人员指南所有钩子的准确顺序。
实现这一点的快速方法是从选项multicols
中删除键lstset
,而是对钩子中的列数进行硬编码。
请注意,multicols 出现在 Init 和 DeInit 中以及标题之前可能是有原因的,因此这种修改在某些时候可能会导致问题。
OP 指出的一个问题是\lstinline
片段现在也是多列的。一个快速的解决方法是引入一个新的 if 并使多列以这个 if 为条件。这需要\applymulticoltrue
在代码之前有一个明确的语句,说明您希望它分为两列,并\applymulticolfalse
在内联代码(或单列常规列表)之前有一个语句。这是一个开关,因此您只需设置一次,然后它将应用于所有后续列表,直到您更改该值。
梅威瑟:
\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}
\usepackage{multicol}
\colorlet{codecolorkeywords}{black}
\colorlet{codecolorcomments}{black}
\colorlet{codecolorstrings}{black}
\lstdefinelanguage{Cpp}{
keywords={auto, double, int, struct, break, else, long,
switch, case, enum, register, typedef, char, extern,
return, union, continue, for, signed, void, do, if, static,
while, default, goto, sizeof, volatile, const, float, short, unsigned, NULL, \#include, \#define},
sensitive=true,
alsoletter = {\#},
comment=[l]{//},
morecomment=[s]{/*}{*/},
morestring=[b]',
morestring=[b]"
}
\lstdefinestyle{mystyle}{
% Basic design
basicstyle=\ttfamily\linespread{1}\small,
frame=t,
%multicols=2,
%framesep=5pt,
framerule=.5pt,
rulecolor=\color{violet},
abovecaptionskip=0pt,
belowcaptionskip=5pt,
% Code design
keywordstyle=\color{codecolorkeywords},
commentstyle=\color{codecolorcomments},
stringstyle=\color{codecolorstrings},
numberstyle=\small\color{gray},
breakatwhitespace=false,
breaklines=true,
captionpos=t,
keepspaces=true,
% Line numbers
numbers=left,
numbersep=2pt,
xleftmargin=.5em,
stepnumber=1,
firstnumber=1,
numberfirstline=true,
% Code
tabsize=4,
showspaces=false,
showstringspaces=false,
showtabs=false,
breaklines=true,
}
\lstset{style=mystyle}
\newif\ifapplymulticol
\makeatletter
\lst@AddToHook{InitVars}{\ifapplymulticol\edef\lst@next{\noexpand\multicols{2}}\expandafter\lst@next\fi}
\lst@AddToHook{ExitVars}{\ifapplymulticol\def\lst@next{\global\let\@checkend\@gobble
\endmulticols
\global\let\@checkend\lst@@checkend}
\expandafter\lst@next\fi}
\makeatother
\begin{document}
\lstset{language=Cpp}
\applymulticoltrue
\begin{lstlisting}[frame=tb, caption={caption}]
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void swap(int *q, int a, int b) {
int tmp = q[a];
q[a] = q[b];
q[b] = tmp;
}
void quick_sort(int *q, int l, int r)
{
if (l >= r) {
return;
}
int x = q[(l + r) >> 1];
int i = l - 1;
int j = r + 1;
while (i < j) {
do i++; while (q[i] < x);
do j--; while (q[j] > x);
if (i < j) {
swap(q, i, j);
}
}
quick_sort(q, l, j);
quick_sort(q, j + 1, r);
}
\end{lstlisting}
\applymulticolfalse
Some text with inline listing \lstinline{i = i + 1;} in a sentence
Some text with inline listing \lstinline{do i++; while (q[i] < x); do j--; while (q[j] > x);} in a longer sentence
\end{document}
结果: