Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Bug fix in pgfSweave's handling of Sconcordance #32

Merged
merged 2 commits into from

2 participants

@aecay

Sweave keeps track of what lines in the weaved output correspond to what lines
in the source. This is useful for programs like the patchDVI R library, which
allow one to click on a spot in the compiled PDF file and be taken to the line
in the Rnw file which generated that portion of the PDF.

Previously, pgfSweave was mangling this info. This commit introduces a helper
function through which all code-chunk output should be passed. As a side
effect, it moves a lot of bolierplate into the helper function, cleaning up
the body of the pgfSweaveRunCode function.

@aecay aecay Fix bookkeeping of output lines.
Sweave keeps track of what lines in the weaved output correspond to what lines
in the source.  This is useful for programs like the patchDVI library, which
allow one to click on a spot in the compiled PDF file and be taken to the line
in the Rnw file which generated that portion of the PDF.

Previously, pgfSweave was mangling this info.  This commit introduces a helper
function through which all code-chunk output should be passed.  As a side
effect, it moves a lot of bolierplate into the helper function, cleaning up
the body of the pgfSweaveRunCode function.
2f90e0d
@cameronbracken

This is great! A much needed fix, I never use concordance so the suport for it was very haphazard, this is also a nice cleanup of the code. See my comment on the commit.

@cameronbracken

I think there is still one small bug when the tidy option is used with the keep.source option and a long code line or comment is wrapped. After running patchSynctex I get the warning:

Warning message:
In matrix(values[-1], nrow = 2) :
  data length [33] is not a sub-multiple or multiple of the number of rows [2]

see: https://gist.github.com/1036173 for an example.

It doesn't seem to negatively affect the output but it is annoying.

@cameronbracken

Do you think you might fix this warning?

@aecay

Sorry for the delayed response -- I've been on vacation and haven't had a chance to look in detail at what is going on in this case. The concordance is supposed to contain an odd number of numbers; superficially it looks like this case is causing an even number to be included. But whether this is a problem with pgfSweave, with patchDVI, or something inherited from base Sweave is not something I've been able to look at.

I'll be back from vacation on the 4th, so I hope to have a bugfix out within a few days of that time.

@cameronbracken

No worries, thanks again for your work!

@aecay

OK, I've had a chance to look more at this problem, and figure out what is causing it. The warning message above is caused by the fact that the concordance (which is supposed to be a list of numbers) winds up containing NAs. This is what causes the parsing code in patchSynctex to barf.

It seems the NAs are caused by the keep.source option -- setting that to FALSE gives OK results for highlight=T. As far as I can see, this option only affects the behavior of the deparse(.tidy) call in pgfSweaveRuncode. I still haven't figured out how this percolates through the rest of the function to make NAs crop up. I'll keep trying to understand what goes on and update again when I have something more.

@cameronbracken

Cool, good to know, let me know if I can help at all.

@yihui yihui referenced this pull request in yihui/knitr
Closed

support concordance #133

@cameronbracken cameronbracken merged commit 02e1264 into from
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 17, 2011
  1. @aecay

    Fix bookkeeping of output lines.

    aecay authored
    Sweave keeps track of what lines in the weaved output correspond to what lines
    in the source.  This is useful for programs like the patchDVI library, which
    allow one to click on a spot in the compiled PDF file and be taken to the line
    in the Rnw file which generated that portion of the PDF.
    
    Previously, pgfSweave was mangling this info.  This commit introduces a helper
    function through which all code-chunk output should be passed.  As a side
    effect, it moves a lot of bolierplate into the helper function, cleaning up
    the body of the pgfSweaveRunCode function.
Commits on Jun 19, 2011
  1. @aecay
This page is out of date. Refresh to see the latest.
Showing with 57 additions and 76 deletions.
  1. +57 −76 R/pgfSweaveDriver.R
