forked from mitchelloharawild/vitae
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bibliography.R
107 lines (95 loc) · 3.32 KB
/
bibliography.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#' Print bibliography section
#'
#' Given a bibliography file, this function will generate bibliographic entries
#' for one or more types of bib entry.
#'
#' @param file A path to a bibliography file understood by [`rmarkdown::pandoc_citeproc_convert()`].
#' @param startlabel Defunct.
#' @param endlabel Defunct.
#'
#' @return A dataset representing the bibliographic entries, suitable for
#' generating a reference section in a document.
#'
#' @author Rob J Hyndman & Mitchell O'Hara-Wild
#'
#' @examples
#'
#' # Create a bibliography from a set of packages
#' bib <- tempfile(fileext = ".bib")
#' knitr::write_bib(c("vitae", "tibble"), bib)
#'
#' # Import the bibliography entries into a CV
#' bibliography_entries(bib)
#'
#' # The order of these entries can be customised using `dplyr::arrange()`
#' bibliography_entries(bib) %>%
#' arrange(desc(title))
#'
#' # For more complex fields like author, you can also sort by component fields.
#' # For example, use `author$family` to sort by family names.
#' bibliography_entries(bib) %>%
#' arrange(desc(author$family))
#'
#' @export
bibliography_entries <- function(file, startlabel = NULL, endlabel = NULL) {
if(!is.null(startlabel)){
warning("The `startlabel` argument is defunct and will be removed in the next release.\nPlease use a different approach to including labels.")
}
if(!is.null(endlabel)){
warning("The `endlabel` argument is defunct and will be removed in the next release.\n. Please use a different approach to including labels.")
}
bib <- rmarkdown::pandoc_citeproc_convert(file)
bib_ptype <- csl_fields[unique(vec_c(!!!lapply(bib, names)))]
bib_ptype <- vctrs::vec_init(bib_ptype, 1)
# Add missing values to complete rectangular structure
bib <- lapply(bib, function(x) {
# missing_cols <- setdiff(names(bib_ptype), names(x))
# x[missing_cols] <- as.list(bib_ptype[missing_cols])
array_pos <- lengths(x) > 1
x[array_pos] <- lapply(x[array_pos], list)
bib_ptype[names(x)] <- x
bib_ptype
})
bib <- vctrs::vec_rbind(!!!bib, .ptype = bib_ptype)
tibble::new_tibble(bib, preserve = "id",
class = c("vitae_bibliography", "vitae_preserve"),
nrow = nrow(bib))
}
#' @importFrom tibble tbl_sum
#' @export
tbl_sum.vitae_bibliography <- function(x) {
x <- NextMethod()
c(x, "vitae type" = "bibliography entries")
}
#' @importFrom knitr knit_print
#' @export
knit_print.vitae_bibliography <- function(x, options = knitr::opts_current$get()) {
# Reconstruct yaml from tibble
yml <- lapply(
dplyr::group_split(dplyr::rowwise(x)),
function(x) {
x <- as.list(x)
el_is_list <- vapply(x, is.list, logical(1L))
x[el_is_list] <- lapply(x[el_is_list], `[[`, i=1)
Filter(function(x) !is.na(x[1]) && length(x) > 0, x)
})
if((options$cache %||% 0) == 0) {
file <- tempfile(fileext = ".yaml")
} else {
file <- paste0(options$cache.path, options$label, ".yaml")
}
yaml::write_yaml(list(references = yml), file = file)
startlabel <- x %@% "startlabel"
endlabel <- x %@% "endlabel"
# Convert file separator to format expected by citeproc
file <- gsub("\\", "/", file, fixed = TRUE)
out <- glue(
'
::: {#bibliography}
<< file >>
:::
',
.open = "<<", .close = ">>"
)
knitr::asis_output(out, meta = list(structure(x$id, class = "vitae_nocite")))
}