[R] Summary (Re: (S|odf)weave : how to intersperse (\LaTeX{}|odf) comments in source code ? Delayed R evaluation ?)

Duncan Murdoch murdoch.duncan at gmail.com
Mon Dec 13 01:12:35 CET 2010


On 12/12/2010 6:30 PM, Emmanuel Charpentier wrote:
> Dear list,
>
> see comment at end.
>
> On Sat, 11 Dec 2010 22:58:10 +0000, Emmanuel Charpentier wrote :
>
>> Dear list,
>>
>> Inspired by the original Knuth tools, and for paedaogical reasons, I
>> wish to produce a document presenting some source code with interspersed
>> comments in the source (see Knuth's books rendering TeX and metafont
>> sources to see what I mean).
>>
>> I seemed to remember that a code chunk could be defined piecewise, like
>> in
>>
>> Comments...
>>
>> <<Chunk1, eval=FALSE, echo=TRUE>>=
>> SomeCode
>> @
>>
>> Some other comments...
>>
>> <<Chunk2, eval=FALSE, echo=TRUE>>=
>> MoreCode
>> @
>>
>> And finally,
>>
>> <<Chunk3, eval=TRUE, echo=TRUE>>=
>> <<Chunk1>>
>> <<Chunk2>>
>> EndOfTheCode
>> @
>>
>> That works ... as long as SomeCode, MoreCode and EndOfTheCode are self-
>> standing pieces of R code, but *not* code fragments. You can *not*
>> intersperse comments in, say, a function body, or  local() environment
>> this way : when Sweaving, *R* complains of an incomplete source (makes
>> noise about an unexpected end of input at the end of Chunk1, IIRC, and
>> never sees Chunk2).
>>
>> I hoped that Sweave's "alternative" syntax could offer a way out : no
>> such luck.
>>
>> There seems to be no way to delay R evaluation of a R chunk passed by
>> Sweave ; at least, the "eval=FALSE" option of chunk declaration is not
>> sufficient for that.
>>
>> Am I missing something in the Sweave nd odfWeve documentations (that I
>> read till I grew green and moldy) ? Or does this require a fundamental
>> change in the relevant Sweave drivers ?
>>
>> Can you suggest alternative ways of doing what I mean to do ? The only
>> workaround I found is to paste a second copy of my code in a \verbatim
>> environment (or, in the case of odfWeave, in the "text" part), and spice
>> it with \end{verbatim} comments.. \begin{verbatim} chunks. This way, I
>> lose any guarantee of consistency between commented text and effective
>> code.
>>
>> Any other idea ?
>>
>> 					Emmanuel Charpentier
>
>
> To summarize the answers I got so far, there seems to be no satisfactory
> solutions to my current problem with either Sweave or odfWeave :
> 	- every (Sw|odfW)eave code chunk has to be parseable in itself.
> One cannot break it in unparseable pieces in home to paste it later ;
> 	- the (hypothetical) "parse=FALSE" option, suggested by Duncan
> Murdoch, is, well, hypothetical ;
> 	- the brew package is not integrated in either Sweave or
> odfWeave ;
> 	- R-style comments will get you only so far (where is math markup
> when you need it ?) ;
> 	- subdivising work in small units is not a practical solution,
> when your "big piece" of software is a collection of small parts and
> local variable assignments, embedded in a (perforce large) local
> environment to keep things clean...
>
> Therefore, I let this problem to sleep. However, I Cc this answer (with
> the original question below) to Max Kuhn and Friedrich Leisch, in the
> (faint) hope that this feature, which does not seem to have been missed
> by anybody in 8 years, might be considered sufficiently useful to grant
> addition someday...
>

I thought about this a little more, and it's not impossible to solve. 
For example, using this file named "test.Rnw":

----------------------------
\documentclass{article}
\usepackage{Sweave}
\SweaveOpts{concordance=TRUE}
\begin{document}

Here is the start:

<<start,engine=noParse, echo=TRUE>>=
f <- function(x) {
@

Here is the end:

<<end,engine=noParse, echo=TRUE>>=
   x + 1
}
@

Here is the whole thing:

<<>>=
<<start>>
<<end>>

f(4)
@

\end{document}
-----------------------------

The following code does approximately what you want:

-----------------------------
testRuncode <- function(object, chunk, options) {
   if(options$engine == "noParse" && options$echo) {
       chunkout <- object$output
       cat("\\begin{Schunk}\n\\begin{Sinput}\n", file=chunkout)
       cat(chunk[-1], sep="\n", file=chunkout)
       cat("\n\\end{Sinput}\n\\end{Schunk}\n", file=chunkout)
       return(object)
   } else return(utils:::RweaveLatexRuncode(object, chunk, options))
}

testRweave <- function() {
   driver <- RweaveLatex()
   driver$runcode <- testRuncode
   driver
}

Sweave("test.Rnw", driver=testRweave())

------------------------------

It could probably use a lot of elaboration, but it's a start.

Duncan Murdoch



More information about the R-help mailing list