當我手動寫入 .toc 檔案時,\contentsline 的第四個參數應該是什麼?

當我手動寫入 .toc 檔案時,\contentsline 的第四個參數應該是什麼?

我想手動更改我的目錄。原因是我的文件不是由「章節」組成,而是由「練習」組成。我已經編寫了一個自訂命令來執行此操作,並且它幾乎可以工作。以下命令放入自訂.sty檔案中,之後載入hyperref

\def\numberline@exer#1{%
\makebox[50pt][l]{\bf Ex. #1\hspace*{1em}}
}

\def\exercise#1{%
\section*{#1}\refstepcounter{exercise}\phantomsection%
\write\@auxout{%
    \protect\@writefile{toc}{%
        \protect\contentsline {section}{\numberline@exer{\theexercise}Title}{\thepage}%
{????}% This is the fourth argument, defined by hyperref
        }%
    }%
}

這基本上完全符合我的要求,只是它不創建書籤。這可能是由於第四個參數。我試圖找到如何hyperref重新定義\contentsline,但我發現hyperref.sty無法理解。

所以我的問題是:我的定義中的第四個參數應該是什麼?我還想知道第四個參數是如何運作的,但優先順序較低。

請注意,我對安裝任何可以自訂目錄的軟體包不感興趣。我這樣做是為了練習,所以我非常想.sty為此使用我自己的文件。

答案1

通常,\contentsline等的任何更改都應該在加載之前完成hyperref,之後必須考慮4th的參數\contentsline,由 添加hyperref

參數4th是超錨點,即類似section.1or 的東西east.17

超錨點可以使用 插入,由於已使用,\@currentHref因此應該提供正確的錨點。\phantomsection

為了添加書籤,請使用\Hy@writebookmark,因為\contentsline它本身不添加書籤,這是在包裝器命令中完成的\addcontentsline,這裡是「繞過」的。

\documentclass{article}


\usepackage[bookmarksopen]{hyperref}


\newcounter{exercise}


\makeatletter

\def\numberline@exer#1{%
\makebox[50pt][l]{\bfseries Ex. #1\hspace*{1em}}
}

\def\exercise#1{%
  \phantomsection
  \refstepcounter{exercise}
  \section*{#1}%
  \Hy@writebookmark{\csname theexercise\endcsname}{#1}{\@currentHref}{\toclevel@section}{toc}
  \write\@auxout{%
    \protect\@writefile{toc}{%
      \protect\contentsline {section}{\numberline@exer{\theexercise}#1}{\thepage}{\@currentHref}%
    }%
  }%

}
\makeatother

\usepackage{blindtext}

\begin{document}
\tableofcontents

\section{First section}\label{foosection}

\clearpage

\blindtext[3]
\exercise{Foo}
\blindtext[2]


\end{document}

在此輸入影像描述

更新通常的版本\addcontentsline

\documentclass{article}


\usepackage[bookmarksopen]{hyperref}


\newcounter{exercise}


\makeatletter

\newcommand*\l@exercise[2]{%
  \ifnum \c@tocdepth >\z@
    \addpenalty\@secpenalty
    \addvspace{1.0em \@plus\p@}%
    \setlength\@tempdima{3.8em}%
    \begingroup
      \parindent \z@ \rightskip \@pnumwidth
      \parfillskip -\@pnumwidth
      \leavevmode \bfseries
      \advance\leftskip\@tempdima
      \hskip -\leftskip
      #1\nobreak\hfil \nobreak\hb@xt@\@pnumwidth{\hss #2}\par
    \endgroup
  \fi}



\let\toclevel@exercise\toclevel@section

\newcommand{\exercisebetter}[1]{%
  \refstepcounter{exercise}
  \section*{#1}%
  \addcontentsline{toc}{exercise}{\protect\numberline{Ex: \theexercise}#1}
}


\makeatother

\usepackage{blindtext}

\begin{document}
\tableofcontents

\section{First section}\label{foosection}

\clearpage

\blindtext[3]

\exercisebetter{Foobar}
\blindtext[2]


\end{document}

答案2

我建議不要\write\@auxout直接使用而是使用\addcontentsline.\addcontentsline自動尊重\nofile和使用\protected@write,因此您可以使用它\protect來保護脆弱的命令。如果您使用.並hyperref自動處理書籤等。\addcontentsline所以你不需要知道如何設定\contentsadded by的第四個參數hyperref。一個非常簡單的解決方案,其工作獨立於使用hyperref與否(並且獨立於hyperref附加程式碼之前還是之後載入):

\documentclass{article}
\usepackage[bookmarksopen]{hyperref}

\providecommand*{\texorpdfstring}[2]{#1}% Needed if `hyperref` is not used.
\newcounter{exercise}
\makeatletter
\def\numberline@exer#1{%
  \texorpdfstring{\makebox[50pt][l]{\bfseries Ex. #1\hspace*{1em}}}{Ex. #1}
}

\newcommand\l@exercise{\l@section}
\newcommand*{\exercise}{%
  \@dblarg\@exercise
}
\newcommand*{\@exercise}[2][]{%
  \refstepcounter{exercise}%
  \section*{#2}%
  \addcontentsline{toc}{exercise}{\protect\numberline@exer{\theexercise}#1}%
}
\let\toclevel@exercise\toclevel@section
\makeatother

\usepackage{blindtext}

\begin{document}
\tableofcontents

\section{First section}\label{foosection}

\clearpage

\blindtext[3]
\exercise{Foo}
\blindtext[2]
\exercise[Bar]{Foo-Bar}
\blindtext

\end{document}

使用此解決方案\exercise\section還可以設定一個可選參數,並為目錄設定不同的文字。請參閱\exercise[Bar]{Foo-Bar}範例。

相關內容