在编写一本书时,我想“忽略”(不编译)除当前章节之外的所有章节。我知道可以使用诸如 include 之类的方法,但我不想使用外部文件或某些复杂的方法。
我只是想使用\iffalse
和fi
(或类似的东西)但我希望它是透明的:
例如,
\ignorechapters{3,4} % <- Ignores all chapters **BUT** 3,4
这就是所需要的全部内容,因此只有第 3 章和第 4 章会显示在 pdf 中。
那么,要做到这一点需要做些什么呢?我认为每个\chapter
宏都需要以一种稳健的方式进行修改,以便有条件地包含或不包含该章节
例如,通常
\chapter[mc]{my chapter}
....
\chapter[mc2]{my chapter 2}
....
\chapter[mc3]{my chapter 3}
我手动执行此操作:
\chapter[mc]{my chapter}
\iffalse
....
\fi
\chapter[mc2]{my chapter 2}
\iffalse
....
\fi
\chapter[mc3]{my chapter 3}
正如您所见,它可以轻松\iffalse
地\fi
被宏使用\chapter
而不会引起问题,并且透明地完成。(假设我们可以\chapter
轻松修改并且不会破坏其原始功能)
---编辑伪代码
newchapter macro
if previous chapter ignored % Obviously if previous chapter doesn't exist this should be ignored
insert `\fi`
end
if chapter ignored
insert `\iffalse`
end
insert `chapter data`
end macro
因此,如果需要的话,newchapter 宏将会在流中插入\fi
一个。\iffalse
如果有必要,我们还必须覆盖\end{document}
以插入最后的\fi
(如果要忽略最后一章(这意味着它有一个\iffalse
并且需要一个\fi
)。
答案1
以下示例实现了问题中描述的语法。我已将其重命名\ignorechapters
为\includechapters
,因为参数中的章节应包含在内,而不是忽略。此外,我遵循的约定\includeonly
:如果\includechapters
未指定,则包含所有章节。否则,将包含指定的章节。始终包含带星号的章节和未跟 \iffalse 的章节。
\chapter
支持以下常规语法:
\chapter*{...}
\chapter{...}
\chapter[...]{...}
排除章节
- 称呼
\cleardoublepage
, - 增加章节编号并
- 在目录中写入一个条目。
ltxcmds
只需要一个更强大的包\ltx@ifnextchar
,它还允许将条件作为下一个标记。
\documentclass{book}
\usepackage{ltxcmds}
\makeatletter
\newcommand*{\includechapters}[1]{%
\def\@includechapters{#1}%
}
\let\@includechapters\relax
\newcommand*{\org@chapter}{}
\let\org@chapter\chapter
\renewcommand*{\chapter}{%
\@ifstar{\org@chapter*}{\chapter@aux}%
}
\newcommand*{\chapter@aux}{%
\begingroup
\@ifnextchar[{\chapter@aux@opt}{%
\toks@{\org@chapter}%
\let\chapter@tocentry\relax
\chapter@@aux
}%
}
\def\chapter@aux@opt[#1]{%
\toks@{\org@chapter[{#1}]}%
\def\chapter@tocentry{#1}%
\chapter@@aux
}
\newcommand*{\chapter@@aux}[1]{%
\toks@\expandafter{\the\toks@{#1}}%
\ifx\chapter@tocentry\relax
\def\chapter@tocentry{#1}%
\fi
\ltx@ifnextchar\iffalse{%
\chapter@select
}{%
\expandafter\endgroup
\the\toks@
}%
}
\newcommand*{\chapter@select}[1]{%
\ifx\@includechapters\relax
\def\x{true}%
\else
\def\x{false}%
\@for\ch:=\@includechapters\do{%
\ifnum\ch=\numexpr\value{chapter}+1\relax
\def\x{true}%
\fi
}%
\fi
\csname if\x\endcsname
\else
\cleardoublepage
\refstepcounter{chapter}%
\addcontentsline{toc}{chapter}{%
\protect\numberline{\thechapter}%
\chapter@tocentry
}%
\fi
\expandafter\endgroup
\csname if\x\expandafter\endcsname
\the\toks@
}
\makeatother
\includechapters{2}
\begin{document}
\tableofcontents
\chapter[mc]{my chapter}
\iffalse
....
\fi
\chapter[mc2]{my chapter 2}
\iffalse
....
\fi
\chapter[mc3]{my chapter 3}
\end{document}
该示例包括目录(带星号的章节),排除“我的章节”,包括“我的章节 2”,因为它在 中列出\includechapters
,并包括“我的章节 3”,因为它后面没有\iffalse
。
更新:如果标记应该隐藏在里面而没有明确的标记用于章节结尾, 则使用 的方法\iffalse
将不起作用。当处于活动状态时,TeX 的快速扫描只会查找条件标记以找到匹配的。因此,无论如何都需要一个命令标记,其含义为不隐藏在宏中。\chapter
\iffalse
\fi
\fi
丢弃页面的方法
以下方法使用章节的属性,即它们在分页符处开始和结束。如果忽略某个章节,则该章节将照常排版,但页面将被丢弃。
\documentclass{book}
\usepackage{atbegshi}
\makeatletter
\newcommand*{\includechapters}[1]{%
\def\@includechapters{#1}%
}
\let\@includechapters\relax
\newcommand*{\org@chapter}{}
\newif\if@ignore@chapter
\renewcommand*{\@ignore@chaptertrue}{\global\let\if@ignore@chapter\iftrue}
\renewcommand*{\@ignore@chapterfalse}{\global\let\if@ignore@chapter\iffalse}
\AtBeginShipout{%
\if@ignore@chapter
\AtBeginShipoutDiscard
\fi
}
\let\org@chapter\chapter
\renewcommand*{\chapter}{%
\cleardoublepage
\@ignore@chapterfalse
\@ifstar{\org@chapter*}{\chapter@aux}%
}
\newcommand*{\chapter@aux}{%
\begingroup
\@ifnextchar[{\chapter@aux@opt}{%
\toks@{\org@chapter}%
\let\chapter@tocentry\relax
\chapter@@aux
}%
}
\def\chapter@aux@opt[#1]{%
\toks@{\org@chapter[{#1}]}%
\def\chapter@tocentry{#1}%
\chapter@@aux
}
\newcommand*{\chapter@@aux}[1]{%
\toks@\expandafter{\the\toks@{#1}}%
\ifx\chapter@tocentry\relax
\def\chapter@tocentry{#1}%
\fi
\ifx\@includechapters\relax
\@ignore@chapterfalse
\else
\@ignore@chaptertrue
\@for\ch:=\@includechapters\do{%
\ifnum\ch=\numexpr\value{chapter}+1\relax
\@ignore@chapterfalse
\fi
}%
\fi
\expandafter\endgroup\the\toks@
}
\makeatother
\includechapters{2}
\begin{document}
\tableofcontents
\chapter[mc]{my chapter}
....\the\currentgrouplevel
\chapter[mc2]{my chapter 2}
....
\chapter[mc3]{my chapter 3}
\end{document}
现在仅包含目录和章节“我的第2章”的页面。
答案2
您可以加载软件包,并用说明comment
包围暂时不需要的章节。请注意,这些说明必须单独成行,且行前不能有空格字符。\begin{comment}
\end{comment}