Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Table of Contents #217

Open
EvaMaeRey opened this issue Jul 5, 2019 · 13 comments
Open

Table of Contents #217

EvaMaeRey opened this issue Jul 5, 2019 · 13 comments

Comments

@EvaMaeRey
Copy link

EvaMaeRey commented Jul 5, 2019

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.

@yihui
Copy link
Owner

yihui commented Jul 5, 2019

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.

@markushhh
Copy link

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

@EvaMaeRey
Copy link
Author

Cool. That seems like a good approach!

@step-
Copy link

step- commented Aug 12, 2019

@EvaMaeRey there's also this

@markushhh
Copy link

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

@step-
Copy link

step- commented Aug 14, 2019

@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

@andrie
Copy link

andrie commented Sep 20, 2019

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
Copy link

andrie commented Sep 20, 2019

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.

@pat-s
Copy link
Collaborator

pat-s commented Sep 20, 2019

Have you tried the beforeInit field?

@yihui
Copy link
Owner

yihui commented Sep 20, 2019

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

@andrie
Copy link

andrie commented Sep 23, 2019

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?

@yihui
Copy link
Owner

yihui commented Sep 23, 2019

That remark.js is not our remark.js.

@GitHunter0
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants