R/markdown_toc.R

Defines functions markdown_toc

markdown_toc <- function(md_fpath, li_type) {
  # Generate Markdown table of contents as character string given a Markdown file.
  #
  # Arguments:
  #   md_fpath {char} -- path to Markdown file
  #   li_type {char} -- type of list item, one of "1" (ordered list), or "-" or "*" (unordered list)
  #
  # Returns:
  #  {char} -- Markdown TOC string
  
  library(rdoni)
  
  # Read Markdown file
  md = readLines(md_fpath)
  
  # Get lines that correspond to headings
  h = md[grepl("^#+ ", md)]
  
  # Indent each item according to heading level (# = 0, ## = 1, ### = 2, ...)
  indent = "\t"
  
  # Add "Table of Contents" item as heading level 2
  first_h2 = min(grep("##", h))
  if (length(first_h2)) {
    # There is an H2, so put TOC item above that one
    h = c(h[1:first_h2-1], "## Table of Contents", h[first_h2:length(h)])
    
  } else {
    # There is no H2, so put TOC item at the very top
    h = c("## Table of Contents", h)
  }
  
  # Add indent and paste into string
  h = sub("#", "", h)
  h = gsub("#", indent, h)
  h = gsub("^(\\t+) ", "\\1", h)  # Remove space between last \t and the text
  h_string = paste0(h, collapse = "\n")
  
  # Add bullet to each item
  h_bullets = strsplit(make_md_list(h_string, li_type = li_type), "\n")[[1]]
  h_bullets[1] = trimws(h_bullets[1])
  
  # Format each item as [TEXT](#text)
  pat = "^( +)(-|\\*|\\d+)( )(.*)$"
  element_names = gsub(pat, "\\4", h_bullets)
  element_names[1] = gsub("^- ", "", element_names[1])
  h_bullets = gsub(pat, "\\1\\2\\3\\[\\4\\]", h_bullets)
  h_toc = sprintf("%s(#%s)", 
    h_bullets,
    tolower(gsub("(\\(|\\)|\\[|\\]|:)", "", gsub(" ", "-", element_names)))
  )
  
  # Add Table of Contents H2
  h_toc = c("## Table of Contents", "", h_toc)
  
  # Return as Markdown string
  return (paste0(h_toc, collapse = "\n"))
}
tsouchlarakis/rdoni documentation built on Sept. 16, 2019, 8:53 p.m.