Спасибо. Понял, в чём была причина ошибки: оригинальный
\label не может идти до оригинального
\caption.
Значит, как вариант, пройтись sed'ом или perl'ом и вынести
\label из
\caption.
Или в
\my@caption переопределить
\label.
У меня получился этот рабочий вариант.
\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 не вылезет за пределы окружения. Но всё же не уверен.