我的环境有问题lstlisting
。我想用它来显示几行很长的、无法重新格式化的行。无论选项为breakatwhitespace=true
否,我的行都不会被分解,因此结尾远远超出了可打印区域。
如何指定允许在任意字符处换行?或者是否可以指定可用于换行的字符(空格除外)?
替代方案:插入一个特殊的(未打印的)字符,表示“在此处断行” - 是否存在这样的事情?
\begin{lstlisting}[]
Test1: 33b7a2f7c4cc93c46dd4ee2ed81aa1eb-9409135542c79d1ed50c9fde07fa600a_cce5a2fe76bfbd0c48d79fb43a7106f0_263e9a8711c1400fb2a716a1b820ac9a
Test2: 33b7a2f7c4cc93c46dd2423423423423-9409135542c79d1ed50c9fde07fa600a_cce5a2fe76bfbd0c48d79fb43a7106f0_263e9a8711c1400fb2a716a1b820ac9a
\end{lstlisting}
更新:
这回答来自埃格尔效果很好。另外,我还发现了一种可直接在环境中使用的不同方法lstlisting
:
\begin{lstlisting}[breakatwhitespace=true, literate={\-}{}{0\discretionary{-}{\\}{}}]
...
\end{lstlisting}
它允许在连字符处换行。它有一些缺点,尤其是换行符看起来与环境中的其他换行符不同。但对于其他人来说,这段代码可能有用...
在此处找到:LaTeX:Lstinline 和连字符
答案1
\begin{lstlisting}[language=TeX,breaklines]
...
\end{lstlisting}
是否可行取决于所使用的语言。例如,使用 TeX 作为语言。
另一个解决方案与 projetmbc 提出的解决方案类似,
\makeatletter
{\obeylines\gdef\bt@eol{^^M}}
\newenvironment{breakabletexttt}
{\ttfamily\hfuzz=0.4em
\list{}{\leftmargin=2em
\itemindent=-\leftmargin
\listparindent=-\leftmargin
\parsep=0pt}
\item\relax\obeylines\breakable@texttt}
{\endlist}
\def\breakable@texttt#1{%
\ifx#1\end
\expandafter\end
\else
\expandafter\ifx\bt@eol#1%
#1%
\else
\string#1\hskip1sp
\fi
\expandafter\breakable@texttt
\fi}
\makeatother
然后
\begin{breakabletexttt}
<long line 1>
<long line 2>
...
\end{breakabletexttt}
将在打印行时在右边距处断开它们。\hfuzz=0.4em
最多允许一个字符突出(行宽应为等宽字体字符的整数倍,或者应在字符之间添加灵活空格,而不是\hskip1sp
)。
编辑:以下变体将尊重空格
\makeatletter
{\obeylines\gdef\bt@eol{^^M}}
\newenvironment{breakabletexttt}
{\ttfamily\hfuzz=0.4em
\list{}{\leftmargin=2em
\itemindent=-\leftmargin
\listparindent=-\leftmargin
\parsep=0pt}
\item\relax\obeylines\obeyspaces\expandafter\breakable@texttt\@gobble}
{\endlist}
\def\breakable@texttt{\futurelet\@let@token\breakable@texttti}
\def\breakable@texttti#1{%
\ifx\@let@token\end
\expandafter\end
\else
\expandafter\ifx\bt@eol\@let@token
\par
\else
\string#1\hskip1sp
\fi
\expandafter\breakable@texttt
\fi}
\makeatother
重要的是编码为
\begin{breakabletexttt}
line
...
\end{breakabletexttt}
在 之后有一个新行\begin
。
答案2
我给你一个我给出的部分解决方案这里。问题是它不适用于特殊字符,例如_
。一个部分解决方案是本地更改的 catcode _
。
我问了一个关于这个问题,以便自动化这里。
% Source : http://forum.mathematex.net/latex-f6/forcer-le-retour-a-la-ligne-dans-texttt-t13246.html#p127511
\documentclass{article}
\makeatletter
\newcommand\breakabletexttt[1]{\texttt{\breakable@texttt#1\@nil}}
\def\@gobble@fi#1\fi{\fi#1}
\def\breakable@texttt#1#2\@nil{%
#1\hspace{0pt plus 0.1pt minus 0.1pt}%
\ifx\relax#2\relax
%
\else
\@gobble@fi\breakable@texttt#2\@nil
\fi
}
\makeatother
\begin{document}
\catcode`_=11
\breakabletexttt{33b7a2f7c4cc93c46dd4ee2ed81aa1eb?9409135542c79d1ed50c9fde07fa600a?cce5a2fe76bfbd0c48d79fb43a7106f0?263e9a8711c1400fb2a716a1b820ac9a}
\catcode`_=8
\end{document}
最后,这里有一个可能的解决方案:
% Sources :
% * http://forum.mathematex.net/latex-f6/forcer-le-retour-a-la-ligne-dans-texttt-t13246.html#p127511
% * https://tex.stackexchange.com/questions/33465/changing-the-catcode-of-in-one-command
\documentclass{article}
\makeatletter
\newcommand\breakabletexttt{\begingroup\catcode`\_12 \breakabletexttt@i}
\newcommand\breakabletexttt@i[1]{\texttt{\breakable@texttt#1\@nil}\endgroup}
\def\@gobble@fi#1\fi{\fi#1}
\def\breakable@texttt#1#2\@nil{%
#1\hspace{0pt plus 0.1pt minus 0.1pt}%
\ifx\relax#2\relax
\else
\@gobble@fi\breakable@texttt#2\@nil
\fi
}
\makeatother
\begin{document}
\breakabletexttt{33b7a2f7c4cc93c46dd4ee2ed81aa1eb?9409135542c79d1ed50c9fde07fa600a?cce5a2fe76bfbd0c48d79fb43a7106f0?263e9a8711c1400fb2a716a1b820ac9a}
\end{document}
答案3
我尝试了问题更新中的解决方案,但当我在 \lstset 中尝试时,它不起作用(它没有编译)。经过一番搜索,我想出了这个,它似乎可以解决问题:
\lstset{various options,
breaklines=true,
literate={\-}{}{0\discretionary{-}{}{-}},
various other options}
答案4
除了其他答案之外,我还想分享一下我在尝试回答 LaTeX IRC 频道上提出的类似问题时想到的办法。定义一个新环境来在任意点处中断代码行似乎有点不幸,因为您会失去 listings 包提供的所有不错的额外功能。
正如之前评论中提到的,换行似乎取决于列表的语言设置。因此,定义一种新的、简单的语言风格(不带任何关键字等)似乎很自然,这种风格可以在任意字符处换行。
我无法弄清楚 listings 究竟是如何确定可能的换行位置的。通过对alsoletter
/ alsodigit
/alsoother
选项的尝试,似乎只允许在两个不同字符类的边界处换行;显然,同一类的字符序列永远不会被换行。这意味着我们不能使用这些选项来定义新的样式,而必须(误)使用技巧literate
:
\documentclass{article}
\usepackage{listings}
\usepackage{xcolor}
\makeatletter
\def\@tempA#1#2\@end{%
\@tempA@{#1}%
\ifx\relax#2\relax
\else
\@tempA#2\@end
\fi
}
\def\@tempA@#1{{\noexpand#1}{{\char`\noexpand#1 \allowbreak}}1 }
\edef\@tempB{\noexpand\lstdefinelanguage{logfile}{%
columns=fixed,%
keepspaces=true,%
breaklines=true,%
literate=\@tempA 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!()*+,-./:;<=>?@[]_|`^"'\&\$\\\~\#\%\{\}\@end
}}
\@tempB
\makeatother
\begin{document}
\newlength\lstbasewidth
\settowidth\lstbasewidth{\ttfamily\small X}
\lstset{
basicstyle=\ttfamily\small,
language=logfile,
breakindent=4\lstbasewidth,
basewidth=\lstbasewidth,
postbreak=\llap{\scriptsize\textcolor{blue}{$\hookrightarrow$}\kern0.25em}
}
\begin{lstlisting}
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./
0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?
@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
\end{lstlisting}
\end{document}
输出
该示例定义了新的语言样式logfile
(显示包含长行的日志文件是频道中最初要求的)。这个想法很简单:将每个可打印字符映射到选项列表中的x
条目。为了避免大量的样板代码,我们使用宏遍历字符列表并将每个字符扩展为给定的条目格式,最后使用完全扩展的条目列表定义新样式。{x}{{\char`x \allowbreak}}1
literate
\@tempA
\@tempB
文档主体中的设置只是在换行发生的位置添加了一些视觉指示,带有箭头和 4 个字符的固定缩进宽度。请注意,样式尚未经过很好的测试,尤其是与不同的包或扩展字符集结合使用时。