Skip to content

Instantly share code, notes, and snippets.

@johnbaums
Last active April 7, 2020 00:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnbaums/40f973e2483150986fb53ca5e4200cbc to your computer and use it in GitHub Desktop.
Save johnbaums/40f973e2483150986fb53ca5e4200cbc to your computer and use it in GitHub Desktop.
Collapse numeric in-text citations produced by bookdown, retaining links to chapter bibliography while ensuring all refs within collapsed ranges are included in the bibliography.
collapse_numeric <- function(index) {
# index: path to home page of bookdown-generated HTML book (e.g. index.html)
doc <- readLines(index)
pages <- file.path(
dirname(index), sub('.*data-path="(.*?)".*', '\\1',
grep('data-level="\\d+"', doc, val=T))
)
lapply(pages, function(p) {
x <- rmarkdown:::read_utf8(p)
idx <- grep('doc-biblioref', x)
if(length(idx) > 0) {
for(idx_ in idx) { # lines (paras) containing cites
m <- regmatches(x[idx_], gregexpr('<span class="citation">.*?</span>',
x[idx_], perl=TRUE))[[1]]
# ^ find in-text citations
m_split <- strsplit(m, ',')
m_split_new <- lapply(m_split, function(x) {
j <- as.numeric(gsub('.*>(\\d+)</a>.*', '\\1', x))
# extract numeric component
n <- length(j)
if(n > 1) {
starts <- c(1, which(diff(j) > 1) + 1)
ends <- c(which(diff(j) > 1), n)
paste(mapply(function(a, b) {
if(b-a > 1) {
paste(x[unique(c(a, b))], collapse='-')
} else {
paste(x[unique(a:b)], collapse=',')
# ^ don't collapse if only a single number or just two consecutive numbers
}
}, starts, ends), collapse=',')
# ^ collapse
} else {
x
}
})
for(i in seq_along(m_split)) {
x <- sub(m[i], m_split_new[[i]], x)
}
rmarkdown:::write_utf8(x, p)
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment