xaringan icon indicating copy to clipboard operation
xaringan copied to clipboard

Table of Contents

Open EvaMaeRey opened this issue 5 years ago • 13 comments

Hi Yihui, pursuant to the discussion on Twitter, I'm writing to request the capability for a table of contents in Xaringan. Thank you!


By filing an issue to this repo, I promise that

  • [X ] I have fully read the issue guide at https://yihui.name/issue/.
  • [ X] I have provided the necessary information about my issue.
    • If I'm asking a question, I have already asked it on Stack Overflow or RStudio Community, waited for at least 24 hours, and included a link to my question there.
    • If I'm filing a bug report, I have included a minimal, self-contained, and reproducible example, and have also included xfun::session_info('xaringan'). I have upgraded all my packages to their latest versions (e.g., R, RStudio, and R packages), and also tried the development version: remotes::install_github('yihui/xaringan').
    • If I have posted the same issue elsewhere, I have also mentioned it in this issue.
  • [ X] I have learned the Github Markdown syntax, and formatted my issue correctly.

I understand that my issue may be closed if I don't fulfill my promises.

EvaMaeRey avatar Jul 05 '19 12:07 EvaMaeRey

I think the TOC could be dynamically generated by JavaScript. I don't have time for it, but I think it is an excellent JS exercise. I'll leave it to other contributors. I'm not sure how long it will take, but for me, I guess it would take less than an hour.

Implementation-wise: use JS to find all h[1-6] header elements (.querySelectorAll()) and generate a bullet list (<ul>) on a slide with a certain attribute (e.g. class: toc). There needs to be a mechanism (e.g. class: no-toc or `.no-toc[# header]`) to exclude certain headers because some of them may not really be headers.

This feature can also be as fancy as beamer: there could be multiple TOC slides, and each TOC fades out the headers that appear before this TOC page, so only headers that have not yet been talked about are highlighted. Or only highlight the next header, like \tableofcontents[currentsection] in beamer.

yihui avatar Jul 05 '19 14:07 yihui

Hey @EvaMaeRey you can try my solution on following SO question.

markushhh avatar Jul 26 '19 13:07 markushhh

Cool. That seems like a good approach!

EvaMaeRey avatar Aug 02 '19 16:08 EvaMaeRey

@EvaMaeRey there's also this

step- avatar Aug 12 '19 07:08 step-

@step- I am aware of that but I couldn't set it up properly, do you have a minimum working example of that?

markushhh avatar Aug 12 '19 09:08 markushhh

@markushhh no, not really. However, inspired by your script, I wrote this hack:

  • Writes TOC as an external, configurable Rmd file
  • Includes TOC file while knitting (no dependency on rstudioapi)
  • The outline slide is a regular, editable xaringan slide
  • A couple of extra options

step- avatar Aug 14 '19 12:08 step-

I have a working prototype, which I'll attempt to document here.

  1. Create file called toc.html that imports jQuery and contains the JavaScript to identify h2 headers.
<script
  src="https://code.jquery.com/jquery-3.4.1.min.js"
  integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
  crossorigin="anonymous">
</script>

<script>
$(document).ready(function() {
  var h2 = $( ":not(.toc) > h2" );
  var items = h2.map(
    function(){return $(this).text()}
    ).get()
  items.shift(); // Remove first item (title)
  items.pop();   // Remove last item (spurious???)
  var item_list = items.join("</li><li>");
  var toc = "<ul><li>" + item_list + "</li></ul>";
  $(".toc > h2").after(toc);
  
});
</script>
  1. Add the toc.html to your xaringan yaml header:
output:  
  xaringan::moon_reader:
    includes:
      in_header:
        - 'toc.html'
  1. Create a slide with class toc:
---
class:toc
## Table of Contents
---

This script will read all the h2 entries, except on the slide with class toc, and then insert a <li> with these entries after the h2 heading on that page. image

andrie avatar Sep 20 '19 10:09 andrie

By the way, there has to be a better way to insert JavaScript into xaringan, but I couldn't find it. So I opened a question at RStudio Community.

andrie avatar Sep 20 '19 11:09 andrie

Have you tried the beforeInit field?

pat-s avatar Sep 20 '19 16:09 pat-s

@pat-s beforeInit may not be a good choice in this case: https://community.rstudio.com/t/40348/3

yihui avatar Sep 20 '19 19:09 yihui

In the list of remark.js plugins, there is a table of contents plugin, remark-toc.

Is there a way to include the plugins into xaringan?

andrie avatar Sep 23 '19 05:09 andrie

That remark.js is not our remark.js.

yihui avatar Sep 23 '19 13:09 yihui

TOC is indeed a very desirable feature to have.

However, it would still be somewhat limited because Xaringan AFAIK does not allow the division by sections, right? ioslides allows that by making # headers for sections and ## for slide titles.

Any chance to implement that in the future?

Thank you

GitHunter0 avatar Sep 24 '21 00:09 GitHunter0