# \input only part of file, without losing SyncTeX support?

I want to include parts of a child document, specified by a range of line numbers, as LaTeX input, while producing useful SyncTeX information. It should also be possible to re-include lines already in the main document.

# Example

Given input files

% -- main.tex
..:  ...
20:  Before input.\par
21:  \inputlines{2}{4}{child.tex}
22:  After input.\par
23:  Repeat: \inputlines{22}{22}{main.tex}
..:  ...

% -- child.tex
1: 1 First line.\par
2: 2 Second line.\par
3: 3 Third line.\par
4: 4 Fourth line.\par
5: 5 Fifth line.\par


I want the output to contain

...
Before input.
2 Second line.
3 Third line.
4 Fourth line.
After input.
Repeat: After input.
...


and invoking inverse search on "2 second line." should actually direct the editor to the correct line in child.tex.

# Existing partial solutions

Related question. In "\input only part of a file", a solution is provided, that does what I want except for SyncTeX support. As far as I can tell, that is an unfortunate side effect of processing a file with the \read mechanism.

Crucially, this solution is robust in situations containing multi-line constructs, such as multi-line \defs or the equation environment.

Package "listings". The command \lstinputlisting of the listings package provides options firstline and lastline, that perform the desired filtering, while providing SyncTeX support.

It is however specialized for including files in verbatim and I was unable to verify

• How their filtering-by-line works, and
• if it can be transferred to LaTeX input without breaking either multi-line constructs or SyncTeX.

Package "catchbetweentags". The catchfilebetweentags package provides a mechanism for including file contents marked explicitly. However, for my purposes requiring explicit %<*tag> ... %</tag> comments is undesirable, and SyncTeX information is lost anyway.

# Purpose

I am researching options for this, in order to rewrite the apxproof package with SyncTeX support. Currently this package creates an auxiliary file, that is later included, thereby creating junk SyncTeX information, that points to the auxiliary file.

Reading files partially, if possible without losing SyncTeX support, would allow building the functionality on a different basis.

# MWE with apxproof, demonstrating the problem

\makeatletter\input{filecontents.sty}\makeatother
\begin{filecontents*}{\jobname.child.tex}
This proof has its contents stored in a child document.
SyncTeX will correctly point to this file
but
\begin{itemize}
\item It doesn't fix the loss of precision in \verb|thmrep|.
\item With many proofs, the large number of child documents
can become rather inconvenient.
\end{itemize}
\end{filecontents*}

\documentclass{article}
\usepackage{apxproof}
\usepackage{etoolbox}
\let\appendixprelim\relax % Prevent newpage before typesetting proofs.
\newtheoremrep{thm}{Theorem}
\preto\appendix{\noindent\hrulefill Appendix starts here}

\begin{document}

\section{Start}

\begin{thmrep}
This is a theorem, that will be repeated in the appendix.

SyncTeX sort of works here, for

It does however point only to the end of the environment,
not to individual paragraphs.
\end{thmrep}

\begin{appendixproof}
This is the proof, which will be put into the appendix via \verb|\VerbatimOut| mechanism.

\textsf{apxproof} defers it to the appendix,
by writing it out to \verb|\jobname.axp|
and then \verb|\input|ing it in the appendix.

Sadly, this mechanism causes SyncTeX to consider
the auxiliary file \verb|\jobname.axp| to be
the source of the contents.
\end{appendixproof}

\begin{appendixproof}
\input{\jobname.child.tex}
\end{appendixproof}

\end{document}


• For my purpose, not really (though I'll keep in in mind for other usecases). (a) For reimplementing/extending apxproof, the solution would have to be able to re-read from the main document too, which creates a bootstrapping problem. (b) Using such constructs, or environments to the same effect, would sabotage the overall usability, leaving the loss of SyncTeX information or workarounds like \begin{proof}\input{proof.123.inc}\end{proof} as lesser evil. – kdb Jun 27 '18 at 7:56
• @JohnKormylo As far as I can tell, storing tokens into macros discards the SyncTeX information. – kdb Jun 27 '18 at 14:40
• @JohnKormylo SyncTeX is the only reason for me to be looking into this actually. The apxproof package is quite useful, but its usability is hindered strongly by the loss of synctex support, so I was hoping to achieve the same behavior in some manner that preserves SyncTeX information. – kdb Jun 28 '18 at 11:22
• A complete MWE would be useful here. I'm wondering if a savebox might work. – John Kormylo Jun 28 '18 at 13:23
• @JohnKormylo Added MWE. Savebox would prevent pagebreaks, which isn't acceptable either (long proofs, formatting near page breaks, etc.). Also, SyncTeX will point to the end of the \savebox\mybox{CONTENT} construct, but not to the correct line within. – kdb Jun 28 '18 at 14:32

I found a solution, under the constraint that what one wants to re-read is delimited by an environment. Having no time to clean it up right now, I just post the raw example.

The work is done by the \InputPartialFile macro.


\documentclass[12pt]{article}
\usepackage{etoolbox}
\newenvironment{fold}{}{}

\makeatletter

\begin{document}

Line \the\inputlineno.
Line \the\inputlineno.
Line \the\inputlineno.

Line \the\inputlineno.
Line \the\inputlineno.
Line \the\inputlineno.

\newcount\startline
\startline=\inputlineno
\begin{fold}
First paragraph inside fold.

\ifcsname IPF@nesting\endcsname\the\IPF@nesting\fi

\begin{fold}
Stuff inside nested fold.
$$content...$$
\end{fold}

Second paragraph inside fold = end of fold.

\end{fold}After fold, same line.
After fold, next line.

%% Must use line-skipping instead of \@gobble, because
%% \@gobble updates \inputlineno only after the first character
%% of the line has been lost.
\begingroup
\global\long\def\IPF@skipline#1{%
\begingroup
\catcode\^^M=13\relax
\IPF@skipline@b{#1}%
}
% next lines are whitespace-sensitive.
\catcode\^^M=13
\global\long\def\IPF@skipline@b#1#2^^M{\endgroup#1}\endgroup

\def\InputPartialFile#1#2{
%% Usage: \InputPartialFile{STARTLINE}{FILENAME}
%%
%% Read FILENAME from STARTLINE until a balanced \end{ENV} form.
%% Technical limitation: Anything after the \end{..} on the same
%% line will be included.
%%
%% Currently NOT nestable.
%%
\begingroup
\newcount\startline
\startline=#1\relax
\begingroup
\long\def\@@gobble##1{\global\long\def\@@gobbled{##1}}
\def\IPF@skip{%
\ifnumcomp{\inputlineno+1}{