From d33e12f849224506d0a33fd10d0eb4225e693ab5 Mon Sep 17 00:00:00 2001 From: Yihui Xie Date: Thu, 25 May 2023 08:20:08 +0000 Subject: [PATCH] version 1.43 --- DESCRIPTION | 29 +++-- MD5 | 60 +++++----- R/block.R | 24 ++-- R/cache.R | 2 +- R/citation.R | 1 + R/engine.R | 12 +- R/hooks-md.R | 1 + R/output.R | 69 ++++++++--- R/parser.R | 5 +- R/plot.R | 6 +- R/table.R | 16 +-- R/utils-rd2html.R | 2 +- R/utils-upload.R | 40 ++++--- R/utils.R | 88 ++++++++++---- build/vignette.rds | Bin 515 -> 514 bytes inst/CITATION | 18 ++- inst/doc/datatables.html | 162 +++++++++++++++---------- inst/doc/docco-classic.html | 88 ++++++++++++-- inst/doc/docco-linear.html | 20 ++-- inst/doc/knit_expand.html | 166 ++++++++++++++++---------- inst/doc/knit_print.html | 210 ++++++++++++++++----------------- inst/doc/knitr-intro.html | 24 ++-- inst/doc/knitr-markdown.html | 172 +++++++++++++++++---------- inst/doc/knitr-refcard.pdf | Bin 79886 -> 78916 bytes inst/misc/gWidgetsWWW2-knitr.R | 2 +- inst/opencpu/apps/index.html | 2 +- inst/shiny/server.R | 2 +- man/imgur_upload.Rd | 17 ++- man/kable.Rd | 10 +- tests/testit/test-hooks-md.R | 4 +- tests/testit/test-utils.R | 14 +-- 31 files changed, 773 insertions(+), 493 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 1c2eb3a..8b60f9c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: knitr Type: Package Title: A General-Purpose Package for Dynamic Report Generation in R -Version: 1.42 +Version: 1.43 Authors@R: c( person("Yihui", "Xie", role = c("aut", "cre"), email = "xie@yihui.name", comment = c(ORCID = "0000-0003-0645-5666")), person("Abhraneel", "Sarma", role = "ctb"), @@ -108,19 +108,21 @@ Authors@R: c( person("Weicheng", "Zhu", role = "ctb"), person("Wush", "Wu", role = "ctb"), person("Zachary", "Foster", role = "ctb"), - person("Zhian N.", "Kamvar", role = "ctb", comment = c(ORCID = "0000-0003-1458-7108")) + person("Zhian N.", "Kamvar", role = "ctb", comment = c(ORCID = "0000-0003-1458-7108")), + person(given = "Posit Software, PBC", role = c("cph", "fnd")) ) Description: Provides a general-purpose tool for dynamic report generation in R using Literate Programming techniques. Depends: R (>= 3.3.0) -Imports: evaluate (>= 0.15), highr, methods, yaml (>= 2.1.19), xfun (>= - 0.34), tools -Suggests: markdown (>= 1.3), formatR, testit, digest, rgl (>= - 0.95.1201), codetools, rmarkdown, htmlwidgets (>= 0.7), - webshot, tikzDevice (>= 0.10), tinytex, reticulate (>= 1.4), - JuliaCall (>= 0.11.1), magick, png, jpeg, gifski, xml2 (>= - 1.2.0), httr, DBI (>= 0.4-1), showtext, tibble, sass, bslib, - ragg, gridSVG, styler (>= 1.2.0), targets (>= 0.6.0) +Imports: evaluate (>= 0.15), highr, methods, tools, xfun (>= 0.39), + yaml (>= 2.1.19) +Suggests: bslib, codetools, DBI (>= 0.4-1), digest, formatR, gifski, + gridSVG, htmlwidgets (>= 0.7), curl, jpeg, JuliaCall (>= + 0.11.1), magick, markdown (>= 1.3), png, ragg, reticulate (>= + 1.4), rgl (>= 0.95.1201), rlang, rmarkdown, sass, showtext, + styler (>= 1.2.0), targets (>= 0.6.0), testit, tibble, + tikzDevice (>= 0.10), tinytex, webshot, rstudioapi, xml2 (>= + 1.2.0) License: GPL URL: https://yihui.org/knitr/ BugReports: https://github.com/yihui/knitr/issues @@ -141,7 +143,7 @@ Collate: 'block.R' 'cache.R' 'utils.R' 'citation.R' 'hooks-html.R' 'utils-vignettes.R' 'zzz.R' RoxygenNote: 7.2.3 NeedsCompilation: no -Packaged: 2023-01-20 05:51:44 UTC; yihui +Packaged: 2023-05-24 02:50:56 UTC; yihui Author: Yihui Xie [aut, cre] (), Abhraneel Sarma [ctb], Adam Vogt [ctb], @@ -249,7 +251,8 @@ Author: Yihui Xie [aut, cre] (), Weicheng Zhu [ctb], Wush Wu [ctb], Zachary Foster [ctb], - Zhian N. Kamvar [ctb] () + Zhian N. Kamvar [ctb] (), + Posit Software, PBC [cph, fnd] Maintainer: Yihui Xie Repository: CRAN -Date/Publication: 2023-01-25 10:20:08 UTC +Date/Publication: 2023-05-25 09:20:08 UTC diff --git a/MD5 b/MD5 index fa11ae5..cf7f533 100644 --- a/MD5 +++ b/MD5 @@ -1,11 +1,11 @@ -dc010f9722094b82abc1131b46729e2d *DESCRIPTION +18c692564000316c2409ff423848752f *DESCRIPTION fcc6203ac0d7feebd6d3935eee50afec *NAMESPACE -fc1fa075f427092bbc823e835179bbef *R/block.R -50388dd9a65dbaf76e3cdd3cab397cdc *R/cache.R -7ce6cdb0e93a3b835e5984a753fe4cd4 *R/citation.R +bc2621c11bdb89cad6c26a5efc495f31 *R/block.R +f1ce1a0e192d0cc0b8d803684ebde1fa *R/cache.R +a476fe6979a1c6640ff7a39adfa346f5 *R/citation.R 3771ee9fea520cb752a15de00a6ee926 *R/concordance.R 461f625b8beb427a0d03d9b43a775d31 *R/defaults.R -fefd1826a5874192f1c9607fb8a0a70c *R/engine.R +458226287f1d17372e15a2acad8bec86 *R/engine.R 2bd8736769f88e4e87060861992fe5a1 *R/header.R 73691d9549452b4c91bb3b27362a74b3 *R/highlight.R ac3146904a77572f10bc89469187e5ec *R/hooks-asciidoc.R @@ -13,63 +13,63 @@ ad8783b17b5906fc6c07f09f4d296f7b *R/hooks-chunk.R 8351360a60549d5c560dec6582db6975 *R/hooks-extra.R 1b22352a49814793ac3438ca65f3c7e5 *R/hooks-html.R d2225e4997e3c17ebcca8f64cf3af2b1 *R/hooks-latex.R -bdba5b4beed6aff99d496bb2843ea647 *R/hooks-md.R +046a551b21848115b85b645d571f3465 *R/hooks-md.R b6ba14a52efac7c61dbe6b52292645a1 *R/hooks-rst.R 4b7cc5acf13b4964d371f09d3b01f1d2 *R/hooks-textile.R d099970247f697104c86564dafb6c54a *R/hooks.R -c09bea533cfef6eae7e983abdcdda569 *R/output.R +2f1acebfa23e02542778f36c6b620ddb *R/output.R ba39aebe40fc0292b1261f626a8be600 *R/package.R 2f5f3a6487b9da7b9b27724aa3279bc8 *R/pandoc.R 62a8271ab2bb4cb847b002d2735c5761 *R/params.R -a8e5435019e281bb9e78b18dc7d429e4 *R/parser.R +f639ee378d58695468c015cdca0154a0 *R/parser.R f3dfe64b5012fe68f420aa3cc05fee6d *R/pattern.R -ed3dba8a69c6309028cdc7d272ce4d80 *R/plot.R +6122363c72616199651c45ec3587613e *R/plot.R bbb5dbe779aa4adcb75d1233d361b163 *R/rocco.R 64a5e41c8412f9199524a21b61ee6ab8 *R/spin.R -86dd844f81fb26de77762d8554632a7f *R/table.R +6dc103da8f6c24f96f633d3996576bec *R/table.R ddb04ceb196da7b51d1bdbf4f78e0f63 *R/template.R cff7000295ea6bf361f0d0f24da1e35a *R/themes.R 864dd90185fec3616cbe7de2ba03c56d *R/utils-conversion.R -f14e41660d66f3302883f037f8d68f4a *R/utils-rd2html.R +7f4ece2de5f8189f8ebba192e7b600d6 *R/utils-rd2html.R bd25a692d9805170d01278f815e63366 *R/utils-string.R aeb29eb209d25167087606e2f5401cd9 *R/utils-sweave.R -74a14744c7f7061522b39ed0a9555cac *R/utils-upload.R +461b10915c50bbf5d0a8baf96531e249 *R/utils-upload.R 00a6ebbbcc313a3d261e5309fdd73cf1 *R/utils-vignettes.R -a40b68b591a00001ca7becd423d58b2a *R/utils.R +fdfa68fded1758fbc868395c0ea9ded3 *R/utils.R 64580757ed828267f6976d73231f1f8f *R/zzz.R -7f3d8d5703a3ba9537ac7f99a01d1f7e *build/vignette.rds +6daf06dd281ffb03ac34aa34b7d134c0 *build/vignette.rds 5320cec79c972798fe0eb5579eb51927 *demo/00Index a0d48f6ce89f9e1d39ee7248ff8c5511 *demo/gwidgets.R a95e58617a42ea5ea95fa99a10f1c120 *demo/notebook.R -48a528acaa5c53e079f84920c5bff748 *inst/CITATION +3982b9421067677ea392b5cc194ce565 *inst/CITATION a70f6f982a3c3cc343b5db3f0bb90949 *inst/NEWS.Rd 4874a71c96d939a22aa11a3f6ee0c0df *inst/bin/knit ade128c7c01d7f8e5fa7f7318154b1b1 *inst/doc/datatables.R 4c1f26b7deb6644603d71c54cfd61bd9 *inst/doc/datatables.Rmd -4f20211d629c7c4663eeb5f0464f6cbb *inst/doc/datatables.html +8adb6fcb25ced778fd77d84577956d66 *inst/doc/datatables.html f65d5ee8789ca5d827dfabdbfec7b881 *inst/doc/docco-classic.R b47c340c4060c759ed158eeb0c258560 *inst/doc/docco-classic.Rmd -5c8c589aa35d93a813cfc19dbb975e42 *inst/doc/docco-classic.html +422ac4f5a8735370a06c12179190cb56 *inst/doc/docco-classic.html d074020b55283431c52887f2040ebe6e *inst/doc/docco-linear.R 5068ad7f6dc06bdf5875a4df35e7ec15 *inst/doc/docco-linear.Rmd -79c4ee876673d4b84d38d8d50956c767 *inst/doc/docco-linear.html +a5f288f175e4b0190ea1212d2b1b2188 *inst/doc/docco-linear.html 3e4b708e32004e6634e71a946d2b7d72 *inst/doc/knit_expand.R 4774af06c0d07027763d929823c5c384 *inst/doc/knit_expand.Rmd -681b9e2a8a2bd51ceb85c95a8142f863 *inst/doc/knit_expand.html +57219a3ceaa771661616a86eac45bcd8 *inst/doc/knit_expand.html 7589790b62a05f2f0e47e5ee939ac6e6 *inst/doc/knit_print.R 2ee45ca25b0161540ce8df5288d8fa15 *inst/doc/knit_print.Rmd -8a48a063c903cfbc15528bffd934c9c1 *inst/doc/knit_print.html +7b2dc139db5eb3c525e1ef0ae3d72665 *inst/doc/knit_print.html 769d05c90e0867719cdee64025753b53 *inst/doc/knitr-html.R 824b923dd4a500fb460a2366aabfb19c *inst/doc/knitr-html.Rhtml 8cf1a20c0eeccae45629b93f1ee60afc *inst/doc/knitr-html.html 23404d775025e833ea59a5e08270fc0e *inst/doc/knitr-intro.R 89f153ccf155fca8ecb1eb304da5c29c *inst/doc/knitr-intro.Rmd -5dc55e91eb7e14d5418b2505d09afc02 *inst/doc/knitr-intro.html +c1f0cfc6404913ef714f9529d488d5f1 *inst/doc/knitr-intro.html 824209ff035524f7767a8968e79a4df6 *inst/doc/knitr-markdown.R e25752b612a2380a1940b03cc5e953d4 *inst/doc/knitr-markdown.Rmd -d850a4bc5962c0f171706e8158575e77 *inst/doc/knitr-markdown.html +9e3702778fac69ca49bbb190f3f5496d *inst/doc/knitr-markdown.html e2713b536f8a81e1071198c985475d5d *inst/doc/knitr-refcard.Rmd -16292ced40c4d7febe65861e473764b3 *inst/doc/knitr-refcard.pdf +6781c06ff89cee70503e47677a3bed74 *inst/doc/knitr-refcard.pdf f16d37ed927336b920c67ce2e958ffc5 *inst/examples/README.md 80d81165446ea535b4368b5f6375d7a1 *inst/examples/Sweavel.sty 5cc86725bad53543ab7cc881a2783269 *inst/examples/child/knitr-child-a.Rnw @@ -116,7 +116,7 @@ a42dd99237d78fbd0ba217973183aa32 *inst/misc/datatables.html 8b56ea1b46b9081df0bbe5ade0400869 *inst/misc/docco-classic.css c35f590b60f24dd3cf26d0f3e0017ca5 *inst/misc/docco-classic.html 7957d35de356f1f07e4c358cc27087b3 *inst/misc/docco-template.html -1104e5cda3b8ffd9a39be39aa3d06582 *inst/misc/gWidgetsWWW2-knitr.R +f7032b8b4e7f41dbd0bfd83c7c411b84 *inst/misc/gWidgetsWWW2-knitr.R e185911fcf189089aa9b39216c652c9c *inst/misc/knitr-template.Rhtml 8da99e02dfa98e2b973985e2beefb518 *inst/misc/knitr-template.Rmd bdd0af9d06749374afb3d36a5916d191 *inst/misc/knitr-template.Rnw @@ -128,8 +128,8 @@ e1bcfa4fa59e6027485d6761cef388ae *inst/misc/toggleR.js b4b12d6702a9a341b6ccea645321c6d7 *inst/misc/tweak_bib.csv 894aacc5f6d190c563d8ec2d83eabe0d *inst/misc/vignette.css fad3311c9fb05d4dce933eca8912e186 *inst/misc/vignette.html -a4c69528ff950bdb71e009c747ec8bf1 *inst/opencpu/apps/index.html -1e3c09e6c09fb52a337c0f539862b542 *inst/shiny/server.R +cd85d3422fa4888bda3dd955aa76c8fe *inst/opencpu/apps/index.html +a380c817783ff2f6cadcf63d1a42bfb3 *inst/shiny/server.R 797e1e356a0cfa4d0057090d54423d38 *inst/shiny/ui.R b2f9b0d4a186b0b1869a8f6fc452e4a5 *inst/shiny/www/ace-shiny.css 531bef721eaec6a9a02a161e68997b42 *inst/shiny/www/ace-shiny.js @@ -237,12 +237,12 @@ c82f1d2262daf76e9860d87eb7362d9e *man/hook_animation.Rd caefcb554d3691e5a7c92bca5bb9db5d *man/hook_document.Rd 71300a86c312a2949bc50393772cf1c6 *man/hook_plot.Rd 7f3b313ee6f7a592d7319198d808e857 *man/image_uri.Rd -fffc0de3eab720f152c70ed61276ac05 *man/imgur_upload.Rd +701e417ae962ffc5708382c9109d0b3e *man/imgur_upload.Rd 7e498e79dfb695cb00582cf448bbab25 *man/include_graphics.Rd 8bdd9512d57176c507216419eab1858e *man/include_url.Rd 339b19fe49695c2640a3876542a13142 *man/inline_expr.Rd 3d8b2f2793a4869444669d2fba2fda6e *man/is_low_change.Rd -18a372852d952aae289f22bc42448968 *man/kable.Rd +1ab81190562281bc462b12802bb149b8 *man/kable.Rd 819cc7352c2b83219a861d1ade0959eb *man/knit.Rd 050cf2b09fb1ef171d20e760d9564b27 *man/knit2html.Rd 3902a1b3dd1b08f7a909e3ce4485df1a *man/knit2pandoc.Rd @@ -304,7 +304,7 @@ f46a49e3fd4a1c142cd6336ab2ee5215 *tests/testit/test-cache.R 621fafe6a1a958b26529fc59594bcff9 *tests/testit/test-citation.R 8434ccf049db2d30d2795e1a605db098 *tests/testit/test-closure.R f2dc0de6ec9d0c4159c4d2673301d4da *tests/testit/test-envir.R -d2d5a3b005bf73ef83c7491da4812870 *tests/testit/test-hooks-md.R +024c233a00dbdc6eabaae3f10106ee7e *tests/testit/test-hooks-md.R c7306a791facc53dbe80cc5b6c244293 *tests/testit/test-output.R ef2beb254ea8bcf4ff1df40b47468d5d *tests/testit/test-params.R c71448003c4bdd77cc70d7d21ec1bf24 *tests/testit/test-parser.R @@ -316,7 +316,7 @@ ad2678c42641605592b9380c89692c1c *tests/testit/test-plot.R 016971c2b18ede41ad47e1a0c357a5a2 *tests/testit/test-tangle.R f7d3197f8f2938e0fef97a1468aed580 *tests/testit/test-templates.R fb3d6b391a3bd94dcd5ca1259640fca5 *tests/testit/test-themes.R -7777cbde98bae7206173754d617b0d9a *tests/testit/test-utils.R +508709b51d53ddd0e811ebfd48c37864 *tests/testit/test-utils.R ff5a827a3097e8f34c36d04450e15b5f *vignettes/assets/template-refcard.tex 4c1f26b7deb6644603d71c54cfd61bd9 *vignettes/datatables.Rmd b47c340c4060c759ed158eeb0c258560 *vignettes/docco-classic.Rmd diff --git a/R/block.R b/R/block.R index f226e85..8ec882d 100644 --- a/R/block.R +++ b/R/block.R @@ -55,17 +55,6 @@ call_block = function(block) { if (opts_knit$get('progress')) print(block) - if (!is.null(params$child)) { - if (!is_blank(params[['code']]) && getOption('knitr.child.warning', TRUE)) warning( - "The chunk '", params$label, "' has the 'child' option, ", - "and this code chunk must be empty. Its code will be ignored." - ) - if (!params$eval) return('') - cmds = lapply(sc_split(params$child), knit_child, options = block$params) - out = one_string(unlist(cmds)) - return(out) - } - params$code = parse_chunk(params$code) # parse sub-chunk references ohooks = opts_hooks$get() @@ -82,6 +71,17 @@ call_block = function(block) { params = fix_options(params) # for compatibility + if (!is.null(params$child)) { + if (!is_blank(params[['code']]) && getOption('knitr.child.warning', TRUE)) warning( + "The chunk '", params$label, "' has the 'child' option, ", + "and this code chunk must be empty. Its code will be ignored." + ) + if (!params$eval) return('') + cmds = lapply(sc_split(params$child), knit_child, options = block$params) + out = one_string(unlist(cmds)) + return(out) + } + # Check cache if (params$cache > 0) { content = c( @@ -593,7 +593,7 @@ process_tangle.block = function(x) { code = parse_chunk(code) if (isFALSE(ev)) code = comment_out(code, params$comment, newline = FALSE) if (opts_knit$get('documentation') == 0L) return(one_string(code)) - # e.g when documentation 1 or 2 with purl() + # e.g. when documentation 1 or 2 with purl() label_code(code, x) } #' @export diff --git a/R/cache.R b/R/cache.R index 0664c62..b45a619 100644 --- a/R/cache.R +++ b/R/cache.R @@ -30,7 +30,7 @@ new_cache = function() { save(list = outname, file = paste(path, 'RData', sep = '.'), envir = knit_global()) if (!lazy) return() # everything has been saved; no need to make lazy db # random seed is always load()ed - keys = setdiff(keys, '.Random.seed') + keys = as.character(setdiff(keys, '.Random.seed')) getFromNamespace('makeLazyLoadDB', 'tools')(knit_global(), path, variables = keys) } diff --git a/R/citation.R b/R/citation.R index 390c954..e59d2e9 100644 --- a/R/citation.R +++ b/R/citation.R @@ -63,6 +63,7 @@ write_bib = function( ) { system.file = function(...) base::system.file(..., lib.loc = lib.loc) citation = function(...) utils::citation(..., lib.loc = lib.loc) + x = x[nzchar(x)] # remove possible empty string idx = mapply(system.file, package = x) == '' if (any(idx)) { warning('package(s) ', paste(x[idx], collapse = ', '), ' not found') diff --git a/R/engine.R b/R/engine.R index 86c74c6..8db2c42 100644 --- a/R/engine.R +++ b/R/engine.R @@ -87,9 +87,9 @@ engine_output = function(options, code, out, extra = NULL) { if (length(out) != 1L) out = one_string(out) out = sub('([^\n]+)$', '\\1\n', out) if (options$engine == 'stata') { - out = gsub('\n+running.*profile.do', '', out) - out = sub('...\n+', '', out) - out = sub('\n. \nend of do-file\n', '', out) + out = gsub('\n+running.*profile\\.do', '', out) + out = sub('\\.\\.\\.\n+', '', out) + out = sub('\n\\. \nend of do-file\n', '', out) } one_string(c( if (length(options$echo) > 1L || options$echo) knit_hooks$get('source')(code, options), @@ -141,7 +141,7 @@ eng_interpreted = function(options) { opts = get_engine_opts(options$engine.opts, engine) # FIXME: for these engines, the correct order is options + code + file - code = if (engine %in% c('awk', 'gawk', 'sed', 'sas')) + code = if (engine %in% c('awk', 'gawk', 'sed', 'sas', 'psql', 'mysql')) paste(code, opts) else paste(opts, code) cmd = get_engine_path(options$engine.path, engine) out = if (options$eval) { @@ -537,7 +537,7 @@ 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) { - out = if (options$eval && is_html_output(excludes = 'markdown')) { + out = if (options$eval && is_html_output()) { one_string(c(prefix, options$code, postfix)) } options$results = 'asis' @@ -546,7 +546,7 @@ eng_html_asset = function(prefix, postfix) { } # include js in a script tag (ignore if not html output) -eng_js = eng_html_asset('') +eng_js = eng_html_asset('') # include css in a style tag (ignore if not html output) eng_css = eng_html_asset('') diff --git a/R/hooks-md.R b/R/hooks-md.R index 4542e80..cda8642 100644 --- a/R/hooks-md.R +++ b/R/hooks-md.R @@ -214,6 +214,7 @@ hooks_markdown = function(strict = FALSE, fence_char = '`') { if (isTRUE(options$collapse)) { r = sprintf('\n([%s]{3,})\n+\\1((\\{[.])?%s[^\n]*)?\n', fence_char, tolower(options$engine)) x = gsub(r, '\n', x) + x = gsub(asis_token, '', x, fixed = TRUE) } x = pandoc_div(x, options[['attr.chunk']], options[['class.chunk']]) if (is.null(s <- options$indent)) return(x) diff --git a/R/output.R b/R/output.R index df51930..fb5ee44 100644 --- a/R/output.R +++ b/R/output.R @@ -288,13 +288,13 @@ process_file = function(text, output) { # when in R CMD check, turn off the progress bar (R-exts said the progress bar # was not appropriate for non-interactive mode, and I don't want to argue) progress = opts_knit$get('progress') && !is_R_CMD_check() + labels = unlist(lapply(groups, function(g) { + if (is.list(g$params)) g[[c('params', 'label')]] else '' + })) if (progress) { - labels = unlist(lapply(groups, function(g) { - if (is.list(g$params)) g[[c('params', 'label')]] else '' - })) pb_fun = getOption('knitr.progress.fun', txt_pb) pb = if (is.function(pb_fun)) pb_fun(n, labels) - on.exit(if (!is.null(pb)) pb$done(), add = TRUE) + on.exit(if (is.function(pb$done)) pb$done(), add = TRUE) } wd = getwd() for (i in 1:n) { @@ -306,16 +306,21 @@ process_file = function(text, output) { } break # must have called knit_exit(), so exit early } - if (progress && !is.null(pb)) pb$update(i) + if (progress && is.function(pb$update)) pb$update(i) group = groups[[i]] res[i] = withCallingHandlers( - if (tangle) process_tangle(group) else process_group(group), + withCallingHandlers( + if (tangle) process_tangle(group) else process_group(group), + # TODO: remove the learnr hack https://github.com/rstudio/learnr/pull/781 + error = function(e) if (xfun::pkg_available('rlang', '1.0.0') && !xfun::check_old_package('learnr', '0.11.3')) rlang::entrace(e) + ), error = function(e) { setwd(wd) - cat(res, sep = '\n', file = output %n% '') + write_utf8(res, output %n% stdout()) message( - 'Quitting from lines ', paste(current_lines(i), collapse = '-'), - ' (', knit_concord$get('infile'), ') ' + '\nQuitting from lines ', paste(current_lines(i), collapse = '-'), + if (labels[i] != '') sprintf(' [%s]', labels[i]), + sprintf(' (%s)', knit_concord$get('infile')) ) } ) @@ -464,6 +469,20 @@ sew.character = function(x, options, ...) { knit_hooks$get('output')(x, options) } +asis_token = '' +wrap_asis = function(x, options) { + # do nothing when inside quarto as it is not needed + # https://github.com/yihui/knitr/pull/2212#pullrequestreview-1292924523 + if (is_quarto()) return(x) + + x = as.character(x) + if ((n <- length(x)) == 0 || !out_format('markdown') || missing(options) || !isTRUE(options$collapse)) + return(x) + x[1] = paste0(asis_token, x[1]) + x[n] = paste0(x[n], asis_token) + x +} + # If you provide a custom print function that returns a character object of # class 'knit_asis', it will be written as is. #' @export @@ -481,10 +500,15 @@ sew.knit_asis = function(x, options, inline = FALSE, ...) { if (inherits(x, 'knit_asis_htmlwidget')) { options$fig.cur = plot_counter() options = reduce_plot_opts(options) - return(add_html_caption(options, x)) + # look for attribute 'aria-labelledby="label"' in the first HTML tag and + # use the label to provide alt text if found + return(add_html_caption( + options, wrap_asis(x, options), + xfun::grep_sub('^[^<]*<[^>]+aria-labelledby[ ]*=[ ]*"([^"]+)".*$', '\\1', x) + )) } } - x = as.character(x) + x = wrap_asis(x, options) if (!out_format('latex') || inline) return(x) # latex output need the \end{kframe} trick options$results = 'asis' @@ -624,12 +648,27 @@ sew.knit_embed_url = function(x, options = opts_chunk$get(), inline = FALSE, ... )) } -add_html_caption = function(options, code) { +add_html_caption = function(options, code, id = NULL) { cap = .img.cap(options) - if (cap == '') return(code) + if (cap == '' && !length(id)) return(code) + + if (length(id)) { + alt = .img.cap(options, alt = TRUE) + if (cap == alt && cap != '') { + # both are the same, so insert cap with id + alttext = sprintf('

%s

\n', id, cap) + # prevent a second insertion + cap = '' + } else { + alttext = sprintf('\n', id, alt) + } + } else alttext = '' + + captext = if (cap == '') '' else sprintf('

%s

\n', cap) + sprintf( - '
\n%s\n

%s

\n
', - css_text_align(options$fig.align), code, cap + '
\n%s\n%s%s
', + css_text_align(options$fig.align), code, captext, alttext ) } diff --git a/R/parser.R b/R/parser.R index a1597b1..fb7f42a 100644 --- a/R/parser.R +++ b/R/parser.R @@ -216,7 +216,7 @@ quote_label = function(x) { # comment characters for various languages comment_chars = list( `#` = c('awk', 'bash', 'coffee', 'gawk', 'julia', 'octave', 'perl', 'powershell', 'python', 'r', 'ruby', 'sed', 'stan'), - '//' = c('asy', 'cc', 'csharp', 'd3', 'dot', 'fsharp', 'go', 'groovy', 'java', 'js', 'node', 'Rcpp', 'sass', 'scala'), + '//' = c('asy', 'cc', 'csharp', 'd3', 'dot', 'fsharp', 'go', 'groovy', 'java', 'js', 'node', 'Rcpp', 'sass', 'scss', 'scala'), `%` = c('matlab', 'tikz'), `/* */` = c('c', 'css'), `* ;` = c('sas'), @@ -375,9 +375,6 @@ print.inline = function(x, ...) { if (nrow(x$location)) { cat(sprintf(' | %s #%s:%s', x$code, x$location[, 1], x$location[, 2]), sep = '\n') } - } else if (nrow(x$location) == 0 && xfun::check_old_package('autonewsmd', '0.0.4')) { - # TODO: remove this hack after https://github.com/kapsner/autonewsmd/pull/6 - cat(' ordinary text without R code\n') } } diff --git a/R/plot.R b/R/plot.R index cd56cab..dddae6e 100644 --- a/R/plot.R +++ b/R/plot.R @@ -203,7 +203,9 @@ patch_tikz_tex = function(path) { # filter the dev.args option get_dargs = function(dargs, dev) { if (length(dargs) == 0) return() - if (is.list(dargs) && all(sapply(dargs, is.list))) { + nms = names(dargs) + if (is.list(dargs) && all(sapply(dargs, is.list)) && length(nms) && + (dev %in% nms || all(nms %in% names(auto_exts)))) { # dev.args is list(dev1 = list(arg1 = val1, ...), dev2 = list(arg2, ...)) dargs = dargs[[dev]] } @@ -371,7 +373,7 @@ plot_crop = function(x, quiet = TRUE) { is_pdf = grepl('[.]pdf$', x, ignore.case = TRUE) x2 = x x = path.expand(x) - if (is_pdf && !has_utility('pdfcrop') && !has_utility('ghostscript')) return(x2) + if (is_pdf && !has_utility('pdfcrop')) return(x2) if (!quiet) message('cropping ', x) if (is_pdf) { diff --git a/R/table.R b/R/table.R index d9890b2..076362b 100644 --- a/R/table.R +++ b/R/table.R @@ -17,11 +17,11 @@ #' returned value from \code{kable()}. #' @param format A character string. Possible values are \code{latex}, #' \code{html}, \code{pipe} (Pandoc's pipe tables), \code{simple} (Pandoc's -#' simple tables), and \code{rst}. The value of this argument will be -#' automatically determined if the function is called within a \pkg{knitr} -#' document. The \code{format} value can also be set in the global option -#' \code{knitr.table.format}. If \code{format} is a function, it must return a -#' character string. +#' simple tables), \code{rst}, and \code{jira}. The value of this argument +#' will be automatically determined if the function is called within a +#' \pkg{knitr} document. The \code{format} value can also be set in the global +#' option \code{knitr.table.format}. If \code{format} is a function, it must +#' return a character string. #' @param digits Maximum number of digits for numeric columns, passed to #' \code{round()}. This can also be a vector of length \code{ncol(x)}, to set #' the number of digits for individual columns. @@ -390,7 +390,7 @@ kable_html = function( #' @noRd kable_mark = function(x, sep.row = c('=', '=', '='), sep.col = ' ', padding = 0, align.fun = function(s, a) s, rownames.name = '', - sep.head = sep.col, ...) { + sep.head = sep.col, newline = NULL, ...) { # when the column separator is |, replace existing | with its HTML entity if (sep.col == '|') for (j in seq_len(ncol(x))) { x[, j] = gsub('\\|', '|', x[, j]) @@ -412,7 +412,9 @@ kable_mark = function(x, sep.row = c('=', '=', '='), sep.col = ' ', padding = 0 res = rbind(if (!is.na(sep.row[1])) s, cn, align.fun(s, align), x, if (!is.na(sep.row[3])) s) res = mat_pad(res, l, align) - add_mark_col_sep(res, sep.col, sep.head) + res = add_mark_col_sep(res, sep.col, sep.head) + if (is.character(newline)) res = gsub('\n', newline, res, fixed = TRUE) + res } # add column separators to header and body separately diff --git a/R/utils-rd2html.R b/R/utils-rd2html.R index 88aa24b..ae16c10 100644 --- a/R/utils-rd2html.R +++ b/R/utils-rd2html.R @@ -48,7 +48,7 @@ knit_rd = function(pkg, links = tools::findHTMLlinks(), frame = TRUE) { ex = ex[-(1L:grep('### ** Examples', ex, fixed = TRUE))] ex = c('```{r}', ex, '```') opts_chunk$set(fig.path = paste0('figure/', p, '-'), tidy = FALSE) - res = try(knit2html(text = ex, envir = parent.frame(2), fragment.only = TRUE, quiet = TRUE)) + res = try(knit2html(text = ex, envir = parent.frame(2), template = FALSE, quiet = TRUE)) if (inherits(res, 'try-error')) { res = ex; res[1] = '
'; res[length(res)] = '
' } diff --git a/R/utils-upload.R b/R/utils-upload.R index c5cc499..4205415 100644 --- a/R/utils-upload.R +++ b/R/utils-upload.R @@ -1,8 +1,8 @@ #' Upload an image to imgur.com #' -#' This function uses the \pkg{httr} package to upload a image to +#' This function uses the \pkg{curl} package to upload a image to #' \url{https://imgur.com}, and parses the XML response to a list with -#' \pkg{xml2} which contains information about the image in the Imgur website. +#' \pkg{xml2}, which contains information about the image on Imgur. #' #' When the output format from \code{\link{knit}()} is HTML or Markdown, this #' function can be used to upload local image files to Imgur, e.g. set the @@ -10,8 +10,10 @@ #' document is completely self-contained, i.e. it does not need external image #' files any more, and it is ready to be published online. #' @param file Path to the image file to be uploaded. -#' @param key Client ID for Imgur. By default, this uses a client ID registered -#' by Yihui Xie. +#' @param key Client ID for Imgur. It can be set via either the global option +#' \code{knitr.imgur.key} or the environment variable \code{R_KNITR_IMGUR_KEY} +#' (see [xfun::env_option()]). If neither is set, this uses a client ID +#' registered by Yihui Xie. #' @return A character string of the link to the image; this string carries an #' attribute named \code{XML} which is a list converted from the response XML #' file; see Imgur API in the references. @@ -31,20 +33,24 @@ #' if (interactive()) browseURL(res) #' #' # to use your own key -#' opts_knit$set(upload.fun = function(file) imgur_upload(file, key = 'your imgur key')) +#' options(knitr.imgur.key = 'your imgur key') #' } -imgur_upload = function(file, key = '9f3460e67f308f6') { +imgur_upload = function(file, key = xfun::env_option('knitr.imgur.key', '9f3460e67f308f6')) { if (!is.character(key)) stop('The Imgur API Key must be a character string!') - resp = httr::POST( - "https://api.imgur.com/3/image.xml", - config = httr::add_headers(Authorization = paste("Client-ID", key)), - body = list(image = httr::upload_file(file)) + h = curl::new_handle(httpheader = paste("Authorization: Client-ID", key)) + curl::handle_setform(h, image = curl::form_file(file)) + res = curl::curl_fetch_memory('https://api.imgur.com/3/image.xml', h)$content + if (loadable('xml2')) { + res = xml2::as_list(xml2::read_xml(res)) + link = res[[1]]$link[[1]] + } else { + res = rawToChar(res) + link = xfun::grep_sub('.*([^<]+).*', '\\1', res) + } + if (length(link) != 1) stop( + 'Failed to upload ', file, sprintf(' (reason: %s)', if (is.character(res)) { + xfun::grep_sub('.*([^<]+).*', '\\1', res) + } else res[[1]]$error[[1]]) ) - httr::stop_for_status(resp, "upload to imgur") - res = httr::content(resp, as = "raw") - res = if (length(res)) xml2::as_list(xml2::read_xml(res)) - # Breaking change in xml2 1.2.0 - if (packageVersion('xml2') >= '1.2.0') res <- res[[1L]] - if (is.null(res$link[[1]])) stop('failed to upload ', file) - structure(res$link[[1]], XML = res) + structure(link, XML = res) } diff --git a/R/utils.R b/R/utils.R index f3edf09..454691f 100644 --- a/R/utils.R +++ b/R/utils.R @@ -371,7 +371,7 @@ fix_options = function(options) { #' # Test if current output format is 'docx' #' knitr::pandoc_to('docx') is_latex_output = function() { - out_format('latex') || pandoc_to(c('latex', 'beamer')) + out_format(c('latex', 'sweave', 'listings')) || pandoc_to(c('latex', 'beamer')) } #' @param fmt A character vector of output formats to be checked against. If not @@ -383,6 +383,7 @@ is_latex_output = function() { #' @rdname output_type #' @export is_html_output = function(fmt = pandoc_to(), excludes = NULL) { + fmt = fmt %n% out_format() if (length(fmt) == 0) return(FALSE) if (grepl('^markdown', fmt)) fmt = 'markdown' if (fmt == 'epub3') fmt = 'epub' @@ -490,24 +491,17 @@ fig_path = function(suffix = '', options = opts_current$get(), number) { if (missing(number)) number = options$fig.cur %n% 1L if (!is.null(number)) suffix = paste0('-', number, suffix) path = valid_path(options$fig.path, options$label) - (if (out_format(c('latex', 'sweave', 'listings'))) sanitize_fn else - paste0)(path, suffix) + if (getOption('knitr.sanitize.paths', out_format(c('latex', 'sweave', 'listings')))) + path = sanitize_fn(path) + paste0(path, suffix) } # sanitize filename for LaTeX -sanitize_fn = function(path, suffix = '') { - if (grepl('[^~:_./\\[:alnum:]-]', path)) { - warning('replaced special characters in figure filename "', path, '" -> "', - path <- gsub('[^~:_./\\[:alnum:]-]', '_', path), '"') - } - # replace . with _ except ../ and ./ - s = strsplit(path, '[/\\\\]')[[1L]] - i = (s != '.') & (s != '..') & grepl('\\.', s) - if (any(i)) { - s[i] = gsub('\\.', '_', s[i]) - path = paste(s, collapse = '/') - warning('dots in figure paths replaced with _ ("', path, '")') - } - paste0(path, suffix) +sanitize_fn = function(path, warn = TRUE) { + p = gsub('[^~:_./\\[:alnum:]-]', '_', path) + if (warn && (p != path)) warning( + "Replaced special characters in figure filename '", path, "' -> '", p, "'" + ) + p } #' Obtain the figure filenames for a chunk @@ -783,16 +777,38 @@ kpsewhich = function() { # check if a utility exists; if it does, save its availability in opts_knit has_utility = function(name, package = name) { - name2 = paste('util', name, sep = '_') # e.g. util_pdfcrop + name2 = paste0('util_', name) # e.g. util_pdfcrop if (is.logical(yes <- opts_knit$get(name2))) return(yes) # a special case: use tools::find_gs_cmd() to find ghostscript - if (name == 'ghostscript') name = tools::find_gs_cmd() - yes = nzchar(Sys.which(name)) - if (!yes) warning(package, ' not installed or not in PATH') + if (name == 'pdfcrop') yes = has_crop_tools() else { + yes = nzchar(Sys.which(name)) + if (!yes) warning(package, ' not installed or not in PATH') + } opts_knit$set(setNames(list(yes), name2)) yes } +# check if pdfcrop and ghostscript are available +has_crop_tools = function(warn = TRUE) { + if (Sys.which('pdfcrop') == '') { + if (warn) warning("'pdfcrop' is required but not found") + return(FALSE) + } + if (is_windows() && Sys.which('tlmgr') != '') { + # assuming users know what this env var means (rstudio/tinytex#391) + if (Sys.getenv('TEXLIVE_WINDOWS_EXTERNAL_GS') != '') return(TRUE) + # TODO: use tinytex::tlmgr_version('list')$year + year = as.integer(xfun::grep_sub('^TeX Live.* version (\\d+).*$', '\\1', tinytex::tlmgr_version())[1]) + if (year < 2023 && warn) warning( + 'TeX Live version too low. Please consider upgrading, e.g., via tinytex::reinstall_tinytex().' + ) + return(year >= 2023) + } + gs = tools::find_gs_cmd() != '' + if (warn && !gs) warning("'ghostscript' is required but not found") + gs +} + #' Query the current input filename #' #' Returns the name of the input file passed to \code{\link{knit}()}. @@ -1099,7 +1115,16 @@ str_split = function(x, split, ...) { # default progress bar function in knitr: create a text progress bar, and return # methods to update/close it txt_pb = function(total, labels) { - s = ifelse(labels == '', '', sprintf(' (%s)', labels)) # chunk labels in () + if (getOption('knitr.progress.linenums', FALSE)) { + nums = sapply(seq_along(labels), function(i) { + paste(current_lines(i), collapse = '-') + }) + labels = sprintf( + '%s%s%s:%s', labels, ifelse(labels == '', '', ' @ '), + knit_concord$get('infile'), nums + ) + } + s = ifelse(labels == '', '', sprintf(' [%s]', labels)) # chunk labels in [] w = nchar(s) # widths of labels n = max(w) # right-pad spaces for same width of all labels so a wider label of the @@ -1107,17 +1132,32 @@ txt_pb = function(total, labels) { s = paste0(s, strrep(' ', n - w)) w2 = getOption('width') con = getOption('knitr.progress.output', '') + cat_line = function(...) cat(..., sep = '', file = con) + # test if it is a "terminal" connection (whether \r is supported) + simple = (function() { + # a global option to decide whether to use the simple progress output + if (!is.null(res <- getOption('knitr.progress.simple'))) return(res) + if (identical(con, '')) con = stdout() + if (!inherits(con, 'connection')) return(TRUE) + if (isatty(con)) return(FALSE) + # when RStudio is available, return FALSE + is.null(tryCatch(rstudioapi::versionInfo(), error = function(e) NULL)) + })() + # use simple progress output without the bar but only progress and labels + if (simple) return(list( + update = function(i) cat_line(i, '/', total, s[i], '\n') + )) pb = txtProgressBar( 0, total, 0, '.', width = max(w2 - 10 - n, 10), style = 3, file = con ) list( update = function(i) { setTxtProgressBar(pb, i) - cat(s[i], file = con) # append chunk label to the progress bar + cat_line(s[i]) # append chunk label to the progress bar }, done = function() { # wipe the progress bar - cat(paste0('\r', strrep(' ', max(w2, 10) + 10 + n)), file = con) + cat_line('\r', strrep(' ', max(w2, 10) + 10 + n)) close(pb) } ) diff --git a/build/vignette.rds b/build/vignette.rds index 4a595ca53915323dd59194bfcbeaa6e3c7c1bfe5..a028e9f28e488e52d82f10ff5eca0dc4e22e8328 100644 GIT binary patch literal 514 zcmV+d0{#6TiwFP!000001FcifZ__Xo_S$Z+iLHfk9Ma>$kHdQ74?vA3*xG68D#UH_ z5_h$h*pcH=dgH(5MtO1U>^TygrpQkGy&rz><@>%LFvfap(8nDY>mTE`hiimupAB#^ zc66_#y(x`Uc04aKj}B|poFZs6fnPST5zCaDj2MnGZt=OzMb*u6BYu`#QRh*UWo3(e zJg;|;ziRM;oBK?!6}>mpX{t}toL7}hX{yGMOC`8*c--CV$wOsz0atZ@FcWsAv&!2} zF0}=&;A`Dv_K;es6<7_fiV*J(Fc(Wg`34rQZ&*va0=p7$&VTUh z)X37pRNfkHHjvOb-KTEc-a8)nkkEf_Y>zE^l;np)$b}^phg*h=T7MVSt3fI zT9H4$5Sz6&c#bdHH+nq|mmT8j{laa#-Tv-YVOR64nxfb}|TxOX(&k9=CJj1D+q2Pj1W%0PXx8qf~6Ofiu$7@NMm?NiF@s-PQ~+rDAV^%C@w!B_f7 zuQSCf4HJH+sM3($y-+L&be+6y{q)nf9{0-U!<&J zq80heZ)~%c%ADhi_LW?Z!exhMCBMwJ-EMz(E3yOj6$S91`JtnQGV$j0=PwS_Q diff --git a/inst/CITATION b/inst/CITATION index ec1b64a..70200f9 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -1,20 +1,18 @@ -citHeader("To cite the 'knitr' package in publications use:") - year = sub('.*(2[[:digit:]]{3})-.*', '\\1', meta$Date, perl = TRUE) vers = paste('R package version', meta$Version) +if (length(year) == 0) year = format(Sys.Date(), '%Y') -citEntry( - entry = 'manual', +bibentry( + 'manual', title = paste('knitr:', meta$Title), author = Filter(function(p) 'aut' %in% p$role, as.person(meta$Author)), year = year, note = vers, - url = meta$URL, - textVersion = paste('Yihui Xie (', year, '). knitr: ', meta$Title, '. ', vers, '.', sep = '') + url = meta$URL ) -citEntry( - entry = 'book', +bibentry( + 'book', title = 'Dynamic Documents with {R} and knitr', author = 'Yihui Xie', publisher = 'Chapman and Hall/CRC', @@ -27,8 +25,8 @@ citEntry( '2nd edition. Chapman and Hall/CRC. ISBN 978-1498716963') ) -citEntry( - entry = 'incollection', +bibentry( + 'incollection', booktitle = 'Implementing Reproducible Computational Research', editor = 'Victoria Stodden and Friedrich Leisch and Roger D. Peng', title = 'knitr: A Comprehensive Tool for Reproducible Research in {R}', diff --git a/inst/doc/datatables.html b/inst/doc/datatables.html index c53a25d..74735e1 100644 --- a/inst/doc/datatables.html +++ b/inst/doc/datatables.html @@ -3,106 +3,155 @@ - jQuery DataTables - - - - - - + - - -
-
-

jQuery DataTables

-
-

jQuery DataTables

+

jQuery DataTables

We can use the JavaScript library DataTables to generate enhanced tables in HTML. In the example below, we create a table for the mtcars data:

library(knitr)
 kable(mtcars, 'html', table.attr='id="mtcars_table"')
@@ -699,17 +748,10 @@ 

jQuery DataTables

This vignette is only a toy example. I’d recommend you to use the DT package instead: https://github.com/rstudio/DT

-
-
-
- - - + + - diff --git a/inst/doc/docco-classic.html b/inst/doc/docco-classic.html index cdff2c7..7c15fe9 100644 --- a/inst/doc/docco-classic.html +++ b/inst/doc/docco-classic.html @@ -5,9 +5,74 @@ - - +#!mathjax# + + - + - +
@@ -149,9 +215,9 @@ %\VignetteEngine{knitr::docco_classic} %\VignetteIndexEntry{R Markdown with the Docco Classic Style} --> -

R Markdown with the Docco Classic Style

+

R Markdown with the Docco Classic Style

This is an example of Markdown vignettes using the Docco style.

-

Docco

+

Docco

To use the Docco style for Markdown vignettes in an R package, you need to

  • add *.Rmd files under the vignettes directory
  • @@ -161,7 +227,7 @@

    Docco

    After building and installing the package, you can view vignettes via

    browseVignettes(package = 'Your_Package')
     
    -

    Examples

    +

    Examples

    Below are some code chunks as examples.

    cat('_hello_ **markdown**!', '\n')
     
    @@ -191,7 +257,7 @@

    Examples

    n=300; set.seed(123)
     par(mar=c(4,4,.1,.1))
     plot(rnorm(n), rnorm(n), pch=21, cex=5*runif(n), col='white', bg='gray')
    -

    How does it work

    +

    How does it work

    The markdown package (>= v0.6.2) supports custom HTML templates, and the docco engine in knitr uses a custom template to compile Markdown to HTML:

    head(knitr::rocco, 5)
     
    @@ -209,7 +275,7 @@

    Examples

- - + + diff --git a/inst/doc/docco-linear.html b/inst/doc/docco-linear.html index 6b8e2d5..a42dd83 100644 --- a/inst/doc/docco-linear.html +++ b/inst/doc/docco-linear.html @@ -12,16 +12,12 @@ .page pre{width:100%;max-width:768px;} pre, code{font-size:90%;} - - + + - - - - + +#!mathjax# -
@@ -29,9 +25,9 @@ %\VignetteEngine{knitr::docco_linear} %\VignetteIndexEntry{R Markdown with the Docco Linear Style} --> -

R Markdown with the Docco Linear Style

+

R Markdown with the Docco Linear Style

This is an example of Markdown vignettes using the Docco style.

-

Docco

+

Docco

To use the Docco style for Markdown vignettes in an R package, you need to

  • add *.Rmd files under the vignettes directory
  • @@ -41,7 +37,7 @@

    Docco

    After building and installing the package, you can view vignettes via

    browseVignettes(package = 'Your_Package')
     
    -

    Examples

    +

    Examples

    Below are some code chunks as examples.

    cat('_hello_ **markdown**!', '\n')
     
    @@ -71,7 +67,7 @@

    Examples

    plot(rnorm(n), rnorm(n), pch=21, cex=5*runif(n), col='white', bg='gray')

    plot of chunk unnamed-chunk-2

    -

    How does it work

    +

    How does it work

    The markdown package (>= v0.6.2) supports custom HTML templates, and the docco engine in knitr uses a custom template to compile Markdown to HTML:

    knit2html(..., template = system.file('misc', 'docco-template.html', package='knitr'))
     
    diff --git a/inst/doc/knit_expand.html b/inst/doc/knit_expand.html index 754b92b..4526281 100644 --- a/inst/doc/knit_expand.html +++ b/inst/doc/knit_expand.html @@ -3,106 +3,155 @@ - Demos of <code>knit_expand()</code> - - - - - - + - - -
    -
    -

    Demos of knit_expand()

    -
    -

    Demos of knit_expand()

    +

    Demos of knit_expand()

    A few simple examples:

    library(knitr)
     knit_expand(text = 'The value of pi is {{pi}}.')
    @@ -111,7 +160,7 @@ 

    Demos of knit_expand()

    knit_expand(text = 'The value of a is {{a}}, so a + 1 is {{a+1}}.', a = rnorm(1))
     
    -
    ## [1] "The value of a is -0.0285346304466519, so a + 1 is 0.971465369553348."
    +
    ## [1] "The value of a is -0.953389750100317, so a + 1 is 0.046610249899683."
     
    knit_expand(text = 'The area of a circle with radius {{r}} is {{pi*r^2}}', r = 5)
     
    @@ -135,7 +184,7 @@

    Demos of knit_expand()

    Arbitrary R code:

    knit_expand(text = 'you cannot see the value of x {{x=rnorm(1)}}but it is indeed created: x = {{x}}')
     
    -
    ## [1] "you cannot see the value of x but it is indeed created: x = -0.0747822117264385"
    +
    ## [1] "you cannot see the value of x but it is indeed created: x = -0.0134840593441561"
     
    res = knit_expand(text = c(' x | x^2', '{{x=1:5;paste(sprintf("%2d | %3d", x, x^2), collapse = "\n")}}'))
     cat(res)
    @@ -316,17 +365,10 @@ 

    Demos of knit_expand()

    ## (Intercept) carb ## 25.87 -2.06 ```
    -
    -
    -
    - - - + + - diff --git a/inst/doc/knit_print.html b/inst/doc/knit_print.html index a838b21..8ad1642 100644 --- a/inst/doc/knit_print.html +++ b/inst/doc/knit_print.html @@ -12,7 +12,7 @@ - + Custom Print Methods @@ -378,7 +378,7 @@

    Custom Print Methods

    Yihui Xie

    -

    2023-01-19

    +

    2023-05-23

    @@ -399,7 +399,7 @@

    2023-01-19

    Before knitr v1.6, printing objects in R code chunks basically emulates the R console. For example, a data frame is printed like this1:

    -
    head(mtcars)
    +
    head(mtcars)
                       mpg cyl disp  hp drat    wt  qsec vs am gear carb
     Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
     Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
    @@ -421,8 +421,8 @@ 

    Customize Printing

    or x and .... The default value for the render option is knit_print, an S3 function in knitr:

    -
    library(knitr)
    -knit_print  # an S3 generic function
    +
    library(knitr)
    +knit_print  # an S3 generic function
    ## function (x, ...) 
     ## {
     ##     if (need_screenshot(x, ...)) {
    @@ -432,9 +432,9 @@ 

    Customize Printing

    ## UseMethod("knit_print") ## } ## } -## <bytecode: 0x7fe6d39c8048> +## <bytecode: 0x7f897a13c670> ## <environment: namespace:knitr>
    -
    methods(knit_print)
    +
    methods(knit_print)
    ##  [1] knit_print.css*            knit_print.data.frame*    
     ##  [3] knit_print.default*        knit_print.grouped_df*    
     ##  [5] knit_print.html*           knit_print.knit_asis*     
    @@ -443,46 +443,46 @@ 

    Customize Printing

    ## [11] knit_print.shiny.tag* knit_print.shiny.tag.list* ## [13] knit_print.tbl_sql* ## see '?methods' for accessing help and source code
    -
    getS3method('knit_print', 'default')  # the default method
    +
    getS3method('knit_print', 'default')  # the default method
    ## function (x, ..., inline = FALSE) 
     ## {
     ##     if (inline) 
     ##         x
     ##     else normal_print(x)
     ## }
    -## <bytecode: 0x7fe6d1fbbc98>
    +## <bytecode: 0x7f8974773f08>
     ## <environment: namespace:knitr>
    -
    normal_print
    +
    normal_print
    ## function (x, ...) 
     ## if (isS4(x)) methods::show(x) else print(x)
    -## <bytecode: 0x7fe6ce4c80e8>
    +## <bytecode: 0x7f897786eb18>
     ## <environment: namespace:evaluate>

    As we can see, knit_print() has a default method, which is basically print() or show(), depending on whether the object is an S4 object. This means it does nothing special when printing R objects:

    -
    knit_print(1:10)
    -##  [1]  1  2  3  4  5  6  7  8  9 10
    -knit_print(head(mtcars))
    -##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
    -## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
    -## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
    -## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
    -## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
    -## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
    -## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
    +
    knit_print(1:10)
    +##  [1]  1  2  3  4  5  6  7  8  9 10
    +knit_print(head(mtcars))
    +##                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
    +## Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
    +## Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
    +## Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
    +## Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
    +## Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
    +## Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

    S3 generic functions are extensible in the sense that we can define custom methods for them. A method knit_print.foo() will be applied to the object that has the class foo. Here is quick example of how we can print data frames as tables:

    -
    library(knitr)
    -# define a method for objects of the class data.frame
    -knit_print.data.frame = function(x, ...) {
    -  res = paste(c('', '', kable(x)), collapse = '\n')
    -  asis_output(res)
    -}
    -# register the method
    -registerS3method("knit_print", "data.frame", knit_print.data.frame)
    +
    library(knitr)
    +# define a method for objects of the class data.frame
    +knit_print.data.frame = function(x, ...) {
    +  res = paste(c('', '', kable(x)), collapse = '\n')
    +  asis_output(res)
    +}
    +# register the method
    +registerS3method("knit_print", "data.frame", knit_print.data.frame)

    If you define a method in a code chunk in a knitr document, the call to registerS3method() will be necessary for R >= 3.5.0, because the S3 dispatch mechanism has changed since R @@ -501,17 +501,17 @@

    Customize Printing

    changed. We print a number, a character vector, a list, a data frame, and write a character value using cat() in the chunk below:

    -
    1 + 1
    +
    1 + 1
    ## [1] 2
    -
    head(letters)
    +
    head(letters)
    ## [1] "a" "b" "c" "d" "e" "f"
    -
    list(a = 1, b = 9:4)
    +
    list(a = 1, b = 9:4)
    ## $a
     ## [1] 1
     ## 
     ## $b
     ## [1] 9 8 7 6 5 4
    -
    head(mtcars)
    +
    head(mtcars)
    @@ -630,7 +630,7 @@

    Customize Printing

    -
    cat('This is cool.')
    +
    cat('This is cool.')
    ## This is cool.

    We see all objects except the data frame were printed “normally”2. The data frame was printed as a real table. Note you do not have to use @@ -658,26 +658,26 @@

    Customize Printing

Depending on your application, you may optionally use these arguments. Here are some examples:

-
knit_print.classA = function(x, ...) {
-  # ignore options and inline
-}
-knit_print.classB = function(x, options, ...) {
-  # use the chunk option out.height
-  asis_output(paste0(
-    '<iframe src="https://yihui.org" height="', options$out.height, '"></iframe>',
-  ))
-}
-knit_print.classC = function(x, inline = FALSE, ...) {
-  # different output according to inline=TRUE/FALSE
-  if (inline) {
-    'inline output for classC'
-  } else {
-    'chunk output for classC'
-  }
-}
-knit_print.classD = function(x, options, inline = FALSE, ...) {
-  # use both options and inline
-}
+
knit_print.classA = function(x, ...) {
+  # ignore options and inline
+}
+knit_print.classB = function(x, options, ...) {
+  # use the chunk option out.height
+  asis_output(paste0(
+    '<iframe src="https://yihui.org" height="', options$out.height, '"></iframe>',
+  ))
+}
+knit_print.classC = function(x, inline = FALSE, ...) {
+  # different output according to inline=TRUE/FALSE
+  if (inline) {
+    'inline output for classC'
+  } else {
+    'chunk output for classC'
+  }
+}
+knit_print.classD = function(x, options, inline = FALSE, ...) {
+  # use both options and inline
+}

Note that when using your (or another) knit_print() method inline (if it supports that), you must not call knit_print() on the object, but just have @@ -705,29 +705,29 @@

The render option

use other render functions. For example, we create a dummy function that always says “I do not know what to print” no matter what objects it receives:

-
dummy_print = function(x, ...) {
-  cat("I do not know what to print!")
-  # this function implicitly returns an invisible NULL
-}
+
dummy_print = function(x, ...) {
+  cat("I do not know what to print!")
+  # this function implicitly returns an invisible NULL
+}

Now we use the chunk option render = dummy_print:

-
1 + 1
-## I do not know what to print!
-head(letters)
-## I do not know what to print!
-list(a = 1, b = 9:4)
-## I do not know what to print!
-head(mtcars)
-## I do not know what to print!
-cat('This is cool.')
-## This is cool.
+
1 + 1
+## I do not know what to print!
+head(letters)
+## I do not know what to print!
+list(a = 1, b = 9:4)
+## I do not know what to print!
+head(mtcars)
+## I do not know what to print!
+cat('This is cool.')
+## This is cool.

Note the render function is only applied to visible objects. There are cases in which the objects returned are invisible, e.g. those wrapped in invisible().

-
1 + 1
+
1 + 1
## [1] 2
-
invisible(1 + 1)
-invisible(head(mtcars))
-x = 1:10  # invisibly returns 1:10
+
invisible(1 + 1)
+invisible(head(mtcars))
+x = 1:10  # invisibly returns 1:10

Metadata

@@ -745,17 +745,17 @@

Metadata

dependencies of an object beside printing the object itself.

One way to specify the dependencies is through the meta argument of asis_output(). Here is a pseudo example:

-
# pseudo code
-knit_print.ggvis = function(x, ...) {
-  res = ggvis::print_this_object(x)
-  knitr::asis_output(res, meta = list(
-    ggvis = list(
-      version = '0.1.0',
-      js  = system.file('www', 'js',  'ggvis.js',  package = 'ggvis'),
-      css = system.file('www', 'www', 'ggvis.css', package = 'ggvis')
-    )
-  ))
-}
+
# pseudo code
+knit_print.ggvis = function(x, ...) {
+  res = ggvis::print_this_object(x)
+  knitr::asis_output(res, meta = list(
+    ggvis = list(
+      version = '0.1.0',
+      js  = system.file('www', 'js',  'ggvis.js',  package = 'ggvis'),
+      css = system.file('www', 'www', 'ggvis.css', package = 'ggvis')
+    )
+  ))
+}

Then when knitr prints a ggvis object, the meta information will be collected and stored. After knitting is done, we can obtain a list of all the dependencies via @@ -765,46 +765,46 @@

Metadata

dependencies into the HTML header). We give a few more quick and dirty examples below to see how knit_meta() works.

