Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rmarkdown: Indentation of TOC items in HTML output

I want to indent TOC according to header level.

My example document looks like this:

# Tutorial
## Start a new project
### Project structure
### Analysis code

I'm compiling Rmd document with:

rmarkdown::render("foo.Rmd", 
                  output_options = HTMLlook, 
                  output_file = "foo.html")

HTMLlook <- list(toc = TRUE,
                 toc_depth = 5,
                 toc_float = list(collapsed = FALSE, 
                                  smooth_scroll = TRUE))

This produces document with TOC

enter image description here

However, I want indented TOC (indentation equivalent to header level). Wanted result should look like this: enter image description here

Is it possible to set this option in render or maybe pass css parameters to it?

like image 830
pogibas Avatar asked Sep 13 '17 15:09

pogibas


1 Answers

I am not aware of a built-in solution. But here is a little tweak:

<script>
    $(document).ready(function() {
      $items = $('div#TOC li');
      $items.each(function(idx) {
        num_ul = $(this).parentsUntil('#TOC').length;
        $(this).css({'text-indent': num_ul * 10, 'padding-left': 0});
      });

    });
</script>

The depth of your headers is actually mapped inside the TOC. For each level you go down, a new ul element is created. This is what we are making use of here. In detail:

When the document has finished loading ($(document).ready(....):

  1. Select all list items inside the element with id TOC
  2. For each list item count the number of parent elements until you reach the element with id TOC. This is the number of ul elements.
  3. Change the style for the current list item according to the number of parents.

You can tweak the spacing by playing around with the two parameters for text-indent and padding-left.


MRE:

---
title: "Habits"
author: Martin Schmelzer
date: September 14, 2017
output: 
  html_document:
    toc: true
    toc_depth: 5
    toc_float: 
      collapsed: false
      smooth_scroll: true
---

<script>
$(document).ready(function() {
  $items = $('div#TOC li');
  $items.each(function(idx) {
    num_ul = $(this).parentsUntil('#TOC').length;
    $(this).css({'text-indent': num_ul * 10, 'padding-left': 0});
  });

});
</script>

# In the morning 

## Waking up 

### Getting up

#### Take a shower

##### Make coffee

# In the evening

## Make dinner

This is the result:

enter image description here

like image 199
Martin Schmelzer Avatar answered Oct 24 '22 19:10

Martin Schmelzer