我正在开发一个软件包来简化我的家庭作业和作业的编写。不幸的是,并不是所有的教授都会给我的作业分配连续编号。因此,我希望能够手动覆盖章节的自动编号。
我的目标:
语法类似于
\section[12(e)]{Fermat's Last Theorem}
,其中自定义数字位于括号中。我设想我会忽略正常的部分计数器,并简单地定义我自己的宏来包含手动指定的数字。如果没有可选参数,此宏将简单地镜像\thesection
。在标题和页脚中引用我的自定义编号的功能。我想说“问题 12(e) 继续在下一页……”而不是引用整个部分名称。
最后,我希望将所有这些工作都放在目录和 hyperref 包中。
这可能吗?已经有人这样做了吗?我没有被束缚在某个特定的文档类别中;我尝试将其应用于article
Memoir 和文章模式。
这让我很接近:
\documentclass[article]{memoir}
\newcommand*{\theproblem}{}
\renewcommand*{\cftchaptername}{Problem\space}
\renewcommand*{\chaptername}{Problem\space}
\setcounter{tocdepth}{2}
\newcommand*{\problem}[2][\thechapter]{%
\addtocounter{chapter}{1}
\setcounter{section}{0}
\phantomsection
\addcontentsline{toc}{chapter}{\numberline {\cftchaptername#1}#2}
\chapter*{\chaptername#1\quad#2}
\renewcommand*{\theproblem}{#1}
}
\newcommand*{\subproblem}[2][\thesection]{%
\addtocounter{section}{1}
\phantomsection
\addcontentsline{toc}{section}{\numberline {#1}#2}
\section*{#1\quad#2}
\renewcommand*{\theproblem}{#1}
}
不幸的是,它没有考虑到目录中比预期更长的数字。另外,我最初开始尝试直接重新定义\chapter
和\section
;这肯定不是必要的,但会很好(现在我很好奇这是否可行)。最后,这是我第一次进行软件包破解,所以我并不完全相信我做的事情是合理的。
答案1
呼!我想我终于对 (La)TeX 有了足够的了解,可以找到一个不错的解决方案了。
我相当彻底地破解了文章类来实现它,因此我将以下内容放在了引导的自定义类中article.cls
:
% ...
\LoadClass{article}
\RequirePackage{etoolbox}
\let\@@sect\@sect
\def\@sect#1#2#3#4#5#6[#7]#8{ %
\@sectsplit{#1}{{#2}{#3}{#4}{#5}{#6}}[#7||]{#8}
}
\def\@sectsplit#1#2[#3|#4|#5]#6{ %
\ifcsundef{@theorig#1}
{\expandafter\edef\csname @theorig#1\endcsname{\expandafter\expandonce\csname the#1\endcsname}}
{\relax}
\ifstrempty{#4}
{
\expandafter\edef\csname the#1\endcsname{\expandafter\noexpand\csname @theorig#1\endcsname}
\@@sect{#1}#2[{#3}]{#6}
}{
\expandafter\edef\csname the#1\endcsname{#3}
\@@sect{#1}#2[{#4}]{#6}
}
}
由于延迟扩展和的复杂性,它看起来比实际更复杂。它只是用一个可选前缀\@sect
增强了标准语法: 。\section[TOC name]{section name}
\section[number|TOC name]{section name}
我将自定义数字(如果提供)直接放入\thesection
。这意味着子部分会适当地选择它(如果它们是参考 定义的\thesection
)。但我还保存了 的先前值\thesection
,以便保留用户的偏好,例如阿拉伯数字或罗马数字。
还要注意的是,这在所有章节级别上都同样有效。我注意到一个错误:\section[12(e)|]{Fermat's Last Theorem}
将 12(e) 解析为目录标题,而不是自定义编号。
答案2
以下是分别使用常规章节/节号作为问题/子问题号的尝试。如果这不是问题(因为您在文档中也使用节和章节),您可以考虑覆盖段落/子段落,甚至定义所有新命令。
如果有任何不清楚的地方,请在评论中寻求澄清。
\documentclass[article]{memoir}
\usepackage{calc}
\newcommand\theproblem{\arabic{chapter}}
\newcommand\thesubproblem{\arabic{chapter}(\arabic{section})}
\renewcommand\thesection{\arabic{chapter}(\arabic{section})}
\renewcommand*{\cftchaptername}{Problem\space}
\renewcommand*{\chaptername}{Problem\space}
\setcounter{tocdepth}{2}
\newcommand*{\problem}[2][\value{chapter}+1]{%
\setcounter{chapter}{#1-1}
\chapter{#2}
}
\newcommand*{\subproblem}[2][\value{section}+1]{%
\setcounter{section}{#1-1}
\section{#2}
}
\begin{document}
\tableofcontents*
\problem[2]{problem}
hello problem \theproblem
\subproblem[2]{subproblem}
foo \thesubproblem
\subproblem{subproblem}
bar \thesubproblem
\problem[4]{problem}
hello \theproblem
\subproblem[3]{subproblem}
foo \thesubproblem
\subproblem{subproblem}
bar \thesubproblem
\problem{problem}
hello \theproblem
\subproblem[7]{subproblem}
foo \thesubproblem
\subproblem{subproblem}
bar \thesubproblem
\end{document}
答案3
强制性的 ConTeXt 解决方案:
\setuphead[ownnumber=yes]
然后,对于每个部分标题,你必须使用指定数字
\section[reference]{12(e)}{Fermat's Last Theorem}
这与标记(用于页眉和页脚)和列表(用于目录)无缝配合。
编辑:按照 Will 的评论,要用您自己的编号对特定部分进行编号,您可以使用部分start
-stop
变体。
\开始文本 \startsection[title=第一部分] ... 章节内容 ... \停止部分 \startsection[title=第二部分,ownnumber={12(e)}] .... 章节内容 ... \停止部分 \startsection[title=第三部分] .... 章节内容.... ....本节编号为 3... \停止部分 \停止文本
再次,标记和列表都是自动处理的。
答案4
尝试这个:
\documentclass{article}
\usepackage{hyperref}
\begin{document}
\newcounter{problem}
\setcounter{problem}{0}
\newenvironment{problem}[2][\theproblem]
{\refstepcounter{problem}
\edef\tmpa{#1}
\let\theproblem=\tmpa
\phantomsection
\addcontentsline{toc}{section}{Problem #1: #2}
Problem #1\quad #2.\qquad
}
{}
\tableofcontents
\section{The problems}
\begin{problem}{Exercise}
\label{p:exercise}
Just an exercise.
\end{problem}
\newpage
\begin{problem}[12(e)]{Fermat's Last Theorem}
\label{p:fermat}
$a^n + b^n \neq c^n$ for $n > 2$.
\end{problem}
The first problem is \ref{p:exercise}, and the second is \ref{p:fermat}.
\end{document}
寓意:仅仅因为它说了\theproblem
并不意味着它所写的内容必须与计数器的值有任何关系problem
。
编辑:我出于习惯使用环境,因为在我自己的家庭作业中,我总是用它amsthm
来陈述问题。由于\endproblem
无论如何都是空洞的,您可以轻松地将其变成更像\section
- 的命令,并将其计数器默认为\thesection
而不是\theproblem
。如果您想要真正看起来像节的东西,那么您应该使用\@startsection
它来定义它;请参阅source2e.pdf
(文件 ltsect.dtx)了解语法。