Now we define a print method for foo objects:

-
library(knitr)
-knit_print.foo = function(x, ...) {
-  res = paste('> **This is a `foo` object**:', x)
-  asis_output(res, meta = list(
-    js  = system.file('www', 'shared', 'shiny.js',  package = 'shiny'),
-    css = system.file('www', 'shared', 'shiny.css', package = 'shiny')
-  ))
-}
+
library(knitr)
+knit_print.foo = function(x, ...) {
+  res = paste('> **This is a `foo` object**:', x)
+  asis_output(res, meta = list(
+    js  = system.file('www', 'shared', 'shiny.js',  package = 'shiny'),
+    css = system.file('www', 'shared', 'shiny.css', package = 'shiny')
+  ))
+}

See what happens when we print foo objects:

-
new_foo = function(x) structure(x, class = 'foo')
-new_foo('hello')
+
new_foo = function(x) structure(x, class = 'foo')
+new_foo('hello')

This is a foo object: hello

Check the metadata now:

-
str(knit_meta(clean = FALSE))
+
str(knit_meta(clean = FALSE))
## List of 2
 ##  $ js : chr "/Users/yihui/R/shiny/www/shared/shiny.js"
 ##  $ css: chr ""
 ##  - attr(*, "knit_meta_id")= chr [1:2] "unnamed-chunk-9" "unnamed-chunk-9"

