Skip to content
This repository

Bug fix in pgfSweave's handling of Sconcordance #32

Merged
merged 2 commits into from about 2 years ago

2 participants

Aaron Ecay Cameron Bracken
Aaron Ecay
aecay commented June 16, 2011

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.

Aaron Ecay 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
Cameron Bracken
Owner

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.

Cameron Bracken
Owner

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.

Cameron Bracken
Owner

Do you think you might fix this warning?

Aaron Ecay
aecay commented June 28, 2011

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.

Cameron Bracken
Owner

No worries, thanks again for your work!

Aaron Ecay
aecay commented July 25, 2011

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.

Cameron Bracken
Owner

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

Yihui Xie yihui referenced this pull request in yihui/knitr February 11, 2012
Open

support concordance #133

Cameron Bracken cameronbracken merged commit 02e1264 into from March 19, 2012
Cameron Bracken cameronbracken closed this March 19, 2012
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 2 unique commits by 1 author.

Jun 16, 2011
Aaron Ecay 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
Jun 19, 2011
Aaron Ecay The stream is already open; reopening gives a warning. 02e1264
This page is out of date. Refresh to see the latest.

Showing 1 changed file with 57 additions and 76 deletions. Show diff stats Hide diff stats

  1. 133  R/pgfSweaveDriver.R
133  R/pgfSweaveDriver.R
@@ -133,7 +133,7 @@ pgfSweaveWritedoc <- function(object, chunk)
133 133
       if(length(which)){
134 134
         chunk[which] <- paste(chunk[which],"\\usetikzlibrary{external}",
135 135
           "\\tikzexternalize[mode=list and make]\n", sep="\n")
136  
-        linesout <- linesout[c(1L:which, which, seq(from=which+1L, length.out=length(linesout)-which))]
  136
+        linesout <- linesout[c(1L:which, which, which, seq(from=which+1L, length.out=length(linesout)-which))]
137 137
         object$havetikzexternalize <- TRUE
138 138
       }
139 139
     }
@@ -159,12 +159,12 @@ pgfSweaveWritedoc <- function(object, chunk)
159 159
             # put in the style definitions after the \documentclass command
