我如何修改 \@dottedtocline 以便它为自定义分段命令生成连续线而不是虚线?

我如何修改 \@dottedtocline 以便它为自定义分段命令生成连续线而不是虚线?

我需要在技术文档中表示深度嵌套的容器结构。在我的表示中,每个容器都需要有自己的部分,子容器包含在子部分中。为了实现这一点,我使用 titlesec 的\titleclass命令定义了超出子段落的自定义分段命令。我公司的 .sty 文件使用以下方法将目录中的引线定义为实线:

\renewcommand{\cftdot}{\rule{1pt}{0.4pt}}
\renewcommand{\cftdotsep}{0}

根据tocloft 包文档这应该会\@dottedtocline产生实线而不是虚线。虽然这适用于默认的分段命令,但我的自定义命令仍然会在目录中产生虚线:

\documentclass[a4paper,11pt]{report}

\usepackage{titlesec}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[titles]{tocloft}

%% use solid lines instead of dotted lines for toc
\renewcommand{\cftdot}{\rule{1pt}{0.4pt}}
\renewcommand{\cftdotsep}{0}

%% Indentation
\cftsetindents{section}{2em}{3em}
\cftsetindents{subsection}{2em}{4.0em}
\cftsetindents{subsubsection}{2em}{5.0em}
\cftsetindents{paragraph}{2em}{6.0em}
\cftsetindents{subparagraph}{2em}{7.0em}

\titleformat{\section}{\large\bf}{\thesection}{1em}{}
\titleformat{\subsection}{\bf}{\thesubsection}{1em}{}
\titleformat{\subsubsection}{\bf}{\thesubsubsection}{1em}{}
\titleformat{\paragraph}{\bf}{\theparagraph}{1em}{}
\titleformat{\subparagraph}{\bf}{\thesubparagraph}{1em}{}
\titlespacing{\section}{0pt}{21pt}{3pt}
\titlespacing{\subsection}{0pt}{21pt}{3pt}
\titlespacing{\subsubsection}{0pt}{21pt}{3pt}
\titlespacing{\paragraph}{0pt}{21pt}{3pt}
\titlespacing{\subparagraph}{0pt}{21pt}{3pt}