Another foo object:

-
new_foo('world')
+
new_foo('world')

This is a foo object: world

Similarly for bar objects:

-
knit_print.bar = function(x, ...) {
-  asis_output(x, meta = list(head = '<script>console.log("bar!")</script>'))
-}
-new_bar = function(x) structure(x, class = 'bar')
-new_bar('> **hello** world!')
+
knit_print.bar = function(x, ...) {
+  asis_output(x, meta = list(head = '<script>console.log("bar!")</script>'))
+}
+new_bar = function(x) structure(x, class = 'bar')
+new_bar('> **hello** world!')

hello world!

-
new_bar('> hello **world**!')
+
new_bar('> hello **world**!')

hello world!

The final version of the metadata, and clean it up:

-
str(knit_meta())
+
str(knit_meta())
## List of 6
 ##  $ js  : chr "/Users/yihui/R/shiny/www/shared/shiny.js"
 ##  $ css : chr ""
@@ -813,7 +813,7 @@ 

Metadata

## $ head: chr "<script>console.log(\"bar!\")</script>" ## $ head: chr "<script>console.log(\"bar!\")</script>" ## - attr(*, "knit_meta_id")= chr [1:6] "unnamed-chunk-9" "unnamed-chunk-9" "unnamed-chunk-11" "unnamed-chunk-11" ...
-
str(knit_meta()) # empty now, because clean = TRUE by default
+
str(knit_meta()) # empty now, because clean = TRUE by default
##  list()
@@ -834,12 +834,12 @@