160 160
       if(length(which)) {
161 161
         chunk <- c(chunk[1:which],hstyle,chunk[(which+1):length(chunk)])
162  
-        linesout <- linesout[c(1L:which, which, seq(from = which +
  162
+        linesout <- linesout[c(1L:which, rep(which, length(hstyle)), seq(from = which +
163 163
             1L, length.out = length(linesout) - which))]
164 164
         object$haveHighlightSyntaxDef <- TRUE
165 165
       }
166 166
     }
167  
-    
  167
+
168 168
     while(length(pos <- grep(object$syntax$docexpr, chunk)))
169 169
     {
170 170
         cmdloc <- regexpr(object$syntax$docexpr, chunk[pos[1L]])
@@ -265,6 +265,20 @@ pgfSweaveRuncode <- function(object, chunk, options) {
265 265
   }
266 266
   else  chunkout <- object$output
267 267
 
  268
+  write.chunk <- function(str, file = chunkout) {
  269
+    cat(str, file=file, append=TRUE)
  270
+    lo <- linesout
  271
+    tl <- thisline
  272
+
  273
+    nlines <- sum(strsplit(str, NULL)[[1]] == "\n")
  274
+
  275
+    if (nlines > 0) {
  276
+      lo[tl + 1:nlines] <- srcline
  277
+      assign("linesout", lo, parent.env(environment()))
  278
+      assign("thisline", tl + nlines, parent.env(environment()))
  279
+    }
  280
+   }
  281
+
268 282
   saveopts <- options(keep.source=options$keep.source)
269 283
   on.exit(options(saveopts))
270 284
 
@@ -357,12 +371,10 @@ pgfSweaveRuncode <- function(object, chunk, options) {
357 371
     if(options$echo && length(dce)){
358 372
       if(!openSinput){
359 373
         if(!openSchunk){
360  
-          cat("\\begin{Schunk}\n",file=chunkout, append=TRUE)
361  
-            linesout[thisline + 1] <- srcline
362  
-            thisline <- thisline + 1
  374
+          write.chunk("\\begin{Schunk}\n")
363 375
             openSchunk <- TRUE
364 376
         }
365  
-          cat("\\begin{", Sinputenv, "}", sep="", file=chunkout, append=TRUE)
  377
+          write.chunk(paste("\\begin{", Sinputenv, "}", sep=""))
366 378
           openSinput <- TRUE
367 379
           beginSinput <- TRUE
368 380
       }
@@ -374,35 +386,38 @@ pgfSweaveRuncode <- function(object, chunk, options) {
374 386
         if(length(grep("^[[:space:]]*$",dce)) >= 1 & length(dce) == 1){
375 387
           
376 388
             # for blank lines for which parser throws an error
377  
-          cat(translator_latex(paste(getOption("prompt"),'\n', sep="")),
378  
-            file=chunkout, append=TRUE, sep="")
379  
-          cat(newline_latex(),file=chunkout, append=TRUE)
380  
-          
  389
+          write.chunk(translator_latex(paste(getOption("prompt"),'\n', sep="")))
  390
+          write.chunk(newline_latex())
381 391
         }else{
  392
+          if (!beginSinput) {
  393
+            write.chunk(newline_latex())
  394
+          }
382 395
 
383  
-          if (!beginSinput) cat(newline_latex(), file=chunkout, append=TRUE)
  396
+          tmpcon <- file()
384 397
 
385 398
           highlight(parser.output=parser(text=dce),
386 399
             renderer=renderer_latex(document=FALSE),
387  
-            output = chunkout, showPrompts=TRUE, 
  400
+            output = tmpcon, showPrompts=TRUE, 
388 401
             size=ifelse(is.null(getOption('highlight.size')),
389 402
               "normalsize", getOption('highlight.size')))
  403
+          cat("\n", file = tmpcon)      # Just in case
  404
+          flush(tmpcon)
  405
+          write.chunk(readLines(tmpcon))
  406
+          close(tmpcon)
390 407
 
391 408
         }
392 409
         beginSinput <- FALSE
393 410
 
394 411
       }else{
395 412
           # regular output, may be tidy'd or not
396  
-        cat("\n",paste(getOption("prompt"), dce[1:leading], sep="",
397  
-          collapse="\n"), file=chunkout, append=TRUE, sep="")
398  
-        if (length(dce) > leading)
399  
-          cat("\n", paste(getOption("continue"), dce[-(1:leading)], sep="",
400  
-            collapse="\n"), file=chunkout, append=TRUE, sep="")
401  
-            
  413
+        write.chunk(paste("\n",paste(getOption("prompt"), dce[1:leading], sep="",
  414
+          collapse="\n"),sep=""))
  415
+        if (length(dce) > leading) {
  416
+          write.chunk(paste("\n", paste(getOption("continue"), dce[-(1:leading)], sep="",
  417
+            collapse="\n"), sep=""))
  418
+        }
402 419
       }
403 420
       
404  
-      linesout[thisline + 1:length(dce)] <- srcline
405  
-      thisline <- thisline + length(dce)
406 421
     }
407 422
 
408 423
       # do not evaluate empty expressions, these may occur when tidy=T
@@ -434,22 +449,16 @@ pgfSweaveRuncode <- function(object, chunk, options) {
434 449
 
435 450
       if(length(output)>0 & (options$results != "hide")){
436 451
         if(openSinput){
437  
-          cat("\n\\end{", Sinputenv, "}\n", sep="", file=chunkout, append=TRUE)
438  
-          linesout[thisline + 1:2] <- srcline
439  
-          thisline <- thisline + 2
  452
+          write.chunk(paste("\n\\end{", Sinputenv, "}\n", sep=""))
440 453
           openSinput <- FALSE
441 454
         }
442 455
 
443 456
         if(options$results=="verbatim"){
444 457
           if(!openSchunk){
445  
-            cat("\\begin{Schunk}\n",file=chunkout, append=TRUE)
446  
-            linesout[thisline + 1] <- srcline
447  
-            thisline <- thisline + 1
  458
+            write.chunk("\\begin{Schunk}\n")
448 459
             openSchunk <- TRUE
449 460
           }
450  
-          cat("\\begin{Soutput}\n",file=chunkout, append=TRUE)
451  
-          linesout[thisline + 1] <- srcline
452  
-          thisline <- thisline + 1
  461
+          write.chunk("\\begin{Soutput}\n")
453 462
         }
454 463
 
455 464
         output <- paste(output,collapse="\n")
@@ -461,48 +470,33 @@ pgfSweaveRuncode <- function(object, chunk, options) {
461 470
             output <- sub("\n[[:space:]]*\n", "\n", output)
462 471
         }
463 472
 
464  
-        cat(output, file=chunkout, append=TRUE)
465  
-        count <- sum(strsplit(output, NULL)[[1]] == "\n")
466  
-
467  
-        if (count > 0) {
468  
-          linesout[thisline + 1:count] <- srcline
469  
-          thisline <- thisline + count
470  
-        }
471  
-
  473
+        write.chunk(output)
472 474
         remove(output)
473 475
 
474 476
         if(options$results=="verbatim"){
475  
-          cat("\n\\end{Soutput}\n", file=chunkout, append=TRUE)
476  
-          linesout[thisline + 1:2] <- srcline
477  
-          thisline <- thisline + 2
  477
+          write.chunk("\n\\end{Soutput}\n")
478 478
         }
479 479
       }
480 480
     }
481 481
   }
482 482
 
483 483
   if(openSinput){
484  
-    cat("\n\\end{", Sinputenv, "}\n", sep="", file=chunkout, append=TRUE)
485  
-    linesout[thisline + 1:2] <- srcline
486  
-    thisline <- thisline + 2
  484
+    write.chunk(paste("\n\\end{", Sinputenv, "}\n", sep=""))
487 485
   }
488 486
 
489 487
   if(openSchunk){
490  
-    cat("\\end{Schunk}\n", file=chunkout, append=TRUE)
491  
-    linesout[thisline + 1] <- srcline
492  
-    thisline <- thisline + 1
  488
+    write.chunk("\\end{Schunk}\n")
493 489
   }
494 490
 
495 491
   if(is.null(options$label) & options$split)
496 492
     close(chunkout)
497 493
 
498 494
   if(options$split & options$include){
499  
-    cat("\\input{", chunkprefix, "}\n", sep="",
500  
-      file=object$output, append=TRUE)
501  
-    linesout[thisline + 1] <- srcline
502  
-    thisline <- thisline + 1
  495
+    write.chunk(paste("\\input{", chunkprefix, "}\n", sep=""),
  496
+      file=object$output)
503 497
   }
504 498
 
505  
-  if(options$fig && options$eval){
  499
+  if(options$fig && options$eval) {
506 500
       
507 501
     chunkChanged <- 
508 502
       if( options$external )
@@ -617,47 +611,34 @@ pgfSweaveRuncode <- function(object, chunk, options) {
617 611
 
618 612
       # Write the extrnalization commands
619 613
     if(options$include && options$external) {
620  
-      cat("\n\\tikzsetnextfilename{",chunkprefix,"}\n",sep="",
621  
-        file=object$output, append=TRUE)
622  
-      cat("\n\\tikzexternalfiledependsonfile{",chunkprefix,"}{",
623  
-        paste(chunkprefix, "tikz", sep="."),"}\n",sep="",
624  
-        file=object$output, append=TRUE)
  614
+      write.chunk(paste("\n\\tikzsetnextfilename{",chunkprefix,"}\n",sep=""),
  615
+                        file=object$output)
  616
+      write.chunk(paste("\n\\tikzexternalfiledependsonfile{",chunkprefix,"}{",
  617
+                        paste(chunkprefix, "tikz", sep="."),"}\n",sep=""),
  618
+                        file=object$output)
625 619
         
626  
-      linesout[thisline + 1] <- srcline
627  
-      thisline <- thisline + 1
628  
-      
629 620
     }
630 621
 
631 622
       # Write the includegraphics command for eps or pdf 
632 623
       # only if we are not useing pgf or tikz
633 624
     if(options$include && !options$pgf && !options$tikz && !options$external) {
634 625
 
635  
-      cat("\\includegraphics{", chunkprefix, "}\n", sep="",
636  
-        file=object$output, append=TRUE)
637  
-      linesout[thisline + 1] <- srcline
638  
-      thisline <- thisline + 1
639  
-
  626
+      write.chunk(paste("\\includegraphics{", chunkprefix, "}\n", sep=""),
  627
+                        file=object$output)
640 628
     }
641 629
       # input statements for tikz and pgf
642 630
     if(options$include && (options$pgf || options$tikz)) {
643  
-
644 631
         #if tikz takes precident over pgf option
645 632
       suffix <- ifelse(options$tikz,'tikz','pgf')
646 633
       if(!options$external){
647  
-        cat("{\\tikzexternaldisable\n", sep="", file=object$output, append=TRUE)
648  
-        linesout[thisline + 1] <- srcline
649  
-        thisline <- thisline + 1
  634
+        write.chunk("{\\tikzexternaldisable\n", file=object$output)
650 635
       }
651 636
       
652  
-      cat("\\input{", paste(chunkprefix,suffix,sep='.'),
653  
-        "}\n", sep="", file=object$output, append=TRUE)
654  
-      linesout[thisline + 1] <- srcline
655  
-      thisline <- thisline + 1
  637
+      write.chunk(paste("\\input{", paste(chunkprefix,suffix,sep='.'),
  638
+                        "}\n", sep=""), file=object$output)
656 639
       
657 640
       if(!options$external){
658  
-        cat("}\n", sep="", file=object$output, append=TRUE)
659  
-        linesout[thisline + 1] <- srcline
660  
-        thisline <- thisline + 1
  641
+        write.chunk("}\n", file=object$output)
661 642
       }
662 643
 
663 644
     }
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.