Merge pull request #440 from jokorn/new_add_header_above

Allow standardized data frame as input to add_header_above
diff --git a/R/add_header_above.R b/R/add_header_above.R
index 92ec294..6beb5a0 100644
--- a/R/add_header_above.R
+++ b/R/add_header_above.R
@@ -10,6 +10,10 @@
 #' for a 3-column table with "title" spanning across column 2 and 3. For
 #' convenience, when `colspan` equals to 1, users can drop the ` = 1` part.
 #' As a result, `c(" ", "title" = 2)` is the same as `c(" " = 1, "title" = 2)`.
+#' Alternatively, a data frame with two columns can be provided: The first
+#' column should contain the header names (character vector) and the second 
+#' column should contain the colspan (numeric vector). This input can be used
+#' if there are problems with unicode characters in the headers.
 #' @param bold A T/F value to control whether the text should be bolded.
 #' @param italic A T/F value to control whether the text should to be emphasized.
 #' @param monospace A T/F value to control whether the text of the selected column
@@ -87,12 +91,28 @@
                                        angle, escape, line, line_sep,
                                        extra_css, include_empty) {
   if (is.null(header)) return(kable_input)
+   
   kable_attrs <- attributes(kable_input)
   kable_xml <- read_kable_as_xml(kable_input)
   kable_xml_thead <- xml_tpart(kable_xml, "thead")
-
-  header <- standardize_header_input(header)
-
+  
+  if (is.data.frame(header)){
+    if(ncol(header) == 2 & is.character(header[[1]]) & is.numeric(header[[2]])){
+      header <- data.frame(header = header[[1]], colspan = header[[2]],
+                           stringsAsFactors = FALSE)
+    }
+    else {
+      stop("If header input is provided as a data frame instead of a named vector ",
+           "it must consist of only two columns: ",
+           "The first should be a character vector with ",
+           "header names and the second should be a numeric vector with ",
+           "the number of columns the header should span.")
+    }
+  }
+  else {
+    header <- standardize_header_input(header)
+  }
+  
   if (escape) {
     header$header <- escape_html(header$header)
   }
@@ -216,7 +236,23 @@
                                       escape, line, line_sep,
                                       border_left, border_right) {
   table_info <- magic_mirror(kable_input)
-  header <- standardize_header_input(header)
+  
+  if (is.data.frame(header)){
+    if(ncol(header) == 2 & is.character(header[[1]]) & is.numeric(header[[2]])){
+      header <- data.frame(header = header[[1]], colspan = header[[2]],
+                           stringsAsFactors = FALSE)
+    }
+    else {
+      stop("If header input is provided as a data frame instead of a named vector ",
+           "it must consist of only two columns: ",
+           "The first should be a character vector with ",
+           "header names and the second should be a numeric vector with ",
+           "the number of columns the header should span.")
+    }
+  }
+  else {
+    header <- standardize_header_input(header)
+  }
 
   if (escape) {
     header$header <- input_escape(header$header, align)
diff --git a/R/group_rows.R b/R/group_rows.R
index 835b036..09fad01 100644
--- a/R/group_rows.R
+++ b/R/group_rows.R
@@ -126,6 +126,10 @@
   if (!is.null(group_header_rows)) {
     group_seq <- positions_corrector(group_seq, group_header_rows,
                                      length(xml_children(kable_tbody)))
+    # Update the old group_header_rows attribute with their new positions
+    kable_attrs$group_header_rows <- ifelse(kable_attrs$group_header_rows > group_seq[1],
+                                            kable_attrs$group_header_rows+1,
+                                            kable_attrs$group_header_rows)
   }
 
   # Insert a group header row
diff --git a/R/util.R b/R/util.R
index 26d593d..df04344 100644
--- a/R/util.R
+++ b/R/util.R
@@ -138,8 +138,12 @@
 
 # Solve enc issue for LaTeX tables
 solve_enc <- function(x) {
+  if (Encoding(x) == "UTF-8"){
+    out <- x
+  } else {
   #may behave differently based on Sys.setlocale settings with respect to characters
-  out <- enc2utf8(as.character(base::format(x, trim = TRUE, justify = 'none')))
+    out <- enc2utf8(as.character(base::format(x, trim = TRUE, justify = 'none')))
+  }
   mostattributes(out) <- attributes(x)
   return(out)
 }