2014 dxdy logo

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

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




Начать новую тему Ответить на тему
 
 Гибкая настройка подписей под рисунком
Сообщение25.07.2018, 13:15 
Аватара пользователя


29/05/11
227
Красноармейск, Донецкая обл.
Добрый день.
Я вообще в (Ла)ТеХе плохо разбираюсь и учу его возможности по мере возникновения прикладных задач. Вот возникла одна и я не смог найти ни стандартное решение, ни примитивными средствами.

Задача:
есть документ с кодом вида
Используется синтаксис 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 
Заслуженный участник
Аватара пользователя


31/01/14
11053
Hogtown
Вытащите \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 
Аватара пользователя


29/05/11
227
Красноармейск, Донецкая обл.
Спасибо. Понял, в чём была причина ошибки: оригинальный \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 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group