自定义逐字将所有空格(“”)设置为可以换行的可见空格(“␣”)

自定义逐字将所有空格(“”)设置为可以换行的可见空格(“␣”)

用等宽字体排版代码是有意义的。有时这样的代码需要嵌入段落上下文中,那么允许它换行就很有用了。为了正确地可视化空格,我想要一个宏\code,它可以将其参数的所有空格排版为可见空格,并且可以换行(在两侧)。例如,它会排版

\code{string with  spaces}

就像string␣with␣␣spaces每个都可以在任一侧换行一样。由于我的问题是关于嵌入段落文本的代码,我们可以假设此类\code宏的参数不包含任何段落换行符。

实际上我的用例更具体。我使用下面显示的宏来排版字符串常量\strC。这对其他人来说可能仍然很有趣,因为它不仅仅是 的变体\verb,自定义\textsl可能会使解决方案复杂化。

我目前使用对宏的显式调用\vsp(简单定义为\allowbreak\textvisiblespace\allowbreak;两个\allowbreak都是需要的)作为解决方法,但如果能够在宏参数中键入(一个或多个)空格就更好了。

\documentclass{article}

\newcommand*{\strC}[1]{\textnormal{`\textsl{\texttt{#1}}'}} % string constant
\newcommand*{\vsp}{\allowbreak\textvisiblespace\allowbreak} % visible space

\begin{document}

\hspace*{31em}\strC{hello world}
% linebreaks as:  ‘hello / world’    (space disappears)

\hspace*{31em}\strC{hello\textvisiblespace{}world}
% linebreaks as:  ‘hello␣world’ / ∅  (no linebreak)

\hspace*{31em}\strC{hello\vsp{}world}
% linebreaks as:  ‘hello / ␣world’   (as intended; a linebreak after ␣ would also be ok)

\end{document}

对于此代码,具体来说,想法是键入\strC{hello world}但获得与相同的结果\strC{hello\vsp{}world}。 多个键入的空格应产生多个-字符;字符串␣␣␣␣␣可能在任何地方中断(开头、中间任何地方、结尾)。

这里是一个相关问题,也询问输入的功能转换(在这种情况下是为了粘贴的特定目的)。


答案总结: 这两个答案都非常好,用户的评论对(就在下面)卡卡梅尔也很好,但截至本文编辑时,没有一个解决方案是完美的。现在,我将坚持使用手动\vsp宏,它可以快速输入并让我完全控制。如果有人对这三种方法中的一种进行了完美的改进,我会接受它作为答案。

答案1

您必须更改活动空间的含义。(当然,这意味着\code不能作为另一个命令的参数(见下文*),但谨慎使用\scantokens可能会有所帮助。)

\documentclass{article}

\newcommand*{\strC}{\begingroup
  \obeyspaces
  \begingroup\lccode`~=`\ %
  \lowercase{\endgroup\let~}\vsp
  \dostrC}
\newcommand{\dostrC}[1]{\textnormal{`{\slshape\ttfamily#1}'}\endgroup} % string constant
\newcommand*{\vsp}{\allowbreak\textvisiblespace\allowbreak} % visible space

\begin{document}

\hspace*{31em}\strC{hello world  x   y}

\end{document}

在此处输入图片描述


*例如,如果我们将命令包装到\ident不修改其参数的宏中(\newcommand*{\ident}[1]{#1}),则

\ident{\strC{hello world  x   y}}

结果就像我们使用了\strC没有任何明确可见空格的原始宏一样:所有空格序列都会缩小为普通(即换行和消失(“软”))空格。

答案2

[已编辑以解决多软空格问题] 该stringstrings包可能适用于此处,但有一个警告。由于 stringstrings 不是逐字字符串处理器,因此参数中的多个空格会被 LaTeX 解释为单个空格标记,除非您明确放置硬空格(~ 字符)来表示多个空格。所以我尝试重新定义\catcode以尝试克服这个限制。只要调用\strC不遵循 的星号版本\hspace,它似乎就可以工作(不确定星号版本有什么特殊之处,但在这种情况下,多软空格被解释为单个软空格)。因此,除了注意到的例外情况外,stringstrings可以解析字符串,将空格和波浪号(每个都转换为可见的空格字符),从而允许换行。

\documentclass{article}
\usepackage{stringstrings}

\newcommand*{\strC}[1]{%
\catcode`\ =12%
\strCB{#1}%
\catcode`\ =13%
}

\newcommand*{\strCB}[1]{%
  \encodetoken[1]{\textvisiblespace}%
  \encodetoken[2]{\allowbreak}%
  \convertchar[e]{#1}{ }{\allowbreak\textvisiblespace\allowbreak}%
  \convertchar[e]{\thestring}{~}{\allowbreak\textvisiblespace\allowbreak}%
  \retokenize{\thestring}%
  \textnormal{`\textsl{\texttt{\thestring}}'}%
  \decodetoken[1]{\textvisiblespace}%
  \decodetoken[2]{\allowbreak}%
} % string constant

\begin{document}

The hspace* affects the bevavior of the subsequent strC (not sure why).

\hspace*{31em}\strC{hello world.  This is a ~ Big   test}

But in other cases, multiple softspaces are correctly interpreted:

\strC{Hello   World}

\strC{hello world.  This is a ~ Big   test}

\hspace{31em}\strC{hello world.  This is a ~ Big   test}

\end{document}

在此处输入图片描述

最后,我想补充一些免责声明:stringstrings 速度很慢,这对于大型操作来说可能是一个问题;stringstrings 无法轻松处理\反斜杠字符。如果您排版的代码是一种不使用反斜杠字符的语言,那么这不是问题,但如果您排版的是 LaTeX 代码,那么显然会这样。

相关内容