Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

When working on a book I'd like to "ignore"(not compile) all chapters but the current one. I know there are methods to use like include and such BUT I do not want to use external files or some complex method.

I simply want to use \iffalse and fi(or something similar) BUT I want it transparent:

e.g.,

\ignorechapters{3,4} % <- Ignores all chapters **BUT** 3,4

and that is all that is needed so that only chapters 3 and 4 show up in the pdf.

So what is needed to do this? I imagine each \chapter macro will need to be modified in a robust way so that it will conditionally include the chapter or not

e.g., normally one has

\chapter[mc]{my chapter}
....
\chapter[mc2]{my chapter 2}
....
\chapter[mc3]{my chapter 3}

and I do this manually:

\chapter[mc]{my chapter}
\iffalse
....
\fi
\chapter[mc2]{my chapter 2}
\iffalse
....
\fi
\chapter[mc3]{my chapter 3}

and as you can see, it each \iffalse and \fi could easily be consumed into the \chapter macro without causing problems and done so transparently. (Assuming we can modify \chapter easily and not break it's original functionality)

--- Edit pseudo-code

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

Hence the the newchapter macro will insert a \fi then an \iffalse into the stream if necessary.

We would also have to override the \end{document} to insert the final \fi if necessary(if the last chapter is to be ignored(which means it has an \iffalse and requires a \fi).

share|improve this question
2  
Why don't you want to use \include for your chapters? –  Gonzalo Medina Sep 13 '12 at 22:01
1  
and then \includeonly keep-chapter-number-of-chapters-inserted-with-include –  cmhughes Sep 13 '12 at 22:03
    
Where does \ignorechapters get you that \includeonly|include get you besides the fact that the 'ignored' chapters are the ones that get included? –  jon Sep 13 '12 at 22:08
    
Are you concerned about inter-chapter references, since \iffalse...\fi would just ignore them and might cause undefined references? –  Werner Sep 13 '12 at 22:32
    
Why does everyone try to rewrite my question into asking about something else instead of just giving me a solution? As I said, I'm not interested in using \include and 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
show 2 more comments

2 Answers

up vote 10 down vote accepted

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.

share|improve this answer
    
I think this is on the right track but you misinterpreted my question slightly. I do not want to have to explicitly use \iffalse and \fi. I want it to be automatically inserted. What you have will work so I have marked it as correct but please try and fix it. –  AbstractDissonance Sep 14 '12 at 2:04
    
your example should look like \chapter[mc]{my chapter} .... \chapter[mc2]{my chapter 2} .... \chapter[mc3]{my chapter 3} at the bottom. –  AbstractDissonance Sep 14 '12 at 2:06
    
(Note that the behavior you have of your example is correct but instead of inserting the \iffalse and \fi's you delete them) –  AbstractDissonance Sep 14 '12 at 2:07
    
That's not possible. The \fi must be visible somehow, otherwise all would be ignored including \end{document} if a chapter is skipped. Even with the comment package you need a markup for the end of chapter that cannot be hidden inside macros. –  Heiko Oberdiek Sep 14 '12 at 2:38
    
huh? It definitely is possible. Your macro must be logical enough to realize it is the last chapter! (the same type of logic must prevent a \fi from the first chapter. I'll ammend my questio with some pseudo code. –  AbstractDissonance Sep 14 '12 at 2:51
show 7 more comments

You could load the comment package and surround the temporarily unwanted chapters with \begin{comment} and \end{comment} instructions. Note that these instructions must be on lines by themselves, with no leading blank (space) characters preceding them on the line.

share|improve this answer
    
You can also add various names for comments, e.g. \includecomment{chapter1} and surround the first chapter by \begin{chapter1} and \end{chapter1}. (You can find more details in the comment package documentation.) –  Martin Sep 14 '12 at 4:31
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.