Pagedown: Adding "Chapter " to each Section Heading like Bookdown

Created on 10 May 2019  路  5Comments  路  Source: rstudio/pagedown

Hello!

I am currently making a thesis template for my university using pagedown and I need to have each first level section header look like:

# Some Title

## Second Level Header

Some text for the title.
Chapter 1. Some Title

1.1. Second Level Header

Some text for the title.

bookdown allows this to be changed in the _bookdown.yaml file link and I was wondering if there is something similar in pagedown that I am missing, or if it should be done a different way. Changing chapter titles and possibly figure caption number formats (maybe "Figure 1.1. Some Text") would be amazing! I will continue to go through as much documentation as I can to find an answer but so far I haven't found anything :(

Thanks again

Most helpful comment

Got it working thanks a bunch!

All 5 comments

So I have accomplished this in a somewhat hacky way and I am sure there is a better solution, however I will show what I did to have it working for now.

For section title that I wanted a "Chapter " label for I simply added the class .chapter and used :before in the css template to define the content to be printed before the title. Here's the code:

rmd

---
output:
  pagedown::html_paged: 
    number_sections: yes
    css: ["mycss.css", "default", "default-page"]
---

# The first chapter {.chapter}

Some paragraph content

# Another H1 but not a chapter

More content

css

.chapter > h1:before {
  content: "Chapter ";
}

The only issue so far is getting the same functionality to work in the table of contents which I still have to figure out.

Hi @brentthorne ,

Sorry for the delay. I would have made the same proposal as yours.
I do not consider that using a ::before pseudo-element is a hack (even if one could argue that Chapter brings some semantic content). FMPOV, it is perfectly legal.

I think that it is possible to achieve your goal using a Paged.js hook. It is well described in this document https://www.pagedmedia.org/paged-js/ (see the section Extending Paged.js).

If I understand well your goal, I would write this hook:

Paged.registerHandlers(class extends Paged.Handler {
  constructor(chunker, polisher, caller) {
    super(chunker, polisher, caller);
  }
  beforeParsed(content) {
    const tocAnchors = content.querySelectorAll('.toc a[href^="#"]:not([href*=":"]');
    for(let anchor of tocAnchors) {
      const ref = anchor.getAttribute('href').replace(/^#/, '');
      const element = content.getElementById(ref);
      if(element.classList.contains('chapter')) {
        anchor.classList.add('chapter-ref');
      }
    }
  }
});

and add a CSS declaration

.chapter > h1::before, .chapter-ref::before {
  content: "Chapter ";
}

In order to see the result in action, here is a dummy Rmd file:

---
output:
  pagedown::html_paged: 
    toc: true
    number_sections: yes
---

```{css, echo=FALSE}
.chapter > h1::before, .chapter-ref::before {
  content: "Chapter ";
}
```

```{js, echo=FALSE}
Paged.registerHandlers(class extends Paged.Handler {
  constructor(chunker, polisher, caller) {
    super(chunker, polisher, caller);
  }
  beforeParsed(content) {
    const tocAnchors = content.querySelectorAll('.toc a[href^="#"]:not([href*=":"]');
    for(let anchor of tocAnchors) {
      const ref = anchor.getAttribute('href').replace(/^#/, '');
      const element = content.getElementById(ref);
      if(element.classList.contains('chapter')) {
        anchor.classList.add('chapter-ref');
      }
    }
  }
});
```

# The first chapter {.chapter}

Some paragraph content

# Another H1 but not a chapter

More content

poke @fchasen & @JulieBlanc for any comment.

This is great thank you!

My only issue now is that I am unsure of how to implement it somewhere other than the Rmd file. I tried to use it as a <script> in the template.html but it did not work. Is there a place you preffer to have these bits of js placed? I am currently working on a pagedown::thesis_paged template on my fork and want to make sure I stick to your usual standards. Also I am very new to js so I could easily be missing the simple solution so I will continue to look into it in the meantime!

Cheers

I am currently working on a pagedown::thesis_paged template on my fork

What a great news! Thanks!
The dedicated file for Paged.js hooks is https://github.com/rstudio/pagedown/blob/master/inst/resources/js/hooks.js
You can simply add a new Paged.js handler that registers hooks in this file.
The hooks.js file is already attached as a HTML dependency here: https://github.com/rstudio/pagedown/blob/11b75c9879dc084e00a83af8e50b9face6a2478c/R/paged.R#L94-L100
If there are other JS scripts (i.e. JS libraries) that cannot be register in a Paged.js handler, they have to be added as HTML dependencies. In this case, we will have to be sure that the synchronization with Paged.js works well (this is the hardest part). Please, let us now if you are in trouble with this kind of stuff.

Got it working thanks a bunch!

Was this page helpful?
0 / 5 - 0 ratings