我\llap
在自定义环境中使用 在文档左边距中写入一些文本,与代码列表对齐(使用 完成代码列表lstlisting
)。每当代码列表位于页面底部时,标签llap
都会停留在上一页,而代码列表会移动到下一页。下面显示了一个示例(深色矩形代表文档的边距):
此示例中的问题在于Out [9]:
标签位于页面底部边距以下,而相关的代码列表位于下一页。
我需要在多个页面上分隔长代码列表,所以我不想将标签和列表都包装在里面minipage
(这样可以,但不允许在代码列表内分页)。
有什么方法可以llap
尊重底部边距吗?下面是 MWE。
\documentclass{article}
\usepackage{listings}
\usepackage[breakable]{tcolorbox}
\usepackage{ifthen}
\usepackage{xcolor}
\usepackage{lipsum}
\usepackage{showframe}
% custom colors
\definecolor{incolor}{HTML}{868686}
\definecolor{outcolor}{HTML}{868686}
\definecolor{cellbackground}{HTML}{F7F7F7}
% prompt
\makeatletter
\newcommand{\boxspacing}{\kern\kvtcb@left@rule\kern\kvtcb@boxsep}
\makeatother
\newcounter{cellcounter}
\lstdefinestyle{style}{
language=Python,
aboveskip=-1.4\medskipamount,
belowskip=0.5em,
backgroundcolor=\color{cellbackground},
numbers=none,
}
\makeatletter
\lst@Key{showprompt}{true}{\def\showprompt{#1}}
\lst@Key{promptnumber}{\thecellcounter}{\def\promptnumber{#1}}
\makeatother
\lstnewenvironment{code}[1][]
{
\lstset{
style=style,
#1
}
\addtocounter{cellcounter}{1}
\ifthenelse{\boolean{\showprompt}}
{\footnotesize\ttfamily\llap{{\color{outcolor}Out\,[\thecellcounter]:\hspace{3pt}\boxspacing}}}
{\phantom{\footnotesize\ttfamily\llap{{\color{outcolor}Out\,[\thecellcounter]:\hspace{3pt}\boxspacing}}}}
}{
}
%----------------------------------------------------------------------------------------
% DOCUMENT
%----------------------------------------------------------------------------------------
\setlength\parindent{0pt}
\setlength\parskip{83pt}
\begin{document}
\lipsum[70]
\lipsum[70]
\lipsum[70]
\lipsum[66]
\begin{code}
df.head()
\end{code}
\begin{code}
0 False False ...
1 False False ...
3 False False ...
4 False False ...
... ... ... ...
9064 False False ...
9065 False False ...
9066 False False ...
9067 False False ...
\end{code}
\end{document}
答案1
我认为使用在 的第二个强制参数中明确插入标签的方法来实现这一点会很棘手\lstnewenviroment
。这与 无关\llap
,而是因为此参数用于设置环境而不是插入文本。在列表真正开始之前明确允许分页符,即在插入标签之后。
但是,您可以通过将标签放在字段中来实现相同的效果title
。由于标题后不允许分页符,因此您的标签将始终与第一行内容显示在同一页上。我设置belowcaptionskip=-\baselineskip
字段以使标题与内容位于同一行,并将标签放在\makebox
宽度为的范围内\linewidth
,因为否则它将居中。
这是您的 MWE 的修改版本。更改标记为ADDED
或REMOVED
。
\documentclass{article}
\usepackage{listings}
\usepackage[breakable]{tcolorbox}
\usepackage{ifthen}
\usepackage{xcolor}
\usepackage{lipsum}
\usepackage{showframe}
% custom colors
\definecolor{incolor}{HTML}{868686}
\definecolor{outcolor}{HTML}{868686}
\definecolor{cellbackground}{HTML}{F7F7F7}
% prompt
\makeatletter
\newcommand{\boxspacing}{\kern\kvtcb@left@rule\kern\kvtcb@boxsep}
\makeatother
\newcounter{cellcounter}
%% Following commands are ADDED:
\newcommand*\hbotcodefont{\footnotesize\ttfamily}
\newcommand*\hbotoutlabeltext[1]{Out\,[#1]:\hspace{3pt}}
\newcommand*{\hbotOutTitle}{%
\hbotcodefont
\ifthenelse{\boolean{\showprompt}}{%
\makebox[\linewidth][l]{\llap{%
\color{outcolor}%
\hbotoutlabeltext{\thecellcounter}\boxspacing
}}%
}{}%
}
\lstdefinestyle{style}{
language=Python,
title=\hbotOutTitle, %% <- ADDED
belowcaptionskip=-\baselineskip, %% <- ADDED
%% <- REMOVED aboveskip=...
backgroundcolor=\color{cellbackground},
numbers=none,
}
\makeatletter
\lst@Key{showprompt}{true}{\def\showprompt{#1}}
\lst@Key{promptnumber}{\thecellcounter}{\def\promptnumber{#1}}
\makeatother
\lstnewenvironment{code}[1][]
{
\lstset{style=style,#1}
\hbotcodefont
\addtocounter{cellcounter}{1}
%% <- REMOVED label insertion code
}{
}
%----------------------------------------------------------------------------------------
% DOCUMENT
%----------------------------------------------------------------------------------------
\setlength\parindent{0pt}
\setlength\parskip{83pt}
\begin{document}
\lipsum[70]
\lipsum[70]
\lipsum[70]
\lipsum[66]
\begin{code}
df.head()
\end{code}
\begin{code}
0 False False ...
1 False False ...
3 False False ...
4 False False ...
... ... ... ...
9064 False False ...
9065 False False ...
9066 False False ...
9067 False False ...
\end{code}
\end{document}
答案2
按照@David Carlisle 的回答这个帖子正如我在评论中所说,您可以在环境定义中\llap
替换。\makebox[0pt][r]
以下是您提出的代码,其中有两处进行了更改:
\llap
替换(两次)为\makebox[0pt][r]
- 删除了
\lipsum[xx]
几个blabla\par
以便在分页符测试中获得更高的精度。
您可以取消部分注释blabla\par
以获得注释中描述的效果:
我希望这能帮助你解决问题。
这个“答案”只是为了向您展示代码,以便您可以告诉我它是否按预期工作。
\documentclass{article}
\usepackage{listings}
\usepackage[breakable]{tcolorbox}
\usepackage{ifthen}
\usepackage{xcolor}
\usepackage{lipsum}
\usepackage{showframe}
% custom colors
\definecolor{incolor}{HTML}{868686}
\definecolor{outcolor}{HTML}{868686}
\definecolor{cellbackground}{HTML}{F7F7F7}
% prompt
\makeatletter
\newcommand{\boxspacing}{\kern\kvtcb@left@rule\kern\kvtcb@boxsep}
\makeatother
\newcounter{cellcounter}
\lstdefinestyle{style}{
language=Python,
aboveskip=-1.4\medskipamount,
belowskip=0.5em,
backgroundcolor=\color{cellbackground},
numbers=none,
}
\makeatletter
\lst@Key{showprompt}{true}{\def\showprompt{#1}}
\lst@Key{promptnumber}{\thecellcounter}{\def\promptnumber{#1}}
\makeatother
\lstnewenvironment{code}[1][]
{
\lstset{
style=style,
#1
}
\addtocounter{cellcounter}{1}
\ifthenelse{\boolean{\showprompt}}
{\footnotesize\ttfamily\makebox[0pt][r]{{\color{outcolor}Out\,[\thecellcounter]:\hspace{3pt}\boxspacing}}}
{\phantom{\footnotesize\ttfamily\makebox[0pt][r]{{\color{outcolor}Out\,[\thecellcounter]:\hspace{3pt}\boxspacing}}}}
}{
}
%----------------------------------------------------------------------------------------
% DOCUMENT
%----------------------------------------------------------------------------------------
\setlength\parindent{0pt}
\begin{document}
\lipsum[1-4]
blabla\par
blabla\par
blabla\par
blabla\par
blabla\par
blabla\par
blabla\par
blabla\par
blabla\par % "Out [1]" and the first two lines of "Out [2]" on page 1, the rest on page 2
% blabla\par % "Out [1]" on the penultimate line of page 1 (last line blank)
% blabla\par % Only "Out [1]" on last line of page 1
% blabla\par % Everything on page 2
\begin{code}
df.head()
\end{code}
\begin{code}
0 False False ...
1 False False ...
3 False False ...
4 False False ...
... ... ... ...
9064 False False ...
9065 False False ...
9066 False False ...
9067 False False ...
\end{code}
\begin{code}
blabla
\end{code}
\end{document}