2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Гибкая настройка подписей под рисунком
Сообщение25.07.2018, 13:15 
Аватара пользователя
Добрый день.
Я вообще в (Ла)ТеХе плохо разбираюсь и учу его возможности по мере возникновения прикладных задач. Вот возникла одна и я не смог найти ни стандартное решение, ни примитивными средствами.

Задача:
есть документ с кодом вида
Используется синтаксис LaTeX
\begin{figure}[t]
  \includegraphics[width=\textwidth]{img.png}
  \caption{Подпись к первому рисунку}
\end{figure}

\begin{figure}[t]
  \includegraphics[width=\textwidth]{img.png}
  \caption{Подпись ко второму рисунку}
\end{figure}

Нужно текст подписи (далее - подпись) подставить под рисунком и под ним "Рисунок #" (далее - маркер).

Стандартные средства и пакет caption, судя по документации, не позволяют менять порядок маркера и подписи.

Моё решение:
код: [ скачать ] [ спрятать ]
Используется синтаксис LaTeX
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1, T2A]{fontenc}
\usepackage[russian]{babel}
\selectlanguage{russian}
\usepackage{graphicx}

\usepackage{caption}
\DeclareCaptionLabelSeparator{dash}{}
\captionsetup[figure]{name=Рисунок}

\makeatletter

\let\original@figure\figure
\let\original@endfigure\endfigure

\newcommand{\my@caption}[2][]{
  \def\@title{#1}
  % подпись
  \par \centering #2
  % маркер
  \ifx\@title\empty
    \original@caption[#2]{}
  \else
    \original@caption[#1]{}
  \fi
}

\renewcommand{\figure}[1][]{
  % парсим аргументы
  \def\@arg{#1}
  \ifx\@arg\empty
    \original@figure[\@arg] % вызываем оригинальный \figure
  \else
    \original@figure
  \fi
  % подменяем \caption
  \let\original@caption\caption
  \def\caption{\my@caption}
}

\begin{document}

\begin{figure}[t]
  \includegraphics[width=\textwidth]{img.png}
  \caption{\label{fig:a}Подпись к первому рисунку}
\end{figure}

\begin{figure}[t]
  \includegraphics[width=\textwidth]{img.png}
  \caption{Подпись ко второму рисунку}
\end{figure}

См. \ref{fig:a}.

\end{document}

Основной недостаток решения: \label сбит. Ссылки не возможны.

Возможно ли достичь того же расположения стандартными или библиотечными средствами?
Возможно ли в приведённом решении решить проблемы ссылок?

 
 
 
 Re: Гибкая настройка подписей под рисунком
Сообщение25.07.2018, 15:25 
Аватара пользователя
Вытащите \label{} из \caption{}


код: [ скачать ] [ спрятать ]
Используется синтаксис LaTeX
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1, T2A]{fontenc}
\usepackage[russian]{babel}
\selectlanguage{russian}
\usepackage{hyperref}
\usepackage{tikz}

\usepackage{caption}
\DeclareCaptionLabelSeparator{dash}{}
\captionsetup[figure]{name=Рисунок}

\makeatletter

\let\original@figure\figure
\let\original@endfigure\endfigure

\newcommand{\my@caption}[2][]{
  \def\@title{#1}
  % подпись
  \par \centering #2
  % маркер
  \ifx\@title\empty
    \original@caption[#2]{}
  \else
    \original@caption[#1]{}
  \fi
}

\renewcommand{\figure}[1][]{
  % парсим аргументы
  \def\@arg{#1}
  \ifx\@arg\empty
    \original@figure[\@arg] % вызываем оригинальный \figure
  \else
    \original@figure
  \fi
  % подменяем \caption
  \let\original@caption\caption
  \def\caption{\my@caption}
}

\begin{document}

\begin{figure}[t]
  \begin{tikzpicture}
  \draw (0,0) circle (1);
  \end{tikzpicture}
 
  \caption{Подпись к первому рисунку}\label{fig:a}
\end{figure}

\begin{figure}[t]
  \begin{tikzpicture}
  \fill(0,0) circle (1);
  \end{tikzpicture}
  \caption{Подпись ко второму рисунку}
\end{figure}

См. \ref{fig:a} : \nameref{fig:a}

\end{document}

 
 
 
 Re: Гибкая настройка подписей под рисунком
Сообщение25.07.2018, 17:04 
Аватара пользователя
Спасибо. Понял, в чём была причина ошибки: оригинальный \label не может идти до оригинального \caption.

Значит, как вариант, пройтись sed'ом или perl'ом и вынести \label из \caption.
Или в \my@caption переопределить \label.
У меня получился этот рабочий вариант.
код: [ скачать ] [ спрятать ]
Используется синтаксис LaTeX
\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1, T2A]{fontenc}
\usepackage[russian]{babel}
\selectlanguage{russian}
\usepackage{hyperref}
\usepackage{tikz}

\usepackage{caption}
\DeclareCaptionLabelSeparator{dash}{}
\captionsetup[figure]{name=Рисунок}

\makeatletter

\let\original@figure\figure
\let\original@endfigure\endfigure

\newcommand{\my@caption}[2][]{
   \def\@title{#1}
   \let\original@label\label
   \let\label\my@label
   % подпись
   \par \centering #2
   % маркер
   \ifx\@title\empty
     \original@caption[#2]{}
   \else
     \original@caption[#1]{}
   \fi
   \let\label\original@label
   \expandafter\label\expandafter{\current@label}
}

\newcommand{\my@label}[1]{
  \def\current@label{#1}
}

\renewcommand{\table}[1][]{
   % парсим аргументы
   \def\@arg{#1}
   \ifx\@arg\empty
     \original@figure[\@arg] % вызываем оригинальный \figure
   \else
     \original@figure
   \fi
   % подменяем \caption
   \let\original@caption\caption
   \def\caption{\my@caption}
}

\begin{document}

\begin{figure}[t]
   \begin{tikzpicture}
   \draw (0,0) circle (1);
   \end{tikzpicture}
   \caption{\label{fig:a}Подпись к первому рисунку}
\end{figure}

\begin{figure}[t]
   \begin{tikzpicture}
   \fill(0,0) circle (1);
   \end{tikzpicture}
   \caption{Подпись ко второму рисунку}
\end{figure}

 См. \ref{fig:a} : \nameref{fig:a}

\end{document}


Ещё прошу посмотрерь, с точки зрения программирования в (La)TeX нет ли каких подводных камней в предложенном коде.
Я не до конца понимаю работу областей видимостей и локализацию переменных, поэтому боюсь возможных конфликтов. Кажется, оригинальные \figure и \endfigure содержат внутри себя \bgroup \egroup, поэтому переопределение \caption не вылезет за пределы окружения. Но всё же не уверен.

 
 
 [ Сообщений: 3 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group