View
133 R/pgfSweaveDriver.R
@@ -133,7 +133,7 @@ pgfSweaveWritedoc <- function(object, chunk)
if(length(which)){
chunk[which] <- paste(chunk[which],"\\usetikzlibrary{external}",
"\\tikzexternalize[mode=list and make]\n", sep="\n")
- linesout <- linesout[c(1L:which, which, seq(from=which+1L, length.out=length(linesout)-which))]
+ linesout <- linesout[c(1L:which, which, which, seq(from=which+1L, length.out=length(linesout)-which))]
object$havetikzexternalize <- TRUE
}
}
@@ -159,12 +159,12 @@ pgfSweaveWritedoc <- function(object, chunk)
# put in the style definitions after the \documentclass command
if(length(which)) {
chunk <- c(chunk[1:which],hstyle,chunk[(which+1):length(chunk)])
- linesout <- linesout[c(1L:which, which, seq(from = which +
+ linesout <- linesout[c(1L:which, rep(which, length(hstyle)), seq(from = which +
1L, length.out = length(linesout) - which))]
object$haveHighlightSyntaxDef <- TRUE
}
}
-
+
while(length(pos <- grep(object$syntax$docexpr, chunk)))
{
cmdloc <- regexpr(object$syntax$docexpr, chunk[pos[1L]])
@@ -265,6 +265,20 @@ pgfSweaveRuncode <- function(object, chunk, options) {
}
else chunkout <- object$output
+ write.chunk <- function(str, file = chunkout) {
+ cat(str, file=file, append=TRUE)
+ lo <- linesout
+ tl <- thisline
+
+ nlines <- sum(strsplit(str, NULL)[[1]] == "\n")
+
+ if (nlines > 0) {
+ lo[tl + 1:nlines] <- srcline
+ assign("linesout", lo, parent.env(environment()))
+ assign("thisline", tl + nlines, parent.env(environment()))
+ }
+ }
+
saveopts <- options(keep.source=options$keep.source)
on.exit(options(saveopts))
@@ -357,12 +371,10 @@ pgfSweaveRuncode <- function(object, chunk, options) {
if(options$echo && length(dce)){
if(!openSinput){
if(!openSchunk){
- cat("\\begin{Schunk}\n",file=chunkout, append=TRUE)
- linesout[thisline + 1] <- srcline
- thisline <- thisline + 1
+ write.chunk("\\begin{Schunk}\n")
openSchunk <- TRUE
}
- cat("\\begin{", Sinputenv, "}", sep="", file=chunkout, append=TRUE)
+ write.chunk(paste("\\begin{", Sinputenv, "}", sep=""))
openSinput <- TRUE
beginSinput <- TRUE
}
@@ -374,35 +386,38 @@ pgfSweaveRuncode <- function(object, chunk, options) {
if(length(grep("^[[:space:]]*$",dce)) >= 1 & length(dce) == 1){
# for blank lines for which parser throws an error
- cat(translator_latex(paste(getOption("prompt"),'\n', sep="")),
- file=chunkout, append=TRUE, sep="")
- cat(newline_latex(),file=chunkout, append=TRUE)
-
+ write.chunk(translator_latex(paste(getOption("prompt"),'\n', sep="")))
+ write.chunk(newline_latex())
}else{
+ if (!beginSinput) {
+ write.chunk(newline_latex())
+ }
- if (!beginSinput) cat(newline_latex(), file=chunkout, append=TRUE)
+ tmpcon <- file()
highlight(parser.output=parser(text=dce),
renderer=renderer_latex(document=FALSE),
- output = chunkout, showPrompts=TRUE,
+ output = tmpcon, showPrompts=TRUE,
size=ifelse(is.null(getOption('highlight.size')),
"normalsize", getOption('highlight.size')))
+ cat("\n", file = tmpcon) # Just in case
+ flush(tmpcon)
+ write.chunk(readLines(tmpcon))
+ close(tmpcon)
}
beginSinput <- FALSE
}else{
# regular output, may be tidy'd or not
- cat("\n",paste(getOption("prompt"), dce[1:leading], sep="",
- collapse="\n"), file=chunkout, append=TRUE, sep="")
- if (length(dce) > leading)
- cat("\n", paste(getOption("continue"), dce[-(1:leading)], sep="",
- collapse="\n"), file=chunkout, append=TRUE, sep="")
-
+ write.chunk(paste("\n",paste(getOption("prompt"), dce[1:leading], sep="",
+ collapse="\n"),sep=""))
+ if (length(dce) > leading) {
+ write.chunk(paste("\n", paste(getOption("continue"), dce[-(1:leading)], sep="",
+ collapse="\n"), sep=""))
+ }
}
- linesout[thisline + 1:length(dce)] <- srcline
- thisline <- thisline + length(dce)
}
# do not evaluate empty expressions, these may occur when tidy=T
@@ -434,22 +449,16 @@ pgfSweaveRuncode <- function(object, chunk, options) {
if(length(output)>0 & (options$results != "hide")){
if(openSinput){
- cat("\n\\end{", Sinputenv, "}\n", sep="", file=chunkout, append=TRUE)
- linesout[thisline + 1:2] <- srcline
- thisline <- thisline + 2
+ write.chunk(paste("\n\\end{", Sinputenv, "}\n", sep=""))
openSinput <- FALSE
}
if(options$results=="verbatim"){
if(!openSchunk){
- cat("\\begin{Schunk}\n",file=chunkout, append=TRUE)
- linesout[thisline + 1] <- srcline
- thisline <- thisline + 1
+ write.chunk("\\begin{Schunk}\n")
openSchunk <- TRUE
}
- cat("\\begin{Soutput}\n",file=chunkout, append=TRUE)
- linesout[thisline + 1] <- srcline
- thisline <- thisline + 1
+ write.chunk("\\begin{Soutput}\n")
}
output <- paste(output,collapse="\n")
@@ -461,48 +470,33 @@ pgfSweaveRuncode <- function(object, chunk, options) {
output <- sub("\n[[:space:]]*\n", "\n", output)
}
- cat(output, file=chunkout, append=TRUE)
- count <- sum(strsplit(output, NULL)[[1]] == "\n")
-
- if (count > 0) {
- linesout[thisline + 1:count] <- srcline
- thisline <- thisline + count
- }
-
+ write.chunk(output)
remove(output)
if(options$results=="verbatim"){
- cat("\n\\end{Soutput}\n", file=chunkout, append=TRUE)
- linesout[thisline + 1:2] <- srcline
- thisline <- thisline + 2
+ write.chunk("\n\\end{Soutput}\n")
}
}
}
}
if(openSinput){
- cat("\n\\end{", Sinputenv, "}\n", sep="", file=chunkout, append=TRUE)
- linesout[thisline + 1:2] <- srcline
- thisline <- thisline + 2
+ write.chunk(paste("\n\\end{", Sinputenv, "}\n", sep=""))
}
if(openSchunk){
- cat("\\end{Schunk}\n", file=chunkout, append=TRUE)
- linesout[thisline + 1] <- srcline
- thisline <- thisline + 1
+ write.chunk("\\end{Schunk}\n")
}
if(is.null(options$label) & options$split)
close(chunkout)
if(options$split & options$include){
- cat("\\input{", chunkprefix, "}\n", sep="",
- file=object$output, append=TRUE)
- linesout[thisline + 1] <- srcline
- thisline <- thisline + 1
+ write.chunk(paste("\\input{", chunkprefix, "}\n", sep=""),
+ file=object$output)
}
- if(options$fig && options$eval){
+ if(options$fig && options$eval) {
chunkChanged <-
if( options$external )
@@ -617,47 +611,34 @@ pgfSweaveRuncode <- function(object, chunk, options) {
# Write the extrnalization commands
if(options$include && options$external) {
- cat("\n\\tikzsetnextfilename{",chunkprefix,"}\n",sep="",
- file=object$output, append=TRUE)
- cat("\n\\tikzexternalfiledependsonfile{",chunkprefix,"}{",
- paste(chunkprefix, "tikz", sep="."),"}\n",sep="",
- file=object$output, append=TRUE)
+ write.chunk(paste("\n\\tikzsetnextfilename{",chunkprefix,"}\n",sep=""),
+ file=object$output)
+ write.chunk(paste("\n\\tikzexternalfiledependsonfile{",chunkprefix,"}{",
+ paste(chunkprefix, "tikz", sep="."),"}\n",sep=""),
+ file=object$output)
- linesout[thisline + 1] <- srcline
- thisline <- thisline + 1
-
}
# Write the includegraphics command for eps or pdf
# only if we are not useing pgf or tikz
if(options$include && !options$pgf && !options$tikz && !options$external) {
- cat("\\includegraphics{", chunkprefix, "}\n", sep="",
- file=object$output, append=TRUE)
- linesout[thisline + 1] <- srcline
- thisline <- thisline + 1
-
+ write.chunk(paste("\\includegraphics{", chunkprefix, "}\n", sep=""),
+ file=object$output)
}
# input statements for tikz and pgf
if(options$include && (options$pgf || options$tikz)) {
-
#if tikz takes precident over pgf option
suffix <- ifelse(options$tikz,'tikz','pgf')
if(!options$external){
- cat("{\\tikzexternaldisable\n", sep="", file=object$output, append=TRUE)
- linesout[thisline + 1] <- srcline
- thisline <- thisline + 1
+ write.chunk("{\\tikzexternaldisable\n", file=object$output)
}
- cat("\\input{", paste(chunkprefix,suffix,sep='.'),
- "}\n", sep="", file=object$output, append=TRUE)
- linesout[thisline + 1] <- srcline
- thisline <- thisline + 1
+ write.chunk(paste("\\input{", paste(chunkprefix,suffix,sep='.'),
+ "}\n", sep=""), file=object$output)
if(!options$external){
- cat("}\n", sep="", file=object$output, append=TRUE)
- linesout[thisline + 1] <- srcline
- thisline <- thisline + 1
+ write.chunk("}\n", file=object$output)
}
}
Something went wrong with that request. Please try again.