例子

例子

我想将子文档的部分内容(由行号范围指定)作为 LaTeX 输入,同时生成有用的 SyncTeX 信息。还应该可以重新包含主文档中已有的行。


例子

给定输入文件

% -- 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

我希望输出包含

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

并对“2 秒行”调用反向搜索。实际上应该将编辑器引导至 中的正确行child.tex


现有的部分解决方案

相关问题。 在 ”\仅输入文件的一部分“,提供了一个解决方案,可以满足我的要求。除了用于 SyncTeX 支持。据我所知,这是使用该\read机制处理文件的一个不幸的副作用。

至关重要的是,该解决方案在包含多行构造(例如多行\defequation环境)的情况下非常强大。

包裹“清单”。\lstinputlisting该包的 命令listings提供了选项firstlinelastline,执行所需的过滤,同时提供 SyncTeX 支持。

然而,它专门用于包含文件逐字 我无法核实

  • 他们的逐行过滤是如何工作的,以及
  • 如果它可以在不破坏多行构造或 SyncTeX 的情况下转换为 LaTeX 输入。

包“catchbetweentags”。catchfilebetweentags软件包提供了一种包含明确标记的文件内容的机制。但是,对于我的目的而言,要求明确 %<*tag> ... %</tag>注释是不可取的,而且 SyncTeX 信息无论如何都会丢失。


目的

我正在研究这方面的选项,以便重写apxproof支持 SyncTeX 的软件包。目前,此软件包会创建一个辅助文件,该文件稍后会被包含进去,从而创建指向该辅助文件的垃圾 SyncTeX 信息。

如果可能的话,在不失去 SyncTeX 支持的情况下部分读取文件,将允许在不同的基础上构建功能。

MWE 与 apxproof 一起演示问题

\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}

编译截图

答案1

我找到了一个解决方案,但限制条件是,想要重读的内容受环境限制。现在没有时间清理它,所以我只发布了原始示例。

该工作由宏完成\InputPartialFile

%% == filterfiles-selfreparse.tex
\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.
  \begin{equation}
  content...
  \end{equation}
  \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}{<}{\startline}{%
      \IPF@skipline\IPF@skip
    }{%
      \endgroup
      \newcount\IPF@nesting
      \IPF@nesting=0
      \pretocmd{\begin}{%
        \advance\IPF@nesting by 1
      }{}{\errmessage{Failure to patch \string\begin}}%
      \apptocmd{\end}{%
        \advance\IPF@nesting by -1
        \ifnum\IPF@nesting=0
          \endinput
        \fi
      }{}{\errmessage{Failure to patch \string\end}}%
    }%
  }
  \ttfamily\noindent
  \expandafter\IPF@skip
  \@@input #2\relax
  \endgroup
  %\endgroup
}



\framebox[\linewidth]{\parbox{\linewidth}{
  \texttt{\string\InputPartialFile\{16\}\{filterfiles-selfreparse\}}
  \par\hrulefill\par
  \InputPartialFile{16}{filterfiles-selfreparse}
  \par\hrulefill\par
  \texttt{\string\InputPartialFile\{17\}\{\string\jobname\}}
  \par\hrulefill\par
  \InputPartialFile{17}{\jobname}
}}


\end{document}

答案2

使用 LuaLaTeX,可以使用回调来实现这一点。请参阅在 LuaLaTeX 中,如何将环境的内容逐字传递给 Lua?其他示例。

%! TEX program = lualatex
\documentclass[12pt]{article}
\usepackage[paper=a4paper,margin=0.6cm]{geometry}
\usepackage{currfile}

\iffalse
line 1

line 2

line 3
\fi

\directlua{
saved_synctex_tag=tex.get_synctex_tag()
function readbuf(buf)
    if not (saved_synctex_tag==nil) then
        --[[ this code should only be executed once after the \\input ]]
        tex.set_synctex_tag(saved_synctex_tag)
        tex.set_synctex_no_files(0)
        saved_synctex_tag=nil
    end
    if 7<=tex.inputlineno and tex.inputlineno<=11 then
        return nil
    else
        return ""
    end
end
}

\begin{document}

start

\directlua{
    tex.set_synctex_no_files(1)
    saved_synctex_tag=tex.get_synctex_tag()
    luatexbase.add_to_callback('process_input_buffer', readbuf, 'readbuf')
    }\input{\currfilename}\directlua{luatexbase.remove_from_callback('process_input_buffer', 'readbuf')}

end

\end{document}

...只是为了演示\iffalse\fi那里不需要命令,行号就足够了。

向前和向后搜索都很好用。如果你不需要在子文件外进行向前搜索,可以删除 synctex 部分。


关于向前搜索,这里的问题是,如果有多个标签对应于同一个文件,synctex 实用程序将仅输出对应于最后一个标签(阅读man 5 synctex和其他来源以了解 synctex 文件格式的详细信息)。

为了解决这个问题,可以tex.set_synctex_tag在 LuaTeX 中使用与父文件相同的标签,并且不要记录子文件的标签条目(用 表示set_synctex_no_files)。

还要确保 与\input在同一行\directlua,否则一次性调用将在 之前执行\input

也可以看看https://tex.stackexchange.com/a/632368/250119作为前一个函数用法的示例。

相关内容