\mkbibquote не закрывает кавычки, если за ними сразу следует двоеточие

\mkbibquote не закрывает кавычки, если за ними сразу следует двоеточие

Следующая запись biblatex (встроенная в минимальный пример LaTeX):

\begin{filecontents*}{\jobname.bib}
@article{test1,
Author = {Craft, Robert},
Title = {Stravinsky at His \mkbibquote{Bird-Best}: Robert Craft Untangles the Tales Surrounding the Creation of \foreignlanguage{french}{\mkbibemph{Le rossignol}}},
Journaltitle = {Opera News},
Date = {1982},
Volume = {46},
Number = {8},
Pages = {14-15, 34}
}
\end{filecontents*}
\documentclass{article}
\usepackage[autostyle=true, english=american, french=guillemets, german=guillemets]{csquotes}
\usepackage[french, german, american]{babel}
\usepackage{biblatex}
\addbibresource{\jobname.bib}
\begin{document}
\cite{test1}
\printbibliography
\end{document}

неправильно отображается pdflatexкак:

Роберт Крафт, «Стравинский в своем «птичьем» превосходстве: Роберт Крафт распутывает истории, окружающие созданиеLe rossignol,'”Новости оперы, 1982, № 8, 14–15, 34.

Обратите внимание, что закрывающая кавычка после Bird-Best отсутствует.

Однако с lualatexтакой проблемой не возникает. Ссылка отформатирована правильно:

Роберт Крафт, «Стравинский в своей «птичьей» красоте: Роберт Крафт распутывает истории, окружающие созданиеLe rossignol,”Новости оперы, 1982, № 8, 14–15, 34.

Я перепробовал все последние стабильные и разрабатываемые ветки biblatex, включая 2.9a и 3.0. Проблема, скорее всего, связана с csquotes?

PLK, biblatexавтор, и я уже обсуждали это на GitHub (https://github.com/plk/biblatex/issues/259), но нам пока не удалось выяснить причину.

решение1

В описанном случае biblatexиспользуется макрос \blx@usqcheck, который используется для цитат в стиле США с «движущейся» пунктуацией. Он проверяет знаки препинания, пробелы и т. д., но также включает проверку:

\if\noexpand\@let@token\relax
  \blx@usqcheck@i\blx@tempb
\fi

где \blx@usqcheck@i\blx@tempbне вставляет закрывающую кавычку, но сохраняет ее для будущего использования. (Есть несколько внутренних ветвей, совместно использующих приведенный выше код, поэтому это не сразу очевидно.)

Первоначальный автор biblatexне оставил нам никаких заметок о том, что этот код должен был делать, но я думаю, что он хотел разрешить \relaxиспользовать явное указание, чтобы предотвратить перемещение знаков препинания.

\mkbibquote{some odd text}\relax ,

Проблема в том, что конструкция \if\noexpand\foo\relaxистинна, если \fooэто вообще макрос, а не только если он равен по значению \relax. ( \noexpandПримитив временно делает \fooравным , \relaxесли это макрос, но не если, скажем, вы сделали \let\foo=a.)

Это приводит нас к проблеме. Когда используется pdfTeX и frenchуказана опция для babel, символ :«активен» и имеет макроопределениедаже если активный язык не французский. Таким образом, тест идет biblatex«неправильным путем»: он находит макрос после цитаты, думает, что это расслабление, и пропускает закрывающую пунктуацию. Этого не происходит с LuaTeX, поскольку он не использует актив :для французской типографики, поэтому проблема никогда не проявляется.

Предложенное мной исправление заключается в добавлении второго теста в нужном месте: в виде короткого патча.

\makeatletter
\def\blx@usqcheck#1#2{%
  \def\blx@tempa{#1}%
  \def\blx@tempb{#2}%
  \ifx\@let@token\space
    \blx@usqcheck@i\blx@tempa
  \fi
  \ifx\@let@token\@sptoken
    \blx@usqcheck@i\blx@tempa
  \fi
  \if\noexpand\@let@token\relax
    \ifx\relax\@let@token
      \blx@usqcheck@i\blx@tempb
    \fi
  \fi
  \expandafter\blx@usqcheck@ii\blx@quotepunct\relax&}

\def\blx@usqcheck@i#1#2&{\fi#1}
\makeatother

Теперь это проверяет, чтозначениеследующего макроса начинается с \relax. Все еще есть случаи, когда что-то может пойти не так, но на данный момент это кажется исправлением с «наименьшим риском». Как я уже сказал, не хватает примечания о том, почему этот тест там: не сразу очевидно, в чем причина!

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