我正在写一本书,其中每一章都以编号练习列表结尾。我想让 LaTeX 计算书中练习的总数,以便引用\ref
或类似的东西(例如\total
来自totcount
)。每章都使用 单独加载\include
,我希望即使使用 计数也正确\includeonly
。
看起来像包裹totcount
可能会有帮助,只要我以某种方式调整练习环境以达到合适的计数器。但我不太清楚如何以与包中的\suspend
和命令兼容的方式做到这一点。\resume
mdwlist
有什么建议可以让我定义一个exercises
可以与和协同工作totcount
并兼容的环境吗?或者建议另一种完全不同的方法?\suspend
\resume
这是一个 MWE,其中每个练习都正确编号:第 1 章中的练习编号为 1 到 4,第 2 章中的练习也是如此。我试图解决的问题是在序言中累积正确的总数(8)。
\documentclass{book}
\usepackage{totcount}
\usepackage{mdwlist}
\newtotcounter{exercises}
\newenvironment{exercises}
{\enumerate} % need something here to count each exercise
{\endenumerate}
\begin{document}
\section*{Preface}
There are \total{exercises} exercises. (Should be~8.)
% this chapter meant to be in a separate file loaded with \include
\chapter{Diet}
\section{Omnivorous}
\begin{exercises}
\item
Which do you prefer?
\begin{enumerate}
\item
Fish
\item
Fowl
\end{enumerate}
\item
What won't you touch?
\begin{enumerate}
\item
Snakes
\item
Snails
\end{enumerate}
\suspend{exercises}
\section{Vegetarian}
\resume{exercises}
\item
Which do you prefer?
\begin{enumerate}
\item
Corn
\item
Squash
\end{enumerate}
\item
What won't you touch?
\begin{enumerate}
\item
Broccoli
\item
Cilantro
\end{enumerate}
\end{exercises}
% this chapter meant to be in a separate file loaded with \include
\chapter{Technology}
\section{Typesetting}
\begin{exercises}
\item
Which do you prefer?
\begin{enumerate}
\item
Plain \TeX
\item
\LaTeX
\end{enumerate}
\item
What won't you touch?
\begin{enumerate}
\item
Word
\item
Scribe
\end{enumerate}
\suspend{exercises}
\section{Operating systems}
\resume{exercises}
\item
Which do you prefer?
\begin{enumerate}
\item
Debian
\item
Arch
\end{enumerate}
\item
What won't you touch?
\begin{enumerate}
\item
BeOS
\item
NeXT
\end{enumerate}
\end{exercises}
\end{document}
答案1
您可以定义自己的环境和计数器。
\documentclass{article}
\usepackage{etoolbox}
\usepackage{expl3}
\usepackage{xparse}
\usepackage{enumitem}
\begin{document}
\ExplSyntaxOn
% define and initialize exercise counter
\int_new:N \g_exercise_count_int
\int_gset:Nn \g_exercise_count_int {0}
\NewDocumentEnvironment{exercise}{O{}}{
% increment counter when environment starts
\int_gincr:N \g_exercise_count_int
% forward optional arguments
\begin{enumerate}[#1]
}{
\end{enumerate}
}
\newcommand{\exercisecount}{
\int_use:N \g_exercise_count_int
}
\ExplSyntaxOff
\begin{exercise}[font=\bfseries]
\item Question 1
\item Question 2
\end{exercise}
\begin{exercise}[label=\Roman*.]
\item Question 1
\item Question 2
\end{exercise}
\begin{exercise}
\item Question 1
\item Question 2
\end{exercise}
Number of exercises: \exercisecount
\end{document}
答案2
要求提供一个最小的工作示例,但我认为准备示例所需的时间最好花在尝试解决问题上。我定义了一个exercises
环境,旨在像enumerate
书中的练习一样运行,并跟踪书中练习的总数。我还使用了包totcounter
。以下是我学到的东西:
您不能只是要求
\item
增加一个计数器,因为这会在嵌套列表内增加。要求在环境结束时增加计数器是可行的
exercises
,但\suspend
包中的宏mdwlist
会多次结束环境。我尝试了一些技巧,比如为各种挂起的环境定义一个钩子,但最终一个简单的钩子\ifsuspended
更容易工作。这个条件使它能够\end{exercises}
分辨出真正结束和只是被挂起的区别。
下面的代码。
\newtotcounter{exercises}
\newif\ifexercising
\makeatletter
\newenvironment{exercises}
{\ifexercising
\@latexerr{Nested exercises}{Don't nest exercise environments}%
\else
\exercisingtrue
\ifnum \@listdepth >1\relax
\@latexerr{Nested exercises}{Don't put exercises inside another list}%
\fi
\fi
\enumerate
}
{\ifsuspended\else\addtocounter{exercises}{\value{enumi}}\fi
\endenumerate
}
\def\@suspend@exercises{\addtocounter{exercises}{-\value{enumi}}}
\newif\ifsuspended
\suspendedfalse
\def\suspend@i[#1]#2{%
\edef\@tempa{%
\noexpand\suspendedtrue
\noexpand\end{#2}%
\def\expandafter\noexpand\csname resume.#1\endcsname{%
\csname c@\@listctr\endcsname\the\csname c@\@listctr\endcsname%
}%
}%
\@tempa%
}
\makeatother