Estou tentando modificar o \label
comando para que armazene o capítulo no arquivo .aux além de page e \@currentlabel
. Eu tentei o que segue e não funciona.
\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}
O novo comando \chapref
funciona bem mesmo que não seja reconhecido, while \ref
e \pageref
retorna a concatenação de \@currentlabel
\thepage
e thechapter
.
Eu realmente não entendo o que as variáveis representam, \@newl@bel
o que torna difícil para mim ver o que estou fazendo de errado.
Como mencionei no comentário, estou interessado em uma solução que não requeira nenhum pacote de referência. Estou ciente da boa solução emessa questão, mas gostaria de saber se isso pode ser feito modificando o \newlabel.
Responder1
Isso é bastante fácil de zref
definir uma nova chapterprop
propriedade, armazenando o \thechapter
arquivo then.
O preço a pagar é \zref
e \zlabel
e \zpageref
, no entanto
\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}
AtualizarSem nenhum *ref
pacote relacionado, apenas hackeando \label
e \ref
fornecendo \pageref
os \@...ofthree
comandos.
\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}
Responder2
Parece que seu código funciona depois de comentar algumas coisas que não são necessárias e adicionar definições para \@firstofthree
e \@secondofthree
. ( \@thirdoftree
já está definido.)
Seu código quebra ohiperref-package e, portanto, só funciona enquanto ohiperref-pacote não está carregado.
\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}
Caso você realmente não queira usar ozref-package posso oferecer outro hack bruto que parece não quebrar ohiperref-pacote:
Redefina/corrija o \label
-command para que o \label
-command corrija a \@currentlabel
-macro de uma forma que leve à \@currentlabel
expansão para dois argumentos precedidos por um comando robusto para selecionar um dos dois argumentos, o primeiro argumento contendo o que \@currentlabel
era mantido antes de ser corrigido, o segundo argumento segurando \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}
No caso de usarhiperref, os hiperlinks com \chapref
não levarão ao início do capítulo em questão, mas sim à âncora que foi colocada como última antes de colocar o correspondente \label
. Assim, com o exemplo acima, o hiperlink com \chapref{theo}
irá para o início do teorema em questão, embora exibindo o número do capítulo onde esse teorema ocorre.
No caso de usarhiperref, você marcou variantes com estrela \ref
e \pageref
exibiu os números em questão, mas não produziu um hiperlink. Portanto em caso dehiperrefsendo carregado, há também uma variante "com estrela" de \chapref
.
!!!Não tenho ideia se algum desses hacks grosseiros pode quebrar a funcionalidade de qualquer classe de documento ou pacote.!!!
!!!Portanto não dou nenhuma garantia. Se algo quebrar, o manuseio dos pedaços é com você.!!!
!!!O medo de quebrar a funcionalidade de qualquer documentclass ou pacote me leva a recomendar fortemente o uso do pacote zref.!!!