我的文档有几个minipage
环境需要内部分段,其编号与文档的“正常”分段无关。到目前为止,我使用了一种变通方法,只是将标题硬编码为段落,然后手动应用编号和格式,例如
\begin{minipage}
\begin{center}Title\end{center}
\textbf{1 First section}
Some Text
\textit{1.1 First subsection}
Some more Text
\textit{1.2 Second subsection}
\begin{enumerate}
\item Foo
\item Bar
\end{enumerate}
\textbf{2 Second section}
Even more Text
\end{minipage}
但是,这会导致一些瑕疵,例如,标题和普通段落之间的垂直间距太窄,而“标题”后面紧接着列表环境之间的垂直间距则相对较大。此外,我希望节之后的第一个段落不缩进。简而言之:我希望拥有所有这些由适当的节段命令应用的出色间距校正“魔法”。
我想定义三个特殊的小页面(mp)分段宏:
\mptitle
:minipage 中第一个打印居中标题的命令\mpsection
:一级切片\mpsubsection
:二级切片
具有以下属性
- 为每个小页面重新开始编号(即类似于小页面内的脚注)
- TOC 中不要求也不希望输入
- 通过所有这些良好的间距校正,前后都有适当的垂直间距,如果两个分段命令紧接着彼此,则后面的段落没有缩进,列表校正等。
- 工作交叉引用(即使用
\label
)很好,但还不是必需的。
我查看了 source2e.pdf 第 61 章,试图弄清楚\@startsection
、\@sect
和 friends 的作用以及我是否可以重新使用它们,但我失败了。首先,我完全不明白这些命令是如何工作的。其次,我得到的印象是 LEVEL 参数总是会干扰正常的分段(我读到它必须是唯一的),而且似乎、\@startsection
总是\@sect
操纵 TOC。
如果有人能帮助我定义\mptitle
,我会非常高兴,\mpsection
并且\mpsubsection
类似于正常分段命令所做的那样,但省略了 TOC 所需的所有不必要的代码。
答案1
根据代码你发了,这实现了您的第 1、2 和 3 项(第 2 项,即删除惩罚插入,但似乎并不重要)。
您可能需要考虑定义自己的环境来包装minipage
和重置高级计数器(下面给出的代码minipage
根据您的要求执行此操作):
\AtBeginEnvironment{yourminipagewrapper}{%
\setcounter{mpsection}{0}%
}
如果将来需要进一步定制,这可能会有所帮助。请注意,低级计数器mpsubsection
不需要手动重置,因为mpsection
根据您的定义,它从属于更高级别的计数器:
\newcounter{mpsubsection}[mpsection]
此外,您的minipage
-wrapping 环境可以接受定义时使用的附加参数\@currentlabel
,否则当您看到像“1.2”这样的参考文本时,您知道它是第 1.2 节,但不知道minipage
它属于哪个部分(hyperref
虽然知道)。但这在很大程度上取决于您将如何使用所有这些,所以我只能提供这样的简单建议。
代码:
\documentclass{article}
\usepackage{lipsum}
\usepackage{etoolbox}
\usepackage{hyperref}
\makeatletter
% #1 Name
% #2 Indent
% #3 Beforeskip
% #4 Afterskip
% #5 Style
% #6 Heading
\newcommand*{\@mpstartsection}[6]{%
\if@noskipsec \leavevmode \fi
\par
\@tempskipa #3\relax
\@afterindenttrue
\ifdim \@tempskipa <\z@
\@tempskipa -\@tempskipa \@afterindentfalse
\fi
\if@nobreak
\everypar{}%
\else
\addvspace\@tempskipa
\fi
\refstepcounter{cont@#1}% this counter is never reset, used for hyperref
\stepcounter{#1}% counter used for display purposes
\protected@edef\@currentlabel{% define how refs look
\csname p@#1\endcsname \csname the#1\endcsname
}%
\protected@edef\@svsec{\@seccntformat{#1}\relax}%
\begingroup
#5{\@hangfrom{\hskip #2\relax\@svsec}#6\@@par}%
\endgroup
\par
\vskip #4\relax
% \@afterheading deals with penalities related to page breaking that aren't
% needed inside a minipage, but it also honors the \if@afterindent switch,
% therefore leave it here.
\@afterheading
\ignorespaces
}
\newcounter{mpsection}
\newcounter{mpsubsection}[mpsection]
\newcounter{cont@mpsection}
\newcounter{cont@mpsubsection}
\renewcommand\thempsection{\@arabic\c@mpsection}
\renewcommand\thempsubsection{\thempsection.\@arabic\c@mpsubsection}
\AtBeginEnvironment{minipage}{%
\setcounter{mpsection}{0}%
}
\newcommand\mpsection{\@mpstartsection{mpsection}{\z@}{-3.5ex \@plus -1ex \@minus -.2ex}{2.3ex \@plus.2ex}{\normalfont\normalsize\bfseries}}
\newcommand\mpsubsection{\@mpstartsection{mpsubsection}{\z@}{-3.25ex \@plus -1ex \@minus -.2ex}{1.5ex \@plus .2ex}{\normalfont\normalsize\itshape}}
\makeatother
\setlength{\parindent}{0pt}
\begin{document}
\begin{minipage}{\linewidth}
\mpsection{Foo bar section}
\label{sec-foobar}%
\lipsum[1]. See~\ref{sec-subbleh}.
\mpsection{The baz and the quux}
\label{sec-baz-quux}%
\lipsum[2]. See~\ref{sec-foobar} and~\ref{sec-other-subbleh}.
\end{minipage}
\bigskip
\begin{minipage}[t]{0.4\linewidth}
\mpsection{Bleh}
\label{sec-bleh}%
\lipsum[1][2-3]. See~\ref{sec-baz-quux}.
\mpsubsection{Sub-bleh}
\label{sec-subbleh}%
\lipsum[2][4-5]. See~\ref{sec-subouch}.
\mpsubsection{Other sub-bleh}
\label{sec-other-subbleh}%
Bla bla \lipsum[12].
\end{minipage}\hfill
\begin{minipage}[t]{0.4\linewidth}
\mpsection{Ouch!}
\label{sec-ouch}%
\lipsum[1][6-7]
\mpsubsection{Sub-ouch!}
\label{sec-subouch}%
\lipsum[2][8]. See~\ref{sec-ouch} and~\ref{sec-baz-quux}.
\mpsection{Pouet}
\label{sec-pouet}%
\lipsum[3][1-2].
\mpsubsection{Sub-pouet}
\lipsum[3][4-5]
\end{minipage}
\end{document}
在第 1 页:
在第 2 页:
答案2
部分答案-- 欢迎改进
这就是我已经实现的。解决方案基于原始\@startsection
和\@sect
和\@xsect
宏的功能。我省略了一些小页面不需要的 if-then-else 分支,丢弃了 TOC 代码并将剩余代码合并到一个宏中。
\makeatletter
% #1 Name
% #2 Indent
% #3 Beforeskip
% #4 Afterskip
% #5 Style
% #6 Heading
\def\@mpstartsection#1#2#3#4#5#6{%
\if@noskipsec \leavevmode \fi
\par
\@tempskipa #3\relax
\@afterindenttrue
\ifdim \@tempskipa <\z@
\@tempskipa -\@tempskipa \@afterindentfalse
\fi
\if@nobreak
\everypar{}%
\else
\addpenalty\@secpenalty\addvspace\@tempskipa
\fi
\refstepcounter{#1}%
\protected@edef\@svsec{\@seccntformat{#1}\relax}%
\begingroup
#5{\@hangfrom{\hskip #2\relax\@svsec}\interlinepenalty \@M #6\@@par}
\endgroup
\par\nobreak
\vskip #4\relax
\@afterheading
\ignorespaces
}
\newcounter{mpsection}
\newcounter{mpsubsection}[mpsection]
\renewcommand\thempsection{\@arabic\c@mpsection}
\renewcommand\thempsubsection{\thempsection.\@arabic\c@mpsubsection}
\newcommand\mpsection{\@mpstartsection{mpsection}{\z@}{-3.5ex \@plus -1ex \@minus -.2ex}{2.3ex \@plus.2ex}{\normalfont\normalsize\bfseries}}
\newcommand\mpsubsection{\@mpstartsection{mpsubsection}{\z@}{-3.25ex \@plus -1ex \@minus -.2ex}{1.5ex \@plus .2ex}{\normalfont\normalsize\itshape}}
\makeatother
需要改进
- 重置
mpsection
每个小页面的计数器。 - 上述代码可能可以进一步简化,并且一些惩罚是多余的,因为在小页面内分页是不可能的。
- 如果实施了 1.,我会收到很多“重复目标”错误以及 hyperef 和交叉引用,因为有一个部分n在每个小页面中。该
\mptitle
命令(尚未实现)需要以某种方式实现一个“不可见”计数器,以使各部分独一无二。