我正在尝试生成一个没有标题、深度为两层且格式如下的内联目录:
1.第一节 ‖ 1.1.第一小节;1.2.第二小节 ‖ 2.第二部分
我尝试了一下titletoc
并几乎得到了正确的结果,只是目录是左对齐而不是两端对齐,而且我的格式实际上覆盖了标准格式,我不知道之后如何恢复。
因此我尝试重新定义\tableofcontents
,\contensline
但却\numberline
遇到了以下问题:
- 我怎样才能从内部找出
\numberline
我正在格式化的标题级别(以便区分大胆的对于\section
s 和斜体或者\subsection
, - 我怎样才能摆脱对in参数
\numberline
内部的调用?并且,#2
\contensline
file.toc
- 我如何知道我正在格式化的(
sub
)section
是行中的第一个还是最后一个,以便将“‖”和“;”分隔符放在正确的位置?
实际上,我对学习用 TeX 编写宏比解决这个特定问题更感兴趣,因此,如果这不是问题的话,我将非常感激一个解释,而不是简单的解决方案。
编辑:一个最小的例子(忽略标准字体中缺少的“‖”;这不是问题):
\documentclass{article}
\makeatletter
\renewcommand{\tableofcontents}{\noindent\@starttoc{toc}}
\renewcommand{\l@section}[2]{#1~‖} % How can I tell here if anything (and what?) follows?
\renewcommand{\l@subsection}[2]{#1;} % As above.
\renewcommand{\numberline}[1]{\textbf{#1}.~} % How can I tell here if it's a section or a subsection?
\makeatother
\begin{document}
\tableofcontents
\section{Section one}
\subsection{Subsection one}
\subsection{Subsection two}
\section{Section two}
\end{document}
以上内容如下:
1.第一节 ‖ 1.1.第一小节;1.2.第二小节;2.第二部分 ‖
问题在于:
- 小节编号大胆的而不是斜体。
Subsection two
后面跟着一个分号。Section two
后面跟着一个“‖”。
答案1
以下解决方案符合您的要求:
\documentclass{article}
\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newtoggle{section}\togglefalse{section}% "In section" toggle
\newtoggle{atstarttoc}% "First entry in ToC" toggle
\newcounter{tocsubsection}% Keep track of first subsection
\makeatletter
\renewcommand{\tableofcontents}{\noindent\toggletrue{atstarttoc}\@starttoc{toc}}
\renewcommand{\l@section}[2]{%
\iftoggle{atstarttoc}{\togglefalse{atstarttoc}\relax}
{$\vert$~}%
\setcounter{tocsubsection}{0}%
\toggletrue{section}% We're in a section
#1%
}
\renewcommand{\l@subsection}[2]{%
\ifnum\value{tocsubsection}<1
$\vert$~%
\else
\unskip;~%
\fi%
\stepcounter{tocsubsection}%
\togglefalse{section}% We're not in a section
#1} % As above.
\renewcommand{\numberline}[1]{%
\iftoggle{section}
{\textbf{#1}.~}
{\textit{#1}.~}%
}
\makeatother
\begin{document}
\tableofcontents
\section{Section one}
\subsection{Subsection one}
\subsection{Subsection two}
\section{Section two}
\subsection{Subsection one}
\subsection{Subsection two}
\subsection{Subsection three}
\subsection{Subsection four}
\section{Section three}
\section{Section four}
\subsection{Subsection one}
\subsection{Subsection two}
\end{document}
etoolbox
提供“切换”(布尔真/假变量),用于识别(1)section
- 您是否设置了特定标题(\section
或\subsection
)或(2)atstarttoc
- 您是否处于 ToC 的开始处。
上述解决方案假设您只有\section
和\subsection
标题,但它可以扩展以容纳更多级别。
答案2
首先,我将尝试解释为什么完整回答您的答案非常困难。
\l@section
和朋友是定义外貌目录中各种项目,此时 LaTeX 无法知道我们在哪个章节或小节中。
如果您想影响它们的处理方式,您应该在更高级别上进行,即在分段命令的定义中。所有较低的划分(从节开始向下)都是在 LaTeX2e 中使用该\@startsection
命令定义的,显然,尝试修改该命令是非常不明智的。您可以在 latex.ltx 文件中查看它。
此外,LaTeX 在看到这些文档划分时会对其进行处理 - 因此我们有办法知道某个章节或子章节是否是第一个(或第二个,等等),但我们没有简单的方法找出它是否是最后一个。如果你想这样做,你需要让 LaTeX 在每次重置之前将计数器的数字写入单独的文件,然后在第二次运行 LaTeX 时检索它以便使用它。例如,这就是目录的编写方式(以及为什么它们需要两次编译)。
我提出的解决方案将尝试解决第一个问题 [编辑:第二个问题也是如此]。我们将重新定义命令,\subsection
以便第一个小节始终在其自身之前排版 ||,并且每个小节在目录中都以分号结尾 [编辑:每个小节的最后一个小节除外]。我们还将定义一个命令来负责格式化小节的编号。
% Used for playing around with the semicolons
\usepackage{refcount}
\makeatletter
\renewcommand{\tableofcontents}{\noindent\@starttoc{toc}}
\renewcommand{\l@section}[2]{#1}% No other modification needed here
\renewcommand{\l@subsection}[2]{#1}% No other modification needed here
\renewcommand{\numberline}[1]{\textbf{#1}.~}
% Create a new command for italic numbers in the TOC
\newcommand{\numbersubsec}[1]{\textit{#1}.~}
% Create a new counter for the semicolons. It is reset at every \section
\newcounter{cntsemicolon}[section]
% Save the old definition of \subsection under the name \oldsubsection
\let\oldsubsection=\subsection
% Overwrite \subsection
\renewcommand{\subsection}[1]{%
% Increase the subsection counter, as it will not be increased automatically + Increase the semicolon counter
\refstepcounter{subsection}%
\refstepcounter{cntsemicolon}\label{mycounterref@\thesection}%
% Check whether this is the first subsection or not
\ifnum\value{subsection}<2%
% If the value of the subsection counter is <2, it is the first subsection
% Add the subsection to the TOC with the extra || (\textbar) and ;
\addcontentsline{toc}{subsection}{\unskip~\textbar\textbar~\numbersubsec{\thesubsection}#1%
% If the value of the subsection counter is not equal to the maximum value of the semicolon counter for the section, add a semicolon
\ifnum\value{subsection}=\number\numexpr\getrefnumber{mycounterref@\number\value{section}}~\textbar\textbar~\unskip\else;\fi}%
\else%
% Else (i.e. if it is not the first subsection)
% Add the subsection to the TOC with ; at the end
\addcontentsline{toc}{subsection}{\numbersubsec{\thesubsection}#1%
% If the value of the subsection counter is not equal to the maximum value of the semicolon counter for the section, add a semicolon
\ifnum\value{subsection}=\number\numexpr\getrefnumber{mycounterref@\number\value{section}}~\textbar\textbar~\unskip\else;\fi}%
\fi%
% Create a subsection heading in the main text
% The \hspace command create the white-space between the number and the text.
% Its value is copied from the original \subsection command.
\oldsubsection*{\thesubsection\hspace{1.5ex \@plus .2ex}#1}}
\makeatother
注意:我们使用带星号的版本\subsection
,它不会增加计数器,也不会向目录中添加任何内容(它也不会设置任何页眉,因此您可能还需要在新命令中手动设置它们)。这样,就有可能篡改实际添加到目录中的数据。
如你所见,之后三运行后,结果将类似如下:
1. 第一节1.1. 第一小节;1.2. 第二小节 2. 第二部分3. 第三部分
编辑:使用@egreg 的回答添加了分号问题的解决方案这个帖子。 编辑2:在下一部分之前添加了 || 而不是分号,因为我刚刚注意到它们在 OP 的问题中。