
С csquotes
, (необязательное) цитирование длинного текста \blockquote
по умолчанию помещается сразу после самой цитаты. Если вы хотите, чтобы цитата была на следующей строке и выровнена по правому краю, вы можете сделать
\renewcommand{\mkblockquote}[4]{#1#2\par\hfill#4#3}
что отлично работает в стандартных классах:
\documentclass{article}
\usepackage{csquotes,lipsum}
\renewcommand{\mkblockquote}[4]{#1#2\par\hfill#4#3}
\begin{document}
\blockquote[Some Bloke][]{\lipsum*[2]}
\end{document}
Однако, beamer
это не работает, переопределение \mkblockquote
не имеет никакого эффекта, насколько я могу судить. Есть ли какой-то способ заставить это работать beamer
и в рамке?
MWE, обратите внимание на положение(Какой-то парень)по сравнению с примером article
выше:
\documentclass{beamer}
\usepackage{csquotes,lipsum}
\renewcommand{\mkblockquote}[4]{#1#2\par\hfill#4#3}
\begin{document}
\begin{frame}
\blockquote[Some Bloke][]{\lipsum*[2]}
\end{frame}
\end{document}
(Кстати, я, конечно, знаю, что мне не нужно csquotes
приводить такую цитату, поэтому ответ, который говорит что-то вроде"откажитесь от \blockquote
и используйте \lipsum*[2]\par\hfill(Some Bloke)
"не так уж и интересно.)
решение1
Это произошло из-за ошибки, csquotes
которая исправлена вверсия 5.2а(дата выпуска 2017-02-03). Анализ и обходной путь для версии до 5.2a приведены ниже.
Применение \tracingall
или размещение «маркера» внутри \mkblockquote
покажет, что он никогда не выполняется в этом beamer
случае. Причина в том, что csquotes
проверяет, находится ли TeX в «соответствующем» режиме для создания отображаемого материала как части \blockquote
. Если этот тест не пройден, цитата устанавливается как текстовая цитата.
Тест, используемый csquotes
примитивом \ifinner
, является истинным внутри примитивных конструкций \hbox
и (что особенно важно) в начале абзаца в \vbox
или \vtop
. (TeX находится в ограниченном горизонтальном режиме и ограниченном вертикальном режиме соответственно.) Фреймы создаются в beamer
виде вертикальных блоков, поэтому первый материал, помещенный во фрейм, имеет именно последнее условие. Это означает, что csquotes
видит контекст как «неподходящий» для отображения и переходит по текстовому маршруту.
Мы можем выйти из вертикального режима в неограниченный горизонтальный режим с помощью \leavevmode
(или ряда других команд горизонтального режима), что решит проблему.
\documentclass{beamer}
\usepackage{csquotes,lipsum}
\renewcommand{\mkblockquote}[4]{#1#2\par\hfill#4#3}
\begin{document}
\begin{frame}
\leavevmode
\blockquote[Some Bloke][]{\lipsum*[2]}
\end{frame}
\end{document}
В этом article
случае TeX находится внеограниченныйвертикальный режим (основной вертикальный список), когда \blockquote
встречается so, \ifinner
то это ложно и выбирается маршрут блочной цитаты.
Дефектный код был
\long\def\csq@bquote#1#2#3#4#5#6{%
\csq@ifnested
{\csq@err@nbquote}
{\csq@getpunct{%
\ifbool{inner}
{\csq@bquote@ii}
{\ifbool{csdisplay}
{\csq@bquote@i}
{\iftoggle{csq@parbox}\csq@bquote@ii\csq@bquote@i}}%
{#1}{#2}{#3}{#4}{#5}{#6}}}}
где неисправная линия \ifbool{inner}
. Как уже отмечалось, это будет справедливо как для горизонтального, так и для вертикального режима. Замена на
\ifboolexpr{ bool {inner} and bool {hmode} }
исправляет это, так как теперь это верно только внутри \hbox
. Исправление делает задокументированное поведение внутри \parbox
и подобных активным, поскольку они устанавливают csq@parbox
, в то время как beamer
использует 'raw' \vbox
для кадров, теперь это работает как для основного вертикального списка.
Можно использовать etoolbox
для исправления дефектного кода во время ожидания обновления:
\makeatletter
\patchcmd{\csq@bquote}{\ifbool{inner}}{\ifboolexpr{ bool {inner} and bool {hmode} }}
{}{}
\makeatother