diff --git a/DESCRIPTION b/DESCRIPTION index 3d99d0bca4..e751e3c154 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.43.14 +Version: 1.43.15 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"), diff --git a/NEWS.md b/NEWS.md index 01b8a74dbc..28abd52646 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,8 @@ ## NEW FEATURES +- `kable()` can generate Emacs org-mode tables now via `kable(..., format = 'org')` (thanks, @xvrdm #1372, @maxecharel #2258). + - Added support for the `qmd` (Quarto) output format to `spin()`, e.g., `spin('script.R', format = 'qmd') (thanks, @cderv, #2284). - `write_bib()` has a new argument `packageURL` to control whether to use a URL from the `DESCRIPTION` file or the one generated by `utils::citation()` (thanks, @dmurdoch, #2264). diff --git a/R/table.R b/R/table.R index 68d1601f39..c2be226363 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), \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. +#' simple tables), \code{rst}, \code{jira}, and \code{org} (Emacs Org-mode). +#' 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. @@ -408,7 +408,7 @@ kable_mark = function(x, sep.row = c('=', '=', '='), sep.col = ' ', padding = 0 ifelse(align == 'c', 2, 1) } l = pmax(l + padding, 3) # at least of width 3 for Github Markdown - s = unlist(lapply(l, function(i) paste(rep(sep.row[2], i), collapse = ''))) + s = strrep(sep.row[2], l) 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) @@ -431,7 +431,7 @@ kable_rst = function(x, rownames.name = '\\', ...) { } # Pandoc's pipe table -kable_pipe = function(x, caption = NULL, padding = 1, ...) { +kable_pipe = function(x, caption = NULL, padding = 1, caption.label = 'Table:', ...) { if (is.null(colnames(x))) colnames(x) = rep('', ncol(x)) res = kable_mark(x, c(NA, '-', NA), '|', padding, align.fun = function(s, a) { if (is.null(a)) return(s) @@ -442,7 +442,7 @@ kable_pipe = function(x, caption = NULL, padding = 1, ...) { s }, ...) res = sprintf('|%s|', res) - kable_pandoc_caption(res, caption) + kable_pandoc_caption(res, caption, caption.label) } # Pandoc's simple table @@ -468,9 +468,20 @@ kable_jira = function(x, caption = NULL, padding = 1, ...) { kable_pandoc_caption(tab, caption) } -kable_pandoc_caption = function(x, caption) { +# Emacs Org-mode table +kable_org = function(...) { + res = kable_pipe(..., caption.label = '#+CAPTION:') + i = grep('^[-:|]+$', res) # find the line like |--:|---| under header + if (length(i)) { + i = i[1] + res[i] = gsub('(-|:)[|](-|:)', '\\1+\\2', res[i]) # use + as separator + } + res +} + +kable_pandoc_caption = function(x, caption, label = 'Table:') { if (identical(caption, NA)) caption = NULL - if (length(caption)) c(paste('Table:', caption), "", x) else x + if (length(caption)) c(paste(label, caption), '', x) else x } # pad a matrix diff --git a/man/kable.Rd b/man/kable.Rd index 109491c445..e43b362675 100644 --- a/man/kable.Rd +++ b/man/kable.Rd @@ -28,11 +28,11 @@ returned value from \code{kable()}.} \item{format}{A character string. Possible values are \code{latex}, \code{html}, \code{pipe} (Pandoc's pipe tables), \code{simple} (Pandoc's -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.} +simple tables), \code{rst}, \code{jira}, and \code{org} (Emacs Org-mode). +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.} \item{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 diff --git a/tests/testit/test-table.R b/tests/testit/test-table.R index b5cb419f1f..dc4dba44d6 100644 --- a/tests/testit/test-table.R +++ b/tests/testit/test-table.R @@ -39,6 +39,10 @@ assert('kable() works with the jira format', { (kable2(m, 'jira') %==% c('|| || x|| y||', '|a | 1| 2|')) }) +assert('kable() works with the org format', { + (kable2(m, 'org') %==% c('| | x| y|', '|:--+--:+--:|', '|a | 1| 2|')) +}) + assert('kable() does not add extra spaces to character columns', { (kable2(data.frame(x = c(1.2, 4.87), y = c('fooooo', 'bar')), 'latex') %==% ' \\begin{tabular}{r|l} @@ -136,7 +140,7 @@ assert('kable() works on matrices with NA colname', { x1 = matrix(NA, 0, 0) x2 = matrix(NA, 0, 1) x3 = matrix(NA, 1, 0) -for (f in c('simple', 'html', 'latex', 'rst', 'jira')) { +for (f in c('simple', 'html', 'latex', 'rst', 'jira', 'org')) { kable(x1, f) kable(x2, f) kable(x3, f)