
我想手動更改我的目錄。原因是我的文件不是由「章節」組成,而是由「練習」組成。我已經編寫了一個自訂命令來執行此操作,並且它幾乎可以工作。以下命令放入自訂.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.1
or 的東西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
所以你不需要知道如何設定\contents
added 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}
範例。