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.
\includefor your chapters? – Gonzalo Medina Sep 13 '12 at 22:01\includeonlykeep-chapter-number-of-chapters-inserted-with-include – cmhughes Sep 13 '12 at 22:03\ignorechaptersget you that\includeonly|includeget you besides the fact that the 'ignored' chapters are the ones that get included? – jon Sep 13 '12 at 22:08\iffalse...\fiwould just ignore them and might cause undefined references? – Werner Sep 13 '12 at 22:32\includeand it's my business as to why I do not want to use external files... and that should be good enough! – AbstractDissonance Sep 13 '12 at 23:02