Следующая запись 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
. Все еще есть случаи, когда что-то может пойти не так, но на данный момент это кажется исправлением с «наименьшим риском». Как я уже сказал, не хватает примечания о том, почему этот тест там: не сразу очевидно, в чем причина!