Skip to content

Commit

Permalink
Prepare new person and refactor tests and API
Browse files Browse the repository at this point in the history
  • Loading branch information
dieghernan committed Feb 29, 2024
1 parent e5e7c7a commit b5f6d85
Show file tree
Hide file tree
Showing 46 changed files with 2,890 additions and 2,762 deletions.
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ references:
name: R Foundation for Statistical Computing
address: Vienna, Austria
year: '2024'
version: '>= 3.6.0'
version: '>= 4.0.0'
- type: software
title: cli
abstract: 'cli: Helpers for Developing Command Line Interfaces'
Expand Down
4 changes: 2 additions & 2 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ S3method(print,cff)
S3method(tail,cff)
S3method(toBibtex,cff)
export(as.cff)
export(as_bibentry)
export(cff)
export(cff_create)
export(cff_create_bib_text)
export(cff_create_person)
export(cff_extract_to_bibtex)
export(cff_from_bibtex)
Expand All @@ -21,7 +23,6 @@ export(cff_parse_person)
export(cff_parse_person_bibtex)
export(cff_read)
export(cff_read_bib)
export(cff_read_biblines)
export(cff_read_cff_citation)
export(cff_read_citation)
export(cff_read_description)
Expand All @@ -30,7 +31,6 @@ export(cff_schema_definitions_person)
export(cff_schema_definitions_refs)
export(cff_schema_keys)
export(cff_schema_keys_license)
export(cff_to_bibentry)
export(cff_to_bibtex)
export(cff_validate)
export(cff_write)
Expand Down
4 changes: 2 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ to non-core functions** that an user would rarely call, while `cff_create()`,
modified:

- The conversion from `cff` to `bibentry` is performed now by a new function
`cff_to_bibentry()`. Previous names of this function were `cff_to_bibtex()`
`as_bibentry()`. Previous names of this function were `cff_to_bibtex()`
and `cff_extract_to_bibtex()` that are now superseded.

- Now reading from external files is performed exclusively by `cff_read()` and
additionally by the more-specific new functions `cff_read_cff_citation()`,
`cff_read_description()`, `cff_read_citation()` and `cff_read_bib()`. It is
also possible to read BibTeX lines with `cff_read_biblines()`. Previous
also possible to read BibTeX lines with `cff_create_bib_text()`. Previous
function `cff_from_bibtex()` is now superseded.

- `write_bib()` and `write_citation()` superseded by `cff_write_bib()` and
Expand Down
109 changes: 62 additions & 47 deletions R/cff_to_bibentry.R → R/as_bibentry.R
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
#' Create BibTeX entries from several sources
#' Create `bibentry` objects from several sources
#'
#' @rdname cff_to_bibentry
#' @name cff_to_bibentry
#' @rdname as_bibentry
#' @name as_bibentry
#' @order 1

#' @description
#'
#' This function creates [bibentry()] objects
#' from different metadata sources (`cff` objects, `DESCRIPTION` files, etc.).
#' This function creates `bibentry` objects (see [utils::bibentry()]) from
#' different metadata sources (`cff` objects, `DESCRIPTION` files, etc.). Note
#' that a **R** `bibentry` object is the representation of a BibTeX entry,
#' see **Examples**
#'
#' The function tries to map the information of the source `x` into a `cff`
#' object and performs a mapping of the metadata to BibTeX, according to
#' `vignette("bibtex_cff", "cffr")`.
#'
#' Note that a **R** [bibentry()] object is the representation of a BibTeX
#' entry, see **Examples**.
#'
#' @seealso
#' [utils::bibentry()]
#'
#' @references
#' - Patashnik, Oren. "BIBTEXTING" February 1988.
Expand Down Expand Up @@ -44,9 +46,11 @@
#' both the preferred citation info and the references.
#'
#' @family bibtex
#' @family coercing
#'
#' @return A `bibentry` object or a list of `bibentry` objects. This could
#' be parsed to BibTeX using [toBibtex()]
#' @return
#' `as_bibentry()` returns s `bibentry` object (or a list of `bibentry`
#' objects).
#'
#' @export
#'
Expand All @@ -58,7 +62,7 @@
#' cff_object
#'
#' # bibentry object
#' bib <- cff_to_bibentry(cff_object)
#' bib <- as_bibentry(cff_object)
#'
#' class(bib)
#'
Expand All @@ -75,26 +79,26 @@
#' # From a CITATION.cff file with options
#'
#' path <- system.file("examples/CITATION_complete.cff", package = "cffr")
#' cff_file <- cff_to_bibentry(path, what = "all")
#' cff_file <- as_bibentry(path, what = "all")
#'
#' toBibtex(cff_file)
#'
#' # For an installed package
#'
#' installed_package <- cff_to_bibentry("jsonvalidate")
#' installed_package <- as_bibentry("jsonvalidate")
#'
#' toBibtex(installed_package)
#'
#'
#' # Use a DESCRIPTION file
#'
#' path2 <- system.file("examples/DESCRIPTION_gitlab", package = "cffr")
#' desc_file <- cff_to_bibentry(path2)
#' desc_file <- as_bibentry(path2)
#'
#' toBibtex(desc_file)
#' }
cff_to_bibentry <- function(x,
what = c("preferred", "references", "all")) {
as_bibentry <- function(x,
what = c("preferred", "references", "all")) {
what <- match.arg(what)
if (is.null(x)) {
return(NULL)
Expand All @@ -109,28 +113,52 @@ cff_to_bibentry <- function(x,
} else {
obj <- cff_create(x)
}
if (what == "preferred") {
return(cff_bibtex_parser(obj))
}

if (what == "references") {
if (is.null(obj$references)) {
return(NULL)

# Three cases:
# A) Full cff reference object or
# B) Individual reference list
# C) List of references


# Detect case A
is_full_cff <- "cff-version" %in% names(obj)
# Detect case B
is_single_ref <- "type" %in% names(obj)

if (is_full_cff) {
# Try to generate preferred if not present
if (!("preferred-citation" %in% names(obj))) {
prefcit <- obj
prefcit$type <- "generic"
prefcit <- prefcit[names(prefcit) %in% cff_schema_definitions_refs()]
prefcit <- new_cff(prefcit)
# And add to the object
obj$`preferred-citation` <- prefcit
}

ref <- lapply(obj$references, cff_bibtex_parser)
return(do.call(c, ref))
# Select type to extract
obj_extract <- switch(what,
"preferred" = list(obj$`preferred-citation`),
"references" = obj$references,
c(list(obj$`preferred-citation`), obj$references)
)
} else if (is_single_ref) {
obj_extract <- list(obj)
} else {
obj_extract <- obj

Check warning on line 149 in R/as_bibentry.R

View check run for this annotation

Codecov / codecov/patch

R/as_bibentry.R#L149

Added line #L149 was not covered by tests
}

pref <- cff_bibtex_parser(obj)

if (!is.null(obj$references)) {
ref <- lapply(obj$references, cff_bibtex_parser)
ref <- do.call(c, ref)
return(c(pref, ref))
# Cleanup
obj_extract <- obj_extract[lengths(obj_extract) > 0]
if (length(obj_extract) == 0) {
return(NULL)
}

return(pref)
ref <- lapply(obj_extract, cff_bibtex_parser)
ref <- do.call(c, ref)

return(ref)
}


Expand All @@ -141,22 +169,6 @@ cff_bibtex_parser <- function(x) {

stopifnotcff(x)

# Read cff of CITATION.cff file
if (!is_cff(x)) {
x <- cff(x)
}

# Try to generate preferred if not present
if (!("preferred-citation" %in% names(x))) {
origtype <- clean_str(x$type)

if (is.null(origtype)) {
x$type <- "misc"
}
} else {
x <- x$`preferred-citation`
}

# Partially based on ruby parser
# https://github.com/citation-file-format/ruby-cff/blob/main/lib/cff/ >>
# (cont) formatter/bibtex_formatter.rb
Expand Down Expand Up @@ -528,5 +540,8 @@ cff_bibtex_parser <- function(x) {
return(NULL)
}

# Unlist easy to undo the do.call effect
bib <- bib[[1]]

return(bib)
}
28 changes: 23 additions & 5 deletions R/cff-methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,26 @@ as.data.frame.cff <- function(x, row.names = NULL, optional = FALSE, ...) {
return(the_df)
}

#' Persons
#' @rdname cff_create_person
#' @name as.person.cff
#' @order 2
#'
#' @noRd
#' @description
#' Additionally, it is also provided a method for [as.person()], that can
#' convert [`cff`][cff-class] objects to `person` objects as
#' provided by [utils::person()].
#'
#' This method only works with CFF persons, not with full `cff` objects.
#'
#' @family s3method
#' @export
#' @seealso [utils::person()]
#'
#' @param x `cff` object representing a person or entity.
#'
#' @return
#'
#' `as.person.cff()` returns a `person` object.
as.person.cff <- function(x) {
# If single enclose on a list
is_single <- any(grepl("^name$|^given-names|^family-names", names(x)))
Expand Down Expand Up @@ -81,7 +97,8 @@ tail.cff <- function(x, n = 6L, ...) {
}


#' @rdname cff_to_bibentry
#' @rdname as_bibentry
#' @name toBibtex.cff
#' @order 2
#'
#' @description
Expand All @@ -99,13 +116,14 @@ tail.cff <- function(x, n = 6L, ...) {
#'
#' @return
#'
#' `toBibtex.cff()` returns a `Bibtex` object.
#' `toBibtex.cff()` returns a `Bibtex` object that can be printed as BibTeX
#' markup.
toBibtex.cff <- function(object, ...,
what = c("preferred", "references", "all")) {
# If a single reference...
if ("cff-version" %in% names(object)) {
# If full cff
biblist_cff <- cff_to_bibentry(x = object, what = what)
biblist_cff <- as_bibentry(x = object, what = what)
} else {
# Need to enlist if single
if ("type" %in% names(object)) {
Expand Down
Loading

0 comments on commit b5f6d85

Please sign in to comment.