如何计算总节数之内每章?
我正在尝试使用该totcount
包,但它返回了最后的章节数,而不是章节总数当前的章节。
在以下 MWE 中,期望的行为是报告第一章的 3 个部分,以及第二章和最后一章的 1 个部分。
totcount
仅报告 1 个部分(最后一章的计数器值)。
\documentclass[12pt]{book}
\usepackage{totcount}
\regtotcounter{section}
\begin{document}
\chapter*{First Chapter}
The total number of sections in this chapter should be 3.
The totcount package reports: \total{section}
\section{First Section}
First text
\section{Second Section}
Second text
\section{Third Section}
Third text
\chapter*{Last Chapter}
The total number of sections in this chapter should be 1.
The totcount package reports: \total{section}
\section{First and only section}
Section text
\end{document}
如何计算每章内的总节数?
注意:totcount
如果使用则报告 0 个部分\section*
,请参阅 Sigur 的评论。
答案1
编辑提前了解每章节数的预测版本位于本文的最后。它需要运行两次编译。
这个问题导致了一个新的软件包cntperchap
,其版本 0.2 自 2015/9/5 起在 CTAN 上可用
这使用了assoccnt
包(我偶然很了解它的作者 ;-))
它将一个计数器totalsections
与section
计数器关联起来——每次section
计数器增加时,totalsections
计数器也会增加。
但是,没有自动重置\chapter*
使用。在这种情况下,可以通过在包中\chapter
添加一些代码来自动完成\xpretocmd
xpatch
笔记作者assoccnt
应该真正将其纳入到他的包中;-)
\documentclass[12pt]{book}
\usepackage{assoccnt}
\usepackage{xpatch}
\newcounter{totalsections}[chapter] % Does not work with `chapter*`
% Automatically provide for resetting of the section counter each time
%`\chapter` or `\chapter*` is used -- in this setup this is requested.
\xpretocmd{\chapter}{\setcounter{totalsections}{0}}{}{}
\DeclareAssociatedCounters{section}{totalsections}
\begin{document}
\chapter*{First Chapter}
The total number of sections in this chapter should be 3.
\section{First Section}
First text
\section{Second Section}
Second text
\section{Third Section}
Third text
There \number\value{totalsections} sections in this chapter
\chapter*{Last Chapter}
\section{First and only section}
Section text
There \number\value{totalsections} sections in this chapter
\end{document}
编辑一些新版本使用每章的节数(需要两次运行才能成功)。
解释:每次使用新章节时,累计的章节数都会写入外部文件,\jobname.seccnt
简称foo.seccnt
。下次运行 latex 编译时会再次读取此文件,并将值存储到列表中etoolbox
。宏\GetTotalSectionCounter
将通过此列表前进,直到到达正确位置,然后打印出本章的章节数,甚至向前。(宏应该是可扩展的,我认为是这样的)
foo.seccnt
目前,如果章节/部分的数量发生变化,则需要手动删除该文件。
我会尝试解决这个缺点。
\documentclass{book}
\usepackage{ifthen}
\usepackage{assoccnt}
\usepackage{xpatch}
\usepackage{pgffor} % Only for quick usage of a lot of sections, demo only
\newwrite\seccountfile%
\newread\seccountinfile%
\listgadd{\seccountlist}{}% Initialize an empty list
\newcounter{currentchapter}
\newcounter{totalsections}
\newcounter{togglecounter}
\DeclareAssociatedCounters{section}{totalsections}
\newcommand{\getsectioncountnumbers}{%
\setcounter{togglecounter}{0}%
\whiledo {\value{togglecounter} < 1}{%
\read\seccountinfile to \gandalf%
\ifeof\seccountinfile%
\stepcounter{togglecounter}%
\else%
\listxadd{\seccountlist}{\gandalf}%
\fi%
}%
}
\xpretocmd{\chapter}{%
\stepcounter{currentchapter}%
\immediate\write\seccountfile{%
\number\value{totalsections}%
}%
\setcounter{totalsections}{0}
}{}{}
\makeatletter
\newcounter{tempcount@a}
\newcommand{\@getsectiontotalcounter}[1]{%
\setcounter{tempcount@a}{0}%
\renewcommand*{\do}[1]{%
\ifnumequal{\value{#1}}{\value{tempcount@a}}{%
##1\listbreak%
}{%
\stepcounter{tempcount@a}%
}%
}%
\dolistloop{\seccountlist}%
}
\newcommand{\GetSectionTotalCounter}[1][currentchapter]{%
\ifdef{\seccountlist}{%
\@getsectiontotalcounter{#1}%
}{}%
}
\makeatother
\AtBeginDocument{%
\IfFileExists{\jobname.seccnt}{%
% Open for reading
\immediate\openin\seccountinfile=\jobname.seccnt%
\getsectioncountnumbers%
}{%
% Open for writing
\immediate\openout\seccountfile=\jobname.seccnt%
}%
}
\AtEndDocument{%
\immediate\write\seccountfile{%
\number\value{totalsections}%
}%
\immediate\closeout\seccountfile%
}
\begin{document}
\chapter*{First}
This chapter will have \GetSectionTotalCounter sections
\section{First}
\section{Second}
\chapter*{Second}
This chapter will have \GetSectionTotalCounter sections
\section{First}
\section{Second}
\section{Third}
\section{Fourth}
% Now a really large chapter
\chapter*{Third}
This chapter will have \GetSectionTotalCounter sections
\foreach \x in {1,...,100} {%
\section{\x}
}
\end{document}
编辑foo.seccnt
这是没有明确删除文件的版本
我使用的addtocontents
方法让将LaTeX
章节编号写入单独的文件,就像处理toc
相关内容一样。foo.seccnt
然后将它视为伪造的目录,在运行中重写之前读入(并临时存储值)。
\documentclass{book}
\usepackage{ifthen}
\usepackage{assoccnt}
\usepackage{xpatch}
\usepackage{pgffor}
\listgadd{\seccountlist}{}% Initialize an empty list
\newcounter{currentchapter}
\newcounter{totalsections}
\newcounter{togglecounter}
\DeclareAssociatedCounters{section}{totalsections}
\makeatletter
\newcommand{\getsectioncountnumbers}{%
\setcounter{togglecounter}{0}%
\whiledo {\value{togglecounter} < 1}{%
\read\tf@seccnt to \seccountnumberfromfile%
\ifeof\tf@seccnt
\stepcounter{togglecounter}%
\else%
\listxadd{\seccountlist}{\seccountnumberfromfile}%
\fi%
}%
}
\xpretocmd{\chapter}{%
\stepcounter{currentchapter}%
\addtocontents{seccnt}{%
\number\value{totalsections}%
}%
\setcounter{totalsections}{0}
}{}{}
\newcounter{tempcount@a}
\newcommand{\@getsectiontotalcounter}[1]{%
\setcounter{tempcount@a}{0}%
\renewcommand*{\do}[1]{%
\ifnumequal{\value{#1}}{\value{tempcount@a}}{%
##1\listbreak%
}{%
\stepcounter{tempcount@a}%
}%
}%
\dolistloop{\seccountlist}%
}
\newcommand{\GetSectionTotalCounter}[1][currentchapter]{%
\ifdef{\seccountlist}{%
\@getsectiontotalcounter{#1}%
}{}%
}
% This is a modified version from \@starttoc, being defined latex.ltx
\def\@startfaketoc#1{%
\begingroup
% Generate the file handle first
\expandafter\newwrite\csname tf@#1\endcsname%
\makeatletter
% Read first before deleting it
\ifcsdef{tf@#1}{%
\IfFileExists{\jobname.#1}{%
\immediate\openin\csname tf@#1\endcsname \jobname.#1\relax
\getsectioncountnumbers%
}{}
}{%
\typeout{No section count numbers so far}
}%
\if@filesw
% Write only if not `\nofiles` is specified
\immediate\openout \csname tf@#1\endcsname \jobname.#1\relax
\fi
\@nobreakfalse
\endgroup%
}
\AtBeginDocument{%
\@startfaketoc{seccnt}
}
\AtEndDocument{%
% Write the last section count to the file
\addtocontents{seccnt}{%
\number\value{totalsections}%
}%
}
\makeatother
\begin{document}
\tableofcontents
\chapter*{First}
This chapter will have \GetSectionTotalCounter sections
\section{First}
\section{Second}
\chapter*{Second}
This chapter will have \GetSectionTotalCounter sections
\section{First}
\section{Second}
\section{Third}
\section{Fourth}
% Now a really large chapter
\chapter*{Third}
This chapter will have \GetSectionTotalCounter sections
\foreach \x in {1,...,100} {%
\section{\x}
}
\chapter{Fourth}
This chapter will have \GetSectionTotalCounter sections
\section{A single section}
\end{document}
编辑OP gsl 指出此代码中存在一些错误。我可以将其追溯到第一次运行中\@startfaketoc
尝试读取外部foo.seccnt
文件的事实。这当然会失败,因为如果删除了该文件或第一次编译文档,则不存在这样的文件。