Skip to content

Instantly share code, notes, and snippets.

@friendly
Created June 14, 2023 20:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save friendly/65d93883b260676ed2f543f4727eb454 to your computer and use it in GitHub Desktop.
Save friendly/65d93883b260676ed2f543f4727eb454 to your computer and use it in GitHub Desktop.
Generate a BibTeX file of all installed packages
#' Generate a BibTeX file of all installed packages
#'
#' This function finds all packages installed in your R library and calls
#' `citation()` for each, collecting the BibTeX entries and writing these to
#' a file. It handles situations where there are multiple citations for a package.
#'
#' @param filename Name of the .bib file to write to.
#' @param header Include a header giving `sessionInfo()` ?
#' @param preamble Preamble for the BibTeX file
#' @param prefix String to prefix the in the bibtex key
#' @param suppress.warnings Whether to suppress warnings
#' @param verbose
#'
#' @author Achim Zeileis, Michael Friendly
#' @seealso [knitr::write_bib()]
#'
#' @return Invisibly returns the bibtex entries
#' @export
#'
#' @examples
#' Rpackages_bib()
#' Rpackages_bib(prefix="R-") # match what knitr::write_bib() does
#'
#'
# Original code by Achim Zeileis, 16 Dec 2009, R-help
# Revised code for R 2.14.0 by Achim Zeleis, 16 Dec 2011, R-devel
# Added: support for header and preamble
## TODO:
# - fix page numbers from (\d+)-(\d+) to $1--$2
# - fix title MiXed CaSe words to {MiXed} {CaSe}
## Temp fix: use perl
#% Fixups:
#% title MiXed CaSe words modified to {MiXed} {CaSe} by:
#% perl -pi~ -e "m|title| && s|\s(\w+[A-Z]+\w*)(\b)| {$1}$2|g" Rpackages-2.14.0.bib
#% [This still does not handle strings like "S", "R", "(Voroni)", etc.]
#% page numbers modified from dd-dd to dd--dd by
#% perl -pi~ -e "m|pages| && s|(\d+)-(\d+)|$1--$2|" Rpackages-2.14.0.bib
Rpackages_bib <- function(filename = paste0("Rpackages-",getRversion(), ".bib"),
header=TRUE,
preamble=NULL,
prefix = NULL,
suppress.warnings=TRUE,
verbose = TRUE)
{
## query packages and their bibentries
pkgs <- unique(installed.packages()[,1])
if (suppress.warnings) {
warn <- options(warn=-1)
on.exit(options(warn))
}
bibs <- lapply(pkgs, function(x) try(citation(x)))
n.installed <- length(bibs)
## exclude those with errors
ok <- !(sapply(bibs, class) == "try-error")
pkgs <- pkgs[ok]
bibs <- bibs[ok]
n.converted <- sum(ok)
## number of bibentries per package
nref <- sapply(bibs, length)
ncit <- sum(nref)
## merge all bibentries
bibs <- do.call("c", bibs)
## add citation keys; need to number those where there's more than one
bibkeys <- lapply(1:length(nref), function(i)
if(nref[i] > 1) paste0(prefix, pkgs[i], 1:nref[i], sep = "-")
else paste0(prefix, pkgs[i]))
bibs$key <- as.list(unlist(bibkeys))
# make page numbers proper: fix from (\d+)-(\d+) to $1--$2
# this doesn't quite work-- it screws up the structure of the bibs object
# for (i in 1:length(bibs)) {
# if(!is.null(bibs[[i]]$pages)) {
# bibs[[i]]$pages <- sub('(\\d+)-(\\d+)', '\\1--\\2', bibs[[i]]$pages)
# }
# }
if(header) {
header <- gsub("^", "%", toLatex(sessionInfo()))
header <- c(paste("%BibTeX file:", filename, "written", Sys.Date(), "by Rpackages.bib()\n"),
header)
}
unlink(filename)
output <- file(filename, "a")
cat(header, preamble, sep='\n', file=output, append=TRUE)
writeLines(toBibtex(bibs), con=output)
close(output)
if(verbose) cat("Converted", n.converted, "citations in", n.installed,
"packages to BibTeX, containing", ncit, "entries.",
"\nResults written to file", filename, "\n")
## return Bibtex items invisibly
invisible(bibs)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment