Commit de5d7451 authored by Andreas Tille's avatar Andreas Tille

New upstream version 1.17

parent 7aa7d004
Package: knitr
Type: Package
Title: A General-Purpose Package for Dynamic Report Generation in R
Version: 1.15.1
Date: 2016-11-22
Version: 1.17
Date: 2017-08-09
Authors@R: c(
person("Yihui", "Xie", email = "xie@yihui.name", role = c("aut", "cre")),
person("Adam", "Vogt", role = "ctb"),
......@@ -21,16 +21,21 @@ Authors@R: c(
person("Duncan", "Murdoch", role = "ctb"),
person("Fabian", "Hirschmann", role = "ctb"),
person("Fitch", "Simeon", role = "ctb"),
person("Forest", "Fang", role = "ctb"),
person(c("Frank", "E", "Harrell", "Jr"), role = "ctb", comment = "the Sweavel package at inst/misc/Sweavel.sty"),
person("Garrick", "Aden-Buie", role = "ctb"),
person("Gregoire", "Detrez", role = "ctb"),
person("Hadley", "Wickham", role = "ctb"),
person("Heewon", "Jeon", role = "ctb"),
person("Henrik", "Bengtsson", role = "ctb"),
person("Hiroaki", "Yutani", role = "ctb"),
person("Ian", "Lyttle", role = "ctb"),
person("Hodges", "Daniel", role = "ctb"),
person("Jake", "Burkhead", role = "ctb"),
person("James", "Manton", role = "ctb"),
person("Jared", "Lander", role = "ctb"),
person("Jason", "Punyon", role = "ctb"),
person("Javier", "Luraschi", role = "ctb"),
person("Jeff", "Arnold", role = "ctb"),
person("Jeremy", "Ashkenas", role = c("ctb", "cph"), comment = "the CSS file at inst/misc/docco-classic.css"),
person("Jeremy", "Stephens", role = "ctb"),
......@@ -46,6 +51,7 @@ Authors@R: c(
person("Julien", "Barnier", role = "ctb"),
person("Kaiyin", "Zhong", role = "ctb"),
person("Kamil", "Slowikowski", role = "ctb"),
person("Karl", "Forner", role = "ctb"),
person(c("Kevin", "K."), "Smith", role = "ctb"),
person("Kirill", "Mueller", role = "ctb"),
person("Kohske", "Takahashi", role = "ctb"),
......@@ -64,6 +70,7 @@ Authors@R: c(
person("Sebastian", "Meyer", role = "ctb"),
person("Sietse", "Brouwer", role = "ctb"),
person(c("Simon", "de"), "Bernard", role = "ctb"),
person("Sylvain", "Rousseau", role = "ctb"),
person("Taiyun", "Wei", role = "ctb"),
person("Thibaut", "Assus", role = "ctb"),
person("Thibaut", "Lamadon", role = "ctb"),
......@@ -85,12 +92,12 @@ Suggests: formatR, testit, rgl (>= 0.95.1201), codetools, rmarkdown,
htmlwidgets (>= 0.7), webshot, tikzDevice (>= 0.10), png, jpeg,
XML, RCurl, DBI (>= 0.4-1), tibble
License: GPL
URL: http://yihui.name/knitr/
URL: https://yihui.name/knitr/
BugReports: https://github.com/yihui/knitr/issues
VignetteBuilder: knitr
SystemRequirements: Package vignettes based on R Markdown v2 require
Pandoc (http://pandoc.org). The function rst2pdf() and
vignettes based on reStructuredText require rst2pdf
SystemRequirements: Package vignettes based on R Markdown v2 or
reStructuredText require Pandoc (http://pandoc.org). The
function rst2pdf() require rst2pdf
(https://github.com/rst2pdf/rst2pdf).
Collate: 'block.R' 'cache.R' 'utils.R' 'citation.R' 'hooks-html.R'
'plot.R' 'defaults.R' 'concordance.R' 'engine.R' 'highlight.R'
......@@ -101,9 +108,9 @@ Collate: 'block.R' 'cache.R' 'utils.R' 'citation.R' 'hooks-html.R'
'template.R' 'utils-base64.R' 'utils-conversion.R'
'utils-rd2html.R' 'utils-sweave.R' 'utils-upload.R'
'utils-vignettes.R' 'zzz.R'
RoxygenNote: 5.0.1
RoxygenNote: 6.0.1
NeedsCompilation: no
Packaged: 2016-11-22 05:33:02 UTC; yihui
Packaged: 2017-08-09 06:32:13 UTC; yihui
Author: Yihui Xie [aut, cre],
Adam Vogt [ctb],
Alastair Andrew [ctb],
......@@ -122,16 +129,21 @@ Author: Yihui Xie [aut, cre],
Duncan Murdoch [ctb],
Fabian Hirschmann [ctb],
Fitch Simeon [ctb],
Forest Fang [ctb],
Frank E Harrell Jr [ctb] (the Sweavel package at inst/misc/Sweavel.sty),
Garrick Aden-Buie [ctb],
Gregoire Detrez [ctb],
Hadley Wickham [ctb],
Heewon Jeon [ctb],
Henrik Bengtsson [ctb],
Hiroaki Yutani [ctb],
Ian Lyttle [ctb],
Hodges Daniel [ctb],
Jake Burkhead [ctb],
James Manton [ctb],
Jared Lander [ctb],
Jason Punyon [ctb],
Javier Luraschi [ctb],
Jeff Arnold [ctb],
Jeremy Ashkenas [ctb, cph] (the CSS file at
inst/misc/docco-classic.css),
......@@ -148,6 +160,7 @@ Author: Yihui Xie [aut, cre],
Julien Barnier [ctb],
Kaiyin Zhong [ctb],
Kamil Slowikowski [ctb],
Karl Forner [ctb],
Kevin K. Smith [ctb],
Kirill Mueller [ctb],
Kohske Takahashi [ctb],
......@@ -166,6 +179,7 @@ Author: Yihui Xie [aut, cre],
Sebastian Meyer [ctb],
Sietse Brouwer [ctb],
Simon de Bernard [ctb],
Sylvain Rousseau [ctb],
Taiyun Wei [ctb],
Thibaut Assus [ctb],
Thibaut Lamadon [ctb],
......@@ -177,4 +191,4 @@ Author: Yihui Xie [aut, cre],
Wush Wu [ctb],
Zachary Foster [ctb]
Repository: CRAN
Date/Publication: 2016-11-22 09:36:46
Date/Publication: 2017-08-10 04:27:37 UTC
This diff is collapsed.
# Generated by roxygen2: do not edit by hand
S3method("$",knitr_strict_list)
S3method(knit_print,default)
S3method(knit_print,knit_asis)
......@@ -57,6 +59,7 @@ export(inline_expr)
export(kable)
export(knit)
export(knit2html)
export(knit2pandoc)
export(knit2pdf)
export(knit2wp)
export(knit_child)
......
......@@ -259,7 +259,11 @@ block_exec = function(options) {
# make sure all objects to be saved exist in env
objs = intersect(c(objs, obj.new), ls(env, all.names = TRUE))
if (options$autodep) {
cache$objects(objs, code, options$label, options$cache.path)
# you shall manually specify global object names if find_symbols() is not reliable
cache$objects(
objs, options$cache.globals %n% find_symbols(code), options$label,
options$cache.path
)
dep_auto()
}
if (options$cache < 3) {
......@@ -343,7 +347,11 @@ filter_evaluate = function(res, opt, test) {
# find recorded plots in the output of evaluate()
find_recordedplot = function(x) {
vapply(x, evaluate::is.recordedplot, logical(1))
vapply(x, is_plot_output, logical(1))
}
is_plot_output = function(x) {
evaluate::is.recordedplot(x) || inherits(x, 'knit_image_paths')
}
# move plots before source code
......@@ -375,7 +383,8 @@ merge_class = function(res, class = c('source', 'message', 'warning')) {
if (idx2 - idx1 == 1) {
res2 = res[[idx2]]
# merge warnings/messages only if next one is identical to previous one
if (class == 'source' || identical(res1, res2)) {
if (class == 'source' || identical(res1, res2) ||
(class == 'message' && !grepl('\n$', tail(res1[[el]], 1)))) {
res[[k1]][[el]] = c(res[[k1]][[el]], res2[[el]])
k2 = c(k2, idx2)
} else {
......@@ -444,6 +453,7 @@ process_tangle.block = function(x) {
try(params[o] <- list(eval_lang(params[[o]])))
if (isFALSE(params$purl)) return('')
label = params$label; ev = params$eval
if (params$engine != 'R') return(comment_out(knit_code$get(label)))
code = if (!isFALSE(ev) && !is.null(params$child)) {
cmds = lapply(sc_split(params$child), knit_child)
paste(unlist(cmds), collapse = '\n')
......@@ -459,13 +469,23 @@ process_tangle.block = function(x) {
}
#' @export
process_tangle.inline = function(x) {
if (opts_knit$get('documentation') == 2L) {
return(paste(line_prompt(x$input.src, "#' ", "#' "), collapse = '\n'))
}
output = if (opts_knit$get('documentation') == 2L) {
output = paste(line_prompt(x$input.src, "#' ", "#' "), collapse = '\n')
} else ''
code = x$code
if (length(code) == 0L || !any(idx <- grepl('knit_child\\(.+\\)', code)))
return('')
paste(c(sapply(code[idx], function(z) eval(parse_only(z))), ''), collapse = '\n')
if (length(code) == 0L) return(output)
if (getOption('knitr.purl.inline', FALSE)) output = c(output, code)
idx = grepl('knit_child\\(.+\\)', code)
if (any(idx)) {
cout = sapply(code[idx], function(z) eval(parse_only(z)))
output = c(output, cout, '')
}
paste(output, collapse = '\n')
}
......
......@@ -48,10 +48,9 @@ new_cache = function() {
} else lines = x
writeLines(lines, con = path)
}
cache_objects = function(keys, code, label, path) {
cache_objects = function(keys, globals, label, path) {
save_objects(keys, label, valid_path(path, '__objects'))
# find globals in code; may not be reliable
save_objects(find_globals(code), label, valid_path(path, '__globals'))
save_objects(globals, label, valid_path(path, '__globals'))
}
cache_load = function(hash, lazy = TRUE) {
......@@ -116,6 +115,14 @@ known_globals = c(
'{', '[', '(', ':', '<-', '=', '+', '-', '*', '/', '%%', '%/%', '%*%', '%o%', '%in%'
)
# analyze code and find out all possible variables (not necessarily global variables)
find_symbols = function(code) {
if (is.null(code) || length(p <- parse(text = code, keep.source = TRUE)) == 0) return()
p = getParseData(p)
p = p[p$terminal & p$token %in% c('SYMBOL', 'SYMBOL_FUNCTION_CALL', 'SPECIAL'), ]
unique(p$text)
}
# a variable name to store the metadata object from code chunks
cache_meta_name = function(hash) sprintf('.%s_meta', hash)
# a variable name to store the text output of code chunks
......@@ -144,7 +151,7 @@ cache_rx = '_[abcdef0123456789]{32}[.](rdb|rdx|RData)$'
#' files \file{__objects} and \file{__globals}.
#' @export
#' @seealso \code{\link{dep_prev}}
#' @references \url{http://yihui.name/knitr/demo/cache/}
#' @references \url{https://yihui.name/knitr/demo/cache/}
dep_auto = function(path = opts_chunk$get('cache.path')) {
# this function should be evaluated in the original working directory
owd = setwd(opts_knit$get('output.dir')); on.exit(setwd(owd))
......@@ -243,7 +250,7 @@ load_cache = function(
#' effect.
#' @export
#' @seealso \code{\link{dep_auto}}
#' @references \url{http://yihui.name/knitr/demo/cache/}
#' @references \url{https://yihui.name/knitr/demo/cache/}
dep_prev = function() {
labs = names(knit_code$get())
if ((n <- length(labs)) < 2L) return() # one chunk or less; no sense of deps
......@@ -263,7 +270,7 @@ dep_prev = function() {
#' references.
#' @export
#' @format NULL
#' @references \url{http://yihui.name/knitr/demo/cache/}
#' @references \url{https://yihui.name/knitr/demo/cache/}
#' @examples eval(rand_seed)
#' rnorm(1) # .Random.seed is created (or modified)
#' eval(rand_seed)
......
......@@ -94,7 +94,7 @@ write_bib = function(
})
}
bib = bib[sort(x)]
if (!is.null(file)) cat(unlist(bib), sep = '\n', file = file)
if (!is.null(file) && length(x)) writeUTF8(unlist(bib), file)
invisible(bib)
}
......
......@@ -39,14 +39,11 @@ new_defaults = function(value = list()) {
#' the options in this chunk itself, and that is why we often need to set global
#' options in a separate chunk.
#'
#' Below is a list of default chunk options, retrieved via
#' \code{opts_chunk$get()}:
#'
#' \Sexpr[results=verbatim]{str(knitr::opts_chunk$get())}
#' @references Usage: \url{http://yihui.name/knitr/objects}
#' See \code{str(knitr::opts_chunk$get())} for a list of default chunk options.
#' @references Usage: \url{https://yihui.name/knitr/objects/}
#'
#' A list of available options:
#' \url{http://yihui.name/knitr/options#chunk_options}
#' \url{https://yihui.name/knitr/options/#chunk_options}
#' @note \code{opts_current} is read-only in the sense that it does nothing if
#' you call \code{opts_current$set()}; you can only query the options via
#' \code{opts_current$get()}.
......@@ -134,14 +131,11 @@ set_alias = function(...) {
#' correspond to options in \code{opts_knit}. This can be useful to set package
#' options in \file{~/.Rprofile} without loading \pkg{knitr}.
#'
#' Below is a list of default package options, retrieved via
#' \code{opts_knit$get()}:
#'
#' \Sexpr[results=verbatim]{str(knitr::opts_knit$get())}
#' @references Usage: \url{http://yihui.name/knitr/objects}
#' See \code{str(knitr::opts_knit$get())} for a list of default package options.
#' @references Usage: \url{https://yihui.name/knitr/objects/}
#'
#' A list of available options:
#' \url{http://yihui.name/knitr/options#package_options}
#' \url{https://yihui.name/knitr/options/#package_options}
#' @export
#' @examples opts_knit$get('verbose'); opts_knit$set(verbose = TRUE) # change it
#' if (interactive()) {
......
......@@ -20,15 +20,13 @@
#' passed through \code{options$engine.opts}, e.g. \code{engine='ruby',
#' engine.opts='-v'}.
#'
#' Below is a list of built-in language engines, retrieved via
#' \code{knit_engines$get()}:
#'
#' \Sexpr[results=verbatim]{str(knitr::knit_engines$get())}
#' See \code{str(knitr::knit_engines$get())} for a list of built-in language
#' engines.
#' @export
#' @note The Leiningen engine \code{lein} requires lein-exec plugin; see
#' \url{https://github.com/yihui/knitr/issues/1176} for details.
#' @references Usage: \url{http://yihui.name/knitr/objects}; examples:
#' \url{http://yihui.name/knitr/demo/engines/}
#' @references Usage: \url{https://yihui.name/knitr/objects/}; examples:
#' \url{https://yihui.name/knitr/demo/engines/}
#' @examples knit_engines$get('python'); knit_engines$get('awk')
#' names(knit_engines$get())
knit_engines = new_defaults()
......@@ -100,7 +98,10 @@ eng_interpreted = function(options) {
stata = {
logf = sub('[.]do$', '.log', f)
on.exit(unlink(c(logf)), add = TRUE)
paste(switch(Sys.info()[['sysname']], Windows='/q /e do', Darwin='-q -e do', Linux='-q -b do', '-q -b do'), f)
paste(switch(
Sys.info()[['sysname']], Windows = '/q /e do', Darwin = '-q -e do',
Linux = '-q -b do', '-q -b do'
), shQuote(normalizePath(f)))
},
f
)
......@@ -317,7 +318,8 @@ eng_cat = function(options) {
if (!identical(file, '')) cat(..., file = file)
}
do.call(cat2, c(list(options$code, sep = '\n'), options$engine.opts))
if (is.null(lang <- options$engine.opts$lang)) return('')
if (is.null(lang <- options$engine.opts$lang) && is.null(lang <- options$class.source))
return('')
options$engine = lang
engine_output(options, options$code, NULL)
}
......@@ -383,7 +385,7 @@ eng_block2 = function(options) {
# {}; when encoded in integers, they won't be escaped, but will need to
# restore them later; see bookdown:::restore_block2
if (l1 != '') l1 = paste(
c('\\iffalse{', utf8ToInt(enc2utf8(l1)), '}\\fi'), collapse = '-'
c('\\iffalse{', utf8ToInt(enc2utf8(l1)), '}\\fi{}'), collapse = '-'
)
h2 = options$html.tag %n% 'div'
h3 = options$html.before %n% ''
......@@ -400,10 +402,12 @@ eng_block2 = function(options) {
# helper to create engines the wrap embedded html assets (e.g. css,js)
eng_html_asset = function(prefix, postfix) {
function(options) {
if (options$eval && is_html_output(excludes = 'markdown')) {
out = if (options$eval && is_html_output(excludes = 'markdown')) {
code = c(prefix, options$code, postfix)
paste(code, collapse = '\n')
}
options$results = 'asis'
engine_output(options, options$code, out)
}
}
......@@ -425,7 +429,10 @@ is_sql_update_query = function(query) {
# sql engine
eng_sql = function(options) {
if (isFALSE(options$eval)) return(engine_output(options, options$code, ''))
# return chunk before interpolation eagerly to avoid connection option check
if (isFALSE(options$eval) && !isTRUE(options$sql.show_interpolated)) {
return(engine_output(options, options$code, ''))
}
# Return char vector of sql interpolation param names
varnames_from_sql = function(conn, sql) {
......@@ -458,6 +465,7 @@ eng_sql = function(options) {
# extract options
conn = options$connection
if (is.character(conn)) conn = get(conn, envir = knit_global())
if (is.null(conn)) stop2(
"The 'connection' option (DBI connection) is required for sql chunks."
)
......@@ -467,9 +475,11 @@ eng_sql = function(options) {
max.print = -1
sql = paste(options$code, collapse = '\n')
query = interpolate_from_env(conn, sql)
if (isFALSE(options$eval)) return(engine_output(options, query, ''))
# execute query -- when we are printing with an enforced max.print we
# use dbFetch so as to only pull down the required number of records
query = interpolate_from_env(conn, sql)
if (is.null(varname) && max.print > 0 && !is_sql_update_query(query)) {
res = DBI::dbSendQuery(conn, query)
data = DBI::dbFetch(res, n = max.print)
......@@ -535,8 +545,45 @@ eng_sql = function(options) {
# assign varname if requested
if (!is.null(varname)) assign(varname, data, envir = knit_global())
# reset query to pre-interpolated if not expanding
if (!isTRUE(options$sql.show_interpolated)) query <- options$code
# return output
engine_output(options, options$code, output)
engine_output(options, query, output)
}
# go engine, added by @hodgesds https://github.com/yihui/knitr/pull/1330
eng_go = function(options) {
f = tempfile('code', '.', fileext = ".go")
writeLines(code <- options$code, f)
on.exit(unlink(f), add = TRUE)
cmd = get_engine_path(options$engine.path, options$engine)
fmt_args = sprintf('fmt %s', f)
tryCatch(
system2(cmd, fmt_args, stdout = TRUE, stderr = TRUE, env = options$engine.env),
error = function(e) {
if (!options$error) stop(e)
}
)
run_args = sprintf(" run %s", f)
extra = if (options$eval) {
message('running: ', cmd, run_args)
tryCatch(
system2(cmd, run_args, stdout = TRUE, stderr = TRUE, env = options$engine.env),
error = function(e) {
if (!options$error) stop(e)
'Error in executing go code'
}
)
}
if (options$results == 'hide') extra = NULL
engine_output(options, code, extra)
}
# set engines for interpreted languages
......@@ -553,7 +600,7 @@ knit_engines$set(
highlight = eng_highlight, Rcpp = eng_Rcpp, tikz = eng_tikz, dot = eng_dot,
c = eng_shlib, fortran = eng_shlib, fortran95 = eng_shlib, asy = eng_dot,
cat = eng_cat, asis = eng_asis, stan = eng_stan, block = eng_block,
block2 = eng_block2, js = eng_js, css = eng_css, sql = eng_sql
block2 = eng_block2, js = eng_js, css = eng_css, sql = eng_sql, go = eng_go
)
get_engine = function(name) {
......
......@@ -43,11 +43,11 @@
#' turned on (the chunk option \code{cache = TRUE}), no chunk hooks will be
#' executed, hence \code{hook_purl()} will not work, either. To solve this
#' problem, we need \code{cache = 2} instead of \code{TRUE} (see
#' \url{http://yihui.name/knitr/demo/cache/} for the meaning of \code{cache =
#' \url{https://yihui.name/knitr/demo/cache/} for the meaning of \code{cache =
#' 2}).
#' @rdname chunk_hook
#' @param before,options,envir see references
#' @references \url{http://yihui.name/knitr/hooks#chunk_hooks}
#' @references \url{https://yihui.name/knitr/hooks/#chunk_hooks}
#' @seealso \code{\link[rgl]{rgl.snapshot}}, \code{\link[rgl]{rgl.postscript}},
#' \code{\link[rgl]{hook_rgl}}, \code{\link[rgl]{hook_webgl}}
#' @note The two hook functions \code{hook_rgl()} and \code{hook_webgl()} were
......@@ -74,6 +74,8 @@ hook_png = function(
before, options, envir, cmd = c('optipng', 'pngquant'), post_process = identity
) {
if (before) return()
num = options$fig.num
if (length(num) == 0 || num == 0) return() # no figures
ext = tolower(options$fig.ext)
if (ext != 'png') {
warning('this hook only works with PNG at the moment'); return()
......
......@@ -30,8 +30,12 @@ hook_plot_html = function(x, options) {
caption = if (length(caption) == 1 && caption != '') {
paste0('title="', caption, '" alt="', caption, '" ')
}
tag = if (grepl('[.]pdf$', src, ignore.case = TRUE)) {
extra = c(extra, 'type="application/pdf"')
'embed'
} else 'img'
paste0(
'<img src="', opts_knit$get('base.url'), src, '" ', caption,
'<', tag, ' src="', opts_knit$get('base.url'), src, '" ', caption,
.img.attr(w, h, extra), ' />'
)
}
......@@ -85,8 +89,9 @@ hook_ffmpeg = function(x, options, format = 'webm') {
fig.num = options$fig.num
format = sub('^[.]', '', format)
# set up the ffmpeg run
fig.fname = paste0(sub(paste0(fig.num, '$'), '%d', x[1]), '.', x[2])
mov.fname = paste0(sub(paste0(fig.num, '$'), '', x[1]), '.', format)
base = sub(paste0(fig.num, '$'), '', x[1])
fig.fname = paste0(base, '%d', '.', x[2])
mov.fname = paste0(sub('-$', '', base), '.', format)
extra = if (format == 'webm') {
paste('-b:v', options$ffmpeg.bitrate %n% '1M', '-crf 10')
......@@ -114,8 +119,12 @@ hook_ffmpeg = function(x, options, format = 'webm') {
sprintf('width="%s"', options$out.width),
sprintf('height="%s"', options$out.height), opts
)
sprintf('<video %s><source src="%s" /><p>video of chunk %s</p></video>',
opts, paste0(opts_knit$get('base.url'), mov.fname), options$label)
cap = .img.cap(options, alt = TRUE)
if (cap != '') cap = sprintf('<p>%s</p>', cap)
sprintf(
'<video %s><source src="%s" />%s</video>', trimws(opts),
paste0(opts_knit$get('base.url'), mov.fname), cap
)
}
# use SciAnimator to create animations
......
......@@ -20,7 +20,7 @@
#' @param options a list of the current chunk options
#' @rdname hook_plot
#' @return A character string (code with plot filenames wrapped)
#' @references \url{http://yihui.name/knitr/hooks}
#' @references \url{https://yihui.name/knitr/hooks/}
#' @seealso \code{\link{hook_plot_custom}}
#' @export
#' @examples # this is what happens for a chunk like this
......@@ -236,7 +236,7 @@ hook_plot_tex = function(x, options) {
#' @rdname output_hooks
#' @return \code{NULL}; corresponding hooks are set as a side effect
#' @export
#' @references See output hooks in \url{http://yihui.name/knitr/hooks}.
#' @references See output hooks in \url{https://yihui.name/knitr/hooks/}.
#'
#' Jekyll and Liquid:
#' \url{https://github.com/jekyll/jekyll/wiki/Liquid-Extensions};
......@@ -328,7 +328,7 @@ render_listings = function() {
#' you to use the default output hooks for LaTeX (not Sweave or listings), and
#' every figure/table environment must have a label.
#' @export
#' @references \url{http://yihui.name/knitr/hooks}
#' @references \url{https://yihui.name/knitr/hooks/}
#' @examples \dontrun{knit_hooks$set(document = hook_movecode)}
#' # see example 103 at https://github.com/yihui/knitr-examples
hook_movecode = function(x) {
......
......@@ -18,6 +18,10 @@ hook_plot_md = function(x, options) {
options$fig.align = 'default'
}
}
if (options$fig.show == 'hold' && to == 'docx') {
warning('The chunk option fig.show="hold" is not supported for Word output')
options$fig.show = 'asis'
}
hook_plot_md_base(x, options)
}
......@@ -89,6 +93,15 @@ css_text_align = function(align) {
if (align == 'default') '' else sprintf(' style="text-align: %s"', align)
}
# helper function to manage HTML classes; turn "a b" to "{.a .b}" for Pandoc
# fenced code blocks
block_class = function(x){
if (length(x) == 0) return()
classes = unlist(strsplit(x, '\\s+'))
.classes = paste0('.', classes, collapse = ' ')
paste0('{', .classes, '}')
}
#' @rdname output_hooks
#' @export
#' @param strict whether to use strict markdown or reST syntax; for markdown: if
......@@ -104,7 +117,8 @@ render_markdown = function(strict = FALSE, fence_char = '`') {
opts_knit$set(out.format = 'markdown')
fence = paste(rep(fence_char, 3), collapse = '')
# four spaces lead to <pre></pre>
hook.t = function(x, options) {
hook.t = function(x, options, class = NULL) {
# this code-block duplicated from hook.t()
if (strict) {
paste('\n', indent_block(x), '', sep = '\n')
} else {
......@@ -115,20 +129,27 @@ render_markdown = function(strict = FALSE, fence_char = '`') {
l = max(l)
if (l >= 4) fence = paste(rep(fence_char, l), collapse = '')
}
paste0('\n\n', fence, x, fence, '\n\n')
paste0('\n\n', fence, block_class(class), x, fence, '\n\n')
}
}
hook.o = function(x, options) {
hook.t(x, options, options$class.output)
}
hook.r = function(x, options) {
language = tolower(options$engine)
if (language == 'node') language = 'javascript'
if (!options$highlight) language = 'text'
if (!is.null(options$class.source)) {
language = block_class(c(language, options$class.source))
}
paste0('\n\n', fence, language, '\n', x, fence, '\n\n')
}
knit_hooks$set(
source = function(x, options) {
x = hilight_source(x, 'markdown', options)
(if (strict) hook.t else hook.r)(paste(c(x, ''), collapse = '\n'), options)
}, output = hook.t, warning = hook.t, error = hook.t, message = hook.t,
},
output = hook.o, warning = hook.t, error = hook.t, message = hook.t,
inline = function(x) {
fmt = pandoc_to()
fmt = if (length(fmt) == 1L) 'latex' else 'html'
......
......@@ -19,9 +19,9 @@
#' arguments and returns desired output. The object \code{knit_hooks} is used to
#' access or set hooks in this package.
#' @export
#' @references Usage: \url{http://yihui.name/knitr/objects}
#' @references Usage: \url{https://yihui.name/knitr/objects/}
#'
#' Components in \code{knit_hooks}: \url{http://yihui.name/knitr/hooks}
#' Components in \code{knit_hooks}: \url{https://yihui.name/knitr/hooks/}
#' @examples knit_hooks$get('source'); knit_hooks$get('inline')
knit_hooks = new_defaults(.default.hooks)
......@@ -54,7 +54,7 @@ hook_suppress = function(x, options) {
#' \code{opts_hooks$set(FOO = function(options) { options })} (you can manipuate
#' the \code{options} argument in the function and return it), the hook function
#' will be called to update the chunk options.
#' @references \url{http://yihui.name/knitr/hooks}
#' @references \url{https://yihui.name/knitr/hooks/}
#' @export
#' @examples # make sure the figure width is no smaller than fig.height
#' opts_hooks$set(fig.width = function(options) {
......
......@@ -3,7 +3,9 @@
#' This function takes an input file, extracts the R code in it according to a
#' list of patterns, evaluates the code and writes the output in another file.
#' It can also tangle R source code from the input document (\code{purl()} is a
#' wrapper to \code{knit(..., tangle = TRUE)}).
#' wrapper to \code{knit(..., tangle = TRUE)}). The \code{knitr.purl.inline}
#' option can be used to also tangle the code of inline expressions (disabled
#' by default).
#'
#' For most of the time, it is not necessary to set any options outside the
#' input document; in other words, a single call like
......@@ -111,9 +113,9 @@
#' the R script generated by \code{purl()}. This seems to be obvious, but some
#' people \href{http://bit.ly/SnLi6h}{just do not get it}.
#' @export
#' @references Package homepage: \url{http://yihui.name/knitr/}. The \pkg{knitr}
#' \href{http://yihui.name/knitr/demo/manual/}{main manual}: and
#' \href{http://yihui.name/knitr/demo/graphics}{graphics manual}.
#' @references Package homepage: \url{https://yihui.name/knitr/}. The \pkg{knitr}
#' \href{https://yihui.name/knitr/demo/manual/}{main manual}: and
#' \href{https://yihui.name/knitr/demo/graphics/}{graphics manual}.
#'
#' See \code{citation('knitr')} for the citation information.
#' @examples library(knitr)
......@@ -159,6 +161,7 @@ knit = function(input, output = NULL, tangle = FALSE, text = NULL, quiet = FALSE
# restore chunk options after parent exits
optc = opts_chunk$get(); on.exit(opts_chunk$restore(optc), add = TRUE)
ocode = knit_code$get(); on.exit(knit_code$restore(ocode), add = TRUE)
on.exit(opts_current$restore(), add = TRUE)
optk = opts_knit$get(); on.exit(opts_knit$set(optk), add = TRUE)
opts_knit$set(tangle = tangle, encoding = encoding,
progress = opts_knit$get('progress') && !quiet
......@@ -374,7 +377,7 @@ auto_format = function(ext) {
#' @return A character string of the content of the compiled child document is
#' returned as a character string so it can be written back to the parent
#' document directly.
#' @references \url{http://yihui.name/knitr/demo/child/}
#' @references \url{https://yihui.name/knitr/demo/child/}
#' @note This function is not supposed be called directly like
#' \code{\link{knit}()}; instead it must be placed in a parent document to let
#' \code{\link{knit}()} call it indirectly.
......@@ -499,7 +502,7 @@ msg_wrap = function(message, type, options) {
list(c(knit_log$get(type), paste0('Chunk ', options$label, ':\n ', message))),
type
))
msg_sanitize(message, type)
message = msg_sanitize(message, type)
knit_hooks$get(type)(comment_out(message, options$comment), options)
}
......@@ -551,7 +554,7 @@ wrap.recordedplot = function(x, options) {
MoreArgs = list(plot = x, name = name, options = options), SIMPLIFY = FALSE
)[[1]]