给出一些乳胶代码,例如
\section{the first section}
some text
\section{the second section}
some text
\section{the third section}
some text
\section{the fourth section}
some text
我想要创建一个包含三列表格的目录,如下所示:
-------------------------------------------------
| 1. the first | 2. the second | 3. the third |
| section | section | section |
-------------------------------------------------
| 4. the fourth | | |
| section | | |
-------------------------------------------------
如果我使用完全自定义的命令代替section
,那么是可以的,只要文档正文中的编号与表格中的编号匹配即可。
我该如何解决这个问题?
答案1
\documentclass{article}
\makeatletter
\def\l@section#1#2{%
\noindent\begin{minipage}[t]{\dimexpr(.333\linewidth)-2em\relax}%
\def\numberline##1{##1: }\parfillskip0pt\relax
#1 \mbox{}\dotfill #2\end{minipage}\linebreak[0]\hspace{2em plus 2em}}
\makeatletter
\begin{document}
\tableofcontents
\section{the first section}
some text
\section{the second section}
some text
\section{the third section}
some text
\section{the fourth section}
some text
\end{document}
答案2
这是(另一种方法)在 longtable 中执行此操作,这里使用包etoc
。
\documentclass[a4paper]{article}
\usepackage[hscale=0.8]{geometry}
\usepackage{etoc}
\usepackage{array}
\usepackage{longtable}
% It is not at all obvious to display a TOC in a (long)-table,
% using etoc, but it is possible. See in its doc
% "Typesetting the TOC as a table".
% Let's illustrate here in a case which has only sections.
% We will use the *standard* way of displaying the sections in the TOC, except
% it will all take places in p cells of a longtable.
\usepackage[linktoc=all]{hyperref}% let's increase the challenge !
\newcounter{column}
\newtoks\toctabletok
\newcommand*\appendtotok[2]
{% #1=toks variable, #2=macro,
% #2 will be expanded once.
#1\expandafter\expandafter\expandafter{\expandafter\the\expandafter #1#2}%
}
\makeatletter % for \l@section
\newcommand*{\PrepareSectionCell}{%
\toks0 \expandafter{\etocthelinkednumber}% don't worry, etoc always in a group
\toks2 \expandafter{\etocthelinkedname}%
\toks4 \expandafter{\etocthelinkedpage}%
% or we could use \unexpanded from e-TeX, rather than the \toks registers
\edef\toctablecell {\relax % mandatory to stop TeX's future too
% early expansion of cell
\noexpand\par % \l@section MUST start in vertical mode
\noexpand\vspace*{-\baselineskip}% compensate for the \par (I think)
\noexpand\l@section % call the hotline if you have unnumbered sections
{\noexpand\numberline{\the\toks0 }\noexpand\strut\the\toks2 }{\the\toks4 }%
}%
}
%
\newcommand*{\TableTableOfContents}{\begingroup
%
\etocsetstyle{section}{}{}
{\PrepareSectionCell
\appendtotok\toctabletok\toctablecell
\stepcounter{column}%
\ifnum\value{column}=3
\toctabletok \expandafter{\the\toctabletok \\\hline}%
\setcounter{column}{0}%
\else
\toctabletok \expandafter{\the\toctabletok &}%
\fi}
{}
%
\etocsettocstyle
{\toctabletok{%\hypersetup{hidelinks}%
\begin{longtable}{*{3}{|p{.3\linewidth}}|}
\hline
\multicolumn{3}{|c|}{\Large\bfseries\strut TABLE OF CONTENTS}%
\\
\hline\hline}}
{\ifcase\value{column}%
\or\toctabletok\expandafter{\the\toctabletok &\\\hline}%
\or\toctabletok\expandafter{\the\toctabletok \\\hline}%
\fi
\global\toctabletok\expandafter{\the\toctabletok \end{longtable}}%
}
%
\etocsetnexttocdepth {section}%
\tableofcontents
\endgroup
\the\toctabletok % the only thing which survived the closing of the group
}
\makeatother
\begin{document}
\TableTableOfContents
\section{the first section}
some text
\section{the second section}
some text
\section{the third section}
some text
\section{the fourth section}
some text
\newcount\loopcount
\loopcount 50
\loop
\section {and another section}
hello
\clearpage
\advance\loopcount-1
\ifnum\loopcount>0
\repeat
\section {and the final section which happens to have quite a long name. By
the way you can click on it, its number or the page number}
\end{document}
然后继续第 2 页:
p
我添加了一些额外的信息:中的列longtable
和p
标准表格中的列之间存在差异。后者以垂直模式开始。但前者的p
单元格内容排版不是以垂直模式开始的。因此,本来可以直接在单元格开头( 之后)\l@section
使用的 ,但这里需要在 中添加一个额外的。然后我需要补偿由此产生的。由于 ,因此存在剩余的垂直空间。tabular
\relax
longtable
\par
\baselineskip
\addvspace{1em plus 1pt}
\l@section
至于部分名称下方的垂直空间,这是因为当一p
列结束时,\vrule
会通过宏添加一个(不可见的)。此处的 a与 a 中的\@finalstrut
相同。在这两种情况下,这都会引发切换到水平模式,因此再次产生一些垂直空间。tabular
longtable
简而言之,使用\l@section
insidelongtable
很有趣,但我应该直接使用\etocthename
等等......而不是将它们包装起来\l@section
(参见文档埃托克请参阅“将目录排版为表格”部分中的示例)。
答案3
另一种方法的当前缺点(除其他外)是需要.tabtoc
稍后手动删除该文件。
\documentclass{article}
\usepackage{xparse}
\usepackage{etoolbox}
\usepackage{xpatch}
\usepackage{letltxmacro}
\usepackage{longtable}%
\usepackage{hyperref}
\NewDocumentCommand{\TableOfContents}{}{%
\section*{\contentsname}%
\begin{longtable}{*{3}{p{4cm}}}
& & \tabularnewline[1ex]
\InputIfFileExists{\jobname.tabtoc}{\typeout{File exists}}{\typeout{File does not exist}} \tabularnewline[2ex]
\end{longtable}%
}%
\newwrite\tabtoc%
\makeatletter
\newcounter{@@columncounter}
\setcounter{@@columncounter}{0}
\xapptocmd{\@sect}{%
\begingroup
\renewcommand{\thesection}{\arabic{section}. }
\protect\addtocounter{@@columncounter}{1}%
\immediate\write\tabtoc{%
\thesection #7 % \tabularnewline
}%
\ifnumgreater{\value{@@columncounter}}{2}{%
\immediate\write\tabtoc{%
\string\tabularnewline[1ex]^^J
}%
\setcounter{@@columncounter}{0}
}{%
\immediate\write\tabtoc{&}
}%
\endgroup
}{%
\typeout{success}}{\typeout{fail}}
\makeatother
\AtBeginDocument{%
\IfFileExists{\jobname.tabtoc}{%
% Do nothing
}{%
% Open it for writing
\immediate\openout\tabtoc=\jobname.tabtoc%
}%
}%
\AtEndDocument{%
\immediate\closeout\tabtoc
}
\begin{document}
\TableOfContents
\section{First}
\section{Second}
\section{Third}
\section{Fourth}
\section{Fifth}
\section{Sixth}
\section{Seventh with a very long wrapping title}
\section{Eight}
\end{document}