Автоматические неразрывные пробелы в инициалах имен собственных

Автоматические неразрывные пробелы в инициалах имен собственных

Мне нужно использовать неразрывные пробелы в инициалах имен собственных, например:

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 я сократил обсуждение в дальнейшем на внутренностях логики. Я только подведу итог и скажу, что проблемными областями были пробелы, \pars и повторяющиеся точки ..(поскольку точки являются активными символами), которые требовали особого обращения. Кроме того, новая логика с этим пересмотром следует макросу \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}

введите описание изображения здесь

Связанный контент