Closed mattwarkentin closed 1 month ago
I like the style but wonder if it would be a good fit for slides? Have you seen namedropR? I haven't tried it but I saw it in my feed recently and thought it was an interesting approach, esp for citations in slides and live presentations.
namdropR
is new to me. I guess I was thinking about my more academic-focused presentations where the first several slides are background information with citations. It would be nice when presenting or sharing the slides to hover for more information. I am not sure in that space whether a QR code would work, but I'm open to the idea.
Whatever implementation we hypothetically go with would need to be widely appealing, so its worth thinking about format a good deal, assuming the implementation is possible.
How about including the namedropR
citation in a hover popup. Is that getting too crazy? It seems like perhaps that would solve both problems of space and still provide ease of access.
@gadenbuie I think I've got a pretty good start on an implementation. However, I am running into an issue that I think you can probably help with. I've got the implementation working in a standard HTML document (from R Markdown), but when I switch to xaringan
, the HTML returned by my R function is not handled the same.
Is there a recommended way for how an R function should safely return HTML and have that HTML be treated as raw HTML in the output/xaringan document? I've tried a few things without success.
Basically my R function returns a htmltools::tags$a(...)
object but it is not being rendered in the output document as-is. Thoughts?
Can you show me an example of what you expect and what you actually get?
One thing I've run into frequently with xaringan is that the markdown parser eagerly wraps things in paragraph tags in places where I wasn't expecting them. So maybe that's part of it?
I can send some code over when I get to work tomorrow morning. But I think what you described is exactly what is happening. My function returns raw HTML, but part of it is getting spliced into random paragraph tags.
My function returns an <a>
element with an attribute that is a string of more raw HTML (that gets handled by the relevant JS). Something like: <a data-attr="<table>...</table>">Text</a>
. But the attribute string of HTML is getting borked by xaringan
.
Okay, I hacked together a reprex. I think you'll need the dev version of namedropR
to ensure it runs as expected. The R Markdown renders as expected for rmarkdown::html_document
, but not as xaringan::moon_reader
.
---
title: "Citation example"
output:
html_document: default
xaringan::moon_reader: default
bibliography: [refs.bib]
---
<script src="https://unpkg.com/@popperjs/core@2/dist/umd/popper.min.js"></script>
<script src="https://unpkg.com/tippy.js@6/dist/tippy-bundle.umd.js"></script>
<style type="text/css" media="all">
.tippy-box[data-theme~='simple'] {
background-color: white;
border: 1px solid black;
}
</style>
<script type="text/javascript" charset="utf-8">
window.addEventListener('DOMContentLoaded', (event) => {
tippy('[data-tippy-content]', {
interactive: true,
allowHTML: true,
hideOnClick: true,
trigger: 'click',
placement: 'auto',
theme: 'simple',
maxWidth: 'none'
});
});
</script>
```{r echo=FALSE, message=FALSE}
library(namedropR)
library(htmltools)
.keys <- vector('character')
cite <- function(key) {
bibs <- rmarkdown::metadata$bibliography
if (length(bibs) > 1) {
tmp_bib <- tempfile(fileext = '.bib')
purrr::walk(bibs, function(b) write(readLines(b), tmp_bib, append = TRUE))
bibs <- tmp_bib
}
.keys <<- unique(c(.keys, key))
tooltip <- htmltools::includeHTML(
drop_name(
bibs,
output_dir = tempdir(),
cite_key = key,
export_as = "html",
use_xaringan = TRUE,
include_qr = 'embed',
qr_hyperlink = TRUE,
qr_size = 150,
style = 'classic'
)
)
tooltip <- as.character(tooltip)
id <- which(.keys == key)
tags$a(
id,
href = "javascript:void(0)",
`data-tippy-content` = tooltip
)
}
r cite('Eschrich1983')
You will also need `refs.bib`:
```bib
@article{Eschrich1983,
doi = {10.1007/bf00396886},
url = {https://doi.org/10.1007/bf00396886},
year = {1983},
month = may,
publisher = {Springer Science and Business Media {LLC}},
volume = {157},
number = {6},
pages = {540--547},
author = {Walter Eschrich},
title = {Phloem unloading in aerial roots of Monstera deliciosa},
journal = {Planta}
}
I'm very certain that there's some kind of issue with whitespace and newlines going on here.
Since it's a little roundabout to get the namedropR html, I'd recommend collecting the name drop htmls into a JSON object that you embed via <script type="application/json">...</script>
somehow. Then, you'd make the initial tooltip element pretty concise, e.g. <span data-namedropr="key">citation number/text</span>
, and use javascript to inject the tooltip in the right way thereafter.
Okay, sounds good. I will play around with this implementation idea some more and see what works. Will share when I've got something a little more established. Thanks for the suggestion.
Okay, I could actually use a little bit more nudging in the right direction. It is relatively straightforward to have the R function return a span
or a
element with some attribute/key and then use this key to inject the HTML tooltip from the JS side of things. I feel comfortable implementing this.
My issue is with making the JSON object available in a script tag...
I have assumed the usage will be as shown before, using cite()
multiple times throughout the document. So far, each invocation will return a span element, and behind the scenes store the name drop HTML in a hidden named list. The last step should be packaging up the named list as a JSON obejct (jsonlite::toJSON
) and then wrapping that in the script tag.
But when/how do I do this final step? It should run after all of the cite()
calls have been made, so ideally as the last bit of code ran in the document...something like on.exit()
but for the whole knitr rendering. Am I over-thinking this?
I think you could probably pair the <a>
or <span>
tag with a <script>
containing the JSON. You'd want to use a consistent pair of attributes, e.g. data-namedropR="citekey"
on the a/span and data-namedropR-for="citekey"
on the script tag. (And you'd only need to add the script tag once per citekey.)
Then, on load, you'd look for script[data-namedropR-for]
and read the data in them and then use that to build the element you really want with JavaScript to augment the placeholder elements.
Hmm. That was my original strategy but I was unable to have the R function return a tagList
object containing both a span
and a script
element. When I tried this, neither element was to be found in the HTML document.
The two key things that happen in this approach are:
jsonlite::toJSON()
makes minified single-line json by default.When I tried this, neither element was to be found in the HTML document.
Oh weird. Hmmm it should be possible. If you try it again and can make another reprex or PR, I'll be happy to take a look.
Okay, woof. I tried to push a draft PR of this feature but I forgot I have an open PR already for scribble. So these changes are part of that PR at the moment. Not sure how to proceed. Should've used branches...
Assuming that my remote is called upstream
locally (it probably is).
git fetch upstream
# if that errors, then add my repo
git remote add upsream https://github.com/gadenbuie/xaringanExtra.git
Start from your main
branch that's really the PR branch
# then from your main branch
git checkout -b citations upstream/main
git cherry-pick 1367261fd83f732ddbe1c3a1396cf78d332b03d5
git push -u origin citations
That'll send the citations branch to https://github.com/mattwarkentin/xaringanExtra where you can create the PR for the citations feature.
Then go back to your main
and clean up those extra commits, force pushing back to GitHub to remove the extra commits
git checkout main
git reset --hard 972496718ad8fb5c4cd7c44b5dff9314a37036d1
git push --force
Unfortunately, you can't rename your main
branch or move the PR branch without closing the PR. So for now just wait until I merge it and then you'll have to delete your branch and recreate it.
Hi @gadenbuie,
I have always wanted citation support for
xaringan
. I know that the markdown inxaringan
is protected from pandocs rendering, so this would require a clever approach, I think. I know citation support has been requested several times in the mainxaringan
repo (https://github.com/yihui/xaringan/issues/26, https://github.com/yihui/xaringan/issues/74). But I wanted to open an issue here to discuss this with you and assess the feasibility.Personally, I would love to work toward the type of citation support offered in
distill
articles, whereby a citation is denoted by standard markdown syntax[@tag]
and the citation is rendered such that hovering over the in-text citation reveals the full citation (https://rstudio.github.io/distill/#citations).Distill citations: https://rstudio.github.io/distill/citations.html
What are your initial thoughts?