Мне нужно использовать неразрывные пробелы в инициалах имен собственных, например:
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, мне нужно сделать распознавание языка более надежным, поэтому вы можете скачать его с github и установить в свой локальный TEXMFHOME
каталог, если хотите его использовать.
решение2
ОТРЕДАКТИРОВАНО для выявления большего количества случаев (и изучения видов отказов)
Я согласен с рекомендацией Дэвида не делать пространство активным. Поэтому подход, который я здесь использую, заключается в том, чтобы сделать точку активной, с возможностью включать ( \initialsON
) и выключать ( \initialsOFF
) функцию по мере необходимости, если будет обнаружено, что она мешает чему-то еще.
Выбор активной точки повлечет за собой серьезное ограничение, которое мы обнаружим, поскольку активная точка возникаетпослеинициализированной буквы, и поэтому становится невозможным окончательно узнать, предшествовала ли инициал активной точке. Но мы, тем не менее, можем добиться интересного прогресса в достижении этой цели.
В моем первоначальном решении (путь, который следует \specdothelper
), схема обнаружения срабатывала только для инициалов, набранных без пробелов, таких как J.W.Bush
, так что она преобразовывала последовательность .X
в , .~X
если не было пробела между .
и X
, где X
представляет любую заглавную букву. Этот сжатый синтаксис может потребовать некоторого привыкания или даже быть совершенно неприемлемым для многих пользователей.
С этой последней ВЕРСИЕЙ (и моим первым успешным использованием \futurelet
,ура), теперь я также могу искать синтаксис . X.
, где после первой точки идет пробел, затем заглавная буква, за которой следует точка. Если эта последовательность найдена, она преобразуется в .~X.
И если и только если инициалы были недавно найдены, последовательность . Xx
предположит, что фамилия была найдена, и преобразует ее в .~Xx
. Таким образом, в последовательности типа J. Z. A. Bush
, она поймает все три пробела, преобразуя их в жесткие пробелы.
Однако, используя точку в качестве активного символа, я не могу узнать, был ли символ до точки инициалом, и могу только попытаться различить его, заглянув вперед во входной поток. В примере, приведенном G. Washington
, проблема с первой точкой заключается в том, что без уже установленного шаблона инициалов направленный вперед . Wa
набор символов может быть началом предложения, а не именем, следующим за инициалом. И поэтому этот важный случай упускается.
В этом EDIT я сократил обсуждение в дальнейшем на внутренностях логики. Я только подведу итог и скажу, что проблемными областями были пробелы, \par
s и повторяющиеся точки ..
(поскольку точки являются активными символами), которые требовали особого обращения. Кроме того, новая логика с этим пересмотром следует макросу \foundspace
.
Места, где сжатый (без пробелов) синтаксис не сработает, показаны в моем MWE. Если фамилия не начинается с заглавной буквы, это один случай, например C.deLune. Кроме того, если в URL есть точка, за которой следует заглавная буква, это приведет к вставке пробела (хотя его \initialsOFF
следует использовать перед установкой такого нестандартного текста, как URL).
При использовании измененного синтаксиса, где пробелы остаются между инициалами в вашем файле LaTeX, есть три известных режима ошибок (один из них критический). Первый, который был подробно рассмотрен выше, — это случай одной инициали, за которой следует фамилия. Второй случай ошибок — это когда предложение начинается с инициала (хотя это плохая грамматика). Третий случай ошибок — это когда предложение заканчивается чем-то, что выглядит как инициалы, например U. S. A.
В этом случае первое слово следующего предложения воспринимается как фамилия, и вставляется жесткий пробел.
При использовании сжатого синтаксиса требование вводить инициалы без пробелов в вашем документе может быть совершенно неприемлемым для многих пользователей. А в обычном расширенном синтаксисе невозможность обнаружить одиночный инициал в последовательности значительно ограничивает полезность этого подхода.
В следующем MWE я намеренно определил свой жесткий пробел \HS
как a, \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}