[Tex/LaTex] Automating quoting across LaTeX documents

external filesquoting

I occasionally face the following situation when writing LaTeX documents. (This question is probably not LaTeX specific, though). Suppose I have a document, say orig.tex. Then I quote from that document in another document, say new.tex. So, for example… orig.tex is

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

and new.tex is

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

However, the problem is that after I have copied in these quotations to new.tex, I may change the text in orig.tex. I want LaTeX to automatically copy the text across from orig.tex to new.tex. Each quotation could be associated with some kind of label.

The curly braces in orig.tex mark the quotation start and end points. This is a stand-in for proper macro or function usage. This will cause some clutter in the original document, but I can remove these markers after the new.tex has been sent off. Till then, I want these two documents to stay in sync.

For simplicity, let's assume these quotations are non-overlapping, as this would add extra complexity to the problem. However, as shown in the example, they may cross line and paragraph breaks.

The closest thing in terms of functionality that I am aware of is the xr package by our very own David Carlisle :-), but I don't know if it can be adapted for use here.

UPDATE: Apparently this question wasn't as clear as it should have been. I just used {}'s in orig.tex because I wasn't sure what kind of syntax to use, but I was thinking of something along the lines of some macro like \c (for cut) in orig.tex, thus,

...\c[label]{some text to quote}

and then another macro \p for paste, which inserts that text in new.tex, thus.

...\p[label]...

UPDATE2: Thanks to Peter Grill, David Carlisle, and Aditya for their answers.

I have tested both Peter's macro solution and David's solution. A choice between the two of them would have been difficult. However, Peter's approach uses the standalone package, which seems to have some bad interactions with the custom class I'm using, Springer's svmult.cls. I was on a deadline and didn't want to take the time to figure this out, so I went with David's solution, which has no package dependencies, and worked for me.

I think this code is worth packaging – I'm surprised it does not exist as a package already. Handling multiple input files would be a desirable feature, though.

I haven't tested Aditya's solution, but plan to do so.

Best Answer

I don't think picking up just on brace groups is viable, there are too many braces in a TeX document. I used \q{...} here.

After clarification in chat and comments, a version with named references.

enter image description here

orig.tex

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

new.tex

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

The main restrictions are that:

  • You can't have two \q on the same line in the original document. Or more exactly, everything on the line after the } of a \q is ignored.

  • Any \q inside brace groups will not be seen by the scanner (as it uses TeX delimited arguments to look for \q tokens). This may be used to hide \q that may have locally different meaning, but does mean that you have to arrange that any text that you do want to quote is at the top level of the original file.


Extended version of this code placed at

http://code.google.com/p/dpctex/source/browse/#svn%2Ftrunk%2Fqting