Skip to content

Commit

Permalink
Move readers
Browse files Browse the repository at this point in the history
  • Loading branch information
dieghernan committed Feb 20, 2024
1 parent f8673e9 commit d9021af
Show file tree
Hide file tree
Showing 18 changed files with 257 additions and 318 deletions.
46 changes: 0 additions & 46 deletions R/cff-methods.R
Original file line number Diff line number Diff line change
Expand Up @@ -79,49 +79,3 @@ head.cff <- function(x, n = 6L, ...) {
tail.cff <- function(x, n = 6L, ...) {
as.cff(NextMethod())
}

make_r_person <- function(x) {
if (is.null(names(x))) {
return(person())
}
checknames <- grepl("^name$|given-names|family-names", names(x))
if (!isTRUE(any(checknames))) {
return(person())
}
# Prepare list
# Family is special key
fam1 <- clean_str(x$name)
fam2 <- clean_str(
paste(
clean_str(x$`name-particle`), clean_str(x$`family-names`),
clean_str(x$`name-suffix`)
)
)

given <- clean_str(x$`given-names`)
family <- clean_str(c(fam1, fam2))

# Make comments
x_comments <- x[!names(x) %in% c(
"family-names", "given-names",
"name-particle", "name-suffix", "email"
)]

x_comments <- lapply(x_comments, clean_str)
x_comments <- unlist(x_comments, use.names = TRUE)

# Prepare ORCID
x_comments <- gsub("^https://orcid.org/", "", x_comments)
nm <- gsub("orcid", "ORCID", names(x_comments), fixed = TRUE)
names(x_comments) <- nm

pers_list <- list(
given = given,
family = family,
email = clean_str(x$email),
comment = x_comments
)


do.call(person, pers_list)
}
4 changes: 2 additions & 2 deletions R/cff_create.R
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,10 @@ cff_create <- function(x, keys = list(), cff_version = "1.2.0",
cit_path <- gsub("DESCRIPTION$", "CITATION", x)
}
if (file.exists(cit_path)) {
citobj <- parse_r_citation(desc_path, cit_path)
citobj <- lapply(citobj, cff_parse_citation)
citobj <- cff_safe_read_citation(desc_path, cit_path)
if (length(citobj) == 0) citobj <- NULL
citobj <- drop_null(citobj)
citobj <- unname(citobj)
}
} else {
msg <- paste0(
Expand Down
109 changes: 95 additions & 14 deletions R/cff_read.R
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,66 @@
#' @param encoding Encoding to be assumed for `path`. See [readLines()].
#' @param meta A list of package metadata as obtained by
#' [utils::packageDescription()] or `NULL` (the default). See **Details**.
#' @param ... Arguments to be passed to other functions.
#' @param ... Arguments to be passed to other functions (i.e. to
#' [yaml::read_yaml()], [bibtex::read.bib()], etc.).
#'
#' @return
#' A [`cff`][cff-class] object. In the case of [cff_read_cff_citation()] and
#' [cff_read_description()] a full and (potentially) valid `cff` object.
#'
#'
#' In the case of [cff_read_bib()] and [cff_read_citation()], the result is
#' the `cff` version of a [bibentry()] object (i.e. a bibliographic reference),
#' that can be used to complement another `cff` object.
#' that can be used to complement another `cff` object. See
#' `vignette("bibtex_cff", "cffr")` to get further insights on how this
#' conversion is performed.
#'
#'
#' @references
#'
#' R Core Team (2023). _Writing R Extensions_.
#' <https://cran.r-project.org/doc/manuals/r-release/R-exts.html>
#' - R Core Team (2023). _Writing R Extensions_.
#' <https://cran.r-project.org/doc/manuals/r-release/R-exts.html>
#'
#' - Hernangomez D (2022). "BibTeX and CFF, a potential crosswalk."
#' *The cffr package, Vignettes*. \doi{10.21105/joss.03900},
#' <https://docs.ropensci.org/cffr/articles/bibtex_cff.html>.
#'
#' @details
#'
#' # The `meta` object
#'
#' Section 1.9 CITATION files of *Writing R Extensions* (R Core Team 2023)
#' specifies how to create dynamic `CITATION` files using `meta` object, hence
#' the `meta` argument in [cff_read_citation()] may be needed for reading
#' some files correctly.
#'
#' @examples
#' # TODO
#'
#' # Create cff object from cff file
#'
#' from_cff_file <- cff_read(system.file("examples/CITATION_basic.cff",
#' package = "cffr"
#' ))
#'
#' head(from_cff_file, 7)
#'
#' # Create cff object from DESCRIPTION
#' from_desc <- cff_read(system.file("examples/DESCRIPTION_basic", package = "cffr"))

Check warning on line 76 in R/cff_read.R

View workflow job for this annotation

GitHub Actions / Run lintr scanning

file=R/cff_read.R,line=76,col=81,[line_length_linter] Lines should not be more than 80 characters. This line is 85 characters.

Check notice

Code scanning / lintr

Lines should not be more than 80 characters. This line is 85 characters. Note

Lines should not be more than 80 characters. This line is 85 characters.
#'
#' from_desc
#'
#' # Create cff object from BibTex
#'
#' from_bib <- cff_read(system.file("examples/example.bib", package = "cffr"))
#'
#' # First item only
#' from_bib[[1]]
#'
#' # Create cff object from CITATION
#' from_citation <- cff_read(system.file("CITATION", package = "cffr"))
#'
#' # First item only
#' from_citation[[1]]
#'
cff_read <- function(path, ...) {
if (length(path) > 1) {
Expand Down Expand Up @@ -95,7 +130,7 @@ cff_read_cff_citation <- function(path, ...) {
)
}

cffobj <- yaml::read_yaml(path)
cffobj <- yaml::read_yaml(path, ...)
new_cff(cffobj)
}

Expand Down Expand Up @@ -199,8 +234,15 @@ cff_read_citation <- function(path, meta = NULL, ...) {
}
# nocov end
}
tocff <- cff_parse_citation(the_cit)
new_cff(tocff)
tocff <- lapply(the_cit, cff_parse_citation)
make_names <- vapply(tocff, function(x) {
myname <- gsub("[^a-z]", "", tolower(x$title))
substr(myname, 1, 10)
}, character(1))

names(tocff) <- make_names
tocff <- new_cff(tocff)
unname(tocff)
}

