Hao Zhu | 37975a3 | 2019-01-15 14:59:34 -0600 | [diff] [blame] | 1 | --- |
| 2 | title: "Use kableExtra and xml2 in the HARD way" |
| 3 | author: "Hao" |
| 4 | date: "1/15/2019" |
| 5 | output: html_document |
| 6 | --- |
| 7 | |
| 8 | ```{r setup, include=FALSE} |
| 9 | knitr::opts_chunk$set(echo = TRUE) |
| 10 | ``` |
| 11 | |
| 12 | Behind the scene, for HTML tables, `kableExtra` uses `xml2` to add styles and new contents to existing table. `kableExtra` is trying its best to get you the result in a literal way but in some rare case, I hope you can have the ability to freedom to be a HTML Ninja (quoting @yihui's xaringan). :) |
| 13 | |
| 14 | In `kableExtra` 1.0, I exported two functions that were previously used internally in this package: `kable_as_xml` and `xml_as_kable`. Here is an example for how to use these 2 function and xml2 to hack your table and do something `kableExtra` is not capable to do (at least right now). |
| 15 | |
Hao Zhu | 84102ed | 2019-01-16 00:06:25 -0600 | [diff] [blame] | 16 | <style> |
| 17 | @-webkit-keyframes rotate { |
| 18 | 0% {transform: rotate(0deg)} |
| 19 | 100% {transform: rotate(360deg)} |
| 20 | } |
| 21 | |
| 22 | .badIdea { |
| 23 | position:relative; |
| 24 | animation: rotate 3s linear infinite; |
| 25 | } |
| 26 | </style> |
| 27 | |
Hao Zhu | 37975a3 | 2019-01-15 14:59:34 -0600 | [diff] [blame] | 28 | ```{r} |
| 29 | library(kableExtra) |
| 30 | library(xml2) |
| 31 | |
Hao Zhu | 84102ed | 2019-01-16 00:06:25 -0600 | [diff] [blame] | 32 | demo <- kable(mtcars[1:4, 1:4]) %>% # As always, mtcars ;) |
Hao Zhu | 37975a3 | 2019-01-15 14:59:34 -0600 | [diff] [blame] | 33 | kable_styling(full_width = F) %>% |
| 34 | kable_as_xml() |
| 35 | |
| 36 | demo %>% # Transform to xml |
| 37 | xml_child(2) %>% # Select <tbody> (1 is <thead>) |
| 38 | xml_child(2) %>% # Select 2nd row <tr> in <tbody> |
| 39 | xml_child(1) %>% # Select 1st cell in 2nd row <td> |
Hao Zhu | 84102ed | 2019-01-16 00:06:25 -0600 | [diff] [blame] | 40 | xml_set_attr("class", "badIdea") # Add attribute to style |
Hao Zhu | 37975a3 | 2019-01-15 14:59:34 -0600 | [diff] [blame] | 41 | |
| 42 | xml_as_kable(demo) # Render that xml back as kable |
| 43 | ``` |
| 44 | |
Hao Zhu | 84102ed | 2019-01-16 00:06:25 -0600 | [diff] [blame] | 45 | > Only for illustration. Animating your texts like this is a **horrible** idea and will distract audience's attention. |
| 46 | > I mean seriously, what I want to show here is `xml2`... |
| 47 | |
| 48 | |
Hao Zhu | 37975a3 | 2019-01-15 14:59:34 -0600 | [diff] [blame] | 49 | For those `%>%` fans, keep in mind that since `xml2` makes modification to an external xml object. Although it looks like you can put everything in one pipe, the reality is that you will have to save the entire xml first, run the `xml2` code and then get it rendered. |
Hao Zhu | 84102ed | 2019-01-16 00:06:25 -0600 | [diff] [blame] | 50 | |
| 51 | *** |
| 52 | |
| 53 | Note: |
| 54 | Here is my simple rotation css. You need to put them in rmarkdown to get things work. |
| 55 | ```{css, eval = F} |
| 56 | @-webkit-keyframes rotate { |
| 57 | 0% {transform: rotate(0deg)} |
| 58 | 100% {transform: rotate(360deg)} |
| 59 | } |
| 60 | |
| 61 | .badIdea { |
| 62 | position:relative; |
| 63 | animation: rotate 3s linear infinite; |
| 64 | } |
| 65 | ``` |