我正在排版一些技术文档,其中包含名称很长的标识符。不可接受拆分或连接这些名称因为这样看起来会像并列标识符或减法一样令人困惑,并使输出 PDF 无法搜索。如果名称超出物理页面,也是不可接受的。偶尔出现溢出的水平盒子是可以的,只要标识符仍在页面内,就可以扩展到右边距。
在这些限制内,我当然希望输出看起来尽可能漂亮。但是,我没法花时间对每个段落进行微调以添加\sloppy
或\raggedright
类似的声明。在文档的某些部分,我根本无法做到这一点,因为 LaTeX 代码是由不允许我在文本中注入任意 LaTeX 的工具生成的。TeX 必须从我设置的参数中一劳永逸地找到正确的方法。
我发现解决基本问题的工具是\sloppy
,,\raggedright
以及\RaggedRight
ragged2e
. 它们对我来说都不太管用。
梅威瑟:
\documentclass{article}
\usepackage{ragged2e}
\usepackage[vmargin=0in]{geometry}
\pagestyle{empty}
\newcommand{\mytext}[2]{
\subsubsection*{#1}
{ #2 %
Some libraries define extremely long names such as
\texttt{AVAssetResourceLoadingContentInformationRequest} or
\texttt{UIViewControllerTransitionCoordinatorContext} or even
\texttt{MFMessageComposeViewControllerTextMessageAvailabilityDidChangeNotification}
(yeech!). It is unacceptable to hyphenate these very long names or for them to
disappear off the side of the page. Beyond that, the output should not
look too ugly: there should be no extra-long white spaces, and long text
paragraphs tend to look bad without right justification.
\par
}
}
\begin{document}
\mytext{Default}{}
\mytext{Sloppy}{\sloppy}
\mytext{Ragged right}{\raggedright}
\mytext{Ragged2e RaggedRight}{\RaggedRight}
\mytext{Ragged2e RaggedRight + sloppy}{\RaggedRight\sloppy}
\end{document}
\sloppy
满足了硬性限制,但允许空间过度拉伸,从而降低了可读性。\raggedright
也满足了硬性限制,但右侧的空白很大(浪费纸张)并且不均匀(不好看)。\RaggedRight
无法使所有内容都适合物理页面。plus\RaggedRight
是\sloppy
我最好的选择,但对于长段文本,它明显不如正常的左右对齐。
我怎样才能既满足严格的限制(适合一些非常长的单词不会破坏),并获得美观的输出(特别是在没有长标识符的段落中)?例如,在上面的示例段落中,我希望输出“Default”,但在“even”之后有一个换行符。
答案1
这个答案与我的其他答案完全不同。它的目标是用\textt
可拆分的填充引导表达式,以便长单词在必要时可以单独占据一行。
该方法不会分解任何标识词。
该方法的核心是
\let\svtexttt\texttt
\newcommand\Texttt[1]{\hfil\discretionary{}{}{}\relax\svtexttt{#1}}
它可以单独使用,也可以像我在这里所做的那样,\let
用来替代\texttt
。
原帖指出的一个问题是,如果段落以 结尾,则可能会有过多的水平空间。可以通过在段落末尾\texttt
添加双引号来手动克服这种情况(可能很少见) ,我在 MWE 中称之为这种情况。\hfill
\Hfill
\documentclass{article}
\usepackage{ragged2e}
\usepackage[vmargin=0in]{geometry}
\pagestyle{empty}
\newcommand{\mytext}[2]{
\subsubsection*{#1}
{ #2 %
Some libraries define extremely long names such as
\texttt{AVAssetResourceLoadingContentInformationRequest} or
\texttt{UIViewControllerTransitionCoordinatorContext} or even
\texttt{MFMessageComposeViewControllerTextMessageAvailabilityDidChangeNotification}
(yeech!). It is unacceptable to hyphenate these very long names or for them to
disappear off the side of the page. Beyond that, the output should not
look too ugly: there should be no extra-long white spaces, and long text
paragraphs tend to look bad without right justification.
But some names are \texttt{Short} too.
\texttt{ThisIsSuchAnExtremelyLongName} \texttt{TheNameGoesOnAndOnMyFriend}
\Hfill% THIS CAN HELP WHEN \texttt FOUND AT PARAGRAPH ENDS
\par
}
}
\def\Hfill{\hfill\hfill}
\let\svtexttt\texttt
\newcommand\Texttt[1]{\hfil\discretionary{}{}{}\relax\svtexttt{#1}}
\let\texttt\Texttt
\begin{document}
\mytext{Default}{}
\mytext{Sloppy}{\sloppy}
\mytext{Ragged right}{\raggedright}
\mytext{Ragged2e RaggedRight}{\RaggedRight}
\mytext{Ragged2e RaggedRight + sloppy}{\RaggedRight\sloppy}
\end{document}
答案2
这个答案不能满足 OP 的需求,因为该accsupp
方法虽然适用于 Adobe Acrobat,但并不适用于 OP 需要支持的所有 PDF 阅读器。尽管如此,我还是把它留在这里,因为它可能对其他面临类似挑战的人有用。
应用 egreg 使用小写字母技巧的变体(如何在不使用 url 包的情况下模拟 \url 连字?),我创建了\Texttt{}
它,在本例中激活了 3 个大写字母(您可能希望将其扩展到更多字母以用于一般用例),以允许随意换行。如您所见,对于 OP 的 MWE,它在默认情况下有效,允许在那些指定的大写(现在处于活动状态)字母处换行。
这就是 EDIT 出现的地方。
然而,原帖作者强调,标识符中的换行符会干扰 PDF 搜索和复制/粘贴的要求。因此,我引用了我在是否存在“仅视觉空白”之类的东西?将答案转换为“仅可视”空格,这样标识符在复制/粘贴时仍保持完整,即使它们在可视页面上遇到换行符(这使用包accsupp
)。此时,应该\ncs{}
为这些长标识符参数调用宏,这反过来又调用\Texttt{}
。
此外,OP 同意(在本文后面的评论中)允许/考虑使用特殊连字符标记(不是-
),只要它们(就像换行符本身一样)不是 PDF 复制/粘贴的一部分。因此,出于演示目的,我使用右箭头$\rightarrow$
作为标识符连字符。由于 位于\IDhyphen
框中,因此可以使用任何符号作为标识符连字符。
理想情况下,用户的代码应该调用 来\ncs{}
处理这些长标识符。但是,对于这个 MWE, I \let\texttt\ncs
可以完全替代\texttt
。但是,如果您在参数中调用大写命名宏,这可能会很危险\texttt
。更好的方法是仅使用\ncs
这些特殊的长单词。
\documentclass{article}
\usepackage{ragged2e}
\usepackage[vmargin=0in]{geometry}
\pagestyle{empty}
\usepackage{accsupp}
\newcommand\ncs[1]{%
\def\actual{}\ncshelper#1 \relax%
\BeginAccSupp{method=escape,ActualText=\actual}%
\Texttt{#1}%
\EndAccSupp{}%
}
\def\ncshelper#1 #2\relax{\edef\actual{\actual#1}%
\if\relax#2\relax\else\ncshelper#2\relax\fi}
%
\newcommand{\Texttt}[1]{%
\begingroup
\ttfamily
\begingroup\lccode`~=`R\lowercase{\endgroup\def~}{\discretionary{\IDhyphen}{R}{R}}%
\begingroup\lccode`~=`I\lowercase{\endgroup\def~}{\discretionary{\IDhyphen}{I}{I}}%
\begingroup\lccode`~=`C\lowercase{\endgroup\def~}{\discretionary{\IDhyphen}{C}{C}}%
\catcode`R=\active\catcode`I=\active\catcode`C=\active
\scantokens{#1\noexpand}%
\endgroup%
}
\let\texttt\ncs
\newcommand{\mytext}[2]{
\subsubsection*{#1}
{ #2 %
Some libraries define extremely long names such as
\texttt{AVAssetResourceLoadingContentInformationRequest} or
\texttt{UIViewControllerTransitionCoordinatorContext} or even
\texttt{MFMessageComposeViewControllerTextMessageAvailabilityDidChangeNotification}
(yeech!). It is unacceptable to hyphenate these very long names or for them to
disappear off the side of the page. Beyond that, the output should not
look too ugly: there should be no extra-long white spaces, and long text
paragraphs tend to look bad without right justification.
\par
}
}
\newsavebox\IDhyphenbox
\savebox\IDhyphenbox{$\rightarrow$}
\def\IDhyphen{\usebox{\IDhyphenbox}}
\begin{document}
\mytext{Default}{}
\mytext{Sloppy}{\sloppy}
\mytext{Ragged right}{\raggedright}
\mytext{Ragged2e RaggedRight}{\RaggedRight}
\mytext{Ragged2e RaggedRight + sloppy}{\RaggedRight\sloppy}
\end{document}
使用 Adobe Acrobat 作为查看器复制粘贴默认段落,结果如下,表明标识符保持完整。此外,即使标识符跨行,Adobe 对完整标识符字符串的搜索也会成功。(请注意,复制/粘贴过程中存在连字符问题,但这是 OP 必须解决的另一个问题,尽管连字符不会影响内容\ttfamily
)
Some libraries dene extremely long names such as AVAssetResourceLoadingContentInformationRequest
or UIViewControllerTransitionCoordinatorContext or even MFMessageComposeViewControllerTextMessageAvailabilityDidChangeNotification
(yeech!). It is unacceptable to hy-
phenate these very long names or for them to disappear o the side of the page. Beyond that, the
output should not look too ugly: there should be no extra-long white spaces, and long text para-
graphs tend to look bad without right justication.