Commit 7aa7d004 authored by Andreas Tille's avatar Andreas Tille

New upstream version 1.15.1

parent 2fb7fe31
Package: knitr
Type: Package
Title: A General-Purpose Package for Dynamic Report Generation in R
Version: 1.14
Date: 2016-08-11
Version: 1.15.1
Date: 2016-11-22
Authors@R: c(
person("Yihui", "Xie", email = "xie@yihui.name", role = c("aut", "cre")),
person("Adam", "Vogt", role = "ctb"),
......@@ -45,6 +45,7 @@ Authors@R: c(
person("Joseph", "Larmarange", role = "ctb"),
person("Julien", "Barnier", role = "ctb"),
person("Kaiyin", "Zhong", role = "ctb"),
person("Kamil", "Slowikowski", role = "ctb"),
person(c("Kevin", "K."), "Smith", role = "ctb"),
person("Kirill", "Mueller", role = "ctb"),
person("Kohske", "Takahashi", role = "ctb"),
......@@ -77,12 +78,12 @@ Authors@R: c(
Maintainer: Yihui Xie <xie@yihui.name>
Description: Provides a general-purpose tool for dynamic report generation in R
using Literate Programming techniques.
Depends: R (> 3.0.2)
Imports: evaluate (>= 0.8), digest, formatR, highr, markdown, stringr
(>= 0.6), yaml (>= 2.1.5), methods, tools
Suggests: testit, rgl (>= 0.95.1201), codetools, rmarkdown,
htmlwidgets, webshot, tikzDevice (>= 0.10), png, jpeg, XML,
RCurl, DBI (>= 0.4-1), tibble
Depends: R (>= 3.1.0)
Imports: evaluate (>= 0.10), digest, highr, markdown, stringr (>= 0.6),
yaml, methods, tools
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/
BugReports: https://github.com/yihui/knitr/issues
......@@ -102,7 +103,7 @@ Collate: 'block.R' 'cache.R' 'utils.R' 'citation.R' 'hooks-html.R'
'utils-vignettes.R' 'zzz.R'
RoxygenNote: 5.0.1
NeedsCompilation: no
Packaged: 2016-08-11 21:15:37 UTC; yihui
Packaged: 2016-11-22 05:33:02 UTC; yihui
Author: Yihui Xie [aut, cre],
Adam Vogt [ctb],
Alastair Andrew [ctb],
......@@ -146,6 +147,7 @@ Author: Yihui Xie [aut, cre],
Joseph Larmarange [ctb],
Julien Barnier [ctb],
Kaiyin Zhong [ctb],
Kamil Slowikowski [ctb],
Kevin K. Smith [ctb],
Kirill Mueller [ctb],
Kohske Takahashi [ctb],
......@@ -175,4 +177,4 @@ Author: Yihui Xie [aut, cre],
Wush Wu [ctb],
Zachary Foster [ctb]
Repository: CRAN
Date/Publication: 2016-08-13 11:33:17
Date/Publication: 2016-11-22 09:36:46
4f6e54f74c0bffb5c6898b9cb05b6d73 *DESCRIPTION
f4f8b6d2118344ce5ab90f941fa0e004 *NAMESPACE
009aca1248e7901b7b50f9405304ac55 *R/block.R
a8ba49072c3d22c83482d6c282aa429a *R/cache.R
78f0c1b52b86356fa7e4942678b4b275 *R/citation.R
b0acd6b4402bebffe304e38ea3eb80e9 *DESCRIPTION
37621070683a68a4bc227566e0a03721 *NAMESPACE
2020a5be55f21396e99866ad276388cb *R/block.R
397799b33f6c92366eb231e7064b368b *R/cache.R
f4de17ed656fa9124cce2e7429e27d6a *R/citation.R
d3066cdaec8d60368dfa30093222ac88 *R/concordance.R
dcd2c08d9ce1917ce089d8578cb40457 *R/defaults.R
6362ed2940ecc13aa27f46e4432496f0 *R/engine.R
77b340611c485589d7441d395852defe *R/engine.R
44370920d24fd560ceeb3f5985c83215 *R/header.R
e36c54d9b272ea1245ab8e0bcba9c8a1 *R/highlight.R
ef19e925acc44824076bc6eb2dfc50aa *R/hooks-asciidoc.R
ad8783b17b5906fc6c07f09f4d296f7b *R/hooks-chunk.R
22921f2a49542ae19e31e742f9a7392b *R/hooks-extra.R
abd182fc3b689669351e2af89820004b *R/hooks-html.R
cb3c9a24ff30adeee62403c354c71abb *R/hooks-latex.R
be602dec68f60269d7d9bb0c06c2d3a7 *R/hooks-extra.R
e4ada63ee08edeb85d8989d51407edad *R/hooks-html.R
209d5b0c6fcf3e44d6bff450f3d3662f *R/hooks-latex.R
692badbd7b542004c8d6f23618bc7d3a *R/hooks-md.R
7f13635b1aeb3df12f6a52e7c0faf79b *R/hooks-rst.R
55d62c24863e7bec5bc1520c619e43d0 *R/hooks-textile.R
b80b7bce5ee48bf8401c56bf1701a75b *R/hooks.R
0fb2903ac01d55c5292135c5d6c5e910 *R/output.R
025eb1cbdca610e4782f08bb8c3657a8 *R/package.R
0bdaab66b0f9a480dc5a5b0b6bc25d3a *R/hooks.R
e257dc01156580249316cb45eed9018e *R/output.R
21ce69e8540725f8206050bc4e71ea3c *R/package.R
dbfc00595b8621af0cb83c20274ed99f *R/pandoc.R
4f2a820f12d00290dc4977bc0539ba9c *R/params.R
fbfd5ef8ced2129428264347871308d5 *R/parser.R
35d1e691811f3397f5297f36ea76be80 *R/pattern.R
6baffc083d744d8890865effb2d50d5f *R/plot.R
bfffd7d37228dba6fc19745f53a7a608 *R/params.R
1eea1417232ec06100f9c58fefc10622 *R/parser.R
40a3f7837f7cceecd189b0fb2a396152 *R/pattern.R
d4246a8aa0b1e2ebdea43123149a1f3a *R/plot.R
d7c050d76dac22d51e77dc7368300315 *R/rocco.R
0e8f95317d4b2104d569e1fef512480f *R/spin.R
9b86689b45bb7bb82ad268fab7a7357d *R/table.R
6e5fba47e9a2adb05898576092d30201 *R/table.R
936a43bf96e691fc2bb6ea78622102cf *R/template.R
c5804ad7464fae1634b6535c7761f40f *R/themes.R
cef5bab6cd92a77e0dbe91d5f8235098 *R/utils-base64.R
c5dc1f070fee2aca2212e93e13ff9173 *R/utils-conversion.R
048f821226ec29449f56a420ac8a0dc2 *R/utils-rd2html.R
13e95b55d11d54c27eedb0c1e2a13626 *R/utils-conversion.R
04fbb2dd8f97e6952973fda49cefae31 *R/utils-rd2html.R
23af4f0015d0962834886111691c820e *R/utils-sweave.R
0d71f4398f4cbef50256109d1e0eac4b *R/utils-upload.R
4afee617fe2c1cbe1600e64bf03dc662 *R/utils-vignettes.R
9db0057bb38de067cdc0caca03633336 *R/utils.R
18927d3734faccb549ae7a93c038f664 *R/utils-vignettes.R
70a9b341689125a0de4c2c0edb887329 *R/utils.R
64580757ed828267f6976d73231f1f8f *R/zzz.R
d651706f6a72d80af95501d5d3ca6c68 *README.md
b395b4b3a46651f44cc395b07dce4b72 *build/knitr.pdf
2ff50222ef055fec2c1c66f17f90c3e6 *build/vignette.rds
d341508952d70b263d2c079e2b9e4424 *README.md
5df8c6a245231c66b4543f6c82d34bb0 *build/knitr.pdf
c5617fe42ca44b01644e6da5e63774cd *build/vignette.rds
5320cec79c972798fe0eb5579eb51927 *demo/00Index
a0d48f6ce89f9e1d39ee7248ff8c5511 *demo/gwidgets.R
a95e58617a42ea5ea95fa99a10f1c120 *demo/notebook.R
......@@ -57,22 +57,23 @@ b47c340c4060c759ed158eeb0c258560 *inst/doc/docco-classic.Rmd
0a3c5c8a96824d354a8573aa1e5a7e75 *inst/doc/docco-linear.html
d060cc6329c3b03347a61d5240cbb527 *inst/doc/knit_expand.R
45dec121925f328760fee414d1890168 *inst/doc/knit_expand.Rmd
46b3db364eccf83da861e0c4809c0044 *inst/doc/knit_expand.html
d16dc4b606ff71296097a82cd2b58455 *inst/doc/knit_expand.html
4eea99d3bf4431c606eacdf79713ded6 *inst/doc/knit_print.R
c90ac685808dfe85c05d21191dfe36a8 *inst/doc/knit_print.Rmd
ac0eef8e6b19ed5f5cab02d3c9e20a74 *inst/doc/knit_print.html
e6f43dfed1f856b04612e1b31a292ec9 *inst/doc/knit_print.html
7c333d10e4255222789dda55dad958d8 *inst/doc/knitr-html.R
824b923dd4a500fb460a2366aabfb19c *inst/doc/knitr-html.Rhtml
8a8a2edbfa2ae3c06f8a335fd22d1c2e *inst/doc/knitr-html.html
97b83b9e94f5690f0dcce82bda0eef48 *inst/doc/knitr-intro.R
fa0189ffab9ee6f23ebf599740a16ddb *inst/doc/knitr-intro.Rmd
5fa857a823abb2559c9a6fcd53a6a897 *inst/doc/knitr-intro.html
a004b0626171a81e690ebce02eebe371 *inst/doc/knitr-intro.html
aa3f1c19ae5b4ba70df72922f67996dc *inst/doc/knitr-markdown.R
3d047ff09d3b18b13466241cda178c57 *inst/doc/knitr-markdown.Rmd
ac7f714854c378569b130d36035a36cd *inst/doc/knitr-markdown.html
d61323ff5fbf6706eb21c9aec6bfa29c *inst/doc/knitr-markdown.html
b41a48fcc33fd13fcb30ff44bb644b03 *inst/doc/knitr-refcard.Rmd
7a7f31b44f9842859c80fe148b5ce271 *inst/doc/knitr-refcard.pdf
7e989013fd52f274aa3160ed0cd0c62f *inst/doc/knitr-refcard.pdf
f16d37ed927336b920c67ce2e958ffc5 *inst/examples/README.md
80d81165446ea535b4368b5f6375d7a1 *inst/examples/Sweavel.sty
5cc86725bad53543ab7cc881a2783269 *inst/examples/child/knitr-child-a.Rnw
7311fa5a656bb6d4a5e3909783a1bcb8 *inst/examples/child/knitr-child-b.Rnw
dc5c401375f6dfe6fee58614f85322b3 *inst/examples/child/knitr-child.Rmd
......@@ -99,7 +100,7 @@ fb4aa1cf9f8f8564ce2dd0855dde8006 *inst/examples/knitr-minimal.Rmd
ac45a560937f5a8d5d5cd63e4560da6c *inst/examples/knitr-minimal.Rrst
d7bccf64e1ae27901b60663a9f603b46 *inst/examples/knitr-minimal.brew
0d0deb24765c30c63e8295f2b0eca00c *inst/examples/knitr-minimal.lyx
7bb6b4efc9ae7b760a5594b349edb700 *inst/examples/knitr-packages.bib
987ce317d801c539d4e4e468dd1ddf95 *inst/examples/knitr-packages.bib
3ace25c82405c8c18da349431c8eec0d *inst/examples/knitr-spin.R
edcc62ef13989859bfab115ef699f8c9 *inst/examples/knitr-spin.Rmd
c3d8458c4cf1753656a850b59dbd38b0 *inst/examples/knitr-spin.html
......@@ -220,11 +221,11 @@ c654ad3c4586084b795513343f0c8761 *inst/themes/xoria256.css
7e4d9ef2703aa32dead65a39c2568fba *inst/themes/zenburn.css
c2abe08ea4638d3c157c8df34a621e47 *inst/themes/zmrok.css
99b505cd66698c2e4325cd47483ad068 *man/Sweave2knitr.Rd
a567d5012581e7f35dcd37d24dc61000 *man/all_labels.Rd
85e96631ee501c9741b3b3c6872f88b8 *man/all_labels.Rd
0d0e0d50e323fe0b63fdddd90bd904dc *man/all_patterns.Rd
c66a982c680ce38bcad35e31d5ff5b8e *man/asis_output.Rd
8ba9a74eb42f834127d9a8a7012a4d32 *man/chunk_hook.Rd
2cb2f07eb1cc454d55caca2f7bb68c6d *man/clean_cache.Rd
27fd66bb85a5a21262f49cbae16a8bae *man/chunk_hook.Rd
f61d44236133b9dae05c6754e3e97e17 *man/clean_cache.Rd
e867bbdfee1ee5f5396acf32b43f6f34 *man/combine_words.Rd
0dc6684ce1d6e71acd2a3d93402b8f37 *man/current_input.Rd
c13e17c759acbc0919fbc8ccb13d6baf *man/dep_auto.Rd
......@@ -240,7 +241,7 @@ e00ba3fc1c4e6bb7ccb125b3f46b44b4 *man/imgur_upload.Rd
99b88443f9028021700223f8fb91b911 *man/include_graphics.Rd
74a737e269213d40529d1213804271b1 *man/include_url.Rd
e82602a9a4ad2aa3ca831a1a2dda7573 *man/inline_expr.Rd
d82c01b4fb879d96a46e2964b63b6ea5 *man/kable.Rd
cc61e949a0f7745a5683e22bbddcf1af *man/kable.Rd
cf704a4eb278a7fc29233294cee9b2c0 *man/knit.Rd
facea2757d69349eee4c1b1a18bf687e *man/knit2html.Rd
049058c992c4fce67413ad217062ed43 *man/knit2pdf.Rd
......@@ -269,8 +270,9 @@ d212b43233f2d26a207429d9074d19b4 *man/load_cache.Rd
0271e2ab66950b8920a49243b03b3e04 *man/output_hooks.Rd
1d1abd571b4d3250b6b26ac81fb33edd *man/pandoc.Rd
0c5b5752971d7de8f4b87ba3c369c399 *man/pat_fun.Rd
52ef7687b243a641a26dae006dddaf12 *man/plot_crop.Rd
2bb3d765a96e6fd91ac453a9b5672dda *man/plot_crop.Rd
5353726990dac2e13313f083a51c1790 *man/rand_seed.Rd
3a43609e4b77db85a2a45445f63a5b8a *man/raw_output.Rd
b97e352024451ad96068c8145845fcb0 *man/read_chunk.Rd
2f672b473e52759234b3346eda98f99c *man/read_rforge.Rd
8ec2f4a6f90da2a81e1286d8f8c1c8cd *man/rocco.Rd
......@@ -283,7 +285,7 @@ b74a94dac427b10adb847adc9ed9b3c5 *man/spin_child.Rd
313c8c6dabe4db4b06a755f26f45f9e2 *man/stitch.Rd
804af3d86879e986c03bc371781e44b3 *man/vignette_engines.Rd
54b3acc757575aeca7126522f3624d78 *man/wrap_rmd.Rd
128ef627c89390f991ca21923dd7481f *man/write_bib.Rd
51fb88bb1d871b63dbd811e0d6cada32 *man/write_bib.Rd
c9999baf2feaa9582fff2870c8a3260d *tests/run-all.R
29b3efe2fa7fd7537cd0b03c0e0c41e7 *tests/testit/knit-envir.Rmd
409a303e08ceca7233025326046382a3 *tests/testit/knit-tikzDevice.Rnw
......@@ -296,10 +298,11 @@ f2dc0de6ec9d0c4159c4d2673301d4da *tests/testit/test-envir.R
0346ea2af0ab31f75a7170b361e7e0a2 *tests/testit/test-params.R
ec39f565dfeab550713a42c09d8bf9d5 *tests/testit/test-parser.R
1f9aef4be23964ebac690c898e8c6674 *tests/testit/test-patterns.R
2d2eb25c89b17f318fdb4fb0cf0b8a21 *tests/testit/test-plot.R
292794953903b1be09a53ad824bf598b *tests/testit/test-table.R
971c80ebffac602768871e9f339a1896 *tests/testit/test-plot.R
233af33c6f30c6966d2fceaf0809e22a *tests/testit/test-sql.R
189a16b4ee801870559e29981e3930a0 *tests/testit/test-table.R
f7d3197f8f2938e0fef97a1468aed580 *tests/testit/test-templates.R
3c2c2e2dd9bda10413d8fa2675266d62 *tests/testit/test-utils.R
e39f34cef2aac8f5f18da92049ee209c *tests/testit/test-utils.R
8e74c48d61c148b17890065ce21f60f3 *tools/covr.R
ff5a827a3097e8f34c36d04450e15b5f *vignettes/assets/template-refcard.tex
4ab33a0b2c409210d1f8d2feff177b16 *vignettes/datatables.Rmd
......
S3method("$",knitr_strict_list)
S3method(knit_print,default)
S3method(knit_print,knit_asis)
S3method(knit_print,knitr_kable)
......@@ -29,6 +30,7 @@ export(current_input)
export(dep_auto)
export(dep_prev)
export(engine_output)
export(extract_raw_output)
export(fig_chunk)
export(fig_path)
export(hook_ffmpeg_html)
......@@ -42,6 +44,7 @@ export(hook_plot_md)
export(hook_plot_rst)
export(hook_plot_tex)
export(hook_plot_textile)
export(hook_pngquant)
export(hook_purl)
export(hook_r2swf)
export(hook_scianimator)
......@@ -92,6 +95,7 @@ export(pat_textile)
export(plot_crop)
export(purl)
export(rand_seed)
export(raw_output)
export(read_chunk)
export(read_demo)
export(read_rforge)
......@@ -104,6 +108,7 @@ export(render_markdown)
export(render_rst)
export(render_sweave)
export(render_textile)
export(restore_raw_output)
export(rocco)
export(rst2pdf)
export(set_alias)
......
......@@ -51,7 +51,7 @@ call_block = function(block) {
warning("The option hook '", opt, "' should be a function")
next
}
if (!is.null(params[[opt]])) params = hook(params)
if (!is.null(params[[opt]])) params = as.strict_list(hook(params))
if (!is.list(params))
stop("The option hook '", opt, "' should return a list of chunk options")
}
......@@ -63,7 +63,7 @@ call_block = function(block) {
getOption('width'), if (params$cache == 2) params[cache2.opts]
)
if (params$engine == 'R' && isFALSE(params$cache.comments)) {
content[['code']] = formatR:::parse_only(content[['code']])
content[['code']] = parse_only(content[['code']])
}
hash = paste(valid_path(params$cache.path, label), digest::digest(content), sep = '_')
params$hash = hash
......@@ -103,7 +103,7 @@ block_exec = function(options) {
if (options$engine != 'R') {
res.before = run_hooks(before = TRUE, options)
engine = get_engine(options$engine)
output = in_dir(opts_knit$get('root.dir') %n% input_dir(), engine(options))
output = in_dir(input_dir(), engine(options))
res.after = run_hooks(before = FALSE, options)
output = paste(c(res.before, output, res.after), collapse = '')
output = knit_hooks$get('chunk')(output, options)
......@@ -124,9 +124,10 @@ block_exec = function(options) {
keep.idx = keep
keep = "index"
}
tmp.fig = tempfile(); on.exit(unlink(tmp.fig), add = TRUE)
# open a device to record plots
if (chunk_device(options$fig.width[1L], options$fig.height[1L], keep != 'none',
options$dev, options$dev.args, options$dpi, options)) {
options$dev, options$dev.args, options$dpi, options, tmp.fig)) {
# preserve par() settings from the last code chunk
if (keep.pars <- opts_knit$get('global.par'))
par2(opts_knit$get('global.pars'))
......@@ -162,11 +163,6 @@ block_exec = function(options) {
if (keep != 'none' && is.null(options$fig.ext))
options$fig.ext = dev2ext(options$dev)
if (!is.null(err.code <- opts_knit$get('stop_on_error'))) {
warning('the package option stop_on_error was deprecated;',
' use the chunk option error = ', err.code != 2L, ' instead')
options$error = err.code != 2L
}
cache.exists = cache$exists(options$hash, options$cache.lazy)
evaluate = knit_hooks$get('evaluate')
# return code with class 'source' if not eval chunks
......@@ -175,7 +171,7 @@ block_exec = function(options) {
} else if (cache.exists && isFALSE(options$cache.rebuild)) {
fix_evaluate(cache$output(options$hash, 'list'), options$cache == 1)
} else in_dir(
opts_knit$get('root.dir') %n% input_dir(),
input_dir(),
evaluate(
code, envir = env, new_device = FALSE,
keep_warning = !isFALSE(options$warning),
......@@ -208,7 +204,7 @@ block_exec = function(options) {
if (options$results == 'hide') res = Filter(Negate(is.character), res)
if (options$results == 'hold') {
i = vapply(res, is.character, logical(1))
if (any(i)) res = c(res[!i], list(paste(unlist(res[i]), collapse = '')))
if (any(i)) res = c(res[!i], merge_character(res[i]))
}
res = filter_evaluate(res, options$warning, evaluate::is.warning)
res = filter_evaluate(res, options$message, evaluate::is.message)
......@@ -254,7 +250,9 @@ block_exec = function(options) {
output = knit_hooks$get('chunk')(output, options)
if (options$cache > 0) {
obj.new = setdiff(ls(globalenv(), all.names = TRUE), obj.before)
# if cache.vars has been specifically provided, only cache these vars and no
# need to look for objects in globalenv()
obj.new = if (is.null(options$cache.vars)) setdiff(ls(globalenv(), all.names = TRUE), obj.before)
copy_env(globalenv(), env, obj.new)
objs = if (isFALSE(ev) || length(code) == 0) character(0) else
options$cache.vars %n% codetools::findLocalsList(parse_only(code))
......@@ -290,7 +288,9 @@ purge_cache = function(options) {
# open a device for a chunk; depending on the option global.device, may or may
# not need to close the device on exit
chunk_device = function(width, height, record = TRUE, dev, dev.args, dpi, options) {
chunk_device = function(
width, height, record = TRUE, dev, dev.args, dpi, options, tmp = tempfile()
) {
dev_new = function() {
# actually I should adjust the recording device according to dev, but here I
# have only considered the png and tikz devices (because the measurement
......@@ -298,18 +298,18 @@ chunk_device = function(width, height, record = TRUE, dev, dev.args, dpi, option
# also the cairo_pdf device (#1235)
if (identical(dev, 'png')) {
do.call(grDevices::png, c(list(
filename = tempfile(), width = width, height = height, units = 'in', res = dpi
filename = tmp, width = width, height = height, units = 'in', res = dpi
), get_dargs(dev.args, 'png')))
} else if (identical(dev, 'tikz')) {
dargs = c(list(
file = paste0(tempfile(), ".tex"), width = width, height = height
file = tmp, width = width, height = height
), get_dargs(dev.args, 'tikz'))
dargs$sanitize = options$sanitize; dargs$standAlone = options$external
if (is.null(dargs$verbose)) dargs$verbose = FALSE
do.call(tikz_dev, dargs)
} else if (identical(dev, 'cairo_pdf')) {
do.call(grDevices::cairo_pdf, c(list(
filename = tempfile(), width = width, height = height
filename = tmp, width = width, height = height
), get_dargs(dev.args, 'cairo_pdf')))
} else if (identical(getOption('device'), pdf_null)) {
if (!is.null(dev.args)) {
......@@ -389,9 +389,27 @@ merge_class = function(res, class = c('source', 'message', 'warning')) {
}
# merge character output for output='hold', if the subsequent character is of
# the same class(es) as the previous one (e.g. should not merge normal
# characters with asis_output())
merge_character = function(res) {
if ((n <- length(res)) <= 1) return(res)
k = NULL
for (i in 1:(n - 1)) {
cls = class(res[[i]])
if (identical(cls, class(res[[i + 1]]))) {
res[[i + 1]] = paste0(res[[i]], res[[i + 1]])
class(res[[i + 1]]) = cls
k = c(k, i)
}
}
if (length(k)) res = res[-k]
res
}
call_inline = function(block) {
if (opts_knit$get('progress')) print(block)
in_dir(opts_knit$get('root.dir') %n% input_dir(), inline_exec(block))
in_dir(input_dir(), inline_exec(block))
}
inline_exec = function(block, envir = knit_global(), hook = knit_hooks$get('inline')) {
......@@ -458,6 +476,6 @@ label_code = function(code, label) {
'----', code)
}
as.source <- function(code) {
as.source = function(code) {
list(structure(list(src = code), class = 'source'))
}
......@@ -283,9 +283,19 @@ rand_seed = quote({
#' multiple documents share the same cache directory. You are recommended to
#' call \code{clean_cache(FALSE)} and carefully check the list of files (if
#' any) before you really delete them (\code{clean_cache(TRUE)}).
#'
#' This function must be called within a code chunk in a source document,
#' since it needs to know all chunk labels of the current document to
#' determine which labels are no longer present, and delete cache
#' corresponding to these labels.
#' @export
clean_cache = function(clean = FALSE, path = opts_chunk$get('cache.path')) {
owd = setwd(opts_knit$get('output.dir')); on.exit(setwd(owd))
odir = opts_knit$get('output.dir')
if (is.null(odir)) {
warning('This function must be called inside a source document')
return()
}
owd = setwd(odir); on.exit(setwd(owd))
if (file_test('-d', path)) {
p0 = path; p1 = ''
} else {
......
......@@ -22,6 +22,8 @@
#' console; ignored if it is \code{NULL})
#' @param tweak whether to fix some known problems in the citations, especially
#' non-standard format of authors
#' @param width the width of lines in bibliographyb entries (if \code{NULL},
#' lines will not be wrapped)
#' @param prefix a prefix string for keys in BibTeX entries; by default, it is
#' \samp{R-} unless \code{\link{option}('knitr.bib.prefix')} has been set to
#' another string
......@@ -55,8 +57,10 @@
#'
#' # what tweak=TRUE does
#' str(knitr:::.tweak.bib)
write_bib = function(x = .packages(), file = '', tweak = TRUE,
prefix = getOption('knitr.bib.prefix', 'R-')) {
write_bib = function(
x = .packages(), file = '', tweak = TRUE, width = NULL,
prefix = getOption('knitr.bib.prefix', 'R-')
) {
idx = mapply(system.file, package = x) == ''
if (any(idx)) {
warning('package(s) ', paste(x[idx], collapse = ', '), ' not found')
......@@ -82,8 +86,10 @@ write_bib = function(x = .packages(), file = '', tweak = TRUE,
}
bib = lapply(bib, function(b) {
b['author'] = sub('Duncan Temple Lang', 'Duncan {Temple Lang}', b['author'])
b['title'] = sub("'RStudio'", 'RStudio', b['title'])
if (!('year' %in% names(b))) b['year'] = .this.year
idx = which(names(b) == '')
if (!is.null(width)) b[-idx] = stringr::str_wrap(b[-idx], width, 2, 4)
structure(c(b[idx[1L]], b[-idx], b[idx[2L]]), class = 'Bibtex')
})
}
......@@ -99,7 +105,7 @@ write_bib = function(x = .packages(), file = '', tweak = TRUE,
# hack non-standard author fields
.tweak.bib = local({
x = read.csv(inst_dir('misc/tweak_bib.csv'), stringsAsFactors = FALSE)
x = x[order(x$package), , drop = FALSE] # reorder entries by package names
x = x[order(xtfrm(x$package)), , drop = FALSE] # reorder entries by package names
write.csv(x, inst_dir('misc/tweak_bib.csv'), row.names = FALSE)
setNames(
lapply(x$author, function(a) c(author = sprintf(' author = {%s},', a))),
......
......@@ -86,9 +86,9 @@ eng_interpreted = function(options) {
writeLines(c(switch(
engine,
sas = "OPTIONS NONUMBER NODATE PAGESIZE = MAX FORMCHAR = '|----|+|---+=|-/<>*' FORMDLIM=' ';title;",
haskell = ':set +m'
NULL
), options$code), f)
on.exit(unlink(f))
on.exit(unlink(f), add = TRUE)
switch(
engine,
haskell = paste('-e', shQuote(paste(':script', f))),
......@@ -106,14 +106,14 @@ eng_interpreted = function(options) {
)
} else paste(switch(
engine, bash = '-c', coffee = '-e', groovy = '-e', lein = 'exec -e',
mysql = '-e', node = '-e', perl = '-e', psql = '-c', python = '-c',
ruby = '-e', scala = '-e', sh = '-c', zsh = '-c', NULL
mysql = '-e', node = '-e', octave = '--eval', perl = '-e', psql = '-c',
python = '-c', ruby = '-e', scala = '-e', sh = '-c', zsh = '-c', NULL
), shQuote(paste(options$code, collapse = '\n')))
# FIXME: for these engines, the correct order is options + code + file
code = if (engine %in% c('awk', 'gawk', 'sed', 'sas'))
paste(code, options$engine.opts) else paste(options$engine.opts, code)
cmd = options$engine.path %n% engine
cmd = get_engine_path(options$engine.path, engine)
out = if (options$eval) {
message('running: ', cmd, ' ', code)
tryCatch(
......@@ -132,12 +132,18 @@ eng_interpreted = function(options) {
engine_output(options, options$code, out)
}
# options$engine.path can be list(name1 = path1, name2 = path2, ...)
get_engine_path = function(path, engine) {
if (is.list(path)) path = path[[engine]]
path %n% engine
}
## C and Fortran (via R CMD SHLIB)
eng_shlib = function(options) {
n = switch(options$engine, c = 'c', fortran = 'f')
n = switch(options$engine, c = 'c', fortran = 'f', fortran95 = 'f95')
f = basename(tempfile(n, '.', paste0('.', n)))
writeLines(options$code, f)
on.exit(unlink(c(f, sub_ext(f, c('o', 'so', 'dll')))))
on.exit(unlink(c(f, sub_ext(f, c('o', 'so', 'dll')))), add = TRUE)
if (options$eval) {
out = system(paste('R CMD SHLIB', f), intern = TRUE)
dyn.load(sub(sprintf('[.]%s$', n), .Platform$dynlib.ext, f))
......@@ -258,7 +264,7 @@ eng_dot = function(options) {
# create temporary file
f = tempfile('code', '.')
writeLines(code <- options$code, f)
on.exit(unlink(f))
on.exit(unlink(f), add = TRUE)
# adapt command to either graphviz or asymptote
if (options$engine == 'dot') {
......@@ -342,7 +348,7 @@ eng_block = function(options) {
# https://github.com/jgm/pandoc/issues/2453)
if (is_pandoc) code = pandoc_fragment(code, to)
l1 = options$latex.options
l1 = if (is.null(l1)) '' else paste0('[', l1, ']')
if (is.null(l1)) l1 = ''
h2 = options$html.tag %n% 'div'
h3 = options$html.before %n% ''
h4 = options$html.after %n% ''
......@@ -357,12 +363,40 @@ eng_block = function(options) {
}
switch(
to,
latex = sprintf('\\begin%s{%s}\n%s\n\\end{%s}', l1, type, code, type),
latex = sprintf('\\begin{%s}%s\n%s\n\\end{%s}', type, l1, code, type),
html = sprintf('%s<%s class="%s">%s</%s>%s', h3, h2, type, code, h2, h4),
code
)
}
eng_block2 = function(options) {
if (isFALSE(options$echo)) return()
code = paste(options$code, collapse = '\n'); type = options$type
if (is.null(type)) return(code)
if (is.null(pandoc_to())) stop('The engine "block2" is for R Markdown only')
l1 = options$latex.options
if (is.null(l1)) l1 = ''
# protect environment options because Pandoc may escape the characters like
# {}; 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 = '-'
)
h2 = options$html.tag %n% 'div'
h3 = options$html.before %n% ''
h4 = options$html.after %n% ''
h5 = options$html.before2 %n% ''
h6 = options$html.after2 %n% ''
sprintf(
'\\BeginKnitrBlock{%s}%s%s<%s class="%s">%s%s%s</%s>%s\\EndKnitrBlock{%s}',
type, l1, h3, h2, type, h5, code, h6, h2, h4, type
)
}
# helper to create engines the wrap embedded html assets (e.g. css,js)
eng_html_asset = function(prefix, postfix) {
function(options) {
......@@ -379,14 +413,26 @@ eng_js = eng_html_asset('<script type="text/javascript">', '</script>')
# include css in a style tag (ignore if not html output)
eng_css = eng_html_asset('<style type="text/css">', '</style>')
# perform basic sql parsing to determine if a sql query is an update query
is_sql_update_query = function(query) {
query = paste(query, collapse = '\n')
# remove line comments
query = gsub('^\\s*--.*\n', '', query)
# remove multi-line comments
if (grepl('^\\s*\\/\\*.*', query)) query = gsub('.*\\*\\/', '', query)
grepl('^\\s*(INSERT|UPDATE|DELETE|CREATE).*', query, ignore.case = TRUE)
}
# sql engine
eng_sql = function(options) {
if (isFALSE(options$eval)) return(engine_output(options, options$code, ''))
# Return char vector of sql interpolation param names
varnames_from_sql = function(conn, sql) {
varPos = DBI::sqlParseVariables(conn, sql)
if (length(varPos$start) > 0) {
varNames = substring(sql, varPos$start, varPos$end)
sub("^\\?", "", varNames)
sub('^\\?', '', varNames)
}
}
......@@ -424,10 +470,9 @@ eng_sql = function(options) {
# 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) {
if (is.null(varname) && max.print > 0 && !is_sql_update_query(query)) {
res = DBI::dbSendQuery(conn, query)
data = if (!DBI::dbHasCompleted(res) || (DBI::dbGetRowCount(res) > 0))
DBI::dbFetch(res, n = max.print)
data = DBI::dbFetch(res, n = max.print)
DBI::dbClearResult(res)
} else {
data = DBI::dbGetQuery(conn, query)
......@@ -479,12 +524,13 @@ eng_sql = function(options) {
# terminate div
if (is_html_output()) cat("\n</div>\n")
# otherwise use tibble if it's available
# otherwise use tibble if it's available
} else if (loadable('tibble')) {
print(tibble::as_tibble(display_data), n = max.print)
} else print(display_data) # fallback to standard print
})
if (options$results == 'hide') output = NULL
# assign varname if requested
if (!is.null(varname)) assign(varname, data, envir = knit_global())
......@@ -497,17 +543,17 @@ eng_sql = function(options) {
local({
for (i in c(
'awk', 'bash', 'coffee', 'gawk', 'groovy', 'haskell', 'lein', 'mysql',
'node', 'perl', 'psql', 'python', 'Rscript', 'ruby', 'sas', 'scala', 'sed',
'sh', 'stata', 'zsh'
'node', 'octave', 'perl', 'psql', 'python', 'Rscript', 'ruby', 'sas',
'scala', 'sed', 'sh', 'stata', 'zsh'
)) knit_engines$set(setNames(list(eng_interpreted), i))
})
# additional engines
knit_engines$set(
highlight = eng_highlight, Rcpp = eng_Rcpp, tikz = eng_tikz, dot = eng_dot,
c = eng_shlib, fortran = eng_shlib, asy = eng_dot, cat = eng_cat,
asis = eng_asis, stan = eng_stan, block = eng_block, js = eng_js, css = eng_css,
sql = eng_sql
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
)
get_engine = function(name) {
......
......@@ -21,6 +21,11 @@
#' provide additional parameters to the program \command{optipng}, e.g.
#' \code{optipng = '-o7'}.
#'
#' The function \code{hook_pngquant()} calls the program \command{pngquant} to
#' optimize PNG images. Note the chunk option \code{pngquant} can be used to
#' provide additional parameters to the program \command{pngquant}, e.g.
#' \code{pngquant = '--speed=1 --quality=0-50'}.
#'
#' When the plots are not recordable via \code{\link[grDevices]{recordPlot}} and
#' we save the plots to files manually via other functions (e.g. \pkg{rgl}
#' plots), we can use the chunk hook \code{hook_plot_custom} to help write code
......@@ -62,26 +67,46 @@ hook_pdfcrop = function(before, options, envir) {
#' @export
#' @rdname chunk_hook
hook_optipng = function(before, options, envir) {
hook_png(before, options, envir, 'optipng')
}
hook_png = function(
before, options, envir, cmd = c('optipng', 'pngquant'), post_process = identity
) {
if (before) return()
ext = tolower(options$fig.ext)
if (ext != 'png') {
warning('this hook only works with PNG at the moment'); return()
}
if (!nzchar(Sys.which('optipng'))) {
warning('cannot find optipng; please install and put it in PATH'); return()
cmd = match.arg(cmd)
if (!nzchar(Sys.which(cmd))) {
warning('cannot find ', cmd, '; please install and put it in PATH'); return()
}
paths = all_figs(options, ext)
in_base_dir(
lapply(paths, function(x) {
message('optimizing ', x)
x = shQuote(x)
cmd = paste('optipng', if (is.character(options$optipng)) options$optipng, x)
cmd = paste(cmd, if (is.character(options[[cmd]])) options[[cmd]], shQuote(x))
(if (is_windows()) shell else system)(cmd)
post_process(x)
})
)
return()
}
#' @export
#' @rdname chunk_hook
hook_pngquant = function(before, options, envir) {
if (is.null(options[['pngquant']])) options$pngquant = '--skip-if-larger'
options[['pngquant']] = paste(options[['pngquant']], '--ext -fs8.png')
hook_png(before, options, envir, 'pngquant', function(x) {