Closed ccamara closed 2 years ago
@yihui , I thought this would be easy to implement, so I tried to do it myself and propose a pull request. Regretfully, I didn't find how the html file is generated (I expected an html template under inst
folder, but I could not find it).
If you A) think this is worth adding, and B) want to spend time guiding me through it (even though it may take more time than if you did it by yourself -considering it make take some further discussion and reviewing my PR), please guide me a little bit on where is (are) the file(s) I need to modify to add those classes based on the field's name and I'd love to contribute in this excellent package.
xaringan work a bit differently than other R Markdown tools using Pandoc. This is because the HTML will contain some Markdown than remark.js will process to convert to HTML in the browser directly.
This means the in the HTML file you'll find this for the title slide. (example with skeleton file)
class: center, middle, inverse, title-slide
# Presentation Ninja
## ⚔<br/>with xaringan
### Yihui Xie
### RStudio, PBC
### 2016/12/12 (updated: 2021-12-23)
This is like what you would write yourself in the Rmd body.
That is why you may not find what you expect.
Adding a class to every field would make things easier to theme using CSS.
As you can see above, the automatic title slide will have a class title-slide
added. This is for the purpose of targeting easily its content, at least The HTML tag
div.remark-slide-content.title-slide > h1 {
}
and other CSS selector could be use.
It is not as perfect as what you are suggesting but it is already helpful.
Unfortunately, I am not sure that remark.js support adding a class to a header when writing Markdown.
Pandoc allows
# Presentation Ninja {.class}
but xaringan does not support this Pandoc syntax.
Anyway, I wanted to share some insights. @yihui is the real expert and can have other ideas.
Thank for the suggestion !
One trick that makes seal: false
a better option is to use the rmarkdown::metadata
object, which contains the information in the yaml frontmatter as a list. This helps avoid the problem of repeating info in both the header and the custom title slide. Here's an example from slides I've created that use the approach: https://github.com/gadenbuie/slides/blob/gh-pages/extra-special-xaringan/index.Rmd
Thank you for your detailed explanation, @cderv ! I may have phrased my initial issue differently: what I want to do is to be able to style subtitle, authors, institute and date individually, and I am limited to select only by heading levels, which is limited given that authors, institute and date are all h3 and do not have any other selector -I can't use its id, as it will change from slide to slide). Hence, my proposal.
I understand that current solution is quite good, but as far as I understand, currently there is no way to achieve what I want to achieve.
@gadenbuie I didn't know about rmarkdown::metadata
. After seeing your example I see I could use that as a workaround if what I was proposing (or any other better option) is not implemented. Thanks for pointing that out.
I may have phrased my initial issue differently: what I want to do is to be able to style subtitle, authors, institute and date individually, and I am limited to select only by heading levels, which is limited given that authors, institute and date are all h3 and do not have any other selector
Ah ok. Yes that would only be possible if we were to write HTML code directly or if remark.js had a way to allow adding classes on headers using Markdown syntax. We may found an idea to allow that though - that would be useful !
Thanks @gadenbuie for the rmarkdown::metadata
reminder: Using seal: false
is for now the best option.
@cderv has replied pretty much all that I'd say.
what I want to do is to be able to style subtitle, authors, institute and date individually, and I am limited to select only by heading levels, which is limited given that authors, institute and date are all h3 and do not have any other selector
That's not true. CSS selectors are very flexible. For example, you can select the 2nd h3 on the title slide:
.title-slide > h3:nth-of-type(2) {
color: red;
}
CSS selectors are very flexible. For example, you can select the 2nd h3 on the title slide:
@yihui , that's right. But it's not as flexible, as the nth h3 may differ, depending on whether the institute, date or authors are used or not. Therefore, having a class would make things easier to theme in any circumstance.
I thought it was relatively easy to add a class to the output, that's why I asked.
As pointed out at the end of https://github.com/yihui/xaringan/issues/340#issuecomment-1000389049, remark.js does not have a way to add classes to headers like Pandoc.
Personally I would use the nth-of-type()
selector that I mentioned above, although I admit classes would be more convenient and robust. For the five elements title
(h1
), subtitle
(h2
), author
(h3
), institute
(h3
), and date
(h3
), I feel it's most likely that the h2
subtitle is optional and may or may not be present, but since it is the only h2
, it wouldn't be a problem to CSS. For the three h3
elements, how often do you omit one of them? Probably not quite often. If you have to omit one, you could use a white space as a placeholder, so you can assume that the first h3 is author, second is institute, and third is date.
If you don't like the placeholder idea, you can add classes to text using remark.js's syntax, e.g.,
title: ".title[My great title]"
date: ".date[2022-02-22]"
but note that this doesn't add the class to the header element, but to a <span>
inside the header.
With the three workarounds (1. nth-of-type()
+ placeholder, 2. .class[]
, and 3. seal: false
+ rmarkdown::metadata
), and the fact that remark.js doesn't support adding classes to headers, I'm afraid that we can't do much about this request...
Well, on second thought, I just added the classes anyway (2ad2a6d7c78cbca919d1687765c118a8e8c4e5ea), but the result will be <div class="title"><h1>Title</h1></div>
. That is, the class is added to the outer div
instead of h1
.
This could be a breaking change if any user was styling these elements using the >
operator, e.g., .title-slide > h1
(i.e., selecting the direct child of .title-slide
), but I guess this might be rare.
Thanks, @yihui! 👏
Currently, the first slide is generated from yaml fields such as title, subtitle, author, institute, date... Whenever they are present, they are rendered as follows:
<h1 id="my-title">My title</h1>
<h2 id="my-subtitle">My subtitle</h2>
<h3 id="author1-name-authorn-name">Author's 1 name, Author's n name</h3>
<h3 id="the-name-of-the-place-where-i-work">The name of the place where I work</h3>
<h3 id="dd-mm-yyyy">DD-MM-YYYY</h3>
I wish a class corresponding to the field could be added, like these ones:
<h1 id="my-great-title" class="title">My great title</h1>
<h2 id="my-greater-subtitle" class="subtitle">My greater subtitle</h2>
<h3 id="author1-name-authorn-name" class="author">Author's 1 name, Author's n name</h3>
<h3 id="the-name-of-the-place-where-i-work" class="institute">The name of the place where I work</h3>
<h3 id="dd-mm-yyyy" class="date">DD-MM-YYYY</h3>
Adding a class to every field would make things easier to theme using CSS. I know I can create a custom initial slide using
seal: false
, but I do find very convenient not having to retype the same information I will be filling in yaml's frontmatter.By filing an issue to this repo, I promise that
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')
.I understand that my issue may be closed if I don't fulfill my promises.