#' @export
Expand Down Expand Up @@ -229,10 +271,42 @@ cff_read_bib <- function(path, encoding = "UTF-8", ...) {
read_bib <- bibtex::read.bib(file = path, encoding = encoding, ...)


tocff <- cff_parse_citation(read_bib)
new_cff(tocff)
tocff <- lapply(read_bib, cff_parse_citation)
tocff <- new_cff(tocff)
unname(tocff)
}

# Internal safe ----
#' Internal version of cff_read_citation, safe
#' @noRd
cff_safe_read_citation <- function(desc_path, cit_path) {
if (!file.exists(cit_path) || !file.exists(desc_path)) {
return(NULL)
}
# Create meta
meta <- desc_to_meta(desc_path)
meta <- clean_package_meta(meta)


the_cit <- try(utils::readCitationFile(cit_path, meta = meta), silent = TRUE)
# Try
if (inherits(the_cit, "try-error")) {
return(NULL)
}

# Need to be named here
tocff <- lapply(the_cit, cff_parse_citation)
make_names <- vapply(tocff, function(x) {
myname <- gsub("[^a-z]", "", tolower(x$title))
substr(myname, 1, 10)
}, character(1))

names(tocff) <- make_names
tocff <- new_cff(tocff)
unname(tocff)
}

# Helpers ----

