Merge pull request #197 from leovan/master
Allow no colnames with PDF output when booktabs enabled
diff --git a/DESCRIPTION b/DESCRIPTION
index f4eab25..eba392d 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -14,7 +14,8 @@
person('Rob', 'Shepherd', role = 'ctb'),
person('Yoni', 'Sidi', role = 'ctb'),
person('Brian', 'Salzer', role = 'ctb'),
- person('George', 'Gui', role = 'ctb')
+ person('George', 'Gui', role = 'ctb'),
+ person('Yeliang', 'Fan', role = 'ctb')
)
Description: Build complex HTML or 'LaTeX' tables using 'kable()' from 'knitr'
and the piping syntax from 'magrittr'. Function 'kable()' is a light weight
diff --git a/R/add_indent.R b/R/add_indent.R
index de6fc32..a8a455e 100644
--- a/R/add_indent.R
+++ b/R/add_indent.R
@@ -39,15 +39,17 @@
table_info <- dup_fx_out[[2]]
}
- if (max(positions) > table_info$nrow - 1) {
+ max_position <- table_info$nrow - table_info$position_offset
+
+ if (max(positions) > max_position) {
stop("There aren't that many rows in the table. Check positions in ",
"add_indent_latex.")
}
- for (i in positions) {
- rowtext <- table_info$contents[i + 1]
+ for (i in positions + table_info$position_offset) {
+ rowtext <- table_info$contents[i]
out <- sub(rowtext, latex_indent_unit(rowtext), out, perl = TRUE)
- table_info$contents[i + 1] <- latex_indent_unit(rowtext)
+ table_info$contents[i] <- latex_indent_unit(rowtext)
}
out <- structure(out, format = "latex", class = "knitr_kable")
attr(out, "kable_meta") <- table_info
diff --git a/R/group_rows.R b/R/group_rows.R
index 85962cf..4352105 100644
--- a/R/group_rows.R
+++ b/R/group_rows.R
@@ -162,8 +162,8 @@
}
if (italic) group_label <- paste0("\\\\textit{", group_label, "}")
# Add group label
- rowtext <- table_info$contents[start_row + 1]
if (table_info$booktabs) {
+ rowtext <- table_info$contents[start_row + table_info$position_offset]
pre_rowtext <- paste0(
"\\\\addlinespace[", gap_space, "]\n",
ifelse(hline_before,"\\\\hline\n", ""),
@@ -174,6 +174,7 @@
"}\\\\\\\\\n", ifelse(hline_after, "\\\\hline\n", '')
)
} else {
+ rowtext <- table_info$contents[start_row + 1]
rowtext <- paste0("\\\\hline\n", rowtext)
pre_rowtext <- paste0(
"\\\\hline\n\\\\multicolumn{", table_info$ncol, "}{", latex_align,"}{",
diff --git a/R/kable_styling.R b/R/kable_styling.R
index 3be1202..f3f9136 100644
--- a/R/kable_styling.R
+++ b/R/kable_styling.R
@@ -281,15 +281,24 @@
styling_latex_striped <- function(x, table_info, color) {
# gray!6 is the same as shadecolor ({RGB}{248, 248, 248}) in pdf_document
if (table_info$tabular == "longtable" & !is.na(table_info$caption)) {
- row_color <- sprintf("\\rowcolors{2}{white}{%s}", color)
+ row_color <- sprintf("\\rowcolors{%s}{white}{%s}",
+ 1 + table_info$position_offset, color)
} else {
- row_color <- sprintf("\\rowcolors{2}{%s}{white}", color)
+ if (table_info$position_offset == 0) {
+ row_color <- sprintf("\\rowcolors{1}{white}{%s}", color)
+ } else {
+ row_color <- sprintf("\\rowcolors{2}{%s}{white}", color)
+ }
}
x <- read_lines(x)
if (table_info$booktabs) {
header_rows_start <- which(x == "\\toprule")[1]
- header_rows_end <- which(x == "\\midrule")[1]
+ if (is.null(table_info$colnames)) {
+ header_rows_end <- header_rows_start
+ } else {
+ header_rows_end <- which(x == "\\midrule")[1]
+ }
} else {
header_rows_start <- which(x == "\\hline")[1]
header_rows_end <- which(x == "\\hline")[2]
@@ -344,7 +353,11 @@
x <- read_lines(x)
if (table_info$booktabs) {
header_rows_start <- which(x == "\\toprule")[1]
- header_rows_end <- which(x == "\\midrule")[1]
+ if (is.null(table_info$colnames)) {
+ header_rows_end <- header_rows_start
+ } else {
+ header_rows_end <- which(x == "\\midrule")[1]
+ }
} else {
header_rows_start <- which(x == "\\hline")[1]
header_rows_end <- which(x == "\\hline")[2]
diff --git a/R/magic_mirror.R b/R/magic_mirror.R
index 5cc2337..09eea05 100644
--- a/R/magic_mirror.R
+++ b/R/magic_mirror.R
@@ -89,7 +89,13 @@
kable_info$nrow <- length(kable_info$contents)
kable_info$duplicated_rows <- (sum(duplicated(kable_info$contents)) != 0)
# Column names
- kable_info$colnames <- str_split(kable_info$contents[1], " \\& ")[[1]]
+ if (kable_info$booktabs & !grepl("\\\\midrule", kable_input)) {
+ kable_info$colnames <- NULL
+ kable_info$position_offset <- 0
+ } else {
+ kable_info$colnames <- str_split(kable_info$contents[1], " \\& ")[[1]]
+ kable_info$position_offset <- 1
+ }
# Row names
kable_info$rownames <- str_extract(kable_info$contents, "^[^ &]*")
diff --git a/R/row_spec.R b/R/row_spec.R
index 47832eb..638c611 100644
--- a/R/row_spec.R
+++ b/R/row_spec.R
@@ -190,7 +190,7 @@
table_info <- dup_fx_out[[2]]
}
- row <- row + 1
+ row <- row + table_info$position_offset
for (i in row) {
target_row <- table_info$contents[i]
new_row <- latex_new_row_builder(target_row, table_info,
diff --git a/R/util.R b/R/util.R
index 57e58b5..446cb2e 100644
--- a/R/util.R
+++ b/R/util.R
@@ -124,10 +124,11 @@
for (i in which(dup_index != 1)) {
dup_row <- table_info$contents[i]
empty_times <- dup_index[i] - 1
+ # insert empty_times before last non whitespace characters
new_row <- str_replace(
- dup_row, "&",
- paste0("& \\\\\\\\vphantom\\\\{", empty_times, "\\\\}"))
- kable_input <- str_replace(kable_input, dup_row, new_row)
+ dup_row, "(?<=\\s)([\\S]+[\\s]*)$",
+ paste0("\\\\\\\\vphantom\\\\{", empty_times, "\\\\} \\1"))
+ kable_input <- sub(dup_row, new_row, kable_input)
table_info$contents[i] <- new_row
}
table_info$duplicated_rows <- FALSE
diff --git a/tests/visual_tests/no_colnames_booktabs_pdf.Rmd b/tests/visual_tests/no_colnames_booktabs_pdf.Rmd
new file mode 100644
index 0000000..b0d1b58
--- /dev/null
+++ b/tests/visual_tests/no_colnames_booktabs_pdf.Rmd
@@ -0,0 +1,172 @@
+---
+title: "no_colnames_booktabs_pdf"
+author: "Leo"
+date: "5/10/2018"
+output: pdf_document
+---
+
+# Create some test data
+
+```{r, include=F}
+library(tidyverse)
+library(knitr)
+library(kableExtra)
+```
+
+```{r}
+simple_df_one_column <- data.frame(
+ text = paste0('TEXT ', seq(1, 6))
+)
+
+simple_df_one_column_math <- data.frame(
+ math = paste0('$\\text{Math:} x = ', seq(1, 6), '$ TEXT')
+)
+
+simple_df_multi_columns <- data.frame(
+ text = paste0('TEXT ', seq(1, 6)),
+ desc = paste0('DESCRIPTION ', seq(1, 6))
+)
+
+simple_df_multi_columns_math <- data.frame(
+ text = paste0('TEXT ', seq(1, 6)),
+ math = paste0('$\\text{Math:} x = ', seq(1, 6), '$ TEXT')
+)
+
+simple_df_longtable_one_column <- data.frame(
+ text = paste0('TEXT ', seq(1, 50))
+)
+
+simple_df_longtable_one_column_math <- data.frame(
+ math = paste0('$\\text{Math:} x = ', seq(1, 50), '$ TEXT')
+)
+
+simple_df_longtable_multi_columns <- data.frame(
+ text = paste0('TEXT ', seq(1, 50)),
+ desc = paste0('DESCRIPTION ', seq(1, 50))
+)
+
+simple_df_longtable_multi_columns_math <- data.frame(
+ text = paste0('TEXT ', seq(1, 50)),
+ math = paste0('$\\text{Math:} x = ', seq(1, 50), '$ TEXT')
+)
+```
+
+# Simple Table with One Column
+
+```{r}
+simple_df_one_column %>%
+ kable("latex", escape = F, booktabs = T) %>%
+ kable_styling(latex_options = c('striped'))
+```
+
+```{r}
+simple_df_one_column %>%
+ kable("latex", escape = F, booktabs = T, col.names = NULL) %>%
+ kable_styling(latex_options = c('striped'))
+```
+
+# Simple Table with One Column and Math
+
+```{r}
+simple_df_one_column_math %>%
+ kable("latex", escape = F, booktabs = T) %>%
+ kable_styling(latex_options = c('striped'))
+```
+
+```{r}
+simple_df_one_column_math %>%
+ kable("latex", escape = F, booktabs = T, col.names = NULL) %>%
+ kable_styling(latex_options = c('striped'))
+```
+
+# Simple Table with Multi Columns
+
+```{r}
+simple_df_multi_columns %>%
+ kable("latex", escape = F, booktabs = T) %>%
+ kable_styling(latex_options = c('striped'))
+```
+
+```{r}
+simple_df_multi_columns %>%
+ kable("latex", escape = F, booktabs = T, col.names = NULL) %>%
+ kable_styling(latex_options = c('striped'))
+```
+
+# Simple Table with Multi Columns and Math
+
+```{r}
+simple_df_multi_columns_math %>%
+ kable("latex", escape = F, booktabs = T) %>%
+ kable_styling(latex_options = c('striped'))
+```
+
+```{r}
+simple_df_multi_columns_math %>%
+ kable("latex", escape = F, booktabs = T, col.names = NULL) %>%
+ kable_styling(latex_options = c('striped'))
+```
+
+# Simple Long Table with One Column
+
+```{r}
+simple_df_longtable_one_column %>%
+ kable("latex", caption = 'Long Table with One Column',
+ escape = F, booktabs = T, longtable = T) %>%
+ kable_styling(latex_options = c('striped', 'repeat_header'))
+```
+
+```{r}
+simple_df_longtable_one_column %>%
+ kable("latex", caption = 'Long Table with One Column without Colnames',
+ escape = F, booktabs = T, longtable = T, col.names = NULL) %>%
+ kable_styling(latex_options = c('striped', 'repeat_header'))
+```
+
+# Simple Long Table with One Column and Math
+
+```{r}
+simple_df_longtable_one_column_math %>%
+ kable("latex", caption = 'Long Table with One Column',
+ escape = F, booktabs = T, longtable = T) %>%
+ kable_styling(latex_options = c('striped', 'repeat_header'))
+```
+
+```{r}
+simple_df_longtable_one_column_math %>%
+ kable("latex", caption = 'Long Table with One Column without Colnames',
+ escape = F, booktabs = T, longtable = T, col.names = NULL) %>%
+ kable_styling(latex_options = c('striped', 'repeat_header'))
+```
+
+# Simple Long Table with Multi Columns
+
+```{r}
+simple_df_longtable_multi_columns %>%
+ kable("latex", caption = 'Long Table with One Column',
+ escape = F, booktabs = T, longtable = T) %>%
+ kable_styling(latex_options = c('striped', 'repeat_header'))
+```
+
+```{r}
+simple_df_longtable_multi_columns %>%
+ kable("latex", caption = 'Long Table with One Column without Colnames',
+ escape = F, booktabs = T, longtable = T, col.names = NULL) %>%
+ kable_styling(latex_options = c('striped', 'repeat_header'))
+```
+
+# Simple Long Table with Multi Columns and Math
+
+```{r}
+simple_df_longtable_multi_columns_math %>%
+ kable("latex", caption = 'Long Table with One Column',
+ escape = F, booktabs = T, longtable = T) %>%
+ kable_styling(latex_options = c('striped', 'repeat_header'))
+```
+
+```{r}
+simple_df_longtable_multi_columns_math %>%
+ kable("latex", caption = 'Long Table with One Column without Colnames',
+ escape = F, booktabs = T, longtable = T, col.names = NULL) %>%
+ kable_styling(latex_options = c('striped', 'repeat_header'))
+```