The following example implements the syntax described in the question. I have renamed \ignorechapters
to \includechapters
, because the chapters in the argument should be included, not ignored. Also I follow the convention of \includeonly
: If \includechapters
is not specified, all chapters are included. Otherwise the chapters are included that are specified. Starred chapters and chapters that are not followed by \iffalse are always included.
The normal syntax for \chapter
is supported:
\chapter*{...}
\chapter{...}
\chapter[...]{...}
Excluded chapters
- call
\cleardoublepage
,
- increment their chapter number and
- write an entry into the table of contents.
Package ltxcmds
is only needed for a more robust \ltx@ifnextchar
that also allows a conditional as next token.
\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}
The example includes the table of contents (starred chapter), excludes "my chapter", includes "my chapter 2", because it is listed in \includechapters
, and includes "my chapter 3", because it is not followed by \iffalse
.
Update:
The method with \iffalse
will not work, if the markup should be hidden inside \chapter
without explicit markup for the end of chapter. When \iffalse
is active, then TeX's fast scanning looks for conditional tokens only to find the matching \fi
. Therefore a command token with the meaning of \fi
that is not hidden inside macros is needed at any case.
Method via discarding pages
The following methods uses the property of chapters that they start and end at page breaks.
If a chapter is ignored, then the chapter is typeset as usual, but the pages are discarded.
\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}
Now only the pages of the table of contents and chapter "my chapter 2" are included.
\include
for your chapters?\includeonly
keep-chapter-number-of-chapters-inserted-with-include\ignorechapters
get you that\includeonly
|include
get you besides the fact that the 'ignored' chapters are the ones that get included?\iffalse
...\fi
would just ignore them and might cause undefined references?\include
and it's my business as to why I do not want to use external files... and that should be good enough!