\newcommand{\levelOneSubsection}[1]{\subsection{#1}}
\newcommand{\levelTwoSubsection}[1]{\subsubsection{#1}}
\newcommand{\levelThreeSubsection}[1]{\paragraph{#1}}
\newcommand{\levelFourSubsection}[1]{\subparagraph{#1}}

% define \levelFiveSubsection
\titleclass{\levelFiveSubsection}{straight}[\subparagraph]
\newcounter{levelFiveSubsection}[subparagraph]
\renewcommand{\thelevelFiveSubsection}{\thesubparagraph.\arabic{levelFiveSubsection}}
\titleformat{\levelFiveSubsection}{\bf}{\thelevelFiveSubsection}{1em}{}
\titlespacing{\levelFiveSubsection}{0pt}{21pt}{3pt}
\makeatletter
  \def\toclevel@levelFiveSubsection{5}
  \def\l@levelFiveSubsection{\@dottedtocline{5}{2em}{8em}}
\makeatother

% define \levelSixSubsection
\titleclass{\levelSixSubsection}{straight}[\levelFiveSubsection]
\newcounter{levelSixSubsection}[levelFiveSubsection]
\renewcommand{\thelevelSixSubsection}{\thelevelFiveSubsection.\arabic{levelSixSubsection}}
\titleformat{\levelSixSubsection}{\bf}{\thelevelSixSubsection}{1em}{}
\titlespacing{\levelSixSubsection}{0pt}{21pt}{3pt}
\makeatletter
  \def\toclevel@levelSixSubsection{6}
  \def\l@levelSixSubsection{\@dottedtocline{6}{2em}{9em}}
\makeatother

%% Number down to levelSixSubsections
\setcounter{secnumdepth}{8}

\setcounter{tocdepth}{6}

%% Indentation
\cftsetindents{section}{2em}{3em}
\cftsetindents{subsection}{2em}{4.0em}
\cftsetindents{subsubsection}{2em}{5.0em}
\cftsetindents{paragraph}{2em}{6.0em}
\cftsetindents{subparagraph}{2em}{7.0em}

\begin{document}
\tableofcontents
\section{Section}
\levelOneSubsection{levelOneSubsection}
  \levelTwoSubsection{levelTwoSubsection}
    \levelThreeSubsection{levelThreeSubsection}
      \levelFourSubsection{levelFourSubsection}
        \levelFiveSubsection{levelFiveSubsection}
          \levelSixSubsection{levelSixSubsection}
\end{document}

生成的 pdf

答案1

的定义\@dottedtocline如下:

\ifnum #1>\c@tocdepth \else
\vskip \z@ \@plus .2\p@ 
{\leftskip #2\relax \rightskip 
\@tocrmarg \parfillskip -\rightskip \parindent #2\relax 
\@afterindenttrue \interlinepenalty \@M \leavevmode 
\@tempdima #3\relax 
\advance \leftskip \@tempdima \null \nobreak 
\hskip -\leftskip {#4}\nobreak
%%% dotfill here
\leaders \hbox {$\m@th \mkern \@dotsep mu\hbox {.}\mkern \@dotsep mu$}
\hfill \nobreak 
\hb@xt@ \@pnumwidth {\hfil \normalfont \normalcolor #5}\par }
\fi

负责虚线的部分是\mkern \@dotsep mu\hbox {.}\mkern \@dotsep mu,因此有一个宽度为的小水平空间(\mkern\@dotsep mu,然后是一个点,然后是另一个小的水平空间。\@dotsep定义为 4.5,mu 是一个“数学单位”,为 1/18 em,em 是一个宽度为 M(在活动字体大小中)的单位,因此点填充的距离是 1/4 M。

您可以使用包更改此定义etoolbox。此包为命令提供了\patchcmd五个参数:要修补的命令、要更改的命令中的代码、替换代码以及修补成功或失败时要执行的代码(最后两个参数可以留空)。

将上面的代码替换为\rule{1pt}{0.4pt}将自定义部分的点变成一条线:

\documentclass[a4paper,11pt]{report}
\usepackage{titlesec}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage[titles]{tocloft}
\usepackage{etoolbox}

%% use solid lines instead of dotted lines for toc
\renewcommand{\cftdot}{\rule{1pt}{0.4pt}}
\renewcommand{\cftdotsep}{0}
\makeatletter
\patchcmd{\@dottedtocline}{\mkern \@dotsep mu\hbox {.}\mkern \@dotsep mu}%
{\rule{1pt}{0.4pt}}{}{}
\makeatother

结果:

在此处输入图片描述

编辑:为了使修补的命令更清晰一些,您还可以用替换整个框\hrule,如另一个答案中所述:

\patchcmd{\@dottedtocline}{\hbox {$\m@th \mkern \@dotsep mu\hbox {.}\mkern \@dotsep mu$}}%
{\hrule}{}{}

答案2

tocloft包不会重新定义\@dottedtocline以获得其效果,而是创建自己的参数化命令版本\l@SECTION以便于自定义。您可以深入研究tocloft文档的后面部分以了解其工作原理。

或者,您可以使用如下所示的定制宏:

\def\@ruledtocline#1#2#3#4#5{%
  \ifnum #1>\c@tocdepth \else
    \vskip \z@ \@plus.2\p@
    {\leftskip #2\relax \rightskip \@tocrmarg \parfillskip -\rightskip
     \parindent #2\relax\@afterindenttrue
     \interlinepenalty\@M
     \leavevmode
     \@tempdima #3\relax
     \advance\leftskip \@tempdima \null\nobreak\hskip -\leftskip
     {#4}\nobreak
     \leaders\hrule\hfill
     \nobreak
     \hb@xt@\@pnumwidth{\hfil\normalfont \normalcolor #5%
                        \kern-\p@\kern\p@}%
     \par}%
  \fi}

它应该与嵌入式兼容\@dottedtocline(请注意,我还没有测试过,所以它可能不起作用)。

相关内容