1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190
|
#' Open file
#'
#' Tries to open a file with operating system's default program.
#' @param f file (with full path)
#' @references This function is a fork of David Hajage's \code{convert} function: \url{https://github.com/eusebe/ascii/blob/master/R/export.r}
#' @export
openFileInOS <- function(f) {
if (missing(f)) {
stop('No file to open!')
}
f <- path.expand(f)
if (!file.exists(f)) {
stop('File not found!')
}
if (grepl('w|W', .Platform$OS.type)) {
## we are on Windows
shell.exec(f) #nolint
} else {
if (grepl('darwin', version$os)) {
## Mac
system(paste(shQuote('open'), shQuote(f)), wait = FALSE, ignore.stderr = TRUE)
} else {
## Linux
system(paste(shQuote('/usr/bin/xdg-open'), shQuote(f)), #nolint
wait = FALSE,
ignore.stdout = TRUE)
}
}
}
#' Converts Pandoc to other format
#'
#' Calling John MacFarlane's great program to convert specified file (see \code{f} parameter below) or character vector {see \code{text} paramater} to other formats like \code{HTML}, \code{pdf}, \code{docx}, \code{odt} etc.
#' @param f Pandoc's markdown format file path. If URL is provided then the generated file's path is \code{tempfile()} but please bear in mind that this way only images with absolute path would shown up in the document.
#' @param text Pandoc's markdown format character vector. Treated as the content of \code{f} file - so the \code{f} parameter is ignored. The generated file's path is \code{tempfile()}.
#' @param format required output format. For all possible values here check out Pandoc homepage: \url{http://johnmacfarlane.net/pandoc/}
#' @param open try to open converted document with operating system's default program
#' @param options optionally passed arguments to Pandoc (instead of \code{pander}'s default)
#' @param footer add footer to document with meta-information
#' @param proc.time optionally passed number in seconds which would be shown in the generated document's footer
#' @param portable.html instead of using local files, rather linking JS/CSS files to an online CDN for portability and including base64-encoded images if converting to \code{HTML} without custom \code{options}
#' @param pandoc.binary path to \code{pandoc}'s binary if not found in the path
#' @references John MacFarlane (2012): _Pandoc User's Guide_. \url{http://johnmacfarlane.net/pandoc/README.html}
#' @note This function depends on \code{Pandoc} which should be pre-installed on user's machine. See the \code{INSTALL} file of the package.
#' @return Converted file's path.
#' @importFrom tools file_path_sans_ext
#' @importFrom utils packageDescription
#' @export
#' @examples \dontrun{
#' Pandoc.convert(text = c('# Demo', 'with a paragraph'))
#' Pandoc.convert('http://rapporter.github.io/pander/minimal.md')
#' # Note: the generated HTML is not showing images with relative path from the above file.
#' # Based on that `pdf`, `docx` etc. formats would not work! If you want to convert an
#' # online markdown file to other formats with this function, please pre-process the file
#' # to have absolute paths instead.
#' }
Pandoc.convert <- function(f, text, format = 'html', open = TRUE, options = '',
footer = FALSE, proc.time, portable.html = TRUE,
pandoc.binary = panderOptions('pandoc.binary')) {
## check for Pandoc
if (pandoc.binary == '') {
if (grepl('w|W', .Platform$OS.type))
message('You may install Pandoc easily with "install.pandoc()" from the "installr" package.')
stop("It seems Pandoc is not installed or path of binary is not found. Did you restarted R after Pandoc install? See installation details by running:\n\n\t readLines(system.file('includes/html/footer.html', package='pander'))\n") #nolint
}
if (!file.exists(pandoc.binary)) {
stop(paste('Pandoc binary is not found at provided location:', pandoc.binary))
}
## dealing with provided character vector
if (!missing(text)) {
f <- tempfile()
cat(text, file = f, sep = '\n')
}
## content
rl <- readLines(f, warn = FALSE)
## dealing with URLs
if (grepl('^https*://.*', f)) {
f.dir <- tempdir()
f.out <- paste0(tempfile(), '.', format)
} else {
f.dir <- dirname(f)
f.out <- paste0(file_path_sans_ext(f), '.', format)
}
## force UTF-8 encoding #nolint
## if (!grepl('utf', Sys.getlocale())) { #nolint
## convert content to UTF-8
text <- iconv(readLines(f, warn = FALSE), from = '', to = 'UTF-8')
## do not touch original input file
if (!missing(f)) {
f <- tempfile()
## remove tempfile if not needed any more
on.exit(unlink(f))
}
## write content with UTF-8 encoding
con <- file(f, 'w', encoding = 'UTF-8')
cat(text, file = con, sep = '\n')
close(con)
## } #nolint
## add nifty HTML/CSS/JS components
if (format == 'html') {
if (options == '') {
options <- sprintf('-A "%s"', system.file('includes/html/footer.html', package = 'pander'))
if (portable.html) {
options <- paste('--self-contain', options)
}
}
} else {
if (options == '' && any(grepl('^#', rl))) {
options <- '--toc'
}
}
## add other formats' templates
## TODO
## add footer to file
if (footer) {
if (length(rl) > 0 && !grepl('This report was generated', tail(rl, 1))) {
cat(sprintf('\n\n-------\nThis report was generated with [R](http://www.r-project.org/) (%s) and [pander](https://github.com/rapporter/pander) (%s)%son %s platform.', sprintf('%s.%s', R.version$major, R.version$minor), packageDescription('pander')$Version, ifelse(missing(proc.time), ' ', sprintf(' in %s sec ', format(proc.time))), R.version$platform), file = f, append = TRUE) #nolint
}
}
## set specified dir
wd <- getwd()
setwd(f.dir)
## call Pandoc
cmd <- sprintf('%s -f markdown -s %s %s -o %s', pandoc.binary, options, shQuote(f), shQuote(f.out))
if (grepl('w|W', .Platform$OS.type)) {
res <- suppressWarnings(tryCatch(shell(cmd, intern = TRUE), error = function(e) e)) #nolint
} else {
res <- suppressWarnings(tryCatch(system(cmd, intern = TRUE), error = function(e) e))
}
## inject HTML header
if (format == 'html'
&& grepl(sprintf('^(--self-contain )*-A "%s"$', system.file('includes/html/footer.html', package='pander')), options)) { #nolint
rl <- readLines(f.out, warn = FALSE)
he <- grep('</head>', rl)
ho <- readLines(system.file('includes/html/header.html', package = 'pander'), warn = FALSE)
if (portable.html) {
ch <- ho
} else {
ch <- gsub('http://cdn.rapporter.net/pander', system.file('includes/', package = 'pander'), ho)
}
writeLines(c(rl[1 : (he - 1)], ch, rl[he:length(rl)]), f.out)
}
## revert settings
setwd(wd)
## return
if (!is.null(attr(res, 'status'))) {
warning(paste0('Pandoc had some problems while converting to ',
format, ': \n\n', paste(res, collapse = '\n'),
'\n\nPandoc was called as:\n\n\t', cmd))
} else {
if (open) {
openFileInOS(f.out)
}
return(f.out)
}
}
|