Ich versuche, den \label
Befehl so zu ändern, dass er zusätzlich zur Seite und das Kapitel in einer .aux-Datei speichert \@currentlabel
. Ich habe Folgendes versucht, aber es funktioniert nicht.
\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}
Der neue Befehl \chapref
funktioniert einwandfrei, auch wenn er nicht erkannt wird, während \ref
und \pageref
eine Verkettung von \@currentlabel
\thepage
und zurückgeben thechapter
.
Ich verstehe nicht wirklich, wofür die Variablen stehen, \@newl@bel
und daher ist es für mich schwer zu erkennen, was ich falsch mache.
Wie ich im Kommentar erwähnt habe, bin ich an einer Lösung interessiert, die keine Referenzpakete erfordert. Ich kenne die schöne Lösung indiese Frage, aber ich würde gerne wissen, ob dies durch Ändern von \newlabel möglich ist.
Antwort1
Dies ist ganz einfach mit zref
der Definition einer neuen chapterprop
Eigenschaft und der \thechapter
anschließenden Speicherung möglich.
Der zu zahlende Preis ist \zref
und \zlabel
und \zpageref
jedoch
\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}
AktualisierenOhne *ref
zugehöriges Paket, nur durch Hacken \label
und \ref
Bereitstellen \pageref
der \@...ofthree
Befehle.
\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}
Antwort2
Ihr Code scheint zu funktionieren, nachdem Sie einige nicht notwendige Dinge auskommentiert und Definitionen für \@firstofthree
und hinzugefügt haben \@secondofthree
. ( \@thirdoftree
ist bereits definiert.)
Ihr Code unterbricht dieHyperref-Paket und funktioniert daher nur, solange dieHyperref-Paket ist nicht geladen.
\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}
Falls Sie denzref-Paket kann ich einen weiteren groben Hack anbieten, der dasHyperref-Paket:
Definieren/patchen Sie den \label
-Befehl neu, damit der \label
-Befehl das \@currentlabel
-Makro so patcht, dass es \@currentlabel
auf zwei Argumente erweitert wird, denen ein robuster Befehl zum Auswählen eines der beiden Argumente vorangestellt ist, wobei das erste Argument das enthält, was \@currentlabel
vor dem Patchen galt, und das zweite Argument Folgendes enthält \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}
Bei VerwendungHyperref, Hyperlinks mit \chapref
führen nicht zum Anfang des betreffenden Kapitels, sondern zu dem Anker, der als letzter vor dem entsprechenden gesetzt wurde \label
. Im obigen Beispiel \chapref{theo}
führt der Hyperlink mit also zum Anfang des betreffenden Theorems, zeigt aber die Nummer des Kapitels an, in dem dieses Theorem vorkommt.
Bei VerwendungHyperrefhaben Sie Varianten von „markiert“ \ref
und \pageref
die betreffenden Nummern angezeigt, aber keinen Hyperlink erstellt. Im Falle vonHyperrefwird geladen, es gibt auch eine „mit Sternchen versehene“ Variante von \chapref
.
!!!Ich habe keine Ahnung, ob einer dieser groben Hacks die Funktionalität irgendeiner Dokumentklasse oder irgendeines Pakets beeinträchtigen könnte.!!!
!!!Daher übernehme ich keinerlei Garantie. Sollte etwas kaputt gehen, obliegt der Umgang mit den Teilen Dir.!!!
!!!Aus Angst, die Funktionalität irgendeiner Dokumentklasse oder eines Pakets zu beeinträchtigen, empfehle ich dringend die Verwendung des zref-Pakets.!!!