Я пытаюсь изменить \label
команду так, чтобы она сохраняла главу в файле .aux в дополнение к странице и \@currentlabel
. Я попробовал то, что указано ниже, но это не работает.
\documentclass{book}
\usepackage{amsthm}
\makeatletter
\def\@newl@bel#1#2#3{%
\@ifundefined{#1@#2}%
\relax
{\gdef \@multiplelabels {%
\@latex@warning@no@line{There were multiply-defined labels}}%
\@latex@warning@no@line{Label `#2' multiply defined}}%
\global\@namedef{#1@#2}{#3}}
\def\newlabel{\@newl@bel r}
\@onlypreamble\@newl@bel
\let \@multiplelabels \relax
\def\label#1{\@bsphack
\protected@write\@auxout{}%
{\string\newlabel{#1}{{\@currentlabel}{\thepage}{\thechapter}}}%
\@esphack}
\def\refstepcounter#1{\stepcounter{#1}%
\protected@edef\@currentlabel
{\csname p@#1\endcsname\csname the#1\endcsname}%
}
\def\ref#1{\expandafter\@setref\csname r@#1\endcsname\@firstofthree{#1}}
\def\pageref#1{\expandafter\@setref\csname r@#1\endcsname\@secondofthree{#1}}
\def\chapref#1{\expandafter\@setref\csname r@#1\endcsname\@thirdofthree{#1}}
\makeatother
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}
\begin{document}
\setcounter{page}{3}
\setcounter{chapter}{1}
\chapter{abc}
\begin{theorem}\label{theo}abc\end{theorem}
Theorem \ref{theo} in chapter \chapref{theo}, page \pageref{theo} says that abc.
\end{document}
Новая команда \chapref
работает нормально, даже если она не распознана, хотя \ref
и \pageref
возвращает конкатенацию \@currentlabel
\thepage
и thechapter
.
Я не совсем понимаю, что означают переменные, \@newl@bel
поэтому мне сложно понять, что я делаю неправильно.
Как я уже упоминал в комментарии, меня интересует решение, которое не требует никаких справочных пакетов. Я знаю о хорошем решении вэтот вопрос, но я хотел бы узнать, можно ли это сделать, изменив \newlabel.
решение1
Это довольно просто сделать zref
, определив новое chapterprop
свойство и сохранив \thechapter
его.
Цена, которую придется заплатить, это \zref
и \zlabel
и \zpageref
, однако
\documentclass{book}
\usepackage{amsthm}
\usepackage[user]{zref}
\makeatletter
\zref@newprop{chapterprop}{\thechapter}
\zref@addprops{main}{chapterprop}
\newcommand{\chapref}[1]{\zref@extract{#1}{chapterprop}}%\expandafter\@setref\csname r@#1\endcsname\@thirdofthree{#1}}
\makeatother
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}
\begin{document}
\setcounter{page}{3}
\setcounter{chapter}{1}
\chapter{abc}
\begin{theorem}\zlabel{theo}abc\end{theorem}
Theorem \zref{theo} in chapter \chapref{theo}, page \zpageref{theo} says that abc.
\end{document}
ОбновлятьБез какого-либо *ref
соответствующего пакета, просто взлом и \label
предоставление команд .\ref
\pageref
\@...ofthree
\documentclass{book}
\usepackage{amsthm}
\makeatletter
\def\label#1{\@bsphack
\protected@write\@auxout{}%
{\string\newlabel{#1}{{\@currentlabel}{\thepage}{\thechapter}}}%
\@esphack}
\long\def\@firstofthree#1#2#3{#1}
\long\def\@secondofthree#1#2#3{#2}
%\long\def\@threeofthree#1#2#3{#3}% Is defined in `latex.ltx` already
\def\ref#1{\expandafter\@setref\csname r@#1\endcsname\@firstofthree{#1}}
\def\pageref#1{\expandafter\@setref\csname r@#1\endcsname
\@secondofthree{#1}}
\def\chapref#1{\expandafter\@setref\csname r@#1\endcsname
\@thirdofthree{#1}}
\makeatother
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}
\begin{document}
\setcounter{page}{3}
\setcounter{chapter}{1}
\chapter{abc}
\begin{theorem}\label{theo}abc\end{theorem}
Theorem \ref{theo} in chapter \chapref{theo}, page \pageref{theo} says that abc.
\end{document}
решение2
Кажется, ваш код работает после того, как вы закомментировали несколько ненужных вещей и добавили определения для \@firstofthree
и \@secondofthree
. ( \@thirdoftree
уже определено.)
Ваш код нарушаетгиперреф-пакет и поэтому работает только до тех пор, покагиперреф-пакет не загружен.
\documentclass{book}
\usepackage{amsthm}
\makeatletter
\renewcommand*\@newl@bel[3]{%
\@ifundefined{#1@#2}%
\relax
{%
\gdef\@multiplelabels{%
\@latex@warning@no@line{There were multiply-defined labels}%
}%
\@latex@warning@no@line{Label `#2' multiply defined}%
}%
\global\@namedef{#1@#2}{#3}%
}%
%\@onlypreamble\@newl@bel
%\let\@multiplelabels\relax
\renewcommand*\label[1]{%
\@bsphack
\protected@write\@auxout
{}%
{\string\newlabel{#1}{{\@currentlabel}{\thepage}{\thechapter}}}%
\@esphack
}%
%\def\refstepcounter#1{%
% \stepcounter{#1}%
% \protected@edef\@currentlabel
% {\csname p@#1\endcsname\csname the#1\endcsname}%
%}%
\renewcommand*\ref[1]{%
\expandafter\@setref\csname r@#1\endcsname\@firstofthree{#1}%
}%
\renewcommand*\pageref[1]{%
\expandafter\@setref\csname r@#1\endcsname\@secondofthree{#1}%
}%
\newcommand*\chapref[1]{%
\expandafter\@setref\csname r@#1\endcsname\@thirdofthree{#1}%
}
\newcommand\@firstofthree[3]{#1}%
\newcommand\@secondofthree[3]{#2}%
%\newcommand\@thirdofthree[3]{#3}%
\makeatother
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}
\begin{document}
\setcounter{page}{3}
\setcounter{chapter}{1}
\chapter{abc}
\begin{theorem}\label{theo}abc\end{theorem}
Theorem \ref{theo} in chapter \chapref{theo}, page \pageref{theo} says that abc.
\end{document}
Если вы действительно не хотите использоватьzref-package Я могу предложить еще один грубый хак, который, похоже, не сломаетгиперреф-упаковка:
Переопределите/исправьте \label
-команду, чтобы она \label
исправила -макрос \@currentlabel
таким образом, чтобы он \@currentlabel
расширился до двух аргументов, которым предшествовала надежная команда для выбора одного из двух аргументов, причем первый аргумент содержит то, что \@currentlabel
было до исправления, а второй аргумент содержит \thechapter
:
\documentclass{book}
\usepackage{amsthm}
%%\usepackage{hyperref}
\makeatletter
\DeclareRobustCommand\My@GetRefArg[2]{#1}%
\DeclareRobustCommand\MyOther@GetRefArg[2]{#2}%
\newcommand\My@saved@currentlabel{}%
\AtBeginDocument{%
\let\My@oldlabel=\label
\renewcommand\label[1]{%
\@bsphack
\let\My@saved@currentlabel=\@currentlabel
\expandafter\def
\expandafter\@currentlabel
\expandafter{%
\expandafter\My@GetRefArg
\expandafter{%
\@currentlabel}{\thechapter}}%
\@esphack
\My@oldlabel{#1}%
\@bsphack
\let\@currentlabel=\My@saved@currentlabel
\@esphack
}%
\@ifpackageloaded{hyperref}{%
\DeclareRobustCommand\chaprefAtNoStar[1]{%
\begingroup
\let\My@GetRefArg\MyOther@GetRefArg
\ref{#1}%
\endgroup
}%
\DeclareRobustCommand\chaprefAtStar[1]{%
\begingroup
\let\My@GetRefArg\MyOther@GetRefArg
\ref*{#1}%
\endgroup
}%
\DeclareRobustCommand\chapref{%
\@ifstar\chaprefAtStar\chaprefAtNoStar
}%
}{%
\DeclareRobustCommand\chapref[1]{%
\begingroup
\let\My@GetRefArg\MyOther@GetRefArg
\ref{#1}%
\endgroup
}%
}%
}%
\makeatother
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}
\begin{document}
\setcounter{page}{3}
\setcounter{chapter}{1}
\chapter{abc}
\begin{theorem}\label{theo}abc\end{theorem}
Theorem \ref{theo} in chapter \chapref{theo}, page \pageref{theo} says that abc.
%%
%%Theorem \ref*{theo} in chapter \chapref*{theo}, page \pageref*{theo} says that abc.
\end{document}
В случае использованиягиперреф, гиперссылки с \chapref
будут вести не к началу рассматриваемой главы, а к якорю, который был помещен последним перед размещением соответствующего \label
. Таким образом, в примере выше гиперссылка с \chapref{theo}
будет вести к началу рассматриваемой теоремы, хотя и отображает номер главы, в которой эта теорема встречается.
В случае использованиягиперреф, у вас есть "звездные" варианты \ref
и \pageref
отображающие номера в вопросе, но не создающие гиперссылку. Поэтому в случаегиперрефзагружается также «звездчатый» вариант \chapref
.
!!!Я понятия не имею, могут ли какие-либо из этих грубых хаков нарушить функциональность какого-либо класса документов или пакета.!!!
!!!Поэтому я не даю никаких гарантий. Если что-то сломается, то разбираться с осколками придется вам.!!!
!!!Опасение нарушить функциональность любого класса документа или пакета заставляет меня настоятельно рекомендовать использовать zref-package.!!!