Estoy intentando modificar el \label
comando para que almacene el capítulo en un archivo .aux además de la página y \@currentlabel
. Probé lo siguiente y no 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}
El nuevo comando \chapref
funciona bien aunque no se reconozca, while \ref
y \pageref
devuelve la concatenación de \@currentlabel
\thepage
y thechapter
.
Realmente no entiendo qué representan las variables, \@newl@bel
lo que me dificulta ver qué estoy haciendo mal.
Como mencioné en el comentario, estoy interesado en una solución que no requiera ningún paquete de referencia. Soy consciente de la buena solución enesta pregunta, pero me gustaría saber si se puede hacer modificando el archivo \newlabel.
Respuesta1
Esto es bastante fácil al zref
definir una nueva chapterprop
propiedad y almacenar el \thechapter
then.
El precio a pagar es \zref
y \zlabel
y \zpageref
, sin embargo
\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}
ActualizarSin ningún *ref
paquete relacionado, simplemente pirateando \label
y \ref
proporcionando \pageref
los \@...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}
Respuesta2
Parece que su código funciona después de comentar algunas cosas que no son necesarias y agregar definiciones para \@firstofthree
y \@secondofthree
. ( \@thirdoftree
ya está definido).
Tu código rompe elhiperreferencia-paquete y por lo tanto sólo funciona mientras elhiperreferencia-el paquete no está cargado.
\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}
En caso de que realmente no desee utilizar elzref-paquete Puedo ofrecer otro truco burdo que parece no romper elhiperreferencia-paquete:
Redefina/parchee el \label
comando para que el \label
comando parchee la \@currentlabel
macro de manera que \@currentlabel
se expanda a dos argumentos precedidos por un comando robusto para seleccionar uno de los dos argumentos, el primer argumento contiene lo que \@currentlabel
tenía antes de ser parcheado, el segundo argumento que sostiene \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}
En caso de utilizarhiperreferencia, los hipervínculos con \chapref
no conducirán al inicio del capítulo en cuestión sino al ancla que se colocó como último antes de colocar el correspondiente \label
. Así, con el ejemplo anterior, el hipervínculo con \chapref{theo}
irá al inicio del teorema en cuestión aunque mostrará el número del capítulo donde ocurre ese teorema.
En caso de utilizarhiperreferencia, ha "destacado" variantes \ref
y \pageref
muestra los números en cuestión pero no genera un hipervínculo. Por lo tanto en caso dehiperreferenciaAl cargarse también hay una variante "estrellada" de \chapref
.
¡¡¡No tengo idea de si alguno de estos trucos burdos podría romper la funcionalidad de cualquier clase de documento o paquete.!!!
!!!Por lo tanto no doy ninguna garantía. Si algo se rompe el manejo de las piezas depende de ti.!!!
!!!El miedo a romper la funcionalidad de cualquier clase de documento o paquete me lleva a recomendar encarecidamente el uso del paquete zref.!!!