Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to convert Lyx knitr to R markdown

Tags:

r

knitr

lyx

I often use knitr in Lyx to be able to write WYSIWYG LATEX equations. After I'm done, it would be nice to be able to convert the whole thing into R Markdown. Is there an easy way to do this? I tried this: https://duncanjg.wordpress.com/2012/09/25/sweave-to-markdown/ but it failed miserably. My external chunk names disappeared and there are dangling } at the end of titles. I also tried this http://www.lemmster.de/lyx-export-to-markdown.html and that worked even worse! Almost everything disappeared.

like image 794
bramtayl Avatar asked Oct 31 '22 05:10

bramtayl


1 Answers

I have a short R program I wrote to do this. The first step is to use Lyx to export the file as a .Rnw (knitr) file. Then that file is processed by the program below. This is REALLY rough because it only handles a small subset of LaTEX features, and does so in a really incomplete way.

setwd("/home/haldane/Dropbox/PhD")

library(magrittr)
library(dplyr)
library(tidyr)
library(stringi)
library(rex)

last_carried_forward = 
  . %>% 
  zoo::na.locf(na.rm = FALSE)

chunk_frame = function(line_frame, start_string, end_string)
  line_frame %>%
  mutate(chunk_ID.raw =
           text %in% 
           c(start_string, end_string) %>%
           cumsum %>%
           last_carried_forward,
         chunk_ID = 
           chunk_ID.raw %>%
           mod(2) %>%
           `==`(1) %>%
           ifelse(chunk_ID.raw, NA) %>%
           `/`(2) %>%
           `+`(0.5) ) %>%
  select(-chunk_ID.raw) %>%
  filter(text %in% c(start_string, end_string) %>% `!`)

section_regex = 
  rex("\\",
      capture(or("section", 
                 "subsection", 
                 "subsubsection",
                 "subsubsection",
                 "paragraph",
                 "subparagraph") ),
      "{",
      capture(anything),
      "}")

citation_regex = 
  rex("\\citep{", 
      capture(anything), 
      "}")

fix_citation_regex = rex("[@",
                         capture_group(1),
                         "]")

backslash_regex = rex(start, "\\")

heading = 
  data_frame(heading = c("section", 
                         "subsection", 
                         "subsubsection",
                         "paragraph",
                         "subparagraph"),
             heading_code = c("#",
                              "##",
                              "###",
                              "####",
                              "#####"))

line.pre_definition = 
  "input.Rnw" %>% 
  readLines %>%
  data_frame(text = .) %>%
  chunk_frame("\\begin{document}", "\\end{document}") %>%
  filter(chunk_ID == 1) %>%
  filter(text %in% 
           c("\\end{itemize}",
             "\\printbibliography",
             "\\SweaveOpts{concordance=TRUE}",
             "\\maketitle",
             "\\tableofcontents{}",
             "\\appendix") %>% 
           `!` ) %>%
  mutate(line__ID = 1:n()) %>%
  extract(text, 
          c("heading", 
            "heading_content"), 
          section_regex,
          remove = FALSE) %>%
  left_join(heading) %>%
  mutate(fixed_line = 
           heading %>%
           is.na %>%
           ifelse(text, 
                  paste(heading_code, 
                        heading_content) ) %>%
           stri_replace_all_fixed("\\item ", 
                                  "- ") %>%
           stri_replace_all_regex(citation_regex, 
                                  "\\[\\@$1\\]") ) %>%
  chunk_frame("\\begin{defn}", "\\end{defn}")

line.definition = 
  line.pre_definition %>%
  filter(chunk_ID %>% is.na %>% `!`) %>%
  group_by(chunk_ID) %>%
  summarize(line__ID = first(line__ID),
            fixed_line = paste0(
              "\n**",
              first(fixed_line),
              "**: ",
              fixed_line[-(1:2)] %>% paste(collapse = "\n"),
              "\n"))

line.pre_table = 
  line.pre_definition %>%
  filter(chunk_ID %>% is.na) %>%
  bind_rows(line.definition ) %>%
  arrange(line__ID) %>%
  chunk_frame("\\[", "\\]") %>%
  mutate(fixed_line = 
           chunk_ID %>%
           is.na %>%
           ifelse(fixed_line,
                  paste0("$$",
                         fixed_line,
                         "$$") ) ) %>%
  chunk_frame("\\begin{table}[H]", "\\end{table}")

line.final =
  line.pre_table %>%
  filter(chunk_ID %>% is.na %>% `!`) %>%
  filter(text %>% 
           stri_detect_regex("^\\\\") %>% 
           not) %>%
  mutate(new_text = 
           text %>% 
           stri_replace_all_regex("\\\\tabularnewline",
                                  "")) %>%
  group_by(chunk_ID) %>%
  summarize(line__ID = 
              first(line__ID),
            fixed_line =
              new_text %>% 
              paste(collapse = "\n") %>%
              read.csv(text = ., sep = "&", check.names = FALSE ) %>%
              knitr::kable() %>%
              paste(collapse = "\n") %>%
              paste("\n", .) ) %>%
  bind_rows(line.pre_table %>% filter(chunk_ID %>% is.na)) %>%
  arrange(line__ID) %>%
  mutate(final_line = 
           fixed_line %in%
           c("<<message = FALSE>>=", "@") %>%
           ifelse("```", fixed_line) %>%
           plyr::mapvalues("\\begin{itemize}", "") )

line.final %>%
  use_series(final_line) %>%
  writeLines("output.Rmd")
like image 61
bramtayl Avatar answered Nov 09 '22 11:11

bramtayl