在编写 LaTeX 文档时,我偶尔会遇到以下情况。(不过,这个问题可能不是 LaTeX 特有的)。假设我有一份文档,比如说orig.tex
。然后我在另一个文档中引用了该文档,比如说new.tex
。因此,例如...orig.tex
是
\documentclass{article}
%% orig.tex
\begin{document}
Here is some text. {This is some text I want to quote.} Here is yet
more text. The quick brown fox ran over the lazy dog.
{I want to quote all the text in this para. Some more text to get this
line to wrap.
And this para as well, in one quotation.}
\end{document}
并且new.tex
是
%% new.tex
\documentclass{article}
\usepackage{quoting}
\begin{document}
Quotation one from orig.tex is
\begin{quoting}
This is some text I want to quote.
\end{quoting}
Quotation two from orig.tex is
\begin{quoting}
I want to quote all the text in this para. Some more text to get
this line to wrap.
And this para as well, in one quotation.
\end{quoting}
\end{document}
然而,问题是,在我将这些引文复制到 之后new.tex
,我可能会更改 中的文本orig.tex
。我希望 LaTeX 自动将文本从 复制orig.tex
到new.tex
。每个引文都可以与某种标签相关联。
中的花括号orig.tex
标记了引文的开始和结束点。这是正确使用宏或函数的替代方法。这会导致原始文档有些混乱,但我可以在new.tex
发送后删除这些标记。在此之前,我希望这两个文档保持同步。
为简单起见,我们假设这些引文不重叠,因为这会增加问题的复杂性。但是,如示例所示,它们可能会跨越行和段落。
就功能而言,我所知道的最接近的是負責我们自己的包装大卫·卡莱尔:-),但我不知道它是否适合在这里使用。
更新:显然这个问题没有它应该的那么清楚。我只是使用了{}
's ,orig.tex
因为我不确定要使用哪种语法,但我正在考虑一些类似于\c
(for cut)的宏orig.tex
,因此,
...\c[label]{some text to quote}
然后是另一个\p
用于粘贴的宏,将该文本插入new.tex
,因此。
...\p[label]...
更新2:感谢 Peter Grill、David Carlisle 和 Aditya 的回答。
我已经测试过了Peter 的宏观解决方案和David 的解决方案。在两者之间做出选择会很困难。然而,Peter 的方法使用了独立包,这似乎与我正在使用的自定义类 Springer 的svmult.cls
。我当时时间紧迫,不想花时间去解决这个问题,所以我采用了 David 的解决方案,它没有软件包依赖关系,而且对我来说很有效。
我认为此代码值得打包 - 我很惊讶它尚未作为包存在。不过,处理多个输入文件将是一个理想的功能。
我还没有测试过Aditya 的解决方案,但计划这么做。
答案1
我认为只选择括号组是不可行的,TeX 文档中的括号太多了。我\q{...}
在这里用过。
在聊天和评论中澄清后,提供一个带有命名参考的版本。
原文本
\documentclass{article}
\usepackage{qting}
%% orig.tex
\begin{document}
Here is some text. \q{aa}{This is some text I want to quote.} Here is yet
more text. The quick brown fox ran over the lazy dog.
\q{bb}{I want to quote all the text in this para. Some more text to get this
line to wrap.
And this para as well, in one quotation.}
\end{document}
新特克斯
\documentclass{article}
\usepackage{qting}
\quotefrom{orig}
\begin{document}
Quotation one from orig.tex is
\quoting{aa}
Quotation two from orig.tex is
\quoting{bb}
And once again, for luck: \quoting{aa}.
\end{document}
qting.sty
% \q is just a marker to place in the original file, it just discards the label
\def\q#1{}
% \quotefrom goes in the new file and specifies which file to read.
% The file is read line by line using `\read` and plain TeX's \loop
% reading each line until end of file (\ifeof).
%
% Crucially, \read reads _at least_ a line, but always reads entire brace groups
% So the second argument of \q with the quotation will always be read in one "go".
\def\quotefrom#1{%
\newread\q@in
\openin\q@in#1\relax
\loop
% This puts the next line/brace group of old.tex into \temp
\read\q@in to \temp
% This puts tests if \temp includes \q, if not it does nothing.
% And we loop to the next line, if it does save the second argument of \q in a macro.
% with name based on the first argument.
\expandafter\testq\temp\testq\q\@nil\relax\testq\quotefrom
% keep going till the end of the file
\ifeof\q@in
\else
\repeat
}
% use a delimited argument to find the next two things after \q.
% If they are \@nil and {}, then this is the "fake" instance inserted in
% the call. In that case do nothing. Otherwise this is a \q in the document, so
% save the second argument of \q (#3) in a macro with name \q-firstArgOfq.
\long\def\testq#1\q#2#3#4\testq#5\quotefrom{%
\def\@tempa{#2}%
\ifx\@tempa\@nnil
\else
\@namedef{q-#2}{#3}%
\fi}
% if the macro for the referenced quotation is defined, use it, otherwise
% warn on the log and in the document.
\def\quoting#1{%
\expandafter\ifx\csname q-#1\endcsname\relax
[Missing quote \texttt{#1}]%
\typeout{what quote [#1] ?}%
\else
\csname q-#1\expandafter\endcsname
\fi}
主要限制如下:
原始文档中不能在同一行中出现两个。或者更确切地说, a
\q
之后的行上的所有内容都将被忽略。}
\q
扫描仪不会看到任何
\q
括号内的内容(因为它使用 TeX 分隔参数来查找\q
标记)。这可用于隐藏\q
可能具有本地不同含义的内容,但确实意味着您必须安排您想要引用的任何文本位于原始文件的顶层。
此代码的扩展版本位于
http://code.google.com/p/dpctex/source/browse/#svn%2Ftrunk%2Fqting
答案2
在 ConTeXt 中,执行此操作的标准方法是使用缓冲区。例如,您可以定义一个名为的文件,quotes.tex
其中包含:
\startenvironment quotes
\startbuffer[quote-1]
A random quote with {\em emphasis} and other commands\footnote{e.g., footntoes}.
\stopbuffer
\startbuffer[quote-2]
A quote with different catcodes, for example, in-line verbatim
\type{\undefined#} or display verbatim
\starttyping
/* Some C code */
#include<stdio.h>
void main() {
printf("Hello World\n");
}
\stoptyping
\stopbuffer
\stopenvironment
然后orig.tex
你可以使用
\environment quotes
\starttext
\getbuffer[quote-1]
\input ward
\getbuffer[quote-2]
\stoptext
和 中的情况类似new.tex
。我知道这并不是 OP 所要求的,但从某种意义上说,它实现了相同的功能。
缓冲区存储在内存中,同时比上面介绍的基于宏的解决方案更强大,因为它们不触及内容的 catcode。因此,您可以在缓冲区内拥有代码列表等,或者在不同的 catcode 机制内使用缓冲区(如果您正在处理 XML 等)。
答案3
这是我认为更灵活的东西。这是根据我过去几天一直在做的类似工作改编的。
环境版本(旧解决方案):
主要的区别在于,我需要取消引用部分文本,因此为了适应您的情况,我需要将其换行全部环境中的文本QuotableText
。可能有办法解决这个问题,但在这个解决方案的当前形式中,您需要换行全部环境中的文本QuotableText
(参见进一步增强部分)。
\begin{QuotableText}
Here is some text.
\end{QuotableText}
在orig.tex中,此环境定义为
\newenvironment{QuotableText}[1][Unnamed Quote]{\ignorespaces}{}%
因此所有文本都按正常方式排版。但是,对于您可能想要引用的话,就给它们起个名字。这里我将这个引文命名为“第一引文”:
\begin{QuotableText}[First Quote]
This is some text I want to quote.
\end{QuotableText}
然后,当你想在另一个文件中引用它时,你可以使用:
\QuoteMyText{orig.tex}{First Quote}
其中您提供文件名以及所需的报价环境的名称。
下面的 MWE 产生(其中蓝色是由原始 MWE 产生的引号,红色是通过\QuoteMyText
从原始文件中提取内容通过宏产生的引号):
笔记:
- 由于此解决方案需要能够整合完整的 LaTeX 文件,包裹
standalone
需要使用。
进一步增强:
所有这些都在宏版本答案中得到修复:
QuotableText
无需将不需要引用的文本包装在环境中。- 进行调整以使得产生的间距相同。
- 如果获取命名引号的请求提供了不存在的名称,则会出现错误消息。就我的情况而言,我采用了以下解决方案:扩展问题:如何检查传递给环境的选项是否被使用解决此问题。强烈推荐使用这种方法,因为我花了好几分钟才弄清楚为什么
\QuoteMyText{orig.tex}{Second Quote}
没有产生任何文本,是因为我的引文名称不正确。
代码:
\documentclass{article}
\usepackage{filecontents}
\begin{filecontents*}{orig.tex}
\documentclass{article}
\newenvironment{QuotableText}[1][Unnamed Quote]{%
\ignorespaces%
}{%
}%
\begin{document}
\begin{QuotableText}
Here is some text.
\end{QuotableText}
\begin{QuotableText}[First Quote]
This is some text I want to quote.
\end{QuotableText}
\begin{QuotableText}
Here is yet more text. The quick brown fox ran over the lazy dog.
\end{QuotableText}
\begin{QuotableText}[Another Quote]
I want to quote all the text in this para. Some more text to get
this line to wrap.
And this para as well, in one quotation.
\end{QuotableText}
\end{document}
\end{filecontents*}
%---------------------------
\usepackage{standalone}
\usepackage{etoolbox}
\usepackage{xcolor}
\usepackage{quoting}
\usepackage{xstring}
\usepackage{environ}
\NewEnviron{QuotableText}[1][Unnamed Quote]{\BODY}%
\newcommand{\QuoteMyText}[2]{%
% #1 = file name
% #2 = name of quotable section
\RenewEnviron{QuotableText}[1][Unnamed Quote]{%
\IfEq{##1}{#2}{% This is the quote we want
\ignorespaces%
\begin{quoting}\color{red}%
\BODY%
\end{quoting}%
}{% This is not the one we are looking for
% so we ignore the \BODY here
}%
}%
\input{#1}%
}%
\begin{document}
Quotation one from orig.tex is
\QuoteMyText{orig.tex}{First Quote}
\begin{quoting}\color{blue}
This is some text I want to quote.
\end{quoting}
Quotation two from orig.tex is
\QuoteMyText{orig.tex}{Another Quote}
\begin{quoting}\color{blue}
I want to quote all the text in this para. Some more text to get
this line to wrap.
And this para as well, in one quotation.
\end{quoting}
\end{document}
答案4
您可以使用该clipboard
包:
\Copy{<key>}{text}
\Paste{<key>}
例如:
source.tex
:
\documentclass{book}
\usepackage{clipboard}
\newclipboard{myclipboard}
\begin{document}
\Copy{dolorem ipsum}{Nor again is there anyone who
loves or pursues or desires to obtain pain of itself},
because it is pain, but occasionally circumstances occur
in which toil and pain can procure him some great pleasure.
\end{document}
target.tex
:
\documentclass{article}
\usepackage{clipboard}
\openclipboard{myclipboard}
\begin{document}
According to Cicero,
\begin{quote}
\Paste{dolorem ipsum}
\end{quote}
\end{document}
现在运行:
$ latex source.tex
$ latex target.tex