guess_type_file <- function(path) {
if (grepl("\\.cff$", path, ignore.case = TRUE)) {
Expand Down Expand Up @@ -260,7 +334,10 @@ guess_type_file <- function(path) {
#' @noRd
clean_package_meta <- function(meta) {
if (!inherits(meta, "packageDescription")) {
return(NULL)
# Add encoding
meta <- list()
meta$Encoding <- "UTF-8"
return(meta)
}

# Convert to a desc object
Expand All @@ -287,17 +364,21 @@ clean_package_meta <- function(meta) {
meta
}

# For testing, packageDescription object from desc
test_meta <- function(x) {


# Convert a DESCRIPTION object to meta object using desc package
desc_to_meta <- function(x) {
src <- x
my_meta <- desc::desc(src)
my_meta$coerce_authors_at_r()


# As list
my_meta_l <- my_meta$get(desc::cran_valid_fields)
my_meta_l <- as.list(my_meta_l)
v_nas <- vapply(my_meta_l, is.na, logical(1))

my_meta_l <- my_meta_l[!v_nas]

meta_proto <- packageDescription("cffr")

class(my_meta_l) <- class(meta_proto)
Expand Down
2 changes: 1 addition & 1 deletion R/cff_to_bibentry.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#' *Ruby CFF Library (Version 0.9.0)* (Computer software).
#' \doi{10.5281/zenodo.1184077}.
#'
#' - Hernangómez D (2022). "BibTeX and CFF, a potential crosswalk."
#' - Hernangomez D (2022). "BibTeX and CFF, a potential crosswalk."
#' *The cffr package, Vignettes*. \doi{10.21105/joss.03900},
#' <https://docs.ropensci.org/cffr/articles/bibtex_cff.html>.
#'
Expand Down
51 changes: 0 additions & 51 deletions R/parse_citation.R
Original file line number Diff line number Diff line change
@@ -1,54 +1,3 @@
## Parsers ----

#' Used for parsing CITATION R-native files
#' @noRd
parse_r_citation <- function(desc_path, cit_path) {
if (!file.exists(cit_path) || !file.exists(desc_path)) {
return(NULL)
}
# Create meta
meta <- parse_package_meta(desc_path)

# First try - Would normally be enough
parsed <- tryCatch(
utils::readCitationFile(cit_path, meta = meta),
warning = function(cit_path, meta) {
# Avoid warnings
# nocov start
suppressWarnings(
utils::readCitationFile(cit_path, meta = meta)
)
},
error = function(x) {
return(NULL)
}
# nocov end
)

parsed
}

#' Parse and clean data from DESCRIPTION to create metadata
#' @noRd
parse_package_meta <- function(desc_path) {
pkg <- desc::desc(desc_path)
pkg$coerce_authors_at_r()
# Extract package data
meta <- pkg$get(desc::cran_valid_fields)

# Clean missing and drop empty fields
meta <- drop_null(lapply(meta, clean_str))

# Check encoding
if (!is.null(meta$Encoding)) {
meta <- lapply(meta, iconv, from = meta$Encoding, to = "UTF-8")
} else {
meta$Encoding <- "UTF-8"
}

meta
}

## Building blocks ----

#' BB for doi
Expand Down
48 changes: 48 additions & 0 deletions R/utils-methods.R
Original file line number Diff line number Diff line change
@@ -1,3 +1,51 @@
# Utils for authors----
make_r_person <- function(x) {
if (is.null(names(x))) {
return(person())
}
checknames <- grepl("^name$|given-names|family-names", names(x))
if (!isTRUE(any(checknames))) {
return(person())
}
# Prepare list
# Family is special key
fam1 <- clean_str(x$name)
fam2 <- clean_str(
paste(
clean_str(x$`name-particle`), clean_str(x$`family-names`),
clean_str(x$`name-suffix`)
)
)

given <- clean_str(x$`given-names`)
family <- clean_str(c(fam1, fam2))

# Make comments
x_comments <- x[!names(x) %in% c(
"family-names", "given-names",
"name-particle", "name-suffix", "email"
)]

x_comments <- lapply(x_comments, clean_str)
x_comments <- unlist(x_comments, use.names = TRUE)

# Prepare ORCID
x_comments <- gsub("^https://orcid.org/", "", x_comments)
nm <- gsub("orcid", "ORCID", names(x_comments), fixed = TRUE)
names(x_comments) <- nm

pers_list <- list(
given = given,
family = family,
email = clean_str(x$email),
comment = x_comments
)


do.call(person, pers_list)
}


# Utils for df ----
unnamed_to_df <- function(key, nm) {
key_l <- as.integer(lengths(key))
Expand Down
Loading

0 comments on commit d9021af

Please sign in to comment.