Skip to content

Commit

Permalink
Output to multiple files with the `onefile' option
Browse files Browse the repository at this point in the history
    - Works just like the `onefile' argument to pdf()

    - Also works with both regular and standAlone mode

    - Trumped by the `console' option as these two modes are mutially exclusive
  • Loading branch information
cameronbracken committed Apr 26, 2011
1 parent b037425 commit d0479af
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 11 deletions.
22 changes: 18 additions & 4 deletions R/tikz.R
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@
#' file.
#' @param width The width of the output figure, in \bold{inches}.
#' @param height The height of the output figure, in \bold{inches}.
#' @param onefile Should output be directed to separate environments in a
#' single file (default \code{TRUE}). If \code{FALSE} this option works
#' exactly like the argument of the same name to \code{\link{pdf}}
#' (see there for more details). This option is superseded by the
#' \code{console} option.
#' @param bg The starting background color for the plot.
#' @param fg The starting foreground color for the plot.
#' @param pointsize Base pointsize used in the LaTeX document. This option is
Expand All @@ -60,7 +65,7 @@
#' embedding one TikZ picture within another. When \code{TRUE} multipage
#' output will be drawn on a single page.
#' @param console Should the output of tikzDevice be directed to the R console
#' (default FALSE). This is useful for dumping tikz output directly into a
#' (default \code{FALSE}). This is useful for dumping tikz output directly into a
#' LaTeX document via \code{\link{sink}}. If TRUE, the \code{file} argument
#' is ignored. Setting \code{file=''} is equivalent to setting
#' \code{console=TRUE}.
Expand Down Expand Up @@ -176,8 +181,13 @@
#' }
#'
#' @export

# this is lame, pretty sure this is a bug in roxygen. Rd cant handle % in
# unless properly escaped but roxygen wont properly escape it, so have to
# use this nasty workaround for now... intToUtf8(37) == %
tikz <-
function (file = "./Rplots.tex", width = 7, height = 7,
function (file = ifelse(onefile, "./Rplots.tex", paste("./Rplot",intToUtf8(37),"03d.tex",sep='')),
width = 7, height = 7, onefile = TRUE,
bg="transparent", fg="black", pointsize = 10, standAlone = FALSE,
bareBones = FALSE, console = FALSE, sanitize = FALSE,
engine = getOption("tikzDefaultEngine"),
Expand All @@ -194,7 +204,7 @@ function (file = "./Rplots.tex", width = 7, height = 7,
# file_path_as_absolute can give us the absolute path to the output
# file---but it has to exist first. So, we use file() to "touch" the
# path.
touch_file <- suppressWarnings(file(file, 'w'))
touch_file <- suppressWarnings(file(file, 'w'))
close(touch_file)

file <- tools::file_path_as_absolute(file)
Expand All @@ -205,6 +215,10 @@ function (file = "./Rplots.tex", width = 7, height = 7,
"\nBecause the directory does not exist or is not writable."
)))
})

# remove the file if we are outputting to multiple files since the file
# name will get changed in the C code
if( !onefile ) file.remove(file)

# Determine which TeX engine is being used.
switch(engine,
Expand Down Expand Up @@ -242,7 +256,7 @@ function (file = "./Rplots.tex", width = 7, height = 7,
packages <- paste( paste( packages, collapse='\n'), collapse='\n')
footer <- paste( paste( footer,collapse='\n'), collapse='\n')

.External('TikZ_StartDevice', file, width, height, bg, fg, baseSize,
.External('TikZ_StartDevice', file, width, height, onefile, bg, fg, baseSize,
standAlone, bareBones, documentDeclaration, packages, footer, console,
sanitize, engine,
PACKAGE='tikzDevice')
Expand Down
65 changes: 59 additions & 6 deletions src/tikzDevice.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ SEXP TikZ_StartDevice ( SEXP args ){
Rboolean standAlone, bareBones;
const char *documentDeclaration, *packages, *footer;
double baseSize;
Rboolean console, sanitize;
Rboolean console, sanitize, onefile;

/*
* pGEDevDesc is a variable provided by the R Graphics Engine
Expand Down Expand Up @@ -112,6 +112,8 @@ SEXP TikZ_StartDevice ( SEXP args ){
/* For now these are assumed to be in inches. */
width = asReal(CAR(args)); args = CDR(args);
height = asReal(CAR(args)); args = CDR(args);

onefile = asLogical(CAR(args)); args = CDR(args);

/* Recover initial background and foreground colors. */
bg = CHAR(asChar(CAR(args))); args = CDR(args);
Expand Down Expand Up @@ -180,7 +182,7 @@ SEXP TikZ_StartDevice ( SEXP args ){
* R graphics function hooks with the appropriate C routines
* in this file.
*/
if( !TikZ_Setup( deviceInfo, fileName, width, height, bg, fg, baseSize,
if( !TikZ_Setup( deviceInfo, fileName, width, height, onefile, bg, fg, baseSize,
standAlone, bareBones, documentDeclaration, packages,
footer, console, sanitize, engine ) ){
/*
Expand Down Expand Up @@ -221,7 +223,7 @@ SEXP TikZ_StartDevice ( SEXP args ){
static Rboolean TikZ_Setup(
pDevDesc deviceInfo,
const char *fileName,
double width, double height,
double width, double height, Rboolean onefile,
const char *bg, const char *fg, double baseSize,
Rboolean standAlone, Rboolean bareBones,
const char *documentDeclaration,
Expand Down Expand Up @@ -265,8 +267,21 @@ static Rboolean TikZ_Setup(
}

/* Copy TikZ-specific information to the tikzInfo variable. */
tikzInfo->outFileName = (char*) calloc(strlen(fileName) + 1, sizeof(char));
strcpy(tikzInfo->outFileName, fileName);
if(onefile == FALSE){

// Hopefully 10 extra digits will be enough for the separate file name
tikzInfo->outFileName = (char*) calloc(strlen(fileName) + 10, sizeof(char));
tikzInfo->originalFileName = (char*) calloc(strlen(fileName) + 1, sizeof(char));
sprintf(tikzInfo->outFileName, fileName, 1);
strcpy(tikzInfo->originalFileName, fileName);
//Rprintf("First file name: %s\n",tikzInfo->outFileName);

}else{

tikzInfo->outFileName = (char*) calloc(strlen(fileName) + 1, sizeof(char));
strcpy(tikzInfo->outFileName, fileName);

}
tikzInfo->engine = engine;
tikzInfo->rasterFileCount = 1;
tikzInfo->firstPage = TRUE;
Expand All @@ -285,6 +300,7 @@ static Rboolean TikZ_Setup(
tikzInfo->polyLine = FALSE;
tikzInfo->console = console;
tikzInfo->sanitize = sanitize;
tikzInfo->onefile = onefile;

/* Incorporate tikzInfo into deviceInfo. */
deviceInfo->deviceSpecific = (void *) tikzInfo;
Expand Down Expand Up @@ -505,7 +521,7 @@ static Rboolean TikZ_Open( pDevDesc deviceInfo ){
if(tikzInfo->outFileName[0] == '\0'){
//If empty file name output to console
tikzInfo->console = TRUE;
}else{
}else{
if( !( tikzInfo->outputFile = fopen(R_ExpandFileName(tikzInfo->outFileName), "w") ) )
return FALSE;
}
Expand Down Expand Up @@ -569,7 +585,10 @@ static void TikZ_NewPage( const pGEcontext plotParams, pDevDesc deviceInfo ){
tikzDevDesc *tikzInfo = (tikzDevDesc *) deviceInfo->deviceSpecific;

if ( tikzInfo->firstPage ){

tikzInfo->firstPage = FALSE;
tikzInfo->pageNum = 1;

}else{

/* End the current TikZ environment, unless we are making bare bones code. */
Expand All @@ -578,6 +597,40 @@ static void TikZ_NewPage( const pGEcontext plotParams, pDevDesc deviceInfo ){
printOutput(tikzInfo, "\\end{scope}\n");
printOutput(tikzInfo, "\\end{tikzpicture}\n");

tikzInfo->pageNum++;

// If we need to output to a new file
if(tikzInfo->onefile == FALSE){

// Close off the document if in standAlone mode
if(tikzInfo->standAlone == TRUE)
printOutput(tikzInfo,"\n\\end{document}\n");

//Close current file
fclose(tikzInfo->outputFile);

//Re-assign new file name with incremented page number
sprintf(tikzInfo->outFileName, tikzInfo->originalFileName, tikzInfo->pageNum);

// Open the new file
if( !( tikzInfo->outputFile = fopen(R_ExpandFileName(tikzInfo->outFileName), "w") ) )
error("Cannot open new file.");

/* Print header comment */
Print_TikZ_Header( tikzInfo );

/* Header for a standalone LaTeX document,
* need to print it again if we are writing to a new file
*/
if(tikzInfo->standAlone == TRUE){
printOutput(tikzInfo,"%s",tikzInfo->documentDeclaration);
printOutput(tikzInfo,"%s",tikzInfo->packages);
printOutput(tikzInfo,"\\begin{document}\n\n");
}

//Rprintf("New file name: %s\n",tikzInfo->outFileName);
}

/*Next clipping region will be the first on the page*/
tikzInfo->firstClip = TRUE;

Expand Down
5 changes: 4 additions & 1 deletion src/tikzDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ typedef struct {
Rboolean polyLine;
Rboolean console;
Rboolean sanitize;
Rboolean onefile;
char *originalFileName;
int pageNum;
} tikzDevDesc;


Expand All @@ -81,7 +84,7 @@ SEXP TikZ_DeviceInfo(SEXP device_num);
static Rboolean TikZ_Setup(
pDevDesc deviceInfo,
const char *fileName,
double width, double height,
double width, double height, Rboolean onefile,
const char *bg, const char *fg, double baseSize,
Rboolean standAlone, Rboolean bareBones,
const char *documentDeclaration,
Expand Down

0 comments on commit d0479af

Please sign in to comment.