How to create pages from a bibtex file with Quarto
I have a bibtex file with all my publications downloaded for the journal websites, so it includes all the data available (title, authors, abstract, etc).
For this website, I wanted to list my publications using this file instead of doing it manually. Here are the steps I followed:
- Create a template qmd file
- Iterate through bibtex to write one file for each publication using the function quarto_render
- Optimize the script
- Configure quarto to run it before rendering the website and create a quarto page listing publications
QMD template
This file will be rendered for each publication to generate one qmd file per paper. The values are passed with the params object. As we keep this file into the publications folder, we put an underscore at the start of the filename (**_pubtemplate.qmd**) so Quarto does not add it to the list of publications.
---
params:
authors: null
abstract: null
ref: null
link: null
year: null
engine: knitr
---
`r params$abstract`
[Full publication](`r params$link`)
#### Reference
`r params$ref`
---`r params$authors`"
authors: "`r params$year`"
year: " ---
Iteration through bibtex
With bibtex and bib2df, we read and convert bibtex file to a dataframe.
library(bibtex)
library(bib2df)
# Read bibtex for references
<- read.bib("publications.bib")
biblio
# Converting bibtex to DF to loop into
<- bib2df("publications.bib")
biblio.df <- biblio.df[biblio.df$CATEGORY %in% c("ARTICLE","MISC","INCOLLECTION"),] biblio.df
Then we iterate through each entry and render it
for(i in 1:nrow(biblio.df)) {
quarto_render(
input = "_pubtemplate.qmd",
output_file = paste0(biblio.df$BIBTEXKEY[i],".qmd"),
output_format = "markdown",
metadata = list(title = biblio.df$TITLE[i]),
execute_params = list(
authors = paste0(unlist(biblio.df$AUTHOR[i]), collapse = "; "),
abstract = biblio.df$ABSTRACT[i],
ref = format(biblio[biblio.df$BIBTEXKEY[i]], style = "text"),
link = biblio.df$URL[i],
year = biblio.df$YEAR[i]
)
) }
Script optimization
The script checks the last modification dates to not render again entries without modifications, so the rendering is faster.
Notice that when the flag run.again
is set to TRUE
, the script will always render the qmd files. Set it to FALSE
to render only new entries.
Here is the final result:
library(bibtex)
library(bib2df)
library(xfun)
# This flag forces to generate again the qmds
<- TRUE
run.again
# Read bibtex for references
<- read.bib("publications.bib")
biblio
# Converting bibtex to DF to loop into
<- bib2df("publications.bib")
biblio.df <- biblio.df[biblio.df$CATEGORY %in% c("ARTICLE","MISC","INCOLLECTION"),]
biblio.df
# bibtex time stamp
<- file.mtime("publications.bib")
bib.mtime
for(i in 1:nrow(biblio.df)) {
# We don't render qmd files if they are more recent than the bibtex file
if (file_exists(paste0("publications/",biblio.df$BIBTEXKEY[i],".qmd"))) {
if(bib.mtime < file.mtime(paste0("publications/",biblio.df$BIBTEXKEY[i],".qmd")) & !run.again) {
next
}
}# quarto_render needs to be executed in the dir where the files are
# that's why we use in_dir
in_dir(
"publications",
::quarto_render(
quartoinput = "_pubtemplate.qmd",
output_file = paste0(biblio.df$BIBTEXKEY[i],".qmd"),
output_format = "markdown",
metadata = list(title = biblio.df$TITLE[i]),
execute_params = list(
authors = paste0(unlist(biblio.df$AUTHOR[i]), collapse = "; "),
abstract = biblio.df$ABSTRACT[i],
ref = format(biblio[biblio.df$BIBTEXKEY[i]], style = "text"),
link = biblio.df$URL[i],
year = biblio.df$YEAR[i]
)
)
) }
We save it as _build.qmds.R
in the root directory.
Wrap it up
Folder structure
In the root directory, we have the following files:
publications.bib
: bibtex where is all the info on the paperspublications.qmd
: listing of publications (see below)_build.qmds.R
: the script to create qmd for each bibtex entry
In the publications directory, we have:
_pubtemplate.qmd
: the template to render- one qmd file for each bibtex entry once the script is executed
To run the script before rendering the website, we modify the _quarto.yml
file as follows:
project:
type: website
pre-render: _build.qmds.R
And create a file called publications.qmd
to list publications with the following code:
---
title: "Publications"
listing:
type: table
contents: publications
fields: [year,title,authors]
sort-ui: [title,year]
sort: "year desc"
field-display-names:
title: "Title"
year: "Year"
authors: "Authors"
---
That’s it!