专有名词首字母中的自动不间断空格

专有名词首字母中的自动不间断空格

我需要在专有名词首字母中使用不间断空格,例如

J.~W.~Bush

有没有办法让 LaTeX 用不间断空格替换常规空格?或者我最好用一些正则表达式/脚本预处理我的 tex 文件?

答案1

我为我的软件包添加了对首字母的支持卢阿维娜。此包使用luatex节点处理回调来在单字母单词和首字母后插入与语言相关的不间断空格。

例子:

\documentclass{article}
\usepackage{fontspec}
\usepackage[czech, english]{babel}
\usepackage{luavlna}
\preventsinglelang{czech}
\begin{document}
  \preventsingledebugon
D. E. Knuth, Ch. Somebody. \selectlanguage{czech} A. Dvořák, 
name in horizontal box \hbox{Č. Zíbrt}, Ř. Jelen \preventsingleoff C. Někdo, 
\preventsingleon Ř. Jelen, Ch. Josef, CH. Thisworkstoo

\end{document}

在此处输入图片描述

您可以看到Ch在捷克语中用作一个字母。如果您不想进行语言敏感处理,请将默认语言设置为,\preventsinglelang{languagename}并且将在整个文档中使用给定语言的规则。

您可以使用 关闭处理\preventsingleoff,然后使用\preventsingleon

luavlna尚未在 CTAN 上,我必须使语言检测更加强大,因此TEXMFHOME如果您想使用它,您可以从 github 下载它并安装到您的本地目录中。

答案2

编辑以捕捉更多案例(并检查故障模式)

我同意 David 的建议,不要让空间处于活动状态。因此,我在这里采取的方法是让点处于活动状态,并能够根据需要打开 ( \initialsON) 和关闭 ( \initialsOFF) 该功能(如果发现它会干扰其他功能)。

我们会发现,活动点的选择会带来严重的限制,因为活动点首字母,因此无法确切知道首字母是否位于活动点之前。但我们仍然可以朝着这一目标取得有趣的进展。

在我最初的解决方案中( 后面的路径\specdothelper),检测方案仅在输入不带空格的首字母时触发,例如,这样如果和 之间没有空格,J.W.Bush它将序列转换.X为,其中代表任何大写字母。这种压缩语法可能需要一点时间来适应,甚至对许多用户来说是完全不可接受的。 .~X.XX

有了这个最新的修订版(也是我第一次成功使用\futurelet),我现在还可以搜索语法. X.,其中第一个点后有一个空格,然后是一个大写字母,后面跟着一个点。如果找到这个序列,它会被转换成.~X. 并且当且仅当最近找到首字母时,该序列. Xx才会假定已找到姓氏并将其转换为.~Xx。因此,在像 这样的序列中J. Z. A. Bush,它会捕获所有三个空格,并将它们转换为硬空格。

但是,通过使用点作为活动字符,我无法知道点之前的字符是否是首字母,只能通过在输入流中向前查找来尝试辨别它。在给出的示例中,G. Washington第一个点的问题在于,如果没有建立首字母模式,向前查找的. Wa字符集可能是句子的开头,而不是首字母后面的名字。因此,这个重要的案例被忽略了。

在这次编辑中,我减少了以后对逻辑核心的讨论。我只会总结并说挑战区域是空格、\pars 和重复的点..(因为点是活动字符),这些需要特殊处理。此外,这次修订的新逻辑遵循宏\foundspace

我的 MWE 中显示了压缩(无空格)语法会失败的地方。如果姓氏不以大写字母开头,例如 C.deLune,就是一个例子。此外,如果 url 中有一个点,后面跟着一个大写字母,则会导致插入空格(尽管\initialsOFF应该在设置 url 等非常规文本之前使用)。

当使用修订后的语法时,在 LaTeX 文件中首字母之间保留空格,有三种已知的失败模式(其中一种至关重要)。第一种,上面已经详细讨论过,是单个首字母后跟姓氏的情况。第二种失败是句子以首字母开头(虽然这是错误的语法)。第三种失败情况是句子以看起来像首字母结尾,例如U. S. A. 在这种情况下,下一个句子的第一个单词被视为姓氏,并插入一个硬空格。

使用压缩语法时,要求在文档中输入首字母且中间不留空格,这对许多用户来说可能是完全不可接受的。而在正常的扩展语法中,无法检测序列中的单个首字母极大地限制了这种方法的实用性。

