我的目标是在每一章的开头显示该章包含的章节数。
section
目前,我的想法是将每章末尾的计数器值存储在辅助文件中,并在第二遍时显示它。我编写的命令示例:
\newcommand{\store@sect@count}{\write\@auxout{\@backslashchar expandafter\@backslashchar gdef\@backslashchar csname sects@in@chap@\roman{chapter}\@backslashchar endcsname{\arabic{section}}}}
% Writes something like \expandafter\gdef\csname sects@in@chap@i\endcsname{2}
\newcommand{\get@sect@count}{\csname sects@in@chap@\roman{chapter}\endcsname}
使用这种方法,我可以\get@sect@count
在每章开头使用它来打印章节数。但是,它还需要\store@sect@count
在每章结尾运行该命令,而我还没有找到如何做到这一点。
一种可能性是为此创建一个自定义环境,但这最终会非常麻烦,特别是如果我将它应用于其他分段级别时。
- 如何才能在每一章(以及文档层次结构的其他级别)结束时可靠地运行命令?
- 有没有比我目前尝试使用的方法更好的方法来实现我的目标?
编辑:MWE 在 Overleaf 上:https://www.overleaf.com/read/hcqjhwbthngs(以下代码)
\documentclass{book}
\usepackage[utf8]{inputenc}
\makeatletter
\newcommand{\store@sect@count}{\write\@auxout{\@backslashchar expandafter\@backslashchar gdef\@backslashchar csname sects@in@chap@\roman{chapter}\@backslashchar endcsname{\arabic{section}}}}
\newcommand{\get@sect@count}{\csname sects@in@chap@\roman{chapter}\endcsname}
\newenvironment
{countingchapter}
{\chapter{} Number of sections: \get@sect@count \\}
{\store@sect@count}
\newenvironment
{countingsection}
{\section{}}
{}
\makeatother
\begin{document}
\begin{countingchapter}
My chapter
\begin{countingsection}
Fisrt section
\end{countingsection}
\begin{countingsection}
Section section
\end{countingsection}
\begin{countingsection}
Third section
\end{countingsection}
\end{countingchapter}
\end{document}
答案1
您可以(小心地)挂接\refstepcounter
,这样,如果执行了该操作,chapter
则会将节数记录在.aux
文件中。
必须特别注意附录和最后一章,因此在\appendix
调用时以及在文档结束时添加适当的记录。
警告:\backmatter
会破坏这一点。
\documentclass[oneside]{book} % oneside just to make a smaller picture
\usepackage[a6paper]{geometry} % just to make a smaller picture
\usepackage{xpatch}
\usepackage{hyperref}
\ExplSyntaxOn
\AtBeginDocument
{
\NewCommandCopy{\latexrefstepcounter}{\refstepcounter}
\cs_set_eq:NN \refstepcounter \countsections_refstepcounter:n
}
\AtEndDocument
{
\countsections_count:
}
\xpretocmd{\appendix}{\countsections_count:}{}{}
\NewDocumentCommand{\sectioncount}{O{\thechapter}}
{
\ref*{cs@#1}
}
\cs_new_protected:Nn \countsections_refstepcounter:n
{
\str_if_eq:nnT { #1 } { chapter } { \countsections_count: }
\latexrefstepcounter{#1}
}
\cs_new_protected:Nn \countsections_count:
{
\iow_now:cx { @auxout }
{
\string\newlabel { cs@\thechapter } { {\arabic{section}}{}{}{}{} }
}
}
\ExplSyntaxOff
\begin{document}
Chapter 1 has \sectioncount[1]~sections.
Chapter 2 has \sectioncount[2]~sections.
Chapter A has \sectioncount[A]~sections.
\chapter{A}
This chapter has \sectioncount~sections.
\section{B}
\section{C}
\chapter{D}
This chapter has \sectioncount~sections.
\section{E}
\section{F}
\section{G}
\appendix
\chapter{H}
This chapter has \sectioncount~sections.
\section{I}
\section{J}
\end{document}
xparse
如果您运行的是 2020-10-01 之前的 LaTeX 版本,则可能需要加载。
答案2
正如 Ulrike 提到的,您可以在每次通话中输入\chapter
并写入节数.aux
以开始新的章节。
\documentclass{book}
\usepackage{lipsum}
\makeatletter
\let\oldchapter\chapter% Store \chapter in \oldchapter
\renewcommand{\chapter}{%
\immediate\write\@auxout{% Write section count to .aux
\global\noexpand\@namedef{chap\roman{chapter}sectioncount}{\arabic{section}}%
}%
\oldchapter% Call original \chapter
}
\newcommand{\thischaptersectioncount}{%
This chapter contains \@nameuse{chap\roman{chapter}sectioncount} sections.%
}
\makeatother
\begin{document}
\sloppy
\chapter{First chapter}
\thischaptersectioncount% 5
\section{First section}\lipsum[1-10]
\section{Second section}\lipsum[11-20]
\section{Third section}\lipsum[21-30]
\section{Fourth section}\lipsum[31-40]
\section{Final section}\lipsum[41-50]
\chapter{Second chapter}
\thischaptersectioncount% 2
\section{First section}\lipsum[1-10]
\section{Second section}\lipsum[11-20]
\chapter{Third chapter}
\thischaptersectioncount% 4
\section{First section}\lipsum[1-10]
\section{Second section}\lipsum[11-20]
\section{Third section}\lipsum[21-30]
\section{Fourth section}\lipsum[31-40]
\chapter{Final chapter}
\thischaptersectioncount% 1
\section{First section}\lipsum[1-10]
\end{document}
由于您使用.aux
作为中间存储机制,因此您必须至少编译两次(第一次或节数发生任何变化时),因为节数仅在第二次编译时可用。