答案1
使用 TeX 通常可以很容易地防止某些事情发生后发生中断,但防止中断前有些事情通常是不可能的。在这里,我们可以挂接到listings
处理命令中,在结束当前行之前检查下一行,这样\penalty
如果下一行包含结束括号,我们就可以插入一个。
警告:这填充使用肮脏的伎俩,所以如果未来的更新或“有趣”的输入以某种方式破坏它,我不会感到惊讶。
\documentclass{article}
\usepackage[paperheight=2.2in, paperwidth=6in, showframe]{geometry}
\usepackage{listings}
\lstset{language=Java}
\ExplSyntaxOn\makeatletter
% Define some constant tokens for later comparisons
\tl_new:N \c__max_end_env_tl
\regex_replace_all:nnN { } {
\cA(\\ end \{ lstlisting \})
} \c__max_end_env_tl
\tl_new:N \c__max_close_brace_tl
\regex_replace_all:nnN { } {
\cA(\})
} \c__max_close_brace_tl
% Inside an lstlisting environment, at the end of each line, we grab the next
% line and process it.
\def\lst@InitFinalize{
\__max_make_newline:n {
\__max_process:n { ##1 }
\tl_if_eq:NnT \c__max_end_env_tl { ##1 } {
\__max_reset_newline:
}
\lst@MProcessListing ##1 ##2
}
}
% Process the line. Here, we insert an infinite penalty if the next line
% contains a closing brace.
\newif\ifpreventbreakbeforebrace
\cs_new:Nn \__max_process:n {
\ifpreventbreakbeforebrace
\tl_if_in:nVTF { #1 } \c__max_close_brace_tl {
\hook_gput_next_code:nn { para / after } {
\penalty20000
}
}
\fi
}
% Auxiliary macros.
\cs_new:Nn \__max_make_newline:n {
\exp_args:NNo \exp_args:No
\__max_make_newline_aux_i:nn
{ \char_generate:nn { 13 } { 13 } }
{ #1 }
}
\cs_new:Nn \__max_make_newline_aux_i:nn {
\cs_set:Nn \__max_make_newline_aux_ii:nn { #2 } { #1 }
\cs_set:Npn #1 ##1 #1 {
\__max_make_newline_aux_ii:nn { ##1 } { #1 }
}
}
\cs_new:Nn \__max_reset_newline: {
\char_set_active_eq:nN { 13 } \scan_stop:
}
\makeatother\ExplSyntaxOff
\begin{document}
\preventbreakbeforebracefalse
\begin{lstlisting}
public static void main(String[] args) {
System.out.println("Hello, world!");
}
public static void main(String[] args) {
System.out.println("Hello, world!");
}
public static void main(String[] args) {
System.out.println("Hello, world!");
}
\end{lstlisting}
\clearpage
\preventbreakbeforebracetrue
\begin{lstlisting}
public static void main(String[] args) {
System.out.println("Hello, world!");
}
public static void main(String[] args) {
System.out.println("Hello, world!");
}
public static void main(String[] args) {
System.out.println("Hello, world!");
}
\end{lstlisting}
\clearpage
\end{document}