I have been trying for some time now to reorganize much of my workflow around Yihui Xie’s great collection of R packages around R Markdown. So when looking for a conventient way to share little tidbits of code, figures, tutorials and other random stuff I stumbled across his blogdown R package and decided to give it a try. Unsurprisingly my initial plan to briefly try it out escalated somewhat and I ended up redoing my academic website from scratch, including this blog, based on blogdown and Hugo.
The tl;dr version of the steps I ended up doing is this:
- Watched blogdown screencast by Daniel Quintana’s
- Familiarized myself with the structure and examples of the academic theme
- Used a modified version of Lorenzo Busetto’s script to import publications
- Followed this post to set up my site on github
- I used Peter Baumgartner’s tutorial to install disqus comments (not sure I will keep them)
- Finally, apparently like everybode else I followed Amber Thomas’s guide on how to make syntax highlighting work.
All the packages are well documented and as always I am totally convinced I will read through all of the documentation once I really commit to them. For now, however, I just wanted to see quickly what they can do and how well they are suited to what I want to do. This initial post is basically a summary of my googling efforts while setting up this site.
To gently ease myself into the topic I watched Daniel Quintana’s very helpful screencast. Like him I am using the academic theme by George Cushen. At this point I was already pretty excited and ready to redo my whole website. The only essential thing on my old website was the publication list. Blogdown wants an md file for each publication so this looked potentially painful. Luckily, Lorenzo Busetto had me covered with a script to import publications from bibtex to blogdown. I made some minor changes to make the script work for me:
- Exporting bibtex from zotero the field containing the document type is called bibtype instead of document_type.
- Added some opportunistic string cleaning code (mostly removing {} and escapes)
- Changed the script to export a folder for each publication instead of only files. This is more convenient when there is more material associated with a publication, for example
- I also export a cite.bib file into each folder to make the entries directly citeable on the website.
I wanted to publish the site on github. Github and I aren’t normally friends and some of the experiences I read sounded a bit daunting. Turns out it took about 6 minutes to create an account and publish the website following these simple steps.
Mostly out of curiosity I installed disqus comments for the blog. Not sure if that is a good or useful idea, especially considering that at least in my case stuff like this normally gets blocked by uMatrix.
Overall, as so often in the universe of R, I am deeply impressed by the genius of people. Now I just need to think of some interesting content to add to this site…
Script to import bibtex publications (modified from Lorenzo Busetto’s script).
#' @title bibtex_2academic
#' @description import publications from a bibtex file to a hugo-academic website
#' @author Lorenzo Busetto, phD (2017) <lbusett@gmail.com>
#' @modified Peter Paul Pichler (2019) <pichler@pik-potsdam.de>
bibtex_2academic <- function(bibfile,
outfold,
abstract = FALSE,
overwrite = FALSE) {
require(RefManageR)
require(dplyr)
require(stringr)
require(anytime)
require(tibble)
# Import the bibtex file and convert to data.frame
mypubs <- ReadBib(bibfile, check = "warn", .Encoding = "UTF-8") %>%
as.data.frame() %>%
rownames_to_column() %>% # retain rownames (as labels for bibtex re-export)
mutate_all(funs(str_remove_all(.,"[{}\"]"))) %>% ### remove {}" from bibtext entries
mutate_all(funs(str_replace_all(.,'\\\\%', '%'))) ### some replace double escaped % for markdown
# make bibtype the name of the type column (default for WriteBib)
if (has_name(mypubs, "document_type") & !(has_name(mypubs, "bibtype"))) {
mypubs <- mypubs %>% rename(bibtype = document_type)
}
# assign "categories" to the different types of publications
mypubs <- mypubs %>%
dplyr::mutate(
pubtype = dplyr::case_when(bibtype == "Article" ~ "2",
bibtype == "Article in Press" ~ "2",
bibtype == "InProceedings" ~ "1",
bibtype == "Proceedings" ~ "1",
bibtype == "Conference" ~ "1",
bibtype == "Conference Paper" ~ "1",
bibtype == "MastersThesis" ~ "3",
bibtype == "PhdThesis" ~ "3",
bibtype == "Manual" ~ "4",
bibtype == "TechReport" ~ "4",
bibtype == "Book" ~ "5",
bibtype == "InCollection" ~ "6",
bibtype == "InBook" ~ "6",
bibtype == "Misc" ~ "0",
TRUE ~ "0"))
# create a function which populates the md template based on the info
# about a publication
create_md <- function(x) {
# define a date and create filename by appending date and start of title
if (!is.na(x[["year"]])) {
x[["date"]] <- paste0(x[["year"]], "-01-01")
} else {
x[["date"]] <- "2999-01-01"
}
foldername <- paste(x[["date"]], x[["title"]] %>%
str_replace_all(fixed(" "), "_") %>%
str_remove_all(fixed(":")) %>%
str_sub(1, 20), sep = "_")
#folder = paste0(outfold, "/", foldername)
dir.create(file.path(outfold, foldername), showWarnings = FALSE)
filename = "index.md"
# start writing
outsubfold = paste(outfold, foldername, sep="/")
# start writing
if (!file.exists(file.path(outsubfold, filename)) | overwrite) {
fileConn <- file.path(outsubfold, filename)
write("+++", fileConn)
# Title and date
write(paste0("title = \"", x[["title"]], "\""), fileConn, append = T)
write(paste0("date = \"", anydate(x[["date"]]), "\""), fileConn, append = T)
# Authors. Comma separated list, e.g. `["Bob Smith", "David Jones"]`.
auth_hugo <- str_replace_all(x["author"], " and ", "\", \"")
auth_hugo <- stringi::stri_trans_general(auth_hugo, "latin-ascii")
write(paste0("authors = [\"", auth_hugo,"\"]"), fileConn, append = T)
# Publication type. Legend:
# 0 = Uncategorized, 1 = Conference paper, 2 = Journal article
# 3 = Manuscript, 4 = Report, 5 = Book, 6 = Book section
write(paste0("publication_types = [\"", x[["pubtype"]],"\"]"),
fileConn, append = T)
# Publication details: journal, volume, issue, page numbers and doi link
publication <- x[["journal"]]
if (!is.na(x[["volume"]])) publication <- paste0(publication,
", (", x[["volume"]], ")")
if (!is.na(x[["number"]])) publication <- paste0(publication,
", ", x[["number"]])
if (!is.na(x[["pages"]])) publication <- paste0(publication,
", _pp. ", x[["pages"]], "_")
if (!is.na(x[["doi"]])) publication <- paste0(publication,
", ", paste0("https://doi.org/",
x[["doi"]]))
write(paste0("publication = \"", publication,"\""), fileConn, append = T)
write(paste0("publication_short = \"", publication,"\""),fileConn, append = T)
# Abstract and optional shortened version.
if (abstract) {
write(paste0("abstract = \"", x[["abstract"]],"\""), fileConn, append = T)
} else {
write("abstract = \"\"", fileConn, append = T)
}
write(paste0("abstract_short = \"","\""), fileConn, append = T)
# other possible fields are kept empty. They can be customized later by
# editing the created md
write("image_preview = \"\"", fileConn, append = T)
write("selected = false", fileConn, append = T)
write("projects = []", fileConn, append = T)
write("tags = []", fileConn, append = T)
#links
write(paste0("url_pdf = \"", x[["url"]],"\""), fileConn, append = T)
write("url_preprint = \"\"", fileConn, append = T)
write("url_code = \"\"", fileConn, append = T)
write("url_dataset = \"\"", fileConn, append = T)
write("url_project = \"\"", fileConn, append = T)
write("url_slides = \"\"", fileConn, append = T)
write("url_video = \"\"", fileConn, append = T)
write("url_poster = \"\"", fileConn, append = T)
write("url_source = \"\"", fileConn, append = T)
#other stuff
write("math = true", fileConn, append = T)
write("highlight = true", fileConn, append = T)
# Featured image
write("[header]", fileConn, append = T)
write("image = \"\"", fileConn, append = T)
write("caption = \"\"", fileConn, append = T)
write("+++", fileConn, append = T)
}
# convert entry back to data frame
df_entry = as.data.frame(as.list(x), stringsAsFactors=FALSE) %>%
column_to_rownames("rowname")
# write cite.bib file to outsubfolder
WriteBib(as.BibEntry(df_entry[1,]), paste(outsubfold, "cite.bib", sep="/"))
}
# apply the "create_md" function over the publications list to generate
# the different "md" files.
apply(mypubs, FUN = function(x) create_md(x), MARGIN = 1)
}