.toc ファイルに手動で書き込む場合、\contentsline の 4 番目の引数は何にすればよいですか?

.toc ファイルに手動で書き込む場合、\contentsline の 4 番目の引数は何にすればよいですか?

目次を手動で変更したいです。その理由は、私の文書は「セクション」ではなく「演習」で構成されているからです。これを行うためにカスタマイズされたコマンドを記述しましたが、ほぼ正常に動作します。次のコマンドは、カスタム.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
        }%
    }%
}

これは基本的に私が望んでいることとまったく同じですが、ブックマークを作成しません。これはおそらく 4 番目の引数によるものです。 がどのようにhyperref再定義されるかを見つけようとしました\contentslineが、hyperref.sty理解するのは不可能です。

そこで質問です。定義の 4 番目の引数は何にすべきでしょうか? この 4 番目の引数がどのように機能するかも知りたいのですが、これは優先度が低いです。

注意: ToC をカスタマイズできるパッケージをインストールすることには興味がありません。これは練習として行っているので、独自の.styファイルを使用したいと考えています。

答え1

通常、 などの変更は がロードされる\contentsline前に行う必要があり、その後はによって追加されるの引数を考慮する必要があります。hyperref4th\contentslinehyperref

引数4thはハイパーアンカー、つまりsection.1または のようなものです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できます。を使用すると、ブックマークなどが自動的に処理されます。したがって、によって追加されたの 4 番目の引数を設定する方法を知る必要はありません。を使用するかどうかに関係なく (および が追加コードの前または後にロードされるかどうかに関係なく)機能する非常に単純なソリューションは次のようになります。\protecthyperref\addcontentsline\contentshyperrefhyperrefhyperref

\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}例を参照してください。

関連情報