我想将 .tex 文件的部分内容包含到另一个 .tex 文件中。我没有修改要包含的文件的选项。要包含的文件可能会发生变化,因此简单地复制和粘贴我需要的部分并不理想。
本质上,我想知道是否有东西可以像
\input[start-end]{file.tex}
文件中要包含的第一行和最后一行在start
哪里?end
答案1
这是纯 TeX(好吧,e-TeX)的方法。主要思想是:要选择文件中的行范围,sed 是多余的,TeX 绰绰有余。作为奖励,不需要临时文件。
\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}
我认为/希望这种方法是可靠的,这主要归功于 e-TeX 的\readline
。请参阅随附的测试文件,了解可行的潜在边缘情况。
答案2
Manuel 发布了一个使用行号的答案;CTAN 上有一个最新包,可让您使用输入文件中的标签来完成此操作:捕捉标签之间的文件。
一个例子是
\usepackage{catchfilebetweentags}
...
\ExecuteMetaData[file.tex]{tag}
外部文件的内容被“标签”包围:
%<*tag>
...
%</tag>
答案3
正如注释中所述,sed -ne 42,99p
将把第 42–99 行(含)从其输入复制到其输出。这是假设您使用的是某种 unix(尽管我认为您也可以在 windows 上使用 sed)。您可以在脚本或 makefile 中执行此操作,将结果放在您包含的临时文件中。
或者,假设你使用的是 unix,你可以使用一些温和的 unix 魔法:假设你想要包含一部分的 TeX 文件名为foo.tex
。然后你可以这样做
mkfifo foosnips.tex
while sed -ne 42,99p foo.tex > foosnips.tex || [ $? == 141 ]; do sleep 1; done &
(如果不是 (ba)sh,请根据您的 shell 进行修改)然后输入foosnips
主 TeX 文件。每次对其进行 TeX 处理时,sed 命令都会提取请求的行。后台作业应该会一直运行,直到您重新启动计算机,但由于 fifo 的工作方式,它实际上不会执行任何操作,直到 fifo 被打开以供读取。当不再需要它时,或者如果您需要调整参数,请手动将其终止。
这样做也许不值得,除非foo.tex
经常更改,或者摘录非常大而您不想将其保存为单独的文件。
(退出状态 141(128+13,其中 13 是 PIPE 信号的信号编号)的测试是为了确保如果您只读取 fifo 的部分输出,循环不会终止,就像 TeX 由于某些错误而退出时一样。并且需要睡眠以确保 fifo 接收端的进程有机会在新的 sed 进程启动之前关闭文件。)
答案4
这是完全没有经过测试的东西!
\newread\pin
\newcount\pcount
\def\partialinput[#1-#2]#3{%
\openin\pin #3
\global\pcount0
\loop\ifnum\pcount<#1\relax
\read\pin to\l
\global\advance\pcount1
\repeat
\loop\ifnum\pcount<#2\relax
\read\pin to\l\l
\global\advance\pcount1
\repeat
\read\pin to\l\l
\closein\pin
}
模数错误,定义了一个\partialinput
应该按照您描述的方式工作的新宏。
实际上,数字行从 0 开始。请将其替换\global\pcount0
为\global\pcount1
从 1 开始。