Skip to content

Commit 356e35a

Browse files
mclementsyihui
andauthored
Allow for column alignment for org table export (#2391)
Co-authored-by: Yihui Xie <xie@yihui.name>
1 parent c47d34f commit 356e35a

File tree

3 files changed

+26
-13
lines changed

3 files changed

+26
-13
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
- Display error traceback when vignettes fail in `R CMD build` (thanks, @hadley, #2390).
88

9+
- `kable()` properly supports column alignment for Org Mode tables now (thanks, @mclements, #2391).
10+
911
## MINOR CHANGES
1012

1113
- Moved implementations of `combine_words()` and `write_bib()` to the **xfun** package as `xfun::join_words()` and `xfun::pkg_bib()`, respectively, since they are not directly relevant to **knitr**. The functions `combine_words()` and `write_bib()` are still kept in **knitr**, and can continue to be used in the future.

R/table.R

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,9 @@ kable_mark = function(x, sep.row = c('=', '=', '='), sep.col = ' ', padding = 0
403403
if (sep.col == '|') for (j in seq_len(ncol(x))) {
404404
x[, j] = gsub('\\|', '&#124;', x[, j])
405405
}
406-
l = if (prod(dim(x)) > 0) apply(x, 2, function(z) max(nchar(remove_urls(z), type = 'width'), na.rm = TRUE))
406+
l = if (prod(dim(x)) > 0) apply(x, 2, function(z) {
407+
max(nchar(remove_urls(z), type = 'width'), na.rm = TRUE)
408+
}) else integer(ncol(x))
407409
cn = colnames(x)
408410
if (length(cn) > 0) {
409411
cn[is.na(cn)] = "NA"
@@ -417,8 +419,10 @@ kable_mark = function(x, sep.row = c('=', '=', '='), sep.col = ' ', padding = 0
417419
}
418420
l = pmax(l + padding, 3) # at least of width 3 for Github Markdown
419421
s = strrep(sep.row[2], l)
420-
res = rbind(if (!is.na(sep.row[1])) s, cn, align.fun(s, align),
421-
x, if (!is.na(sep.row[3])) s)
422+
res = rbind(
423+
if (!is.na(sep.row[1])) s, cn, if (is.null(align)) s else align.fun(s, align),
424+
x, if (!is.na(sep.row[3])) s
425+
)
422426
res = mat_pad(res, l, align)
423427
res = add_mark_col_sep(res, sep.col, sep.head)
424428
if (is.character(newline)) res = gsub('\n', newline, res, fixed = TRUE)
@@ -442,7 +446,6 @@ kable_rst = function(x, rownames.name = '\\', ...) {
442446
kable_pipe = function(x, caption = NULL, padding = 1, caption.label = 'Table:', ...) {
443447
if (is.null(colnames(x))) colnames(x) = rep('', ncol(x))
444448
res = kable_mark(x, c(NA, '-', NA), '|', padding, align.fun = function(s, a) {
445-
if (is.null(a)) return(s)
446449
r = c(l = '^.', c = '^.|.$', r = '.$')
447450
for (i in seq_along(s)) {
448451
s[i] = gsub(r[a[i]], ':', s[i])
@@ -477,14 +480,16 @@ kable_jira = function(x, caption = NULL, padding = 1, ...) {
477480
}
478481

479482
# Emacs Org-mode table
480-
kable_org = function(...) {
481-
res = kable_pipe(..., caption.label = '#+CAPTION:')
482-
i = grep('^[-:|]+$', res) # find the line like |--:|---| under header
483-
if (length(i)) {
484-
i = i[1]
485-
res[i] = gsub('(-|:)[|](-|:)', '\\1+\\2', res[i]) # use + as separator
486-
}
487-
res
483+
kable_org = function(x, caption = NULL, padding = 1, caption.label = '#+CAPTION:', ...) {
484+
has_header = !is.null(colnames(x))
485+
res = kable_mark(x, c(NA, '-', NA), '|', padding, align.fun = function(s, a) {
486+
r = c(l = '<l>', c = '<c>', r = '<r>')
487+
rbind(r[a], if (has_header) s)
488+
}, ...)
489+
if (!is.na(i <- grep('^(---+[|])+---+$', res)[1]))
490+
res[i] = gsub('|', '+', res[i], fixed = TRUE)
491+
res = sprintf('|%s|', res)
492+
kable_pandoc_caption(res, caption, caption.label)
488493
}
489494

490495
kable_pandoc_caption = function(x, caption, label = 'Table:') {

tests/testit/test-table.R

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,13 @@ assert('kable() works with the jira format', {
4040
})
4141

4242
assert('kable() works with the org format', {
43-
(kable2(m, 'org') %==% c('| | x| y|', '|:--+--:+--:|', '|a | 1| 2|'))
43+
(kable2(m, 'org') %==%
44+
c('| | x| y|', '|<l>|<r>|<r>|', '|---+---+---|', '|a | 1| 2|'))
45+
m2 = m; colnames(m2) = NULL # no column names
46+
(kable2(m2, 'org') %==% c('|<l>|<r>|<r>|', '|a | 1| 2|'))
47+
# the case of only one column
48+
(kable2(m[, 1, drop = FALSE], 'org', row.names = FALSE) %==%
49+
c('| x|', '|<r>|', '|---|', '| 1|'))
4450
})
4551

4652
assert('kable() does not add extra spaces to character columns', {

0 commit comments

Comments
 (0)