修改標籤的定義

修改標籤的定義

我正在嘗試修改該\label命令,以便除了 page 和 .aux 檔案之外,還將章節儲存在 .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即使無法識別,也可以正常工作, while\ref\pageref返回\@currentlabel \thepage和的串聯thechapter

我不太明白這些變數代表什麼,\@newl@bel這讓我很難看出我做錯了什麼。

正如我在評論中提到的,我對不需要任何參考包的解決方案感興趣。我知道很好的解決方案這個問題,但我想知道是否可以透過修改\newlabel來完成。

答案1

zref定義一個新chapterprop屬性並儲存 then非常容易\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已經定義了。)

你的程式碼確實打破了超引用-package,因此只有在下列情況下才有效超引用- 包未載入。

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

如果您確實不想使用茲參考-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

!!!因此我不提供任何保證。如果有東西壞了,處理碎片就取決於你了。

相關內容