For package authors

method return structure(x, class = 'knit_asis'), and if there are additional metadata, just put it in the knit_meta attribute; here is the source code of this function:

-
knitr::asis_output
+
knitr::asis_output
## function (x, meta = NULL, cacheable = NA) 
 ## {
 ##     structure(x, class = "knit_asis", knit_meta = meta, knit_cacheable = cacheable)
 ## }
-## <bytecode: 0x7fe6ce76b120>
+## <bytecode: 0x7f897a6420a8>
 ## <environment: namespace:knitr>

Note that you can actually put knitr in the Suggests field in DESCRIPTION, and use diff --git a/inst/doc/knitr-intro.html b/inst/doc/knitr-intro.html index f965023..c9a4224 100644 --- a/inst/doc/knitr-intro.html +++ b/inst/doc/knitr-intro.html @@ -12,7 +12,7 @@ - + Not An Introduction to knitr @@ -400,7 +400,7 @@

Not An Introduction to knitr

Yihui Xie

-

2023-01-19

+

2023-05-23

@@ -414,13 +414,13 @@

2023-01-19

Anyway, here is a code chunk that shows you can compile vignettes with knitr as well using R 3.0.x, which supports non-Sweave vignettes:

-
options(digits = 4)
-rnorm(20)
-
##  [1]  0.61769 -0.80560  0.33799  0.82468  0.27238 -0.01469 -0.53509 -0.28496
-##  [9] -1.00412 -0.92200 -0.33577 -0.16676 -0.40667  0.31883  0.73298  1.09309
-## [17]  0.71330 -1.10522  0.70505  1.38676
-
fit = lm(dist ~ speed, data = cars)
-b = coef(fit)
+
options(digits = 4)
+rnorm(20)
+
##  [1] -1.60955 -1.89175 -1.37949  0.58515  1.66678  0.37082 -1.19981  0.16716
+##  [9]  1.17756 -0.29093 -1.64570  2.26209 -1.79446  1.77168  0.39199  0.81839
+## [17]  0.06991  1.26058 -1.53722 -2.00377
+
fit = lm(dist ~ speed, data = cars)
+b = coef(fit)
@@ -450,9 +450,9 @@

2023-01-19

Regression coefficients.

The fitted regression equation is \(Y=-17.5791+3.9324x\).

-
par(mar=c(4, 4, 1, .1))
-plot(cars, pch = 20)
-abline(fit, col = 'red')
+
par(mar=c(4, 4, 1, .1))
+plot(cars, pch = 20)
+abline(fit, col = 'red')
A scatterplot with a regression line.

diff --git a/inst/doc/knitr-markdown.html b/inst/doc/knitr-markdown.html index 8d2971e..16be241 100644 --- a/inst/doc/knitr-markdown.html +++ b/inst/doc/knitr-markdown.html @@ -3,102 +3,150 @@ - Package vignettes - - - - - - - + - - + -

-
-

Package vignettes

-