Modificando a definição de rótulo

Modificando a definição de rótulo

Estou tentando modificar o \labelcomando 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 \chapreffunciona bem mesmo que não seja reconhecido, while \refe \pagerefretorna a concatenação de \@currentlabel \thepagee thechapter.

Eu realmente não entendo o que as variáveis ​​​​representam, \@newl@belo 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 zrefdefinir uma nova chapterproppropriedade, armazenando o \thechapterarquivo then.

O preço a pagar é \zrefe \zlabele \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 *refpacote relacionado, apenas hackeando \labele \reffornecendo \pagerefos \@...ofthreecomandos.

\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}

insira a descrição da imagem aqui

Responder2

Parece que seu código funciona depois de comentar algumas coisas que não são necessárias e adicionar definições para \@firstofthreee \@secondofthree. ( \@thirdoftreejá 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 à \@currentlabelexpansão para dois argumentos precedidos por um comando robusto para selecionar um dos dois argumentos, o primeiro argumento contendo o que \@currentlabelera 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 \chaprefnã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 \refe \pagerefexibiu 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.!!!

informação relacionada