
Compuso un documento donde el color de los encabezados de las secciones cambia periódicamente. Quiero colorear las entradas de las secciones en el toc y también hacerlas coincidir con los colores de las secciones correspondientes.
Para hacer esto, uso \setkomafont{sectioning}
e "inyecto" comandos de color en el toc. Esto funciona como se esperaba aunque tengo la sensación de que esto último es una especie de mal uso de las entradas del toc. \setkomafont{sectionentry}
y \setkomafont{sectionentrypagenumber}
no funcionan ya que los colorean todos iguales (ya que, por supuesto, están en la misma sección del documento).
El problema es: cuando uso hyperref, recibo esas Token not allowed in a PDF string
advertencias cuando estos comandos "infectados" llegan a la tabla de contenido del archivo PDF. Lo que es aún más problemático es que a medida que hyperref redefine \contentsline
el color del número de página desaparece. \DeclareTOCStyleEntry
de todos modos no ayuda porque no sabe el número de la sección que se necesita para determinar el color correcto. Sin embargo, es necesario hacerlo bien sin hiperreferencia.
Aquí hay un MWE:
\documentclass{scrartcl}
\usepackage{xcolor}
\usepackage{blindtext}
\usepackage{arrayjobx}
\usepackage{pgf}
\usepackage{hyperref}
\colorlet{myblue}{blue!60!green!90!black}
\colorlet{myred}{red!80!black}
\colorlet{mygreen}{green!40!black}
\colorlet{default}{black}
\newarray\structurecolors
\readarray{structurecolors}{mygreen&myblue&myred}
\makeatletter
\newcommand{\structurecolor}[1][\value{section}]{%
\pgfmathparse{int(mod(#1,\total@structurecolors) + 1)}%
\checkstructurecolors(\pgfmathresult)%
\color{\cachedata}%
\ifnum#1=0%
\color{black}
\fi
}
\makeatother
\setkomafont{sectioning}{\sffamily\bfseries\structurecolor}
\renewcommand{\addsectiontocentry}[2]{%
\IfArgIsEmpty{#1}{%
\addtocentrydefault{section}{}{#2}
}{%
\addtocentrydefault{section}{\structurecolor[#1]#1}{\protect\structurecolor[#1]#2}
}
}
\DeclareTOCStyleEntry[pagenumberformat={\sffamily\bfseries}]{default}{section}
\begin{document}
\tableofcontents
\Blinddocument
\Blinddocument
\end{document}
Debo mencionar que usar el tocloft
paquete es solo el último recurso ya que koma-script desaprueba el uso de tocloft.
Descomente \usepackage{hyperref}
para ver el resultado deseado. Gracias por cualquier ayuda o sugerencia.
Respuesta1
Bueno, el "token no permitido" se puede evitar, como siempre \texorpdfstring
, con, por ejemplo, algo como \texorpdfstring{\protect\structurecolor[#1]#2}{#2}
. En cuanto al color: confías en que el texto y el número de página estén en el mismo grupo. Pero, naturalmente, hyperref tiene que agregar llaves y agrupaciones para los enlaces. Guarde el color en alguna variable global y luego repítalo en el número de página:
\documentclass{scrartcl}
\usepackage{xcolor}
\usepackage{blindtext}
\usepackage{arrayjobx}
\usepackage{pgf}
\usepackage{hyperref}
\colorlet{myblue}{blue!60!green!90!black}
\colorlet{myred}{red!80!black}
\colorlet{mygreen}{green!40!black}
\colorlet{default}{black}
\newarray\structurecolors
\readarray{structurecolors}{mygreen&myblue&myred}
\makeatletter
\newcommand{\structurecolor}[1][\value{section}]{%
\pgfmathparse{int(mod(#1,\total@structurecolors) + 1)}%
\checkstructurecolors(\pgfmathresult)%
\color{\cachedata}%
\global\let\currentstructurecolor\cachedata
\ifnum#1=0%
\color{black}
\fi
}
\makeatother
\setkomafont{sectioning}{\sffamily\bfseries\structurecolor}
\renewcommand{\addsectiontocentry}[2]{%
\IfArgIsEmpty{#1}{%
\addtocentrydefault{section}{}{#2}
}{%
\addtocentrydefault{section}{\structurecolor[#1]#1}{\texorpdfstring{\protect\structurecolor[#1]#2}{#2}}
}
}
\DeclareTOCStyleEntry[pagenumberformat={\sffamily\bfseries\color{\currentstructurecolor}}]{default}{section}
\begin{document}
\showoutput
\tableofcontents
\section{a}
\section{b}
% \Blinddocument
% \Blinddocument
\end{document}
Respuesta2
Si lo usa \addtocontents{toc}{}
dentro de \renewcommand{\addsectiontocentry}{...}
él, no afecta el contenido del pdf de ninguna manera. Entonces no es necesario que llames \structurecolor[#1]
al interior de \addtocentrydefault
. Utilícelo \begingroup ... \endgroup
para realizar los cambios de forma local. De esta manera ya \DeclareTOCStyleEntry
ni siquiera es necesario.
\renewcommand{\addsectiontocentry}[2]{%
\IfArgIsEmpty{#1}{%
\addtocentrydefault{section}{}{#2}
}{%
\addtocontents{toc}{\begingroup\structurecolor[#1]}
\addtocentrydefault{section}{#1}{#2}
\addtocontents{toc}{\endgroup}
}
}
MWE completo:
\documentclass{scrartcl}
\usepackage{xcolor}
\usepackage{blindtext}
\usepackage{arrayjobx}
\usepackage{pgf}
\usepackage{hyperref}
\colorlet{myblue}{blue!60!green!90!black}
\colorlet{myred}{red!80!black}
\colorlet{mygreen}{green!40!black}
\colorlet{default}{black}
\newarray\structurecolors
\readarray{structurecolors}{mygreen&myblue&myred}
\makeatletter
\newcommand{\structurecolor}[1][\value{section}]{%
\pgfmathparse{int(mod(#1,\total@structurecolors) + 1)}%
\checkstructurecolors(\pgfmathresult)%
\color{\cachedata}%
\ifnum#1=0%
\color{black}
\fi
}
\makeatother
\setkomafont{sectioning}{\sffamily\bfseries\structurecolor}
\setkomafont{sectionentry}{\sffamily\bfseries}
\renewcommand{\addsectiontocentry}[2]{%
\IfArgIsEmpty{#1}{%
\addtocentrydefault{section}{}{#2}
}{%
\addtocontents{toc}{\begingroup\structurecolor[#1]}
\addtocentrydefault{section}{#1}{#2}
\addtocontents{toc}{\endgroup}
}
}
\begin{document}
\tableofcontents
\section{a}
\section{b}
\end{document}