Это дополнительный вопрос по темеГлоссарии в списке рисунков переполнены, где спрашивалось, как glossaries
можно использовать первую схему использования пакета с термином глоссария в подписи к рисунку. Я дал ответ, который работает до тех пор, пока пакет caption
не загружен.
\documentclass{article}
\usepackage{caption}
\usepackage[colorlinks]{hyperref}
\usepackage{glossaries}
\makeglossaries
\newglossaryentry{acr}{%
name = {ACR-name},%
description = {ACR-description},%
first = {ACR-first-description},%
}
\renewcommand{\glsdisplayfirst}[4]{#1 (1) #4}
\renewcommand{\glsdisplay}[4]{#1 (2+) #4}
\begin{document}
% \listoffigures %% even without \listoffigures the problem shows up
\begin{figure}[h]
\caption[Short title \glshyperlink{acr}]{Long title \gls{acr}}
\end{figure}
\printglossary
\end{document}
Как можно заметить, без caption
подписи к рисунку указана первая форма использования записи глоссария, как и требуется, а с caption
ней — последующая форма использования.
Как мне сохранить его работоспособность во время использования caption
?
решение1
LaTeX помещает заголовок во временную царапину \hbox
, измеряет ее ширину. Если ширина меньше ширины линии,коробкаповторно используется для набора заголовка. Поэтому \gls
вызывается один раз. Однако если ширина заголовка превышает ширину строки, текст заголовка устанавливается дважды, на этот раз как абзац. Затем \gls
вызывается дважды, и вы получаете вывод для второй версии элемента глоссария.
Пакет caption
делает поведение более предсказуемым. Если опция singlelinecheck
установлена (по умолчанию), то текст подписи всегда устанавливается дважды, первый раз для измерения ширины, чтобы проверить, помещается ли текст в одну строку, а затем текст устанавливается снова для конечного результата. С singlelinecheck=false
, измерение отключено, и текст устанавливается только один раз, но центрирование текста подписи теряется.
Обходной путь — поместить результат \gls{acr}
во временный контейнер и использовать этот контейнер внутри \caption
:
\documentclass{article}
\usepackage{caption}
\usepackage{glossaries}
\newsavebox\glsscratchbox
\makeglossaries
\newglossaryentry{acr}{%
name = {ACR-name},%
description = {ACR-description},%
first = {ACR-first-description},%
}
\renewcommand{\glsdisplayfirst}[4]{#1 (1) #4}
\renewcommand{\glsdisplay}[4]{#1 (2+) #4}
\begin{document}
\listoffigures %% even without \listoffigures the problem shows up
\begin{figure}[h]
\sbox\glsscratchbox{\gls{acr}}
\caption[Short title \glshyperlink{acr}]{Long title \unhcopy\glsscratchbox}
\end{figure}
\printglossary
\end{document}
(Эта команда \unhcopy
используется вместо \usebox
(это \copy
). Она удаляет внешний \hbox
слой и позволяет набирать пробелы так же, как и другие пробелы в строке. В противном случае ( \usebox
) пробел внутри повторно используемого блока всегда будет иметь естественную ширину.)
Решение для \gls
в подписи с пакетомcaption
Обновление: добавлено упрощение из комментария Акселя Зоммерфельдта.
Пакет glossaries
должен запомнить первые использования аббревиатур. Идея состоит в том, чтобы отключить это, если ширина подписи измеряется, но не, если текст подписи набирается окончательно.
Пакет caption
необходим, так как он отделяет тест от финального шага набора текста. Также он предоставляет макрос \caption@prepareslc
, который предшествует измерению и вызывается перед измерением. \glsunset
Для измерения временно отключено.
\documentclass{article}
\usepackage{glossaries}
\usepackage{caption}
\makeatletter
\g@addto@macro\caption@prepareslc{%
\let\glsunset\@gobble
}
\makeatother
\makeglossaries
\newglossaryentry{acr}{%
name = {ACR-name},%
description = {ACR-description},%
first = {ACR-first-description},%
}
\renewcommand{\glsdisplayfirst}[4]{#1 (1) #4}
\renewcommand{\glsdisplay}[4]{#1 (2+) #4}
\begin{document}
\listoffigures
\begin{figure}[h]
\caption[Short title \glshyperlink{acr}]{Long title \gls{acr}}
\end{figure}
\printglossary
\end{document}
Уточнение
Если \gls{acr}
используется, то для акронима устанавливается глобальный флаг, acr
чтобы запомнить состояние использования акронима. Таким образом, последующие вызовы могут использовать более короткую форму. Предыдущее решение пропускало установку состояния, если измеряется только текст подписи. Таким образом, состояние не изменилось, когда текст подписи был окончательно установлен.
Однако есть ситуация, которая проскальзывает. Текст заголовка содержит \gls
одну и ту же аббревиатуру несколько раз, включая ее первое использование. Тогда предыдущее решение будет содержать первую форму использования аббревиатуры для использований аббревиатуры на этапе измерения, поскольку настройка состояния там отключена.
Это исправлено путем разрешения изменений нормального состояния акронимов на этапе измерения, но с сохранением первых использований. Затем они сбрасываются перед окончательным набором текста подписи.
Дополнительные замечания:
\if@capmeasure
Вводится переключатель . Обычно он установлен на\iffalse
. Когда проверяется ширина текста внутри\caption
, то он устанавливается на\iftrue
.- Пакет
caption
необходим, поскольку он отделяет тест от финального шага набора текста. Также он предоставляет макрос\caption@prepareslc
, который предшествует измерению. Оба выполняются в одной и той же локальной группе. Поэтому достаточно добавить\@capmeasurefalse
в\caption@prepareslc
. Переключатель автоматически сбрасывается после окончания группы. - После измерения состояние первых использований аббревиатуры сбрасывается.
- Пакет
glossaries
'\glsunset
пропатчен для соблюдения настроек\if@capmeasure
и запоминания первых использований аббревиатур.
Полный пример:
\documentclass{article}
\usepackage{glossaries}
\usepackage{caption}
\makeatletter
\newif\if@capmeasure
\g@addto@macro\caption@prepareslc{%
\global\let\after@capmeasure\@empty
\aftergroup\after@capmeasure
\@capmeasuretrue
}
\CheckCommand*{\glsunset}[1]{%
\glsdoifexists{#1}{%
\expandafter \global \csname glo@#1@flagtrue\endcsname
}%
}
\renewcommand*{\glsunset}[1]{%
\glsdoifexists{#1}{%
\if@capmeasure
\expandafter\ifx\csname ifglo@#1@flag\expandafter\endcsname
\csname iftrue\endcsname
\else
% first use
\g@addto@macro\after@capmeasure{\glsreset{#1}}%
\fi
\fi
\global\csname glo@#1@flagtrue\endcsname
}%
}
\makeatother
\makeglossaries
\newglossaryentry{acr}{%
name = {ACR-name},%
description = {ACR-description},%
first = {ACR-first-long-description},%
}
\renewcommand{\glsdisplayfirst}[4]{#1\textsuperscript{(1)}#4}
\renewcommand{\glsdisplay}[4]{#1\textsuperscript{(2+)}#4}
\begin{document}
\listoffigures
\begin{figure}[h]
\caption[Short title \glshyperlink{acr}]%
{Long title \textit{\gls{acr}} and \gls{acr}}
\end{figure}
\printglossary
\end{document}
решение2
Используя glossaries-extra
у вас есть две альтернативы. Смотритездесь.
- Вы всегда можете вызвать
\glsxtrshort
внутри подписей. Они не будут вызывать первое использование по понятным причинам. У вас также есть параметрыnoindex
иhyper=false
, если вы хотите также избегать ссылок и не хотите, чтобы эти записи отображались в списке глоссария, созданном с помощью\printglossaries
. Что приводит нас к: - Предсказание этого использования
glossaries-extra
включает семейство\glsfmtshort
команд. Они идентичны соответствующим\glsxtrshort[noindex,hyper=false]
командам. Таким образом, у вас есть несколько похожих команд, охватывающих каждую из форм единственного и множественного числа, кратких, длинных и полных форм, а также строчные, заглавные первые буквы и полные заглавные формы.