Цвет записей разделов в содержании соответствует номерам разделов

Цвет записей разделов в содержании соответствует номерам разделов

Я верстаю документ, в котором цвет заголовков разделов периодически меняется. Я хочу также раскрасить записи разделов в toc в соответствии с цветами соответствующих разделов.

Чтобы сделать это, я использую \setkomafont{sectioning}и "внедряю" команды цвета в toc. Это работает так, как и ожидалось, хотя у меня есть ощущение, что последнее является своего рода неправильным использованием записей toc. \setkomafont{sectionentry}и \setkomafont{sectionentrypagenumber}не работает, поскольку они окрашивают их всех одинаково (поскольку они, конечно, находятся в одном и том же разделе документа).

Проблема в следующем: когда я использую hyperref, я получаю эти Token not allowed in a PDF stringпредупреждения, поскольку эти "инжектированные" команды попадают в оглавление файла PDF. Еще большей проблемой является то, что при переопределении hyperref \contentslineцвет номера страницы исчезает. \DeclareTOCStyleEntryне помогает в любом случае, поскольку он не знает номер раздела, который необходим для определения правильного цвета. Тем не менее, он нужен, чтобы сделать это правильно без hyperref.

Вот 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}

Следует отметить, что использование этого tocloftпакета — лишь крайний вариант, поскольку koma-script не рекомендует использовать tocloft.

Раскомментируйте, \usepackage{hyperref}чтобы увидеть желаемый результат. Спасибо за любую помощь или предложения.

решение1

ну, "токен не допускается" можно обойти, как всегда \texorpdfstring, с помощью , например, что-то вроде \texorpdfstring{\protect\structurecolor[#1]#2}{#2}. Относительно цвета: вы полагаетесь на то, что текст и номер страницы находятся в одной группе. Но hyperref, естественно, должен добавить скобки и группировку для ссылок. Сохраните цвет в какой-нибудь глобальной переменной, а затем повторите его в номере страницы:

\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}

введите описание изображения здесь

решение2

Если вы используете \addtocontents{toc}{}внутри \renewcommand{\addsectiontocentry}{...}него, это никак не влияет на pdf toc. Тогда вам не нужно вызывать \structurecolor[#1]внутри \addtocentrydefault. Используйте \begingroup ... \endgroupдля внесения изменений локально. Этот способ даже \DeclareTOCStyleEntryбольше не нужен.

\renewcommand{\addsectiontocentry}[2]{%
  \IfArgIsEmpty{#1}{%
    \addtocentrydefault{section}{}{#2}
  }{%
    \addtocontents{toc}{\begingroup\structurecolor[#1]}
    \addtocentrydefault{section}{#1}{#2}
    \addtocontents{toc}{\endgroup}
  }
}

Полная МВЭ:

\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}

Связанный контент