在随后的 MWE 中,我特意将硬空间定义\HS为,以\rule使其可见。要以预期的方式使用此代码,应将该定义替换为将其定义为硬空间(或细空间)的定义。

\documentclass{article}
\usepackage{ifnextok}
\def\HS{\rule{.66ex}{1ex}}% TO DEMONSTRATE WHERE ACTIVE
%\def\HS{\,}% FOR NARROW SPACE
%\def\HS{~}% FOR NORMAL HARD SPACE
\let\svdot.
\def\knowninit{F}
\makeatletter
\def\specdot{\svdot\IfNextToken\@sptoken{\foundspace}%
  {\gdef\knowninit{F}\specdothelper}}
\long\def\foundspace#1{\IfNextToken\@sptoken{ #1\gdef\knowninit{F}}%
  {\def\savefirst{#1}\lookatsecond}}
\def\lookatsecond{\futurelet\secondchar\processsecond}

\long\def\specdothelper#1{%
  \if\svdot#1%
    \svdot%
  \else%
    \ifx#1\par%
      \par%
    \else%
      \ifnum`#1>`@\ifnum`#1<`[\HS\fi\fi#1%
    \fi%
  \fi%
}
\makeatother

\catcode`.=\active
\def\processsecond{%
  \ifx\secondchar.%
    \HS\gdef\knowninit{T}%
  \else%
    \if T\knowninit%
      \ifnum\expandafter`\savefirst>`@\ifnum\expandafter`\savefirst<`[\HS\else%
        { }\fi\else{ }\fi%
    \else%
      { }%
    \fi%
    \gdef\knowninit{F}%
  \fi%
  \savefirst%
}
\def\initialsON{\catcode`.=\active\def.{\specdot}}
\def\initialsOFF{\catcode`.=12\let.\svdot}
\catcode`.=12
\parskip 1ex
\begin{document}
\footnotesize
\noindent ON\initialsON

Fully spaced initials J. Z. A. Bush being tested, and here we check double and single initials: 
J. Q. Adams and G. Washington.  A single initial cannot be discerned because the dot after 
the G cannot know if the prior letter is an initial and no other initials follow the dot.

U. S. A. is OK, since ``is'' is not capitalized.

We can be fooled by U. S. Olympic Team, in that it considers ``Olympic'' to be the last name.
Can also be fooled if sentence ends in the U. S. A. The new sentence starts with a hard-space, 
with ``The'' as the last name.  Leaving out the spaces will fix U.S.A.  If no spaces are wanted,
\initialsOFF U.S.A. \initialsON 
can be gotten by temporarily turning initials OFF.

Compressed or uncompressed C.deLune and  C. de Lune fail to insert a hard space, because 
``d'' is not a capital letter.

Unspaced combinations: 3.2, a.b, J.Z.A.Bush, and G.Washington being successfully tested
 here, with non-capital letters screened out.

Testing.. successive... dots is OK... Unless the sentence ends with odd number of dots, then 
a space immediately followed by a dotted initial... S. Segletes would never start a sentence 
with an initial.  It is poor grammar in the first place. 

\noindent\hrulefill\\
OFF\initialsOFF (This was the raw text being processed)

Fully spaced initials J. Z. A. Bush being tested, and here we check double and single initials: 
J. Q. Adams and G. Washington.  A single initial cannot be discerned because the dot after 
the G cannot know if the prior letter is an initial and no other initials follow the dot.

U. S. A. is OK, since ``is'' is not capitalized.

We can be fooled by U. S. Olympic Team, in that it considers ``Olympic'' to be the last name.
Can also be fooled if sentence ends in the U. S. A. The new sentence starts with a hard-space, 
with ``The'' as the last name.  Leaving out the spaces will fix U.S.A.  If no spaces are wanted,
U.S.A. 
can be gotten by temporarily turning initials OFF.

Compressed or uncompressed C.deLune and  C. de Lune fail to insert a hard space, because 
``d'' is not a capital letter.

Unspaced combinations: 3.2, a.b, J.Z.A.Bush, and G.Washington being successfully tested
 here, with non-capital letters screened out.

Testing.. successive... dots is OK... Unless the sentence ends with odd number of dots, then 
a space immediately followed by a dotted initial... S. Segletes would never start a sentence 
with an initial.  It is poor grammar in the first place. 
\end{document}

在此处输入图片描述

相关内容