blob: 6e71a447cf7db4a9b9d1ebbbe90013e26e14b060 [file] [log] [blame]
Hao Zhu8f417202017-05-20 16:37:14 -04001#' Add indentations to row headers
Hao Zhubd95bb22017-05-22 16:08:49 -04002#'
3#' @param kable_input Output of `knitr::kable()` with `format` specified
4#' @param positions A vector of numeric row numbers for the rows that need to
5#' be indented.
6#'
Hao Zhu8f417202017-05-20 16:37:14 -04007#' @export
8add_indent <- function(kable_input, positions) {
Hao Zhud972e7f2017-05-22 13:27:15 -04009 if (!is.numeric(positions)) {
10 stop("Positions can only take numeric row numbers (excluding header rows).")
11 }
Hao Zhu8f417202017-05-20 16:37:14 -040012 kable_format <- attr(kable_input, "format")
13 if (!kable_format %in% c("html", "latex")) {
14 message("Currently generic markdown table using pandoc is not supported.")
15 return(kable_input)
16 }
17 if (kable_format == "html") {
Hao Zhu62cdde52017-05-20 22:16:03 -040018 return(add_indent_html(kable_input, positions))
Hao Zhu8f417202017-05-20 16:37:14 -040019 }
20 if (kable_format == "latex") {
21 return(add_indent_latex(kable_input, positions))
22 }
23}
24
Hao Zhu62cdde52017-05-20 22:16:03 -040025# Add indentation for LaTeX
Hao Zhu8f417202017-05-20 16:37:14 -040026add_indent_latex <- function(kable_input, positions) {
Hao Zhud972e7f2017-05-22 13:27:15 -040027 table_info <- magic_mirror(kable_input)
Hao Zhu8f417202017-05-20 16:37:14 -040028
Hao Zhu8f417202017-05-20 16:37:14 -040029 if (max(positions) > table_info$nrow - 1) {
30 stop("There aren't that many rows in the table. Check positions in ",
31 "add_indent_latex.")
32 }
33
34 out <- kable_input
35 for (i in positions) {
36 rowtext <- table_info$contents[i + 1]
37 out <- sub(rowtext, latex_indent_unit(rowtext), out)
38 }
39 return(out)
40}
41
42latex_indent_unit <- function(rowtext) {
43 paste0("\\\\hspace{1em}", rowtext)
44}
Hao Zhu62cdde52017-05-20 22:16:03 -040045
46# Add indentation for HTML
47add_indent_html <- function(kable_input, positions) {
48 kable_attrs <- attributes(kable_input)
49
50 kable_xml <- read_xml(as.character(kable_input), options = "COMPACT")
51 kable_tbody <- xml_tpart(kable_xml, "tbody")
52
53 group_header_rows <- attr(kable_input, "group_header_rows")
54 if (!is.null(group_header_rows)) {
55 positions <- positions_corrector(positions, group_header_rows,
56 length(xml_children(kable_tbody)))
57 }
58 for (i in positions) {
59 node_to_edit <- xml_child(xml_children(kable_tbody)[[i]], 1)
60 if (!xml_has_attr(node_to_edit, "indentLevel")) {
61 xml_attr(node_to_edit, "style") <- paste(
62 xml_attr(node_to_edit, "style"), "padding-left: 2em;"
63 )
64 xml_attr(node_to_edit, "indentLevel") <- 1
65 } else {
66 indentLevel <- as.numeric(xml_attr(node_to_edit, "indentLevel"))
67 xml_attr(node_to_edit, "style") <- sub(
68 paste0("padding-left: ", indentLevel * 2, "em;"),
69 paste0("padding-left: ", (indentLevel + 1) * 2, "em;"),
70 xml_attr(node_to_edit, "style")
71 )
72 xml_attr(node_to_edit, "indentLevel") <- indentLevel + 1
73 }
74 }
75 out <- structure(as.character(kable_xml), format = "html",
76 class = "knitr_kable")
77 attributes(out) <- kable_attrs
78 return(out)
79}