[Tex/LaTex] \input only part of a file

input

I would like to include part of the contents of a .tex file into a different .tex file. I don't have the option of modifying the file to include. The file to include may change so simply copying and pasting the part I need is not ideal.

Essentially, I'm wondering if there is something that would work like

\input[start-end]{file.tex}

where start and end are the first and last lines to include from the file?

Best Answer

Here is an approach in pure TeX (well, e-TeX). The main idea is: to select a range of lines in a file, sed is overkill, TeX is more than enough. As a bonus, no temporary file is needed.

\documentclass[a4paper]{article}
\usepackage[ascii]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{lmodern}

\makeatletter
\newread\pin@file
\newcounter{pinlineno}
\newcommand\pin@accu{}
\newcommand\pin@ext{pintmp}
% inputs #3, selecting only lines #1 to #2 (inclusive)
\newcommand*\partialinput [3] {%
  \IfFileExists{#3}{%
    \openin\pin@file #3
    % skip lines 1 to #1 (exclusive)
    \setcounter{pinlineno}{1}
    \@whilenum\value{pinlineno}<#1 \do{%
      \read\pin@file to\pin@line
      \stepcounter{pinlineno}%
    }
    % prepare reading lines #1 to #2 inclusive
    \addtocounter{pinlineno}{-1}
    \let\pin@accu\empty
    \begingroup
    \endlinechar\newlinechar
    \@whilenum\value{pinlineno}<#2 \do{%
      % use safe catcodes provided by e-TeX's \readline
      \readline\pin@file to\pin@line
      \edef\pin@accu{\pin@accu\pin@line}%
      \stepcounter{pinlineno}%
    }
    \closein\pin@file
    \expandafter\endgroup
    \scantokens\expandafter{\pin@accu}%
  }{%
    \errmessage{File `#3' doesn't exist!}%
  }%
}
\makeatother

% for testing purpose
\begin{filecontents}{pitest}
5 You shouldn't see this.\par
6 Let the fun begin!
7 \iffalse
8 bla
9 \fi

11 New paragraph.
12 \verb*+\foo (two  spaces)~_$^+ bla
13 You shouldn't see this.\par
\end{filecontents}

\begin{document}

\partialinput{6}{12}{pitest} random text

\end{document}

I think/hope this approach is robust, mostly thanks to e-TeX's \readline. See the included test file for potential edge cases that do work.

Related Question