我正在尝试使用以下代码这个答案精确控制列表中分页符的出现位置。我的问题有两个方面:似乎我无法将命令放在它们自己的行上,而且它们的效果似乎偏离了一行。
让我解释一下我的意思。在下面的文件中,清单如下所示:
\begin{lstlisting}
import Clash.Prelude
import qualified Data.List as L
showSS :: Vec 7 Bool -> String
showSS (a :> b :> c :> d :> e :> f :> g :> Nil) = unlines . L.concat $
[ L.replicate 1 $ horiz a
, L.replicate 3 $ vert f b
, L.replicate 1 $ horiz g
, L.replicate 3 $ vert e c
, L.replicate 1 $ horiz d
]
`\allowpgbr`
where
horiz True = " ###### "
horiz False = " ...... "
vert b1 b2 = part b1 <> " " <> part b2
where
part True = "#"
part False = "."
\end{lstlisting}
我希望这会导致列表只能在右侧有分页符前行where
。但是,我在行前得到了一个空行where
(我猜是因为`\allowpgbr`
我不知道如何转义行尾?),然后我得到了where
,并且然后我得到了一个分页符:
所以我的问题是,我该如何改变它,以便之前没有空行where
,并且where
已经在新页面上(如果需要分页符)?
完整代码:
\documentclass{memoir}
\usepackage{listings}
\lstset%
{ basicstyle=\ttfamily
, escapeinside=``
}
\newif\ifpgbrallowed
\newcommand\allowpgbr
{\global\pgbrallowedtrue}
\newcommand\forbidpgbr
{\global\pgbrallowedfalse}
\makeatletter
\lst@AddToHook{PreInit}{\forbidpgbr}
\lst@AddToHook{EveryLine}{%
\ifpgbrallowed%
\forbidpgbr%
\else
\nopagebreak%
\fi
}
\makeatother
\usepackage{blindtext}
\begin{document}
\blindtext[3]
\begin{lstlisting}
import Clash.Prelude
import qualified Data.List as L
showSS :: Vec 7 Bool -> String
showSS (a :> b :> c :> d :> e :> f :> g :> Nil) = unlines . L.concat $
[ L.replicate 1 $ horiz a
, L.replicate 3 $ vert f b
, L.replicate 1 $ horiz g
, L.replicate 3 $ vert e c
, L.replicate 1 $ horiz d
]
`\allowpgbr`
where
horiz True = " ###### "
horiz False = " ...... "
vert b1 b2 = part b1 <> " " <> part b2
where
part True = "#"
part False = "."
\end{lstlisting}
\end{document}
答案1
我还不知道如何避免空行,但至少我弄清楚了修复 off-by-one 错误的方法是将可选的换行符回调从EveryLine
移到EOL
:
\lst@AddToHook{EOL}{%
\ifpgbrallowed%
\forbidpgbr%
\else
\nopagebreak%
\fi
}