Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
yihui authored Apr 1, 2024
2 parents d7437a6 + 74bcff8 commit e1cc7e6
Show file tree
Hide file tree
Showing 20 changed files with 161 additions and 408 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/knitr-examples.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ jobs:
uses: ./.github/actions/checkout-knitr-examples

- name: Install knitr-example dev
run: pak::pak(readLines("knitr-examples/R-packages"))
run: install.packages(readLines("knitr-examples/R-packages"))
shell: Rscript {0}

- name: Install system dependencies
Expand Down
10 changes: 4 additions & 6 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: knitr
Type: Package
Title: A General-Purpose Package for Dynamic Report Generation in R
Version: 1.45.10
Version: 1.45.17
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"),
Expand Down Expand Up @@ -120,7 +120,7 @@ Imports:
highr,
methods,
tools,
xfun (>= 0.39),
xfun (>= 0.43),
yaml (>= 2.1.19)
Suggests:
bslib,
Expand All @@ -131,7 +131,6 @@ Suggests:
gifski,
gridSVG,
htmlwidgets (>= 0.7),
curl,
jpeg,
JuliaCall (>= 0.11.1),
magick,
Expand All @@ -152,8 +151,7 @@ Suggests:
tinytex (>= 0.46),
webshot,
rstudioapi,
svglite,
xml2 (>= 1.2.0)
svglite
License: GPL
URL: https://yihui.org/knitr/
BugReports: https://github.com/yihui/knitr/issues
Expand Down Expand Up @@ -199,4 +197,4 @@ Collate:
'utils-upload.R'
'utils-vignettes.R'
'zzz.R'
RoxygenNote: 7.2.3
RoxygenNote: 7.3.1
18 changes: 16 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@

