[texhax] optionally compiling parts of a document

Neal H. Walfield neal at walfield.org
Sun Dec 2 14:13:47 CET 2012


Hi,

The document that I'm working on now takes about a minute to typeset.
I want to improve this by only compiling a subset of the chapters.  I
know about breaking the document into multiple files and using
\includeonly to only select a subset of the chapters, but I like
having a single file.  I thought that I could get the same effect
using the filecontents package.  I've written some macros that appear
to do what I want, but the file inclusion results in an "infinite"
loop.  Here's the output of the attached example:

  LaTeX Warning: Overwriting file `./b-segment-1.tex'.
  
  
  LaTeX Warning: Overwriting file `./b-segment-2.tex'.
  
  (./b-segment-2.tex
  
  ! LaTeX Error: \include cannot be nested.
  
  See the LaTeX manual or LaTeX Companion for explanation.
  Type  H <return>  for immediate help.
   ...                                              
                                                    
  l.1 

I think that the problem has something to do with the interaction of
\filecontents and \include.  If I replace the \include with just some
text, it seems to work fine.

Thanks for any help!

Neal



Here is a minimal example using my macros:

  \documentclass{report}
  
  \usepackage{lipsum}
  \usepackage{filecontents}
  \usepackage{tikz}
  
  % The segments to include in the document.  If empty or undefined, all
  % segments are included.
  \def\segmentsToInclude{chapter 2, 3}
  
  \def\segmentcount{0}
  % Create a segment of text, which is only included in the compiled
  % document if its name or segment index is in \segmentsToInclude.
  %
  %   \begin{segment}{name}
  %   text.
  %   \end{segment}
  %
  % If name is empty, then a name will be assigned automatically.
  \newenvironment{segment}[1]{%
    % #1 is optional in the sense that it can be empty, but it is
    % required because otherwise TeX starts to convert the text into
    % tokens, which we need to avoid.
    \xdef\segmentname{#1}%
    %
    % Increment the segment count macro.
    \pgfmathparse{\segmentcount + 1}
    % Save the result.  Note: \pgfmathresult is 'XXX.0'.  Strip the
    % trailing .0.
    \def\nozerohelper##1.0{##1}%
    \def\nozero##1{\expandafter\nozerohelper##1}%
    \xdef\segmentcount{\nozero{\pgfmathresult}}%
    %
    % If the provided segment name is empty, use the segment's offset.
    \def\empty{}%
    \ifx\segmentname\empty%
      \xdef\segmentname{\segmentcount}%
    \fi%
    %
    % The segment's filename.
    \xdef\segmentsfilename{\jobname-segment-\segmentcount}%
    %
    % Write out the segment's contents.
    \filecontents{\segmentsfilename.tex}%
  }{%
    % Include the segment if appropriate.
    \def\empty{}%
    \def\doinclude{\include{\segmentsfilename}}%
    %\def\doinclude{including \segmentsfilename}%
    \expandafter \ifx \csname segmentsToInclude\endcsname \relax
      % \segmentsToInclude is undefined.  Include the segment.
      \doinclude%
    \else%
      \ifx\segmentsToInclude\empty%
        % \segmentsToInclude is empty.  Include the segment.
        \doinclude%
      \else%
        \foreach \i in \segmentsToInclude {%
          % Determine whether to include the segment.
          \def\includep{}%
          \ifx \i\segmentname%
            % The segment's name is in \segmentsToInclude.  Include the
            % segment.
            \def\includep{1}%
          \fi%
          \ifx \i\segmentcount%
            % The segment's index is in \segmentsToInclude.  Include the
            % segment.
            \def\includep{1}%
          \fi%
          %
          \ifx \includep\empty%
          \else%
            \doinclude%
            \breakforeach%
          \fi%
        }%
      \fi%
    \fi%
  }
  
  \begin{document}
  
  \begin{segment}{}
  \chapter{One}
  
  Start of chapter one.
  
  \lipsum[1-10]
  
  End of chapter one.
  
  \end{segment}
  
  \begin{segment}{chapter 2}
  \chapter{Two}
  
  Start of chapter two.
  
  \lipsum[11-20]
  
  End of chapter two.
  
  \end{segment}
  
  \begin{segment}{}
  \chapter{Three}
  
  Start of chapter three.
  
  \lipsum[21-30]
  
  End of chapter three.
  
  \end{segment}
  
  \end{document}


More information about the texhax mailing list