Quero alterar meu índice manualmente. A razão é que meu documento não é composto tanto de "seções", mas sim de "exercícios". Eu escrevi um comando personalizado para fazer isso e quase funciona. Os seguintes comandos são colocados em um .sty
arquivo personalizado, carregado depois 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
}%
}%
}
Basicamente, isso faz exatamente o que eu quero, exceto que não cria um marcador. Isto provavelmente se deve ao quarto argumento. Tentei descobrir como hyperref
redefine \contentsline
, mas acho hyperref.sty
impossível entender.
Portanto, minha pergunta é: qual deveria ser o quarto argumento da minha definição? Gostaria também de saber como funciona esse quarto argumento, mas é de baixa prioridade.
Nota: não estou interessado em instalar nenhum pacote que possa personalizar ToCs. Estou fazendo isso como prática, então gostaria muito de usar meu próprio .sty
arquivo para isso.
Responder1
Normalmente, qualquer alteração de \contentsline
etc. deve ser feita antes de hyperref
ser carregado, depois deve-se considerar o 4th
argumento de \contentsline
, sendo adicionado por hyperref
.
O 4th
argumento é a hiperâncora, ou seja, algo como section.1
ou east.17
.
A hiperâncora pode ser inserida com \@currentHref
, o que deve fornecer a âncora correta desde que \phantomsection
foi utilizada.
Para adicionar o marcador, use \Hy@writebookmark
, já que \contentsline
ele próprio não adiciona os marcadores, isso é feito no comando wrapper \addcontentsline
, que é 'ignorado' aqui.
\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}
AtualizarUma versão com o habitual \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}
Responder2
Eu recomendaria não usar \write\@auxout
diretamente, mas usar \addcontentsline
. \addcontentsline
respeita \nofile
e usa automaticamente \protected@write
para que você possa usar \protect
para proteger comandos frágeis. E hyperref
lida automaticamente com marcadores, etc., se você usar \addcontentsline
. Portanto, você não precisa saber como definir o quarto argumento de \contents
add by hyperref
. Uma solução muito simples que funciona independente do uso hyperref
ou não (e independente de hyperref
ser carregada antes ou depois do código adicional) seria:
\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}
Com esta solução \exercise
também \section
existe um argumento opcional para definir um texto diferente para o índice. Veja \exercise[Bar]{Foo-Bar}
no exemplo.