- Added a new chunk option `tab.cap` to specify the table caption for `kable()` (thanks, @ulyngs, #1679). Previously, the caption could only be specified via the `caption` argument of `kable()`. Now you can set it in the chunk header if you want. Please note that this chunk option only works with a single `kable()` in each code chunk, and its value must be of length 1.

- `knitr::spin()` now recognizes `# %%` as a valid code chunk delimiter (thanks, @kylebutts, #2307).
- `spin()` now recognizes `# %%` as a valid code chunk delimiter (thanks, @kylebutts, #2307).

- `spin()` also recognizes `#|` comments as code chunks now (thanks, @kylebutts, #2320).

- Chunk hooks can have the `...` argument now. Previously, only arguments `before`, `options`, `envir`, and `name` are accepted. If a chunk hook function has the `...` argument, all the aforementioned four arguments are passed to the hook. This means the hook function no longer has to have the four arguments explicitly in its signature, e.g., `function(before, ...)` is also valid if only the `before` argument is used inside the hook. See <https://yihui.org/knitr/hooks/#chunk-hooks> for more information.

- For package vignettes, PNG plots will be optimized by `optipng` and `pngquant` if they are installed and can be found from the system `PATH` variable. This can help reduce the package size if vignettes contain PNG plots (thanks, @nanxstats, <https://nanx.me/blog/post/rpkgs-pngquant-ragg/>).

## BUG FIXES

- `spin()` stopped working with input that cannot be parsed as R code due to #1605. Now it works again (thanks, @Hemken, #1773).

- `write_bib()` generated empty entries for packages without URLs (thanks, @bastistician, #2304).

- The `family` argument was not passed to the `pdf` device (thanks, @sebkopf, rstudio/rmarkdown#2526).
Expand All @@ -20,6 +24,10 @@

- `kable()` fails when the value of the `caption` argument is of length > 1 (thanks, @LeeMendelowitz, #2312).

- `include_graphics()` may provide an incorrect plot width to LaTeX when the locale setting for `LC_NUMERIC` is not `C` because the decimal separator may not be a dot (thanks, @tdhock, rstudio/rmarkdown#2525).

- When TinyTeX and the LaTeX package **pdfcrop** are installed, `knitr::pdf_crop()` is unable to find `pdfcrop` (thanks, @dmkaplan2000, rstudio/tinytex#435).

## MAJOR CHANGES

- Unbalanced chunk delimiters (fences) in R Markdown documents are no longer allowed, as announced two years ago at <https://yihui.org/en/2021/10/unbalanced-delimiters/> (#2306). This means the opening delimiter must strictly match the closing delimiter, e.g., if a code chunk starts with four backticks, it must also end with four; or if a chunk header is indented by two spaces, the closing fence must be indented by exactly two spaces. For authors who cannot update their R Markdown documents for any reason at the moment, setting `options(knitr.unbalanced.chunk = TRUE)` (e.g., in `.Rprofile`) can temporarily prevent **knitr** from throwing an error, but it is strongly recommended that you fix the problems as soon as possible, because this workaround will be removed in future.
Expand All @@ -28,7 +36,13 @@

- Fixed broken vignettes, improved CSS for HTML vignettes, and reduced the file sizes.

- Faster processing of cache dependencies (thanks, @knokknok, #2318)
- SQL code chunks that run `ALTER` statements are only executed and not tried to fecth a result (thanks, @maxschmi, #2330).

- The function `imgur_upload()` has been moved to (and enhanced in) the **xfun** package as `xfun::upload_imgur()` so it is no longer tied to **knitr** and can be reused by other pakages. Now `knitr::imgur_upload()` is only a wrapper function of `xfun::upload_imgur()`. You are recommended to use the latter (#2325).

- `spin()` dropped support for `#-` as the chunk delimiter token. Please use `#+` or `# %%` or `#|` instead.

- Faster processing of cache dependencies (thanks, @knokknok, #2318).

# CHANGES IN knitr VERSION 1.45

Expand Down
2 changes: 1 addition & 1 deletion R/engine.R
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ is_sql_update_query = function(query) {
query = gsub('^\\s*--.*\n', '', query)
# remove multi-line comments
if (grepl('^\\s*\\/\\*.*', query)) query = gsub('.*\\*\\/', '', query)
grepl('^\\s*(INSERT|UPDATE|DELETE|CREATE|DROP).*', query, ignore.case = TRUE)
grepl('^\\s*(INSERT|UPDATE|DELETE|CREATE|DROP|ALTER).*', query, ignore.case = TRUE)
}

# sql engine
Expand Down
3 changes: 1 addition & 2 deletions R/highlight.R
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ styler_assistant_latex = function(x) {

col2latexrgb = function(hex) {
# as.character(0.123) -> 0,123 when "OutDec = ,", so make sure . is used
outdec = options(OutDec = '.'); on.exit(options(outdec))
col = col2rgb(hex)[, 1] / 255
paste(round(col, 3), collapse = ',')
xfun::decimal_dot(paste(round(col, 3), collapse = ','))
}
45 changes: 18 additions & 27 deletions R/hooks-md.R
Original file line number Diff line number Diff line change
Expand Up @@ -144,19 +144,6 @@ css_text_align = function(align) {
if (align == 'default') '' else sprintf(' style="text-align: %s"', align)
}

# turn a class string "a b" to c(".a", ".b") for Pandoc fenced code blocks
block_class = function(x) {
if (length(x) > 0) gsub('^[.]*', '.', unlist(strsplit(x, '\\s+')))
}

# concatenate block attributes (including classes) for Pandoc fenced code blocks
block_attr = function(attr, class = NULL, lang = NULL) {
x = c(block_class(class), attr)
if (length(x) == 0) return(lang)
x = c(sprintf('.%s', lang), x)
paste0('{', paste0(x, collapse = ' '), '}')
}

#' @rdname output_hooks
#' @export
#' @param strict Boolean; whether to use strict markdown or reST syntax. For markdown, if
Expand Down Expand Up @@ -194,12 +181,12 @@ hooks_markdown = function(strict = FALSE, fence_char = '`') {
hook.r = function(x, options) {
lang = tolower(options$lang %n% eng2lang(options$engine))
if (!options$highlight) lang = 'text'
fenced_block(x, options$attr.source, options$class.source, lang, .char = fence_char)
fenced_block(x, options$attr.source, c(lang, options$class.source), .char = fence_char)
}
list(
source = function(x, options) {
x = hilight_source(x, 'markdown', options)
if (strict) hook.t(x) else hook.r(c(x, ''), options)
if (strict) hook.t(x) else hook.r(x, options)
},
inline = function(x) {
if (is_latex_output()) .inline.hook.tex(x) else {
Expand All @@ -225,22 +212,26 @@ hooks_markdown = function(strict = FALSE, fence_char = '`') {
)
}

pandoc_div = function(x, .attr = NULL, .class = NULL) {
if (is.null(.attr) && is.null(.class)) return(x)
fenced_block(c(x, ''), .attr, .class, .char = ':', .sep = ' ', .outer = '')
pandoc_div = function(x, attr = NULL, class = NULL) {
if (is.null(attr) && is.null(class)) return(x)
x = fenced_block(x, attr, class, .char = ':')
x = gsub('^\n\n|\n\n$', '', x)
gsub('^(:::+) *', '\\1 ', x) # add a space if necessary
}

# add a fence around content (either fenced code block ``` or Div :::)
fenced_block = function(x, ..., .char = '`', .sep = '', .outer = '\n\n') {
x = one_string(c('', x))
f = create_fence(x, .char)
paste0(.outer, paste(f, block_attr(...), sep = .sep), x, f, .outer)
# turn a class string "a b" to c(".a", ".b") for Pandoc fenced code blocks
block_class = function(x, attr = NULL) {
if (length(x)) x = unlist(strsplit(x, '\\s+'))
if (length(x) > 1 || length(attr)) gsub('^[.]*', '.', x) else x
}

create_fence = function(x, char = '`') {
r = paste0('\n', char, '{3,}')
l = max(if (grepl(r, x)) attr(gregexpr(r, x)[[1]], 'match.length'), 3)
paste(rep(char, l), collapse = '')
# add a fence around content (either fenced code block ``` or Div :::)
fenced_block = function(x, attr = NULL, class = NULL, .char = '`') {
x = sub('\n$', '', x)
x = xfun::fenced_block(x, c(block_class(class, attr), attr), char = .char)
x = one_string(c('', x, '', ''))
# remove the space between ``` and { for backward-compatibility
sub('``` {', '```{', x, fixed = TRUE)
}

# convert some engine names to language names
Expand Down
14 changes: 5 additions & 9 deletions R/output.R
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ process_file = function(text, output) {
if (progress && is.function(pb$update)) pb$update(i)
group = groups[[i]]
knit_concord$set(block = i)
res[i] = handle_error(
res[i] = xfun:::handle_error(
withCallingHandlers(
if (tangle) process_tangle(group) else process_group(group),
error = function(e) if (xfun::pkg_available('rlang', '1.0.0')) rlang::entrace(e)
Expand All @@ -318,7 +318,7 @@ process_file = function(text, output) {
write_utf8(res, output %n% stdout())
paste0('\nQuitting from lines ', loc)
},
if (labels[i] != '') sprintf(' [%s]', labels[i])
if (labels[i] != '') sprintf(' [%s]', labels[i]), get_loc
)
}

Expand All @@ -331,13 +331,9 @@ process_file = function(text, output) {
res
}

# if an expr throws an an error, message the location of the error if possible
handle_error = function(expr, handler, label = '') {
withCallingHandlers(expr, error = function(e) {
# return a string to point out the error location
loc = paste0(current_lines(), label, sprintf(' (%s)', knit_concord$get('infile')))
message(one_string(handler(e, loc)))
})
# return a string to point out the current location in the doc
get_loc = function(label = '') {
paste0(current_lines(), label, sprintf(' (%s)', knit_concord$get('infile')))
}

auto_out_name = function(input, ext = tolower(file_ext(input))) {
Expand Down
Loading

0 comments on commit e1cc7e6

Please sign in to comment.