From d568801d39651419287eb2b3d268c22b8514acd3 Mon Sep 17 00:00:00 2001 From: Diego H Date: Tue, 13 Feb 2024 12:28:21 +0100 Subject: [PATCH] Overhaul of cff-bibtex conversion system (#63) * Start review of article * Update bibtex to cff * Prepare crosswalk * Update vignette * Finish tables * Finish article * Try new test suite * Full results * New testing process in GHA * Finish test new * Ready to merge * Roll back action * Go! --- .github/workflows/test-ci.yaml | 23 +- CITATION.cff | 12 +- DESCRIPTION | 3 +- NAMESPACE | 1 + NEWS.md | 14 + R/assertions.R | 14 +- R/cff-class.R | 12 + R/cff_create.R | 6 +- R/cff_gha_update.R | 3 +- R/cff_git_hook.R | 3 +- R/cff_parse_citation.R | 239 ++- R/cff_parse_person.R | 16 +- R/cff_read.R | 4 +- R/{cff_to_bibtex.R => cff_to_bibentry.R} | 70 +- R/cff_validate.R | 2 +- R/cff_write.R | 4 +- R/deprecated.R | 32 + R/parse_citation.R | 2 +- R/parse_description.R | 8 +- R/utils.R | 6 +- R/write_bib.R | 2 +- R/write_citation.R | 8 +- README.Rmd | 5 +- README.md | 51 +- codemeta.json | 8 +- data-raw/crosswalk_tables.R | 17 + data-raw/crosswalk_tables.xlsx | Bin 0 -> 16689 bytes data/cran_to_spdx.rda | Bin 916 -> 916 bytes inst/WORDLIST | 15 +- .../DESCRIPTION_posit_package_manager | 31 + inst/examples/DESCRIPTION_r_universe | 19 +- inst/extdata/bibtex_field_entry.csv | 26 - inst/extdata/crosswalk_tables.csv | 248 +++ inst/schemaorg.json | 4 +- man/cff-class.Rd | 9 + man/cff_from_bibtex.Rd | 2 +- man/{cff_to_bibtex.Rd => cff_to_bibentry.Rd} | 25 +- man/encoded_utf_to_latex.Rd | 2 +- man/figures/lifecycle-archived.svg | 21 + man/figures/lifecycle-defunct.svg | 21 + man/figures/lifecycle-deprecated.svg | 21 + man/figures/lifecycle-experimental.svg | 22 +- man/figures/lifecycle-maturing.svg | 21 + man/figures/lifecycle-questioning.svg | 21 + man/figures/lifecycle-soft-deprecated.svg | 21 + man/figures/lifecycle-stable.svg | 29 + man/figures/lifecycle-superseded.svg | 21 + man/figures/logo.png | Bin 44443 -> 16971 bytes man/previous_cff_to_bib.Rd | 48 + man/write_bib.Rd | 4 +- man/write_citation.Rd | 8 +- pkgdown/favicon/apple-touch-icon-180x180.png | Bin 9124 -> 9121 bytes pkgdown/favicon/apple-touch-icon-60x60.png | Bin 2528 -> 2504 bytes pkgdown/favicon/apple-touch-icon-76x76.png | Bin 3154 -> 3123 bytes pkgdown/favicon/apple-touch-icon.png | Bin 9124 -> 9121 bytes pkgdown/favicon/favicon-32x32.png | Bin 1581 -> 1578 bytes tests/testthat.R | 4 +- tests/testthat/_snaps/bibtex-check-ruby.md | 3 - tests/testthat/_snaps/bibtex2cff.md | 81 +- tests/testthat/_snaps/cff_description.md | 35 +- tests/testthat/_snaps/cff_parse_citation.md | 2 +- .../{cff_to_bibtex.md => cff_to_bibentry.md} | 3 +- tests/testthat/_snaps/deprecated.md | 9 + tests/testthat/_snaps/merge_desc_cit.md | 66 +- tests/testthat/test-assertions.R | 46 +- tests/testthat/test-bibtex-check-ruby.R | 33 +- tests/testthat/test-bibtex2cff.R | 153 +- tests/testthat/test-cff_description.R | 20 + tests/testthat/test-cff_parse_person.R | 5 + tests/testthat/test-cff_read.R | 10 +- ...cff_to_bibtex.R => test-cff_to_bibentry.R} | 66 +- tests/testthat/test-deprecated.R | 8 + tests/testthat/test-utils.R | 17 + tests/testthat/test_ci/.gitignore | 1 + tests/testthat/test_ci/README.md | 16 +- tests/testthat/test_ci/test-full_cff.R | 186 +- tests/testthat/test_ci/test-new.R | 149 ++ vignettes/REFERENCES.bib | 21 + vignettes/bibtex_cff.Rmd | 1531 +++++++++-------- vignettes/cffr.Rmd | 2 +- vignettes/crosswalk.Rmd | 2 +- 81 files changed, 2419 insertions(+), 1254 deletions(-) create mode 100644 R/cff-class.R rename R/{cff_to_bibtex.R => cff_to_bibentry.R} (89%) create mode 100644 R/deprecated.R create mode 100644 data-raw/crosswalk_tables.R create mode 100644 data-raw/crosswalk_tables.xlsx create mode 100644 inst/examples/DESCRIPTION_posit_package_manager delete mode 100644 inst/extdata/bibtex_field_entry.csv create mode 100644 inst/extdata/crosswalk_tables.csv create mode 100644 man/cff-class.Rd rename man/{cff_to_bibtex.Rd => cff_to_bibentry.Rd} (78%) create mode 100644 man/figures/lifecycle-archived.svg create mode 100644 man/figures/lifecycle-defunct.svg create mode 100644 man/figures/lifecycle-deprecated.svg create mode 100644 man/figures/lifecycle-maturing.svg create mode 100644 man/figures/lifecycle-questioning.svg create mode 100644 man/figures/lifecycle-soft-deprecated.svg create mode 100644 man/figures/lifecycle-stable.svg create mode 100644 man/figures/lifecycle-superseded.svg create mode 100644 man/previous_cff_to_bib.Rd rename tests/testthat/_snaps/{cff_to_bibtex.md => cff_to_bibentry.md} (99%) create mode 100644 tests/testthat/_snaps/deprecated.md rename tests/testthat/{test-cff_to_bibtex.R => test-cff_to_bibentry.R} (88%) create mode 100644 tests/testthat/test-deprecated.R create mode 100644 tests/testthat/test_ci/test-new.R diff --git a/.github/workflows/test-ci.yaml b/.github/workflows/test-ci.yaml index 7ec4d6a1..881ef265 100644 --- a/.github/workflows/test-ci.yaml +++ b/.github/workflows/test-ci.yaml @@ -92,37 +92,34 @@ jobs: # Check packages not installed yet instpack <- as.character(installed.packages()[, "Package"]) - toinstall <- setdiff(all, instpack) + toinstall_init <- setdiff(all, instpack) # Install options(repos = c( ropensci = "https://ropensci.r-universe.dev", ropenscireviewtools = "https://ropensci-review-tools.r-universe.dev", - RSPM = "https://packagemanager.rstudio.com/all/latest", + RSPM = "https://packagemanager.posit.co/cran/latest", CRAN = "https://cloud.r-project.org" )) - message("Installing ", length(toinstall)," packages: ", paste0(toinstall, collapse = ",")) + # Check packages available + pakav <- as.data.frame(available.packages(repos = getOption("repos"))) + toinstall <- toinstall_init[toinstall_init %in% pakav$Package] + message("Installing ", length(toinstall)," packages") install.packages(toinstall, - dependencies = TRUE, - verbose = TRUE, quiet = TRUE + dependencies = TRUE, verbose = TRUE, + quiet = TRUE, type = "binary" ) - # Update binary - # update.packages(type = "binary") - shell: Rscript {0} - name: Test GHA run: | - # Load package - devtools::load_all() - # Run the tests - testthat::test_dir("tests/testthat/test_ci") + source("tests/testthat/test_ci/test-new.R") shell: Rscript {0} @@ -131,5 +128,5 @@ jobs: shell: bash run: | # OK :) - cat ./tests/testthat/test_ci/_snaps/full_cff.md >$GITHUB_STEP_SUMMARY + cat ./tests/testthat/test_ci/results.md >$GITHUB_STEP_SUMMARY diff --git a/CITATION.cff b/CITATION.cff index c7d66878..ae2c7213 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1,5 +1,5 @@ # ----------------------------------------------------------- -# CITATION file created with {cffr} R package, v0.5.0 +# CITATION file created with {cffr} R package, v0.5.0.9000 # See also: https://docs.ropensci.org/cffr/ # ----------------------------------------------------------- @@ -8,7 +8,7 @@ message: 'To cite package "cffr" in publications use:' type: software license: GPL-3.0-or-later title: 'cffr: Generate Citation File Format (''cff'') Metadata for R Packages' -version: 0.5.0 +version: 0.5.0.9000 doi: 10.21105/joss.03900 abstract: The Citation File Format version 1.2.0 is a human and machine readable file format which provides citation metadata for software. @@ -92,11 +92,10 @@ references: url: https://www.R-project.org/ authors: - name: R Core Team - location: - name: Vienna, Austria - year: '2024' institution: name: R Foundation for Statistical Computing + address: Vienna, Austria + year: '2024' version: '>= 3.6.0' - type: software title: cli @@ -139,9 +138,6 @@ references: email: jeroen@berkeley.edu orcid: https://orcid.org/0000-0002-4035-0289 year: '2024' - identifiers: - - type: url - value: https://arxiv.org/abs/1403.2805 version: '>= 1.7.2' - type: software title: jsonvalidate diff --git a/DESCRIPTION b/DESCRIPTION index a1337671..b3eae1d3 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: cffr Title: Generate Citation File Format ('cff') Metadata for R Packages -Version: 0.5.0 +Version: 0.5.0.9000 Authors@R: c( person("Diego", "Hernangómez", , "diego.hernangomezherrero@gmail.com", role = c("aut", "cre", "cph"), comment = c(ORCID = "0000-0001-8457-4658")), @@ -34,6 +34,7 @@ Suggests: VignetteBuilder: knitr Config/testthat/edition: 3 +Config/testthat/parallel: true Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) diff --git a/NAMESPACE b/NAMESPACE index d370f864..16d8f1c6 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -19,6 +19,7 @@ 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) diff --git a/NEWS.md b/NEWS.md index 21bb148f..fe67541a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,17 @@ +# cffr (development version) + +## Major changes in the API + +- 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()` + and `cff_extract_to_bibtex()` that are now superseded. + +## Changes on bibtex crosswalk + +- **\@inbook** and **\@book** gains a new value on [CFF]{.underline} when + **series** is provided: [collection-type: book-series.]{.underline} +- Review and update `vignette("bibtex_cff", package = "cffr")`. + # cffr 0.5.0 ## Lifecycle diff --git a/R/assertions.R b/R/assertions.R index 17ac7038..d703d6f5 100644 --- a/R/assertions.R +++ b/R/assertions.R @@ -1,7 +1,7 @@ #' Check if a string is an email #' @param email The string to be evaluated #' @noRd -is.email <- function(email) { +is_email <- function(email) { if (is.null(email)) { return(FALSE) } @@ -17,7 +17,7 @@ is.email <- function(email) { #' Check if a string is an url #' @param url The url to be evaluated #' @noRd -is.url <- function(url) { +is_url <- function(url) { if (is.null(url)) { return(FALSE) } @@ -31,7 +31,7 @@ is.url <- function(url) { #' @param x string #' @param sub subtring to be evaluated #' @noRd -is.substring <- function(x, sub) { +is_substring <- function(x, sub) { if (is.null(x)) { return(FALSE) } @@ -46,7 +46,7 @@ is.substring <- function(x, sub) { #' Check if a object is cff #' @param x object to be evaluated #' @noRd -is.cff <- function(x) { +is_cff <- function(x) { if (inherits(x, "cff")) { return(TRUE) } else { @@ -57,7 +57,7 @@ is.cff <- function(x) { #' Check if a object is cff file #' @param x object to be evaluated #' @noRd -is.cff_file <- function(x) { +is_cff_file <- function(x) { if (!inherits(x, "character")) { return(FALSE) } @@ -73,7 +73,7 @@ is.cff_file <- function(x) { #' Check if a object is cff #' @param x object to be evaluated #' @noRd -is.github <- function(x) { +is_github <- function(x) { res <- isTRUE(grep( "^http[a-z]://github.com/", x["repository-code"] @@ -86,7 +86,7 @@ is.github <- function(x) { #' @param x file to be evaluated #' @noRd stopifnotcff <- function(x) { - if (is.cff(x)) { + if (is_cff(x)) { return(invisible()) } diff --git a/R/cff-class.R b/R/cff-class.R new file mode 100644 index 00000000..87b0d599 --- /dev/null +++ b/R/cff-class.R @@ -0,0 +1,12 @@ +#' The `cff` class +#' +#' @name cff-class +#' +#' @description +#' TODO +#' +#' @keywords internal +#' +#' +#' +NULL diff --git a/R/cff_create.R b/R/cff_create.R index b11bd6f3..ddb05320 100644 --- a/R/cff_create.R +++ b/R/cff_create.R @@ -117,7 +117,7 @@ cff_create <- function(x, # On missing use package root if (missing(x)) x <- getwd() - if (!is.cff(x) && !is.character(x)) { + if (!is_cff(x) && !is.character(x)) { msg <- "{.arg x} should be a {.cls cff} or {.cls character} object." cli::cli_abort(msg) } @@ -129,7 +129,7 @@ cff_create <- function(x, desc_path <- NULL # Paths - if (is.cff(x)) { + if (is_cff(x)) { # It is already an object cffobj <- x cffobj["cff-version"] <- cff_version @@ -163,7 +163,7 @@ cff_create <- function(x, msg <- paste0( "{.arg x} ({x}) not valid. If it is a package ", "you may need to install it with ", - "{.fun install.packages}" + "{.fn install.packages}" ) cli::cli_abort(msg) } diff --git a/R/cff_gha_update.R b/R/cff_gha_update.R index 00b33f76..5a066074 100644 --- a/R/cff_gha_update.R +++ b/R/cff_gha_update.R @@ -16,7 +16,8 @@ #' @details #' #' Triggers on your action can be modified, see -#' [Events that trigger workflows](https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows). +#' [Events that trigger +#' workflows](https://docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows). #' #' @examples #' \dontrun{ diff --git a/R/cff_git_hook.R b/R/cff_git_hook.R index 3b675cb4..0c54797b 100644 --- a/R/cff_git_hook.R +++ b/R/cff_git_hook.R @@ -3,7 +3,8 @@ #' @description #' #' Install a -#' [pre-commit hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_committing_workflow_hooks) +#' [pre-commit +#' hook](https://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks#_committing_workflow_hooks) #' that remembers you to update your `CITATION.cff` file. #' #' @name cff_git_hook diff --git a/R/cff_parse_citation.R b/R/cff_parse_citation.R index 9001c63f..c7fccc55 100644 --- a/R/cff_parse_citation.R +++ b/R/cff_parse_citation.R @@ -86,11 +86,9 @@ cff_parse_citation <- function(bib) { } # Parse BibTeX entry ---- - parse_cit <- parse_bibtex_entry(bib) ## If no title (case of some Misc) then return null - if (!("title" %in% names(parse_cit))) { entry <- capture.output(print(bib, bibtex = FALSE)) entry <- as.character(entry) @@ -100,29 +98,34 @@ cff_parse_citation <- function(bib) { return(NULL) } - # Parse BibTeX fields ---- parsed_fields <- parse_bibtex_fields(parse_cit) + ## Handle collection types ---- + parsed_fields <- add_bibtex_coltype(parsed_fields) + + ## Add conference + parsed_fields <- add_conference(parsed_fields) + + # Create BibTeX to CFF institution logic ---- + parsed_fields <- parse_bibtex_to_inst(parsed_fields) - # Create BibTeX person models ---- - parsed_fields <- parse_bibtex_person_models(parsed_fields) # Parse persons ---- # Special case: authors # Some keys does not strictly require authors, so we create one for cff - # https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#how-to-deal-with-unknown-individual-authors + # https://github.com/citation-file-format/citation-file-format/blob/main/ + # (cont) schema-guide.md#how-to-deal-with-unknown-individual-authors + if (is.null(parsed_fields$authors)) { parsed_fields$authors <- person(family = "anonymous") } - ## authors ---- parse_all_authors <- drop_null( lapply(parsed_fields$authors, cff_parse_person) ) parsed_fields$authors <- unique(parse_all_authors) - ## other persons---- parse_other_persons <- building_other_persons(parsed_fields) @@ -136,19 +139,8 @@ cff_parse_citation <- function(bib) { # Building blocks---- - # Fallback for year and month: use date-published - - if (is.null(parse_cit$month) && !is.null(parse_cit$`date-published`)) { - parse_cit$month <- format(as.Date(parse_cit$`date-published`), "%m") - } - - - if (is.null(parse_cit$year) && !is.null(parse_cit$`date-published`)) { - parse_cit$year <- format(as.Date(parse_cit$`date-published`), "%Y") - } - - ## month ---- - parse_cit$month <- building_month(parse_cit) + # Fallback for year and month: use date-published ---- + parse_cit <- fallback_dates(parse_cit) ## doi---- bb_doi <- building_doi(parse_cit) @@ -171,8 +163,14 @@ cff_parse_citation <- function(bib) { ) } + ## Add thesis type ---- + parse_cit <- add_thesis(parse_cit) - # Last step: Field models---- + ## Handle location ---- + parse_cit <- add_address(parse_cit) + + + # Last step---- # Initial order but starting with type, title, authors final_order <- unique(c( @@ -183,9 +181,6 @@ cff_parse_citation <- function(bib) { parse_cit <- parse_cit[final_order] - parse_cit <- parse_bibtex_fields_models(parse_cit) - - # Remove non-valid names validnames <- cff_schema_definitions_refs() parse_cit <- parse_cit[names(parse_cit) %in% validnames] @@ -231,6 +226,14 @@ parse_bibtex_entry <- function(bib) { ) + # Check if it an inbook with booktitle (BibLaTeX style) + if (all(init_type == "inbook", "booktitle" %in% names(parse_cit))) { + # Make it incollection + parse_cit$bibtex_entry <- "incollection" + parse_cit$type <- "generic" + } + + return(parse_cit) } @@ -239,7 +242,6 @@ parse_bibtex_entry <- function(bib) { parse_bibtex_fields <- function(parse_cit) { # to lowercase names(parse_cit) <- tolower(names(parse_cit)) - nm <- names(parse_cit) # Standard BibTeX fields: # address annote author booktitle chapter crossref edition editor @@ -250,10 +252,15 @@ parse_bibtex_fields <- function(parse_cit) { # edition journal month publisher title volume year # Mapped: - # author booktitle chapter editor howpublished note number + # author booktitle series chapter editor howpublished note number nm[nm == "author"] <- "authors" + # Make collection title + # booktitle takes precedence over series nm[nm == "booktitle"] <- "collection-title" + if (!"collection-title" %in% nm) { + nm[nm == "series"] <- "collection-title" + } nm[nm == "chapter"] <- "section" nm[nm == "editor"] <- "editors" nm[nm == "howpublished"] <- "medium" @@ -274,8 +281,6 @@ parse_bibtex_fields <- function(parse_cit) { # abstract, doi, isbn, issn, url, version - cff_schema_definitions_refs() - # Keywords may be duplicated, unify if ("keywords" %in% nm) { kwords <- unlist(parse_cit["keywords" == nm]) @@ -284,12 +289,11 @@ parse_bibtex_fields <- function(parse_cit) { parse_cit$keywords <- unique(kwords) } - # Not mapped: # annote crossref key organization series type # - # Fields address, organization, series and type already treated on - # parse_bibtex_for_cff()/main function + # Fields address, organization, series and type are treated on + # main function # key is a special field, treated apart # Fields ignored: annote, crossref @@ -354,76 +358,139 @@ parse_bibtex_fields <- function(parse_cit) { #' Modify mapping of some org. fields on BibTeX to CFF #' @noRd -parse_bibtex_person_models <- function(parsed_fields) { - # Manual - if (parsed_fields$bibtex_entry == "manual") { - parsed_fields$institution <- parsed_fields$organization - } else if (parsed_fields$bibtex_entry %in% c( - "conference", "inproceedings", - "proceedings" - )) { - # Conference, InProceedings, Proceedings - if (!is.null(parsed_fields$series)) { - parsed_fields$conference <- person(family = parsed_fields$series) - } - if (!is.null(parsed_fields$organization)) { - parsed_fields$institution <- person(family = parsed_fields$organization) - } - } else if (parsed_fields$bibtex_entry %in% c("mastersthesis", "phdthesis")) { - # Mastersthesis, PhdThesis - parsed_fields$institution <- person(family = parsed_fields$school) +parse_bibtex_to_inst <- function(parsed_fields) { + # Initial values + bibtex_entry <- parsed_fields$bibtex_entry + to_replace <- switch(bibtex_entry, + "mastersthesis" = "school", + "phdthesis" = "school", + "conference" = "organization", + "inproceedings" = "organization", + "manual" = "organization", + "proceedings" = "organization", + "institution" + ) + + if (to_replace == "institution") { + return(parsed_fields) } + # Rest of cases remove bibtex institution and rename + nms <- names(parsed_fields) + + parsed_fields <- parsed_fields["institution" != nms] + + # Rename + nms2 <- names(parsed_fields) + nms2[nms2 == to_replace] <- "institution" + names(parsed_fields) <- nms2 + + parsed_fields +} + +add_conference <- function(parsed_fields) { + bibtex_entry <- parsed_fields$bibtex_entry + + if (bibtex_entry %in% c("conference", "inproceedings", "proceedings")) { + parsed_fields$conference <- parsed_fields$`collection-title` + } return(parsed_fields) } + + #' Adapt cff keys to bibtex entries #' @noRd -parse_bibtex_fields_models <- function(parse_cit) { - # thesis type ---- - if (parse_cit$bibtex_entry %in% c("phdthesis", "mastersthesis")) { - parse_cit$`thesis-type` <- switch(parse_cit$bibtex_entry, - phdthesis = "PhD Thesis", - "Master's Thesis" - ) +add_thesis <- function(parse_cit) { + bibtex_entry <- parse_cit$bibtex_entry + if (!bibtex_entry %in% c("phdthesis", "mastersthesis")) { + return(parse_cit) } - # address---- - - if (!is.null(parse_cit$location)) { - # Usually the address of the publisher as per BibTeX - if (!is.null(parse_cit$publisher) && - !(parse_cit$bibtex_entry %in% c( - "conference", "inproceedings", - "proceedings" - ))) { - parse_cit$publisher$address <- parse_cit$location$name - parse_cit$location <- NULL - } + parse_cit$`thesis-type` <- switch(bibtex_entry, + phdthesis = "PhD Thesis", + "Master's Thesis" + ) - parse_cit$conference + parse_cit +} - # If this is a conference then add to conference - if (!is.null(parse_cit$conference)) { - parse_cit$conference$address <- parse_cit$location$name - } +add_address <- function(parse_cit) { + loc <- parse_cit$location$name + # If available + if (is.null(loc)) { + return(parse_cit) + } - # If is a report or a thesis, add to institution - if (parse_cit$bibtex_entry %in% c( - "techreport", - "phdthesis", "mastersthesis" - ) && - !is.null(parse_cit$institution)) { - parse_cit$institution$address <- parse_cit$location$name - parse_cit$location <- NULL - } + # At this point is in location, see to move + + # Logic order. + # 1. To conference + # 2. To institution + # 3. To publisher + # Otherwise leave on location + + nms <- names(parse_cit) + has_conf <- "conference" %in% nms + has_inst <- "institution" %in% nms + has_publish <- "publisher" %in% nms + + if (!any(has_conf, has_inst, has_publish)) { + return(parse_cit) + } + + if (has_conf) { + parse_cit$conference$address <- loc + parse_cit$location <- NULL + } else if (has_inst) { + parse_cit$institution$address <- loc + parse_cit$location <- NULL + } else { + parse_cit$publisher$address <- loc + parse_cit$location <- NULL + } + + return(parse_cit) +} + +add_bibtex_coltype <- function(parsed_fields) { + # Add collection-type if applicable and rearrange fields + nms <- names(parsed_fields) + + if (!"collection-title" %in% nms) { + return(parsed_fields) + } + + # Made collection-type if we create collection-title + bibtex_type <- parsed_fields$bibtex_entry + + # Remove `in` at init: inbook, incollection affected + coltype <- clean_str(gsub("^in", "", bibtex_type)) + parsed_fields$`collection-type` <- coltype + + # Rearrange to make both collection keys together + nm_first <- nms[seq(1, match("collection-title", nms))] + + nms_end <- unique(c(nm_first, "collection-type", nms)) + + parsed_fields <- parsed_fields[nms_end] + + return(parsed_fields) +} + +fallback_dates <- function(parse_cit) { + # Fallback for year and month: use date-published + if (is.null(parse_cit$month) && !is.null(parse_cit$`date-published`)) { + parse_cit$month <- format(as.Date(parse_cit$`date-published`), "%m") } - # Book, InBook: collection-title. Use series field - if (parse_cit$bibtex_entry %in% c("book", "inbook")) { - parse_cit$`collection-title` <- clean_str(parse_cit$series) + if (is.null(parse_cit$year) && !is.null(parse_cit$`date-published`)) { + parse_cit$year <- format(as.Date(parse_cit$`date-published`), "%Y") } + ## month ---- + parse_cit$month <- building_month(parse_cit) + return(parse_cit) } diff --git a/R/cff_parse_person.R b/R/cff_parse_person.R index 74b7ba92..a19d87e2 100644 --- a/R/cff_parse_person.R +++ b/R/cff_parse_person.R @@ -60,6 +60,10 @@ cff_parse_person <- function(person) { person <- as.person(person) + if (length(person) == 0) { + return(NULL) + } + if (length(person) > 1) { person <- lapply(person, cff_parse_person) class(person) <- "cff" @@ -68,7 +72,7 @@ cff_parse_person <- function(person) { # Special case for Bioconductor - if (is.substring(person$given, "Bioconductor")) { + if (is_substring(person$given, "Bioconductor")) { person <- person( given = paste( clean_str(person$given), @@ -81,11 +85,9 @@ cff_parse_person <- function(person) { } # Special case for R Core Team - - if (all( - is.substring(clean_str(person$given), "R Core"), - is.substring(person$family, "Team") + is_substring(clean_str(person$given), "R Core"), + is_substring(person$family, "Team") )) { person <- person( given = paste( @@ -112,7 +114,7 @@ cff_parse_person <- function(person) { } # Check if several mails (MomTrunc 6.0) - valid_emails <- unlist(lapply(person$email, is.email)) + valid_emails <- unlist(lapply(person$email, is_email)) email <- person$email[valid_emails][1] parsed_person$email <- clean_str(email) @@ -145,7 +147,7 @@ cff_parse_person <- function(person) { web <- parsed_comments$website if (!is.null(web)) { - parsed_comments$website <- clean_str(web[is.url(web)]) + parsed_comments$website <- clean_str(web[is_url(web)]) } # Add comments diff --git a/R/cff_read.R b/R/cff_read.R index 38ad7880..d2c8433f 100644 --- a/R/cff_read.R +++ b/R/cff_read.R @@ -79,7 +79,7 @@ cff_read <- function(path) { #' @rdname cff_read #' @export cff <- function(path, ...) { - if (!missing(path) && is.cff(path)) { + if (!missing(path) && is_cff(path)) { return(path) } @@ -131,7 +131,7 @@ cff <- function(path, ...) { #' # Nice display thanks to yaml package #' cffobj as.cff <- function(x) { - if (is.cff(x)) { + if (is_cff(x)) { return(x) } diff --git a/R/cff_to_bibtex.R b/R/cff_to_bibentry.R similarity index 89% rename from R/cff_to_bibtex.R rename to R/cff_to_bibentry.R index d4555872..c44fe704 100644 --- a/R/cff_to_bibtex.R +++ b/R/cff_to_bibentry.R @@ -2,12 +2,15 @@ #' #' @description #' -#' This function creates BibTeX entries (in the form of [bibentry()] objects +#' This function creates [bibentry()] objects #' from different metadata sources (`cff` objects, `DESCRIPTION` files, etc.). -#' The function tries to parse the information of the source `x` into a `cff` +#' 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**. +#' #' #' @references #' - Patashnik, Oren. "BIBTEXTING" February 1988. @@ -18,7 +21,7 @@ #' \doi{10.5281/zenodo.1184077}. #' #' - Hernangómez D (2022). "BibTeX and CFF, a potential crosswalk." -#' *The cffr package, Vignettes* +#' *The cffr package, Vignettes*. \doi{10.21105/joss.03900}, #' . #' #' @param x The source that would be used for generating @@ -42,8 +45,8 @@ #' be parsed to BibTeX using [toBibtex()] #' #' @export -#' @name cff_to_bibtex -#' @rdname cff_to_bibtex +#' @name cff_to_bibentry +#' @rdname cff_to_bibentry #' #' @examples #' \donttest{ @@ -53,7 +56,7 @@ #' cff_object #' #' # bibentry object -#' bib <- cff_to_bibtex(cff_object) +#' bib <- cff_to_bibentry(cff_object) #' #' class(bib) #' @@ -66,13 +69,13 @@ #' # From a CITATION.cff file with options #' #' path <- system.file("examples/CITATION_complete.cff", package = "cffr") -#' cff_file <- cff_to_bibtex(path, what = "all") +#' cff_file <- cff_to_bibentry(path, what = "all") #' #' toBibtex(cff_file) #' #' # For an installed package #' -#' installed_package <- cff_to_bibtex("jsonvalidate") +#' installed_package <- cff_to_bibentry("jsonvalidate") #' #' toBibtex(installed_package) #' @@ -80,22 +83,22 @@ #' # Use a DESCRIPTION file #' #' path2 <- system.file("examples/DESCRIPTION_gitlab", package = "cffr") -#' desc_file <- cff_to_bibtex(path2) +#' desc_file <- cff_to_bibentry(path2) #' #' toBibtex(desc_file) #' } -cff_to_bibtex <- function(x, - what = c("preferred", "references", "all")) { +cff_to_bibentry <- function(x, + what = c("preferred", "references", "all")) { what <- match.arg(what) if (is.null(x)) { return(NULL) } - if (is.cff_file(x)) { + if (is_cff_file(x)) { x <- cff_read(x) } - if (is.cff(x)) { + if (is_cff(x)) { obj <- x } else { obj <- cff_create(x) @@ -125,9 +128,9 @@ cff_to_bibtex <- function(x, } #' @export -#' @rdname cff_to_bibtex +#' @rdname cff_to_bibentry #' @usage NULL -cff_extract_to_bibtex <- cff_to_bibtex +cff_to_bibtex <- cff_to_bibentry cff_bibtex_parser <- function(x) { if (is.null(x)) { @@ -137,11 +140,10 @@ cff_bibtex_parser <- function(x) { stopifnotcff(x) # Read cff of CITATION.cff file - if (!is.cff(x)) { + 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) @@ -197,7 +199,7 @@ cff_bibtex_parser <- function(x) { if (all( tobibentry$bibtype == "misc", !is.null(x$`collection-title`), - !is.null(x$publisher) + !is.null(x$publisher), !is.null(x$year) )) { tobibentry$bibtype <- "incollection" } @@ -206,10 +208,10 @@ cff_bibtex_parser <- function(x) { # address---- # BibTeX 'address' is taken from the publisher (book, others) or the # conference (inproceedings). - - if (tobibentry$bibtype %in% c("proceedings", "inproceedings")) { + # Set logic: conference > institution > publisher + if (!is.null(x$conference)) { addr_search <- x$conference - } else if (tobibentry$bibtype == "techreport") { + } else if (!is.null(x$institution)) { addr_search <- x$institution } else { addr_search <- x$publisher @@ -380,6 +382,11 @@ cff_bibtex_parser <- function(x) { # note ---- tobibentry$note <- x$notes + # unpublished needs a note + if (all(is.null(x$notes), tobibentry$bibtype == "unpublished")) { + tobibentry$note <- "Extracted with cffr R package" + } + # number---- @@ -403,18 +410,10 @@ cff_bibtex_parser <- function(x) { # series---- - if (tobibentry$bibtype %in% c( - "book", "inbook" - )) { + if (is.null(tobibentry$booktitle)) { tobibentry$series <- x$`collection-title` } - if (tobibentry$bibtype %in% c( - "proceedings", "inproceedings" - )) { - tobibentry$series <- x$conference$name - } - # title ---- tobibentry$title <- x$title @@ -520,8 +519,17 @@ cff_bibtex_parser <- function(x) { sorted <- unique[unique %in% names(tobibentry)] tobibentry <- tobibentry[sorted] - bib <- do.call(bibentry, tobibentry) + # Shouldn't happen but just in case + # nocov start + if (inherits(bib, "try-error")) { + message <- attributes(bib)$condition$message + cli::cli_alert_danger(paste("Can't convert to {.fn bibentry}: ", message)) + cli::cli_alert_info("Returning {.val NULL}") + return(NULL) + } + # nocov end + return(bib) } diff --git a/R/cff_validate.R b/R/cff_validate.R index 75d9dd9c..ceaa3110 100644 --- a/R/cff_validate.R +++ b/R/cff_validate.R @@ -58,7 +58,7 @@ #' try(cff_validate(system.file("CITATION", package = "cffr"))) cff_validate <- function(x = "CITATION.cff", verbose = TRUE) { # If is a cff create the object - if (is.cff(x)) { + if (is_cff(x)) { tmpfile <- tempfile(fileext = ".cff") suppressMessages(yaml::write_yaml(x, tmpfile)) path <- tmpfile diff --git a/R/cff_write.R b/R/cff_write.R index 031f2580..31865a61 100644 --- a/R/cff_write.R +++ b/R/cff_write.R @@ -84,7 +84,7 @@ cff_write <- function(x, # Fix string if it is not cff - if (!is.substring(outfile, ".cff$")) outfile <- paste0(outfile, ".cff") + if (!is_substring(outfile, ".cff$")) outfile <- paste0(outfile, ".cff") # Check if dir exist and if not create outdir <- dirname(outfile) @@ -122,7 +122,7 @@ cff_write <- function(x, } # Add CITATION.cff to .Rbuildignore - if (!is.cff(x) && x == getwd() && file.exists(".Rbuildignore")) { + if (!is_cff(x) && x == getwd() && file.exists(".Rbuildignore")) { ignore <- readLines(".Rbuildignore") # If not already diff --git a/R/deprecated.R b/R/deprecated.R new file mode 100644 index 00000000..07b26ba9 --- /dev/null +++ b/R/deprecated.R @@ -0,0 +1,32 @@ +#' Previous API: Create BibTeX entries from several sources +#' +#' @description +#' `r lifecycle::badge('superseded')` +#' Please use [cff_to_bibentry()] instead. +#' +#' @rdname previous_cff_to_bib +#' @inheritParams cff_to_bibentry +#' @export +#' @keywords internal +#' +#' @return See [cff_to_bibentry()] +#' @examples +#' \donttest{ +#' # From a cff object +#' cff_object <- cff() +#' +#' cff_object +#' +#' # bibentry object +#' bib <- cff_to_bibentry(cff_object) +#' } +cff_extract_to_bibtex <- function(x, + what = c("preferred", "references", "all")) { + if (requireNamespace("lifecycle", quietly = TRUE)) { + lifecycle::deprecate_soft( + "0.5.0", "cff_extract_to_bibtex()", + "cff_to_bibentry()" + ) + } + cff_to_bibentry(x, what) +} diff --git a/R/parse_citation.R b/R/parse_citation.R index 02bfc071..87d0d65b 100644 --- a/R/parse_citation.R +++ b/R/parse_citation.R @@ -132,7 +132,7 @@ building_url <- function(parse_cit) { allurls <- parse_cit$url } - allurls <- allurls[is.url(allurls)] + allurls <- allurls[is_url(allurls)] # The first url goes to url key url <- unlist(allurls[1]) diff --git a/R/parse_description.R b/R/parse_description.R index 7997e4ae..d26b4e51 100644 --- a/R/parse_description.R +++ b/R/parse_description.R @@ -146,7 +146,7 @@ parse_desc_repository <- function(pkg) { repo <- clean_str(pkg$get("Repository")) # Repo is url - if (is.url(repo)) { + if (is_url(repo)) { return(repo) } @@ -160,7 +160,7 @@ parse_desc_repository <- function(pkg) { # Repo is CRAN # Canonic url to CRAN - if (is.substring(repo, "^CRAN$")) { + if (is_substring(repo, "^CRAN$")) { return( paste0("https://CRAN.R-project.org/package=", name) ) @@ -206,7 +206,7 @@ parse_desc_urls <- function(pkg) { # Join issues and urls allurls <- unique(c(issues, url)) - allurls <- allurls[is.url(allurls)] + allurls <- allurls[is_url(allurls)] @@ -279,7 +279,7 @@ parse_desc_version <- function(pkg) { #' @noRd parse_ghtopics <- function(x) { # Only for GitHub repos - if (!is.github(x)) { + if (!is_github(x)) { return(NULL) } diff --git a/R/utils.R b/R/utils.R index 225a6c6d..2b6e07e4 100644 --- a/R/utils.R +++ b/R/utils.R @@ -91,10 +91,12 @@ search_on_repos <- function(name, detect_repos <- function(repos = getOption("repos")) { # Not use RSPM repos <- repos[names(repos) != "RSPM"] - repos <- repos[!grepl("//rspm", repos)] + repos <- repos[!grepl("rspm", repos)] + repos <- repos[!grepl("posit", repos)] + repos <- repos[!grepl("rstudio", repos)] # If not set use 0-Cloud - if (!is.url(repos["CRAN"])) { + if (!is_url(repos["CRAN"])) { repos["CRAN"] <- "https://cloud.r-project.org/" } diff --git a/R/write_bib.R b/R/write_bib.R index 983d586c..7623cfde 100644 --- a/R/write_bib.R +++ b/R/write_bib.R @@ -3,7 +3,7 @@ #' Creates `a .bib` file from a `bibentry` object(s) #' #' @param x A `bibentry` object created with: -#' - [cff_to_bibtex()] +#' - [cff_to_bibentry()] #' - [citation()] or [bibentry()] #' #' @param file Name of the file. If `NULL` it would display the lines to be diff --git a/R/write_citation.R b/R/write_citation.R index 2ba3239d..36f3f0a4 100644 --- a/R/write_citation.R +++ b/R/write_citation.R @@ -6,9 +6,9 @@ #' CITATION.cff file or `cff` object. #' #' @param x It could be -#' - A `bibentry` object created with [cff_to_bibtex()], [citation()] or +#' - A `bibentry` object created with [cff_to_bibentry()], [citation()] or #' [bibentry()] -#' - Any of the valid inputs of [cff_to_bibtex()]: +#' - Any of the valid inputs of [cff_to_bibentry()]: #' * A missing value. That would retrieve the DESCRIPTION file on your #' in-development package. #' * An existing [`cff`] object, @@ -17,7 +17,7 @@ #' * Path to a DESCRIPTION file (`"*/DESCRIPTION*"`). #' @param file Name of the file to write. #' @inheritParams write_bib -#' @inheritDotParams cff_to_bibtex +#' @inheritDotParams cff_to_bibentry #' #' @export #' @family BibTeX helpers @@ -66,7 +66,7 @@ write_citation <- function(x, verbose = TRUE, ...) { if (!inherits(x, "bibentry")) { - x <- cff_to_bibtex(x, ...) + x <- cff_to_bibentry(x, ...) } bentr <- format(x, style = "R") diff --git a/README.Rmd b/README.Rmd index f6cf504d..09167f48 100644 --- a/README.Rmd +++ b/README.Rmd @@ -15,8 +15,7 @@ knitr::opts_chunk$set( ) ``` -# cffr - +# cffr cffr website [![CRAN-status](https://www.r-pkg.org/badges/version/cffr)](https://CRAN.R-project.org/package=cffr) @@ -197,7 +196,7 @@ We can validate the result using `cff_validate()`: cff_validate(test) ``` -Check the [docs](https://docs.ropensci.org/cffr/reference/index.html) and +Check the [docs](https://docs.ropensci.org/cffr//reference/index.html) and `vignette("cffr", package = "cffr")` to learn how to work with `cff` objects. ### Keep your `CITATION.cff` file up-to-date diff --git a/README.md b/README.md index 7102a86a..b87bcf35 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ -# cffr +# cffr cffr website @@ -72,7 +72,7 @@ file and the `CITATION` file (if present) of your package. Note that **cffr** works best if your package pass `R CMD check/devtools::check()`. -As per 2024-02-06 there are at least 235 repos on GitHub using **cffr**. +As per 2024-02-13 there are at least 235 repos on GitHub using **cffr**. [Check them out here](https://github.com/search?q=cffr%20path%3A**%2FCITATION.cff&type=code). @@ -276,11 +276,10 @@ test <- cff_create("rmarkdown") url: https://www.R-project.org/ authors: - name: R Core Team - location: - name: Vienna, Austria - year: '2024' institution: name: R Foundation for Statistical Computing + address: Vienna, Austria + year: '2024' version: '>= 3.0' - type: software title: bslib @@ -386,9 +385,6 @@ test <- cff_create("rmarkdown") email: jeroen@berkeley.edu orcid: https://orcid.org/0000-0002-4035-0289 year: '2024' - identifiers: - - type: url - value: https://arxiv.org/abs/1403.2805 - type: software title: knitr abstract: 'knitr: A General-Purpose Package for Dynamic Report Generation in R' @@ -408,11 +404,10 @@ test <- cff_create("rmarkdown") notes: Imports authors: - name: R Core Team - location: - name: Vienna, Austria - year: '2024' institution: name: R Foundation for Statistical Computing + address: Vienna, Austria + year: '2024' - type: software title: stringr abstract: 'stringr: Simple, Consistent Wrappers for Common String Operations' @@ -445,22 +440,20 @@ test <- cff_create("rmarkdown") notes: Imports authors: - name: R Core Team - location: - name: Vienna, Austria - year: '2024' institution: name: R Foundation for Statistical Computing + address: Vienna, Austria + year: '2024' - type: software title: utils abstract: 'R: A Language and Environment for Statistical Computing' notes: Imports authors: - name: R Core Team - location: - name: Vienna, Austria - year: '2024' institution: name: R Foundation for Statistical Computing + address: Vienna, Austria + year: '2024' - type: software title: xfun abstract: 'xfun: Supporting Functions for Packages Maintained by ''Yihui Xie''' @@ -757,18 +750,6 @@ test <- cff_create("rmarkdown") given-names: Davis email: davis@posit.co year: '2024' - - type: software - title: cleanrmd - abstract: 'cleanrmd: Clean Class-Less ''R Markdown'' HTML Documents' - notes: Suggests - url: https://pkg.garrickadenbuie.com/cleanrmd/ - repository: https://CRAN.R-project.org/package=cleanrmd - authors: - - family-names: Aden-Buie - given-names: Garrick - email: garrick@adenbuie.com - orcid: https://orcid.org/0000-0002-7111-0077 - year: '2024' - type: software title: withr abstract: 'withr: Run Code ''With'' Temporarily Modified Global State' @@ -806,7 +787,7 @@ cff_validate(test) #> ✔ Congratulations! This is valid ``` -Check the [docs](https://docs.ropensci.org/cffr/reference/index.html) +Check the [docs](https://docs.ropensci.org/cffr//reference/index.html) and `vignette("cffr", package = "cffr")` to learn how to work with `cff` objects. @@ -907,9 +888,9 @@ for more info.
-Boettiger, Carl, and Maëlle Salmon. 2021a. *codemeta: A Smaller codemetar Package*. +Boettiger, Carl, and Maëlle Salmon. 2021a. +*codemeta: A Smaller +codemetar Package*. .
@@ -930,8 +911,8 @@ Among Citation Formats*.
-Dietrich, Jan Philipp, and Waldir Leoncio. 2022. *citation: Software Citation Tools*. +Dietrich, Jan Philipp, and Waldir Leoncio. 2022. +*citation: Software Citation Tools*.
diff --git a/codemeta.json b/codemeta.json index be76fce2..1551c39b 100644 --- a/codemeta.json +++ b/codemeta.json @@ -8,13 +8,13 @@ "codeRepository": "https://github.com/ropensci/cffr", "issueTracker": "https://github.com/ropensci/cffr/issues", "license": "https://spdx.org/licenses/GPL-3.0", - "version": "0.5.0", + "version": "0.5.0.9000", "programmingLanguage": { "@type": "ComputerLanguage", "name": "R", "url": "https://r-project.org" }, - "runtimePlatform": "R version 4.3.2 (2023-10-31)", + "runtimePlatform": "R version 4.3.2 (2023-10-31 ucrt)", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", @@ -200,7 +200,7 @@ }, "isPartOf": "https://ropensci.org", "keywords": ["attribution", "citation", "credit", "citation-files", "cff", "metadata", "r", "r-package", "citation-file-format", "rstats", "ropensci", "cran"], - "fileSize": "906.703KB", + "fileSize": "911.371KB", "citation": [ { "@type": "ScholarlyArticle", @@ -286,7 +286,7 @@ "sameAs": "https://doi.org/10.5281/zenodo.5171937" } ], - "releaseNotes": "https://github.com/ropensci/cffr/blob/master/NEWS.md", + "releaseNotes": "https://github.com/ropensci/cffr/blob/main/NEWS.md", "readme": "https://github.com/ropensci/cffr/blob/main/README.md", "contIntegration": ["https://github.com/ropensci/cffr/actions/workflows/check-full.yaml", "https://app.codecov.io/gh/ropensci/cffr", "https://github.com/ropensci/cffr/actions/workflows/cff-validator.yml"], "developmentStatus": ["https://www.repostatus.org/#active", "https://lifecycle.r-lib.org/articles/stages.html#experimental"], diff --git a/data-raw/crosswalk_tables.R b/data-raw/crosswalk_tables.R new file mode 100644 index 00000000..b2199230 --- /dev/null +++ b/data-raw/crosswalk_tables.R @@ -0,0 +1,17 @@ +## code to prepare `crosswalk_tables.csv` +library(tidyverse) +df <- openxlsx::read.xlsx("data-raw/crosswalk_tables.xlsx") + +unlink("/inst/extdata/crosswalk_tables.csv") +lapply(df, trimws) %>% + bind_rows() %>% + setNames(names(df)) %>% + write.csv("./inst/extdata/crosswalk_tables.csv", row.names = FALSE) + +cli::cli_alert_success("Excel updated") + +# +# lapply(df, trimws) %>% +# bind_rows() %>% +# setNames(names(df)) %>% +# openxlsx::write.xlsx("data-raw/crosswalk_tables.xlsx", overwrite = TRUE) diff --git a/data-raw/crosswalk_tables.xlsx b/data-raw/crosswalk_tables.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..4421650879e2ebcc37c4ab5b4098e665c146cd2a GIT binary patch literal 16689 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 UU!9*^Y}K0_GdS8dS2 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. +License: MIT + file LICENSE +URL: https://dieghernan.github.io/resmush/, + https://github.com/dieghernan/resmush +BugReports: https://github.com/dieghernan/resmush/issues +Depends: R (>= 3.6.0) +Imports: cli, curl, httr2 (>= 1.0.0), tools, utils +Suggests: grid, knitr, png, rmarkdown, testthat (>= 3.0.0) +VignetteBuilder: knitr +Config/Needs/website: dieghernan/gitdevr, xfun, dplyr, tibble, devtools +Config/testthat/edition: 3 +Config/testthat/parallel: true +Encoding: UTF-8 +RoxygenNote: 7.3.1 +X-schema.org-keywords: r, compress-images, optimize-images, resmushit, + api +NeedsCompilation: no +Packaged: 2024-02-01 12:16:47 UTC; diego +Author: Diego Hernangómez [aut, cre, cph] + () +Maintainer: Diego Hernangómez +Repository: RSPM +Date/Publication: 2024-02-02 19:50:02 UTC +Built: R 4.3.0; ; 2024-02-05 12:08:28 UTC; windows diff --git a/inst/examples/DESCRIPTION_r_universe b/inst/examples/DESCRIPTION_r_universe index ebd825c6..5e1fae18 100644 --- a/inst/examples/DESCRIPTION_r_universe +++ b/inst/examples/DESCRIPTION_r_universe @@ -59,12 +59,12 @@ Authors@R: role = "ctb", comment = c(ORCID = "0000-0001-8804-4216")) ) -Description: The 'Codemeta' Project defines a 'JSON-LD' format - for describing software metadata, as detailed at - . This package provides utilities to - generate, parse, and modify 'codemeta.json' files automatically for R - packages, as well as tools and examples for working with - 'codemeta.json' 'JSON-LD' more generally. +Description: The 'Codemeta' Project defines a 'JSON-LD' format for + describing software metadata, as detailed at + . This package provides utilities + to generate, parse, and modify 'codemeta.json' files + automatically for R packages, as well as tools and examples for + working with 'codemeta.json' 'JSON-LD' more generally. License: GPL-3 URL: https://github.com/ropensci/codemetar, https://docs.ropensci.org/codemetar/ @@ -85,10 +85,10 @@ Roxygen: list(markdown = TRUE) Config/testthat/edition: 3 Repository: https://ropensci.r-universe.dev RemoteUrl: https://github.com/ropensci/codemetar -RemoteRef: master -RemoteSha: 4cd7ccc51455f4fad762da8d3cca3f46c368e299 +RemoteRef: main +RemoteSha: bdd9a29d7eabcc43c3195fe461f884932eba763c NeedsCompilation: no -Packaged: 2023-04-05 06:11:53 UTC; root +Packaged: 2024-02-09 05:55:58 UTC; root Author: Carl Boettiger [aut, cre, cph] (), Anna Krystalli [rev, ctb] (), @@ -105,3 +105,4 @@ Author: Carl Boettiger [aut, cre, cph] Sebastian Kreutzer [ctb] (), Thierry Onkelinx [ctb] () Maintainer: Carl Boettiger +Built: R 4.3.2; ; 2024-02-09 05:58:05 UTC; windows diff --git a/inst/extdata/bibtex_field_entry.csv b/inst/extdata/bibtex_field_entry.csv deleted file mode 100644 index 74a7f182..00000000 --- a/inst/extdata/bibtex_field_entry.csv +++ /dev/null @@ -1,26 +0,0 @@ -field,article,book,booklet,inbook,incollection,"conference,inproceedings",manual,"mastersthesis,phdthesis",misc,proceedings,techreport,unpublished -title,x,x,x,x,x,x,x,x,o,x,x,x -year,x,x,o,x,x,x,o,x,o,x,x,o -author,x,(x),o,(x),x,x,o,x,o,,x,x -note,o,o,o,o,o,o,o,o,o,o,o,x -month,o,o,o,o,o,o,o,o,o,o,o,o -address,,o,o,o,o,o,o,o,,o,o, -publisher,,x,,x,x,o,,,,o,, -editor,,(x),,(x),o,o,,,,o,, -number,o,(o),,(o),(o),(o),,,,(o),o, -volume,o,(o),,(o),(o),(o),,,,(o),, -pages,o,,,(x),o,o,,,,,, -series,,o,,o,o,o,,,,o,, -booktitle,,,,,x,x,,,,,, -edition,,o,,o,o,,o,,,,, -type,,,,o,o,,,o,,,o, -chapter,,,,(x),o,,,,,,, -organization,,,,,,o,o,,,o,, -howpublished,,,o,,,,,,o,,, -institution,,,,,,,,,,,x, -journal,x,,,,,,,,,,, -school,,,,,,,,x,,,, -annote,,,,,,,,,,,, -crossref,,,,,,,,,,,, -key,,,,,,,,,,,, - diff --git a/inst/extdata/crosswalk_tables.csv b/inst/extdata/crosswalk_tables.csv new file mode 100644 index 00000000..155c598f --- /dev/null +++ b/inst/extdata/crosswalk_tables.csv @@ -0,0 +1,248 @@ +"table","f1","f2","f3","f4","f5","f6","f7","f8","f9","f10","f11","f12","f13" +"entry_fields","**address**",NA,"o","o","o","o","o","o","o",NA,"o","o",NA +"entry_fields","**annote**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_fields","**author**","x","x","o","x","x","x","o","x","o",NA,"x","x" +"entry_fields","**booktitle**",NA,NA,NA,NA,"x","x",NA,NA,NA,NA,NA,NA +"entry_fields","**chapter**",NA,NA,NA,"x","o",NA,NA,NA,NA,NA,NA,NA +"entry_fields","**crossref**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_fields","**edition**",NA,"o",NA,"o","o",NA,"o",NA,NA,NA,NA,NA +"entry_fields","**editor**",NA,"x",NA,"x","o","o",NA,NA,NA,"o",NA,NA +"entry_fields","**howpublished**",NA,NA,"o",NA,NA,NA,NA,NA,"o",NA,NA,NA +"entry_fields","**institution**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,"x",NA +"entry_fields","**journal**","x",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_fields","**key**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_fields","**month**","o","o","o","o","o","o","o","o","o","o","o","o" +"entry_fields","**note**","o","o","o","o","o","o","o","o","o","o","o","x" +"entry_fields","**number**","o","o",NA,"o","o","o",NA,NA,NA,"o","o",NA +"entry_fields","**organization**",NA,NA,NA,NA,NA,"o","o",NA,NA,"o",NA,NA +"entry_fields","**pages**","o",NA,NA,"x","o","o",NA,NA,NA,NA,NA,NA +"entry_fields","**publisher**",NA,"x",NA,"x","x","o",NA,NA,NA,"o",NA,NA +"entry_fields","**school**",NA,NA,NA,NA,NA,NA,NA,"x",NA,NA,NA,NA +"entry_fields","**series**",NA,"o",NA,"o","o","o",NA,NA,NA,"o",NA,NA +"entry_fields","**title**","x","x","x","x","x","x","x","x","o","x","x","x" +"entry_fields","**type**",NA,NA,NA,"o","o",NA,NA,"o",NA,NA,"o",NA +"entry_fields","**volume**","o","o",NA,"o","o","o",NA,NA,NA,"o",NA,NA +"entry_fields","**year**","x","x","o","x","x","x","o","x","o","x","x","o" +"entry_bib2cff","**\@article**","[article]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_bib2cff","**\@book, \@inbook**","[book]{.underline}","**\@inbook** is a [book]{.underline} with **chapter** and/or **pages**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_bib2cff","**\@booklet**","[pamphlet]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_bib2cff","**\@conference**","[conference-paper]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_bib2cff","**\@incollection**","[generic]{.underline}","Needs additional fields",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_bib2cff","**\@inproceedings**","[conference-paper]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_bib2cff","**\@manual**","[manual]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_bib2cff","**\@mastersthesis, \@phdthesis**","[thesis]{.underline}","Identified by [thesis-type]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_bib2cff","**\@misc**","[generic]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_bib2cff","**\@proceedings**","[proceedings]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_bib2cff","**\@techreport**","[report]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_bib2cff","**\@unpublished**","[unpublished]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_cff2bib","[book]{.underline}","**\@book**, **\@inbook**","**\@inbook** is a [book]{.underline} with [section]{.underline} or [start/end]{.underline} (reference to page number or range).",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_cff2bib","[conference, conference-paper]{.underline}","**\@inproceedings**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_cff2bib","[article, magazine-article, newspaper-article]{.underline}","**\@article**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_cff2bib","[manual]{.underline}","**\@manual**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_cff2bib","[pamphlet]{.underline}","**\@booklet**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_cff2bib","[proceedings]{.underline}","**\@proceedings**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_cff2bib","[report]{.underline}","**\@techreport**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_cff2bib","[thesis]{.underline}","**\@mastersthesis**, **\@phdthesis**","Using [thesis-type]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_cff2bib","[unpublished]{.underline}","**\@unpublished**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_cff2bib","[generic]{.underline}","**\@misc**, **\@incollection**","**\@incollection** is a [generic]{.underline} with [year,publisher,collection-title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"entry_cff2bib","\<[any other value]{.underline}\>","**\@misc**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**address**","Several possibilities","In **BibTeX** it may be the address of a **publisher, conference, organization, institution** or **school**.",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","***annote***","Not clear, won't be mapped",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**author**","[authors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**booktitle**","[collection-title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**chapter**","[section]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","***crossref***","Not clear, won't be mapped",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**edition**","[edition]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**editor**","[editors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**howpublished**","[medium]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**institution, school, organization**","[institution]{.underline}","No overlapping on **BibteX** requirements",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**journal**","[journal]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","***key***","Not clear, won't be mapped",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**month**","[month]{.underline}","Fallback: information in [date-published]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**note**","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**number**","[issue]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**pages**","[start]{.underline} & [end]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**publisher**","[publisher]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**series**","[collection-title]{.underline} if no **booktitle**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**title**","[title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","***type***","Won't be mapped","This is a special key in [CFF]{.underline} resembling the **BibteX** entry.",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**volume**","[volume]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_bib2cff","**year**","[year]{.underline}","Fallback: information in [date-published]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**abstract**","[abstract]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**date**","[date-published]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**doi**","[doi]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**file**","[filename]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**isbn**","[isbn]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**issn**","[issn]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**issuetitle**","[issue-title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**pagetotal**","[pages]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**translator**","[translators]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**url**","[url]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**urldate**","[date-accessed]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"fields_biblatex2cff","**version**","[version]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_article","**\@article**","[type: article, magazine-article, newspaper-article]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_article","**author** (required)","[authors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_article","**title** (required)","[title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_article","**journal** (required)","[journal]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_article","**year** (required)","[year]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_article","**volume**","[volume]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_article","**number**","[issue]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_article","**pages**","[start]{.underline} and [end]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_article","**month**","[month]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_article","**note**","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**\@book, \@inbook**","[type: book]{.underline}","If [section]{.underline} or [start-end]{.underline} informed, it would be treated as **\@inbook**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**author** (required)","[authors]{.underline}","At least one of **author,editor** required",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**editor** (required)","[editors]{.underline}","At least one of **author,editor** required",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**title** (required)","[title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**publisher** (required)","[publisher]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**year** (required)","[year]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**chapter** (required in **\@inbook** only)","[section]{.underline}","Not even optional in **\@book**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**pages** (required in **\@inbook** only)","[start]{.underline} and [end]{.underline}","Not even optional in **\@book**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**volume**","[volume]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**number**","[issue]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**series**","[collection-title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**address**","[address]{.underline} property of [publisher]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**edition**","[edition]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**month**","[month]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**note**","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_book","**type**","Ignored","Only optional in **\@inbook**",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_booklet","**\@booklet**","[type: pamphlet]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_booklet","**title** (required)","[title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_booklet","**author**","[authors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_booklet","**howpublished**","[medium]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_booklet","**address**","[location]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_booklet","**month**","[month]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_booklet","**year**","[year]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_booklet","**note**","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**\@conference / \@inproceedings**","[type: conference-paper, conference]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**author** (required)","[authors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**title** (required)","[title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**booktitle** (required)","[collection-title]{.underline} and [conference]{.underline}","Additionally [collection-type]{.underline} would be populated as ""proceedings""",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**year** (required)","[year]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**editor**","[editors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**volume**","[volume]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**number**","[issue]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**series**","Ignored",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**pages**","[start]{.underline} and [end]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**address**","[address]{.underline} property of [conference]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**month**","[month]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**organization**","[institution]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**publisher**","[publisher]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_inproceedings","**note**","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**\@incollection**","[type: generic]{.underline}","Including a [collection-title]{.underline} value",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**author** (required)","[authors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**title** (required)","[title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**booktitle** (required)","[collection-title]{.underline}","Additionally [collection-type]{.underline} would be populated as ""collection""",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**publisher** (required)","[publisher]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**year** (required)","[year]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**editor**","[editors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**volume**","[volume]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**number**","[issue]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**series**","Ignored",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**type**","Ignored",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**chapter**","[section]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**pages**","[start]{.underline} and [end]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**address**","[address]{.underline} property of [publisher]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**edition**","[edition]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**month**","[month]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_incollection","**note**","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_manual","**\@manual**","[type: manual]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_manual","**title** (required)","[title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_manual","**author**","[authors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_manual","**organization**","[institution]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_manual","**address**","[address]{.underline} property of [organization]{.underline}","On missing [organization]{.underline} mapped to [location]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_manual","**edition**","[edition]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_manual","**month**","[month]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_manual","**year**","[year]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_manual","**note**","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_thesis","**\@mastersthesis, \@phdthesis**","[type: thesis]{.underline}","Use also [thesis-type]{.underline} for identifying the thesis type.",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_thesis","**author** (required)","[authors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_thesis","**title** (required)","[title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_thesis","**school** (required)","[institution]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_thesis","**year** (required)","[year]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_thesis","**type**","Ignored",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_thesis","**address**","[address]{.underline} property of [institution]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_thesis","**month**","[month]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_thesis","**note**","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_misc","**\@misc**","[type: generic]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_misc","**author**","[authors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_misc","**title**","[title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_misc","**howpublished**","[medium]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_misc","**month**","[month]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_misc","**year**","[year]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_misc","**note**","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**\@proceedings**","[type: proceedings]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**title** (required)","[title]{.underline} and [conference]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**year** (required)","[year]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**editor**","[editors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**volume**","[volume]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**number**","[issue]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**series**","[collection-title]{.underline}","Additionally [collection-type]{.underline} would be populated as ""proceedings""",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**address**","[address]{.underline} property of [conference]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**month**","[month]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**organization**","[institution]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**publisher**","[publisher]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_proceedings","**note**","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_techreport","**\@techreport**","[type: report]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_techreport","**author** (required)","[authors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_techreport","**title** (required)","[title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_techreport","**institution** (required)","[institution]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_techreport","**year** (required)","[year]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_techreport","**type**","Ignored",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_techreport","**number**","[issue]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_techreport","**address**","[address]{.underline} property of [institution]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_techreport","**month**","[month]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_techreport","**note**","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_unpublished","**\@unpublished**","[type: unpublished]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_unpublished","**author** (required)","[authors]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_unpublished","**title** (required)","[title]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_unpublished","**note** (required)","[notes]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_unpublished","**month**","[month]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"model_unpublished","**year**","[year]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[art]{.underline}","A work of art, e.g., a painting",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[article]{.underline}",NA,"[[article]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[audiovisual]{.underline}",NA,"[[audiovisual]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[bill]{.underline}","A legal bill","[[bill]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[blog]{.underline}","A blog post","[[blog]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[book]{.underline}","A book or e-book","[[book]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[catalogue]{.underline}",NA,"[[catalogue]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[conference]{.underline}",NA,"[[conference]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[conference-paper]{.underline}",NA,"[[conference-paper]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[data]{.underline}","A data set","[[data]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[database]{.underline}","An aggregated or online database","[[database]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[dictionary]{.underline}",NA,"[[dictionary]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[edited-work]{.underline}","An edited work, e.g., a book","[[edited-work]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[encyclopedia]{.underline}",NA,"[[encyclopedia]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[film-broadcast]{.underline}","A film or broadcast","[[film-broadcast]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[generic]{.underline}","The fallback type","[[generic]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[government-document]{.underline}",NA,"[[government-document]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[grant]{.underline}","A research or other grant","[[grant]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[hearing]{.underline}",NA,"[[hearing]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[historical-work]{.underline}","A historical work, e.g., a medieval manuscript","[[historical-work]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[legal-case]{.underline}",NA,"[[legal-case]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[legal-rule]{.underline}",NA,"[[legal-rule]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[magazine-article]{.underline}",NA,"[[magazine-article]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[manual]{.underline}","A manual","[[manual]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[map]{.underline}","A geographical map","[[map]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[multimedia]{.underline}","A multimedia file","[[multimedia]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[music]{.underline}","A music file or sheet music","[[music]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[newspaper-article]{.underline}",NA,"[[newspaper-article]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[pamphlet]{.underline}",NA,"[[pamphlet]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[patent]{.underline}",NA,"[[patent]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[personal-communication]{.underline}",NA,"[[personal-communication]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[proceedings]{.underline}","Conference proceedings","[[proceedings]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[report]{.underline}",NA,"[[report]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[serial]{.underline}",NA,"[[serial]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[slides]{.underline}","Slides, i.e., a published slide deck","[[slides]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[software]{.underline}","Software","[[software]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[software-code]{.underline}","Software source code","[[software-code]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[software-container]{.underline}","A software container (e.g., a docker container)","[[software-container]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[software-executable]{.underline}","An executable software, i.e., a binary/artifact","[[software-executable]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[software-virtual-machine]{.underline}","A virtual machine/vm image","[[software-virtual-machine]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[sound-recording]{.underline}",NA,"[[sound-recording]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[standard]{.underline}",NA,"[[standard]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[statute]{.underline}",NA,"[[statute]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[thesis]{.underline}","An academic thesis","[[thesis]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[unpublished]{.underline}",NA,"[[unpublished]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[video]{.underline}","A video recording","[[video]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA +"cff_types","[website]{.underline}",NA,"[[website]{.underline}]{.underline}",NA,NA,NA,NA,NA,NA,NA,NA,NA,NA diff --git a/inst/schemaorg.json b/inst/schemaorg.json index 71cc4348..dec7a9c6 100644 --- a/inst/schemaorg.json +++ b/inst/schemaorg.json @@ -26,6 +26,6 @@ "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "runtimePlatform": "R version 4.3.2 (2023-10-31)", - "version": "0.5.0" + "runtimePlatform": "R version 4.3.2 (2023-10-31 ucrt)", + "version": "0.5.0.9000" } diff --git a/man/cff-class.Rd b/man/cff-class.Rd new file mode 100644 index 00000000..79127b37 --- /dev/null +++ b/man/cff-class.Rd @@ -0,0 +1,9 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cff-class.R +\name{cff-class} +\alias{cff-class} +\title{The \code{cff} class} +\description{ +TODO +} +\keyword{internal} diff --git a/man/cff_from_bibtex.Rd b/man/cff_from_bibtex.Rd index b6adf32f..d87fc3b4 100644 --- a/man/cff_from_bibtex.Rd +++ b/man/cff_from_bibtex.Rd @@ -63,7 +63,7 @@ if (requireNamespace("bibtex", quietly = TRUE)) { information between BibTeX and CITATION.cff. Other BibTeX helpers: -\code{\link{cff_to_bibtex}()}, +\code{\link{cff_to_bibentry}()}, \code{\link{encoded_utf_to_latex}()}, \code{\link{write_bib}()}, \code{\link{write_citation}()} diff --git a/man/cff_to_bibtex.Rd b/man/cff_to_bibentry.Rd similarity index 78% rename from man/cff_to_bibtex.Rd rename to man/cff_to_bibentry.Rd index 709b0224..338a14e4 100644 --- a/man/cff_to_bibtex.Rd +++ b/man/cff_to_bibentry.Rd @@ -1,11 +1,11 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/cff_to_bibtex.R -\name{cff_to_bibtex} +% Please edit documentation in R/cff_to_bibentry.R +\name{cff_to_bibentry} +\alias{cff_to_bibentry} \alias{cff_to_bibtex} -\alias{cff_extract_to_bibtex} \title{Create BibTeX entries from several sources} \usage{ -cff_to_bibtex(x, what = c("preferred", "references", "all")) +cff_to_bibentry(x, what = c("preferred", "references", "all")) } \arguments{ \item{x}{The source that would be used for generating @@ -33,11 +33,14 @@ A \code{bibentry} object or a list of \code{bibentry} objects. This could be parsed to BibTeX using \code{\link[=toBibtex]{toBibtex()}} } \description{ -This function creates BibTeX entries (in the form of \code{\link[=bibentry]{bibentry()}} objects +This function creates \code{\link[=bibentry]{bibentry()}} objects from different metadata sources (\code{cff} objects, \code{DESCRIPTION} files, etc.). -The function tries to parse the information of the source \code{x} into a \code{cff} +The function tries to map the information of the source \code{x} into a \code{cff} object and performs a mapping of the metadata to BibTeX, according to \code{vignette("bibtex_cff", "cffr")}. + +Note that a \strong{R} \code{\link[=bibentry]{bibentry()}} object is the representation of a BibTeX +entry, see \strong{Examples}. } \examples{ \donttest{ @@ -47,7 +50,7 @@ cff_object <- cff() cff_object # bibentry object -bib <- cff_to_bibtex(cff_object) +bib <- cff_to_bibentry(cff_object) class(bib) @@ -60,13 +63,13 @@ toBibtex(bib) # From a CITATION.cff file with options path <- system.file("examples/CITATION_complete.cff", package = "cffr") -cff_file <- cff_to_bibtex(path, what = "all") +cff_file <- cff_to_bibentry(path, what = "all") toBibtex(cff_file) # For an installed package -installed_package <- cff_to_bibtex("jsonvalidate") +installed_package <- cff_to_bibentry("jsonvalidate") toBibtex(installed_package) @@ -74,7 +77,7 @@ toBibtex(installed_package) # Use a DESCRIPTION file path2 <- system.file("examples/DESCRIPTION_gitlab", package = "cffr") -desc_file <- cff_to_bibtex(path2) +desc_file <- cff_to_bibentry(path2) toBibtex(desc_file) } @@ -87,7 +90,7 @@ toBibtex(desc_file) \emph{Ruby CFF Library (Version 0.9.0)} (Computer software). \doi{10.5281/zenodo.1184077}. \item Hernangómez D (2022). "BibTeX and CFF, a potential crosswalk." -\emph{The cffr package, Vignettes} +\emph{The cffr package, Vignettes}. \doi{10.21105/joss.03900}, \url{https://docs.ropensci.org/cffr/articles/bibtex_cff.html}. } } diff --git a/man/encoded_utf_to_latex.Rd b/man/encoded_utf_to_latex.Rd index 3a44a611..43cd3d1d 100644 --- a/man/encoded_utf_to_latex.Rd +++ b/man/encoded_utf_to_latex.Rd @@ -47,7 +47,7 @@ ascii_table Other BibTeX helpers: \code{\link{cff_from_bibtex}()}, -\code{\link{cff_to_bibtex}()}, +\code{\link{cff_to_bibentry}()}, \code{\link{write_bib}()}, \code{\link{write_citation}()} } diff --git a/man/figures/lifecycle-archived.svg b/man/figures/lifecycle-archived.svg new file mode 100644 index 00000000..745ab0c7 --- /dev/null +++ b/man/figures/lifecycle-archived.svg @@ -0,0 +1,21 @@ + + lifecycle: archived + + + + + + + + + + + + + + + lifecycle + + archived + + diff --git a/man/figures/lifecycle-defunct.svg b/man/figures/lifecycle-defunct.svg new file mode 100644 index 00000000..d5c9559e --- /dev/null +++ b/man/figures/lifecycle-defunct.svg @@ -0,0 +1,21 @@ + + lifecycle: defunct + + + + + + + + + + + + + + + lifecycle + + defunct + + diff --git a/man/figures/lifecycle-deprecated.svg b/man/figures/lifecycle-deprecated.svg new file mode 100644 index 00000000..b61c57c3 --- /dev/null +++ b/man/figures/lifecycle-deprecated.svg @@ -0,0 +1,21 @@ + + lifecycle: deprecated + + + + + + + + + + + + + + + lifecycle + + deprecated + + diff --git a/man/figures/lifecycle-experimental.svg b/man/figures/lifecycle-experimental.svg index d1d060e9..5d88fc2c 100644 --- a/man/figures/lifecycle-experimental.svg +++ b/man/figures/lifecycle-experimental.svg @@ -1 +1,21 @@ -lifecyclelifecycleexperimentalexperimental \ No newline at end of file + + lifecycle: experimental + + + + + + + + + + + + + + + lifecycle + + experimental + + diff --git a/man/figures/lifecycle-maturing.svg b/man/figures/lifecycle-maturing.svg new file mode 100644 index 00000000..897370ec --- /dev/null +++ b/man/figures/lifecycle-maturing.svg @@ -0,0 +1,21 @@ + + lifecycle: maturing + + + + + + + + + + + + + + + lifecycle + + maturing + + diff --git a/man/figures/lifecycle-questioning.svg b/man/figures/lifecycle-questioning.svg new file mode 100644 index 00000000..7c1721d0 --- /dev/null +++ b/man/figures/lifecycle-questioning.svg @@ -0,0 +1,21 @@ + + lifecycle: questioning + + + + + + + + + + + + + + + lifecycle + + questioning + + diff --git a/man/figures/lifecycle-soft-deprecated.svg b/man/figures/lifecycle-soft-deprecated.svg new file mode 100644 index 00000000..9c166ff3 --- /dev/null +++ b/man/figures/lifecycle-soft-deprecated.svg @@ -0,0 +1,21 @@ + + lifecycle: soft-deprecated + + + + + + + + + + + + + + + lifecycle + + soft-deprecated + + diff --git a/man/figures/lifecycle-stable.svg b/man/figures/lifecycle-stable.svg new file mode 100644 index 00000000..9bf21e76 --- /dev/null +++ b/man/figures/lifecycle-stable.svg @@ -0,0 +1,29 @@ + + lifecycle: stable + + + + + + + + + + + + + + + + lifecycle + + + + stable + + + diff --git a/man/figures/lifecycle-superseded.svg b/man/figures/lifecycle-superseded.svg new file mode 100644 index 00000000..db8d757f --- /dev/null +++ b/man/figures/lifecycle-superseded.svg @@ -0,0 +1,21 @@ + + lifecycle: superseded + + + + + + + + + + + + + + + lifecycle + + superseded + + diff --git a/man/figures/logo.png b/man/figures/logo.png index ea954aa005bf6ac633e7f23659d5fe459a67abb4..c876c2e1abfbf96534c59b280bbbcd79f7364920 100644 GIT binary patch literal 16971 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

!| zH6A>G=TqeCq@e!T`AZg;2SG)6Pav@`+3Y2;zPGWh$^etrFi|W2UPiVF{R%AGVJx;U zQ^VElJVb?OdfTJR0^EYLm(xQW?1!rpAnH2x^f}Nh@;aWaK^51i6`Bgm+X@T%*89Hr z%ioDgy1`5R*2CoIWH~l@-`VTozF*+1*Z$}%kFU1+^0r2EBmSQ45fXtn)pReNCH2{3 z?;NFjPaD{o7H-c_{3tt$l}mfDE$CuH++>~R5jsjAXvNVBoLLD8Vl)Vw_fypx9`joT zu*jZ?SEhCBXYy(6RO=kC^SM32sQ&&y%EbdKWRQLbnv~ubJ)3Kgv&QI9AKY*`$H+v z5|r03&Xa2huf&?VaKC=aysI(9>vUm9+@$kFe5qdab@md{PfOmXLFTgfTacH=p zFch(_$$&2P)-31BASHlK7a98ng6T z{aI?hY;Yqy>VWlUL0SsjS~ruSgL^+(iaEjf0BPqs+gD*i>MCezR&@5YhT_AQ{=ij zIBZH&NbSB8C(D{njRH(=_bB{r)CqqOpM_jwX zZX4kYJ|4Y%kY8#fhp5*72KdIW;EfiRD5kg;mgSZy)_l`&=7_57d zAyYV+eIz!0t#TX1m4_I;@Luh-a9)W!qkrKa1Ho>f+GHOpsd^vghF1jrz83*TJx=D% zagZ6NP@WOhQzprwkv=AYult#$S~G6ZN?qMpauAvf4CccumJ0)8X^%3=9G}33<=>77 zK)%%b@Tr?+kyW8JetTAJ65QM(Em9bz;#&Tv=M1%I-k^P+JIs=*b&k@E-+#5p@Qb(X)Y6i^oyril{|t@UmoXYvY+xub|FMSTQZD`@5IpFz00>D- zY6{AK7t3B)cwR&wmOB%09D``42jR-Vw4-p6br)dn2h&W^o$^X68PxBa5%bYeZf|nh zKaVjDu+I-Dd~S5^-V3|WbF1MpYcy17Xris2`{RLM2uZFD>95_dR8M=ey#yKa5|w0^ z|DcW(^)PFeRtIkyG2|QTbXzld&LiK{5o5)0m|^kQLu4nWj7E&<#_Sfv7^MOx-VY?} zKJJ~%d{t%N|BFA|DL%om=O+5u)j}!mA3=%pN5)+sGDI3JSAn`!XwQ>9fBInCLZvL` zuyAxzTSWpTlQ4&r+au9V`wLVfYinrIYkHC8_O&8?P8(*4tsazXLfPlBnaPfi*a!;; ztu?sYiK#hZTunTHK~Q}!y zReg0;N3}TvAaJtn5U33t)oSyvXM{$Z!hZFFvK6%*0=0qTpwg8&wD#nCOB!E^1m;-!#(Swox?`28}fn3%s+lm{ z+nMQt^}1`M>NxJ$-{xGAA+TL$g0bM}P%lQ+vngsJa4*-94UY1`QPrlX)8AIPR-~8- z{U)gM1AwEs?!_q3QKpy)qX+*F=~k-Ek!pY27I57DT2bf6dz)hN?VV|ZI?DDOI1X*S z7&Wb4D>8Rj9og6*cbywMP`wxh-l1K+Ry5QJ5U3?(6&$Uft-lM_Tr29tIK#_j zfXq*nYelW^DBEk*=BXj&1Y3r{&aERG21muF=u8OI6cRX^_oA6#Bsh+aOXA&YW`eQR f=IF@}R7d^;mh-pRdV6SI00000NkvXXu0mjfWdKI( literal 44443 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 V*Ly=Sh8+L^002ovPDHLkV1n**bC>`C diff --git a/man/previous_cff_to_bib.Rd b/man/previous_cff_to_bib.Rd new file mode 100644 index 00000000..94761d70 --- /dev/null +++ b/man/previous_cff_to_bib.Rd @@ -0,0 +1,48 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/deprecated.R +\name{cff_extract_to_bibtex} +\alias{cff_extract_to_bibtex} +\title{Previous API: Create BibTeX entries from several sources} +\usage{ +cff_extract_to_bibtex(x, what = c("preferred", "references", "all")) +} +\arguments{ +\item{x}{The source that would be used for generating +the \code{\link[=bibentry]{bibentry()}} object via \code{cff}. It could be: +\itemize{ +\item A missing value. That would retrieve the DESCRIPTION +file on your in-development package. +\item An existing \code{\link{cff}} object, +\item Path to a CITATION.cff file (\code{"*/CITATION.cff*"}), +\item The name of an installed package (\code{"jsonlite"}), or +\item Path to a DESCRIPTION file (\code{"*/DESCRIPTION*"}). +}} + +\item{what}{Fields to extract. The value could be: +\itemize{ +\item \code{preferred}: This would create a single entry with the main citation +info of the package. +\item \code{references}: Extract all the entries on \code{references}. +\item \code{all}: A combination of the previous two options. This would extract +both the preferred citation info and the references. +}} +} +\value{ +See \code{\link[=cff_to_bibentry]{cff_to_bibentry()}} +} +\description{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#superseded}{\figure{lifecycle-superseded.svg}{options: alt='[Superseded]'}}}{\strong{[Superseded]}} +Please use \code{\link[=cff_to_bibentry]{cff_to_bibentry()}} instead. +} +\examples{ +\donttest{ +# From a cff object +cff_object <- cff() + +cff_object + +# bibentry object +bib <- cff_to_bibentry(cff_object) +} +} +\keyword{internal} diff --git a/man/write_bib.Rd b/man/write_bib.Rd index 07904f8d..5240e5a0 100644 --- a/man/write_bib.Rd +++ b/man/write_bib.Rd @@ -9,7 +9,7 @@ write_bib(x, file = NULL, append = FALSE, verbose = TRUE, ascii = FALSE) \arguments{ \item{x}{A \code{bibentry} object created with: \itemize{ -\item \code{\link[=cff_to_bibtex]{cff_to_bibtex()}} +\item \code{\link[=cff_to_bibentry]{cff_to_bibentry()}} \item \code{\link[=citation]{citation()}} or \code{\link[=bibentry]{bibentry()}} }} @@ -56,7 +56,7 @@ following packages: Other BibTeX helpers: \code{\link{cff_from_bibtex}()}, -\code{\link{cff_to_bibtex}()}, +\code{\link{cff_to_bibentry}()}, \code{\link{encoded_utf_to_latex}()}, \code{\link{write_citation}()} } diff --git a/man/write_citation.Rd b/man/write_citation.Rd index 09aa9e7b..55d8d8fe 100644 --- a/man/write_citation.Rd +++ b/man/write_citation.Rd @@ -15,9 +15,9 @@ write_citation( \arguments{ \item{x}{It could be \itemize{ -\item A \code{bibentry} object created with \code{\link[=cff_to_bibtex]{cff_to_bibtex()}}, \code{\link[=citation]{citation()}} or +\item A \code{bibentry} object created with \code{\link[=cff_to_bibentry]{cff_to_bibentry()}}, \code{\link[=citation]{citation()}} or \code{\link[=bibentry]{bibentry()}} -\item Any of the valid inputs of \code{\link[=cff_to_bibtex]{cff_to_bibtex()}}: +\item Any of the valid inputs of \code{\link[=cff_to_bibentry]{cff_to_bibentry()}}: \itemize{ \item A missing value. That would retrieve the DESCRIPTION file on your in-development package. @@ -35,7 +35,7 @@ in-development package. \item{verbose}{Display informative messages} \item{...}{ - Arguments passed on to \code{\link[=cff_to_bibtex]{cff_to_bibtex}} + Arguments passed on to \code{\link[=cff_to_bibentry]{cff_to_bibentry}} \describe{ \item{\code{what}}{Fields to extract. The value could be: \itemize{ @@ -91,7 +91,7 @@ R version 4.3.0 (2023-04-21) edition. Other BibTeX helpers: \code{\link{cff_from_bibtex}()}, -\code{\link{cff_to_bibtex}()}, +\code{\link{cff_to_bibentry}()}, \code{\link{encoded_utf_to_latex}()}, \code{\link{write_bib}()} } diff --git a/pkgdown/favicon/apple-touch-icon-180x180.png b/pkgdown/favicon/apple-touch-icon-180x180.png index 32a12c8139bd66d03555b3eded895b19ba24e86b..ca5657ebb8b38fc757b4a0e7bb6be376863df140 100644 GIT binary patch literal 9121 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 Ywtm%b0o|GQpA$+}Qc0pt%sAx#0Ao*SmH+?% literal 9124 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 JPDHLkV1oB8dk+8r delta 2519 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 delta 3100 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 diff --git a/pkgdown/favicon/apple-touch-icon.png b/pkgdown/favicon/apple-touch-icon.png index 32a12c8139bd66d03555b3eded895b19ba24e86b..ca5657ebb8b38fc757b4a0e7bb6be376863df140 100644 GIT binary patch literal 9121 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 Ywtm%b0o|GQpA$+}Qc0pt%sAx#0Ao*SmH+?% literal 9124 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

_TXt?c5tLf+S`>omb zh{*Az((&Z+`l{FUl+E+r?)l8+_QK)yuGa9Z)bQ^1{G!k9tl0MG_5H2a^4stI(CYks zyyut7?627KzvKGo_5O{;>w&-NpV9J^%kRMB`hU6L`}X_(rquJ4%<{S2^tj;rsoD9} z?fj0%?u5wn#^(FF-}j`}_mIo-rPcMY+V#)s{IJ>es@V37%=We0_15kC((C(;$nd(} z_q*Wv#O3>NyzXqe?fLxwlg#pe!taU4@l&qqn9uWLwd}Lo_QT`&L8a(>!S8p!?x&rl zj(-3E09bTVPE!C4!UnTOk9r_wT{Q)q&xu4U5X1q%Nh2{_-{ywBMVgB=8PS6ke zwD`_j%RS_J_qMUT!8#KAyDWa;ZJOBf!s8=p)IWC8L=?A_=t#jNs&NCEYi#p;-R?_ z5s}f+QMueg?#yV?`~t!OnGq2YN&mO5{~ZyL;AwBok1Wq)s zn%ZD%$OD&VRMp{&j)+M4_Pw+7SNf0iooTTV5m9`4x=^R+YiY*-O^=BF+_q`^zkh}u z1v{cZ+=v(>6LXL}t9V8P1hjqn+T5PenfN3cDo|;~3RJ+!1kn%?H#0XrE;=AU?jYqN-v=87*ubjM8{0NQeE~sCn>wKpn87J{4>+%@sk)q;{W zY13QROiDh#7fAsuvLd<<&$)4XR@t2U)!E(22nDQyNr>o)DCsSoS6X@u!pSfNMK=Sl zkY+AiL2Bl#d6!GT%r0(YUVliE(hw7ojEAY1bnen|aQaeKS3;zIE-C5aSZEXEiE|G1u2a7I*e$_V)9UN3|RP;tDERW;~Ra00000NkvXXt^-0~f}11LGynhq delta 1549 zcmV+o2J-o;46O{1Gk;puc);%fZQ1}q&T+i%0A|<#W!GZ0>;;A3v)lFqgx?{T;Qed58z#pL*M zz3wWS<)hT}AeH2_-1cz1?kJh%Zo2IznB}nA^{v?TAeQ8b$A9r$vgQIilwdi{UVx=1QsQd%^Fa)ARs--h9FDhsN;XOXzLZ;}S((@~ut{{QIp{lw(? z^7;PW@B8uj{qy<##^m?JYCpVjx}^ZmWx_ny%4&FK2Q;rXfA`J>eI?tl0G+U@$>@B7H-{IJ>e*zEf6 z`2N!C`@rG%yWjVn(eswh^RLiX#Q{@d>Rv)%dC>iDzU z_0Q@0*6aDF*!h>x_O{;m+3fj>$M2`t_o>(QqSW=T+xf%c^`zGKvEBN%-}#!-^}XNr zv)%Z+;D7m~)b!`{{g%w|zT*1Ch=7W%Ivw|`;Eoxl+5zG z-t>XL>6FXwz~J?!)brWy{JGuqgvj)|-}jEk?zrIlu-f&d)%B3e@~YVO&+7b)%=V4Q z@VegjwcGW?<@;>9?Qp#A`TYNr%<_N2?}^9pQ?BYkrRcNU_IJPTn9uWj!S7?W?A$Kf z{eJ)e09bTVPE!C4!UDnw0m2Fjy&d`*KrjZMxetQVW=j5r<{&;ar2hTTVe?M;&R)w~ z`1d{JwtBR&ygI?V`x4=PENzhZf z0)$CKK~y-)V_-lA%rYUtfy@jzfwZJldVfoh2saLCd$F+a=!l4D2~mGWEYbqv0inea z5s@)5QN=t$ZUSi1Z2W?LHzOh<3jcI%{T&gp&eO(<4OyPo(y=)l%s;eo)L_{Qf|Iy$7zwc+?{-oH5h$saOO{i0J474(Urbonl?%uigUw`|) ztbI`+ZbXK*p)p9FH6T6$0=mC^+tCx>pZhunDv)l<3RJ+!1kn%?*HIiD7n2;50ObR{ z#LfXyzyc9Sm|Fg#y6J1{+lUD43NFmKU6Ql>Q+avH#3D=u(a}XEWhIZRH)AZ`56@N?8P!y!q&%J)*@v@x@I}0||XJ;?Tp8NC$s)F2w z^H!&>teU)L%H|E5>sD{tJa6T+D7XTqjGOs878m5cNzGk1WlMePgu2Cfvr>EO;0hcL z9X@hqV@vm<(k(T;Yx8nHrQ1Qw7>6a+cR@*X$Gn{6JjzdF4xZfxUsM_J*#%X#s#x6L-N3?vk$W7 zuTRRKvVKOvrGrQcV38G(dHUY2Cl6=edtO_bS%6T$%2kMno{0HJE0+_G+osE!z?SOTmZ3S(xj7diFShg=sA#8#l$QUs37+EiK9GR;sRLmmbta. + authors: + - family-names: Hernangómez + given-names: Diego + email: diego.hernangomezherrero@gmail.com + orcid: https://orcid.org/0000-0001-8457-4658 + repository: https://CRAN.R-project.org/package=resmush + repository-code: https://github.com/dieghernan/resmush + url: https://dieghernan.github.io/resmush/ + date-released: '2024-02-02' + contact: + - family-names: Hernangómez + given-names: Diego + email: diego.hernangomezherrero@gmail.com + orcid: https://orcid.org/0000-0001-8457-4658 + keywords: + - r + - compress-images + - optimize-images + - resmushit + - api + # Search package on CRAN Code diff --git a/tests/testthat/_snaps/cff_parse_citation.md b/tests/testthat/_snaps/cff_parse_citation.md index c3ee0d50..c2081654 100644 --- a/tests/testthat/_snaps/cff_parse_citation.md +++ b/tests/testthat/_snaps/cff_parse_citation.md @@ -242,6 +242,7 @@ given-names: A conference: name: A conference + address: A location database-provider: name: Database provider editors: @@ -254,7 +255,6 @@ - name: Another publisher: name: A publisher - address: A location recipients: - family-names: recipient given-names: A diff --git a/tests/testthat/_snaps/cff_to_bibtex.md b/tests/testthat/_snaps/cff_to_bibentry.md similarity index 99% rename from tests/testthat/_snaps/cff_to_bibtex.md rename to tests/testthat/_snaps/cff_to_bibentry.md index 1da2feca..80e419b9 100644 --- a/tests/testthat/_snaps/cff_to_bibtex.md +++ b/tests/testthat/_snaps/cff_to_bibentry.md @@ -222,7 +222,6 @@ publisher = {International Joint Conference on Artificial Intelligence}, address = {Murray Hill, New Jersey}, editor = {Jan Alexandersson}, - series = {A Series}, pages = {81--86}, organization = {IJCAI}, } @@ -280,6 +279,7 @@ title = {Computer-Aided Analysis of English Punctuation on a Parsed Corpus: The Special Case of Comma}, author = {Murat Bayraktar}, year = {1996}, + address = {Ankara, Turkey}, note = {Forthcoming}, school = {Department of Computer Engineering and Information Science, Bilkent University, Turkey}, } @@ -307,6 +307,7 @@ title = {Presupposition and Assertion in Dynamic Semantics}, author = {David I. Beaver}, year = {1995}, + address = {Edinburgh}, school = {Centre for Cognitive Science, University of Edinburgh}, } diff --git a/tests/testthat/_snaps/deprecated.md b/tests/testthat/_snaps/deprecated.md new file mode 100644 index 00000000..ac22bc72 --- /dev/null +++ b/tests/testthat/_snaps/deprecated.md @@ -0,0 +1,9 @@ +# cff_extract_to_bibtex + + Code + old1 <- cff_extract_to_bibtex(a_cff) + Condition + Warning: + `cff_extract_to_bibtex()` was deprecated in cffr 0.5.0. + i Please use `cff_to_bibentry()` instead. + diff --git a/tests/testthat/_snaps/merge_desc_cit.md b/tests/testthat/_snaps/merge_desc_cit.md index 50bd133f..4476fa32 100644 --- a/tests/testthat/_snaps/merge_desc_cit.md +++ b/tests/testthat/_snaps/merge_desc_cit.md @@ -562,6 +562,70 @@ isbn: 978-3-319-24277-4 url: https://ggplot2.tidyverse.org +--- + + Code + merged + Output + cff-version: 1.2.0 + message: 'To cite package "resmush" in publications use:' + type: software + title: 'resmush: Optimize and Compress Image Files with ''reSmush.it''' + version: 0.1.0 + authors: + - family-names: Hernangómez + given-names: Diego + email: diego.hernangomezherrero@gmail.com + orcid: https://orcid.org/0000-0001-8457-4658 + abstract: Compress local and online images using the 'reSmush.it' API service . + repository: https://CRAN.R-project.org/package=resmush + repository-code: https://github.com/dieghernan/resmush + url: https://dieghernan.github.io/resmush/ + date-released: '2024-02-02' + contact: + - family-names: Hernangómez + given-names: Diego + email: diego.hernangomezherrero@gmail.com + orcid: https://orcid.org/0000-0001-8457-4658 + keywords: + - r + - compress-images + - optimize-images + - resmushit + - api + license: MIT + doi: 10.1111/2041-210X.12469 + preferred-citation: + type: article + title: 'RNeXML: A Package for Reading and Writing Richly Annotated Phylogenetic, + Character, and Trait Data in R' + authors: + - family-names: Boettiger + given-names: Carl + - family-names: Chamberlain + given-names: Scott + - family-names: Vos + given-names: Rutger + - family-names: Lapp + given-names: Hilmar + journal: Methods in Ecology and Evolution + year: '2016' + volume: '7' + doi: 10.1111/2041-210X.12469 + start: '352' + end: '357' + references: + - type: book + title: 'ggplot2: Elegant Graphics for Data Analysis' + authors: + - family-names: Wickham + given-names: Hadley + publisher: + name: Springer-Verlag New York + year: '2016' + isbn: 978-3-319-24277-4 + url: https://ggplot2.tidyverse.org + --- Code @@ -587,7 +651,7 @@ repository: https://ropensci.r-universe.dev repository-code: https://github.com/ropensci/codemetar url: https://docs.ropensci.org/codemetar/ - date-released: '2023-04-05' + date-released: '2024-02-09' contact: - family-names: Boettiger given-names: Carl diff --git a/tests/testthat/test-assertions.R b/tests/testthat/test-assertions.R index 920d6027..aaebfdb9 100644 --- a/tests/testthat/test-assertions.R +++ b/tests/testthat/test-assertions.R @@ -1,49 +1,49 @@ -test_that("Check is.email", { +test_that("Check is_email", { # Examples from https://www.nicebread.de/validating-email-adresses-in-r/ # Valid addresses expect_true( all( - is.email("felix@nicebread.de"), - is.email("felix.123.honeyBunny@nicebread.lmu.de"), - is.email("felix@nicebread.de "), - is.email(" felix@nicebread.de"), - is.email("felix+batman@nicebread.de"), - is.email("felix@nicebread.office") + is_email("felix@nicebread.de"), + is_email("felix.123.honeyBunny@nicebread.lmu.de"), + is_email("felix@nicebread.de "), + is_email(" felix@nicebread.de"), + is_email("felix+batman@nicebread.de"), + is_email("felix@nicebread.office") ) ) # invalid addresses expect_false( any( - is.email("felix@nicebread"), - is.email("felix@nicebread@de"), - is.email("felixnicebread.de"), - is.email("@felixnicebread"), - is.email(NULL), - is.email(NA) + is_email("felix@nicebread"), + is_email("felix@nicebread@de"), + is_email("felixnicebread.de"), + is_email("@felixnicebread"), + is_email(NULL), + is_email(NA) ) ) }) -test_that("Check is.url", { +test_that("Check is_url", { # Valid urls expect_true( all( - is.url("https://github.com/dieghernan"), - is.url("http://github.com/dieghernan"), - is.url("ftp://github.com/dieghernan"), - is.url("sftp://github.com/dieghernan") + is_url("https://github.com/dieghernan"), + is_url("http://github.com/dieghernan"), + is_url("ftp://github.com/dieghernan"), + is_url("sftp://github.com/dieghernan") ) ) # invalid addresses expect_false( any( - is.url("https:/github.com/dieghernan"), - is.url("http:/github.com/dieghernan"), - is.url("ftp:/github.com/dieghernan"), - is.url("sftp:/github.com/dieghernan"), - is.url("www.github.com/dieghernan") + is_url("https:/github.com/dieghernan"), + is_url("http:/github.com/dieghernan"), + is_url("ftp:/github.com/dieghernan"), + is_url("sftp:/github.com/dieghernan"), + is_url("www.github.com/dieghernan") ) ) }) diff --git a/tests/testthat/test-bibtex-check-ruby.R b/tests/testthat/test-bibtex-check-ruby.R index c6347475..6dd4f780 100644 --- a/tests/testthat/test-bibtex-check-ruby.R +++ b/tests/testthat/test-bibtex-check-ruby.R @@ -1,4 +1,5 @@ -# See https://github.com/citation-file-format/ruby-cff/tree/main/test/files/formatted +# See ´ +# https://github.com/citation-file-format/ruby-cff/tree/main/test/files/formatted test_that("preferred-citation-book-missing", { @@ -6,7 +7,7 @@ test_that("preferred-citation-book-missing", { package = "cffr" ) - expect_warning(expect_error(cff_to_bibtex(x))) + expect_warning(expect_error(cff_to_bibentry(x))) }) test_that("preferred-citation-book", { @@ -14,7 +15,7 @@ test_that("preferred-citation-book", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -23,7 +24,7 @@ test_that("preferred-citation-conference-paper-2", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -32,7 +33,7 @@ test_that("preferred-citation-conference-paper-missing", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -41,7 +42,7 @@ test_that("preferred-citation-conference-paper", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -50,7 +51,7 @@ test_that("preferred-citation-manual", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -59,7 +60,7 @@ test_that("preferred-citation-no-month", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -68,7 +69,7 @@ test_that("preferred-citation-no-vol", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -78,7 +79,7 @@ test_that("preferred-citation-pamphlet", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -87,7 +88,7 @@ test_that("preferred-citation-report-no-institution", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -96,7 +97,7 @@ test_that("preferred-citation-report", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -106,7 +107,7 @@ test_that("preferred-citation-unpublished", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -115,7 +116,7 @@ test_that("reprozip", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -125,7 +126,7 @@ test_that("smith-et-al", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -134,6 +135,6 @@ test_that("tidyverse-joss-paper", { package = "cffr" ) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) diff --git a/tests/testthat/test-bibtex2cff.R b/tests/testthat/test-bibtex2cff.R index 4af1feb7..29a49e4b 100644 --- a/tests/testthat/test-bibtex2cff.R +++ b/tests/testthat/test-bibtex2cff.R @@ -21,6 +21,13 @@ test_that("Article", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) + + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- sort(names(unclass(bib)[[1]])) + fld2 <- sort(names(unclass(tobib)[[1]])) + expect_identical(fld1, fld2) }) @@ -53,6 +60,13 @@ test_that("Book", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) + + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- sort(names(unclass(bib)[[1]])) + fld2 <- sort(names(unclass(tobib)[[1]])) + expect_identical(fld1, fld2) }) @@ -78,6 +92,15 @@ test_that("Booklet", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) + + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- sort(names(unclass(bib)[[1]])) + fld2 <- sort(names(unclass(tobib)[[1]])) + + # Keyword is not parsed + expect_identical(setdiff(fld1, fld2), "keywords") }) test_that("Conference", { @@ -108,8 +131,6 @@ test_that("Conference", { bib <- list(bib_un) class(bib) <- "bibentry" - - bibparsed <- cff_parse_citation(bib) expect_snapshot(bibparsed) @@ -119,6 +140,14 @@ test_that("Conference", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) + + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(setdiff(fld1, fld2), "series") }) test_that("InBook", { @@ -150,6 +179,13 @@ test_that("InBook", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(setdiff(fld1, fld2), "type") }) test_that("InCollection", { @@ -183,8 +219,15 @@ test_that("InCollection", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) -}) + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(setdiff(fld1, fld2), c("series", "type")) +}) test_that("InProceedings", { bib <- bibentry("InProceedings", @@ -214,8 +257,15 @@ test_that("InProceedings", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) -}) + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(setdiff(fld1, fld2), "series") +}) test_that("Manual", { bib <- bibentry("Manual", @@ -238,8 +288,15 @@ test_that("Manual", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) -}) + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(fld1, fld2) +}) test_that("MastersThesis", { bib <- bibentry("MastersThesis", @@ -255,7 +312,6 @@ test_that("MastersThesis", { month = "August", note = "Example modified for testing purposes" ) - bibparsed <- cff_parse_citation(bib) expect_snapshot(bibparsed) @@ -264,8 +320,15 @@ test_that("MastersThesis", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) -}) + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(setdiff(fld1, fld2), "type") +}) test_that("Misc", { bib <- bibentry("Misc", @@ -286,6 +349,14 @@ test_that("Misc", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) + + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(fld1, fld2) }) @@ -311,6 +382,14 @@ test_that("PhdThesis", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) + + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(setdiff(fld1, fld2), "type") }) @@ -338,6 +417,14 @@ test_that("Proceedings", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) + + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(fld1, fld2) }) test_that("TechReport", { @@ -362,6 +449,14 @@ test_that("TechReport", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) + + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(setdiff(fld1, fld2), "type") }) test_that("Unpublished", { @@ -382,8 +477,52 @@ test_that("Unpublished", { ) expect_true(cff_validate(cffobj, verbose = FALSE)) + + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(fld1, fld2) }) +test_that("InBook with booktitle", { + bib <- bibentry("InBook", + title = "Bibliographies and citations", + year = "2020", + author = "Yihui Xie and Christophe Dervieux and Emily Riederer", + booktitle = "{R} Markdown Cookbook", + publisher = "Chapman and Hall/CRC", + address = "Boca Raton, Florida", + series = "The {R} Series", + isbn = "9780367563837", + url = "https://bookdown.org/yihui/rmarkdown-cookbook", + chapter = "4.5" + ) + + bibparsed <- cff_parse_citation(bib) + expect_snapshot(bibparsed) + + cffobj <- cff_create(cff(), + keys = list(references = list(bibparsed)) + ) + + expect_true(cff_validate(cffobj, verbose = FALSE)) + + # Should be an incollection now + res <- cff_to_bibentry(bibparsed) + init_type <- attr(unclass(res)[[1]], "bibtype") + expect_identical(tolower(init_type), "incollection") + + # Back to bibtex and check names + tobib <- cff_to_bibentry(bibparsed) + + fld1 <- unique(sort(names(unclass(bib)[[1]]))) + fld2 <- unique(sort(names(unclass(tobib)[[1]]))) + + expect_identical(setdiff(fld1, fld2), "series") +}) test_that("Test entry without author", { bib <- bibentry("Proceedings", diff --git a/tests/testthat/test-cff_description.R b/tests/testthat/test-cff_description.R index b096a052..2a6f8f1d 100644 --- a/tests/testthat/test-cff_description.R +++ b/tests/testthat/test-cff_description.R @@ -172,6 +172,26 @@ test_that("Parsing Bioconductor", { expect_true(cff_validate(parsed, verbose = FALSE)) }) +test_that("Parsing Posit Package Manager", { + desc_path <- system.file("examples/DESCRIPTION_posit_package_manager", + package = "cffr" + ) + + parsed <- cff_create(desc_path, + gh_keywords = FALSE, + keys = list(references = NULL) + ) + + expect_length(parsed$repository, 1) + expect_identical( + parsed$repository, + "https://CRAN.R-project.org/package=resmush" + ) + expect_s3_class(parsed, "cff") + expect_snapshot(parsed) + expect_true(cff_validate(parsed, verbose = FALSE)) +}) + test_that("Search package on CRAN", { basic_path <- system.file("examples/DESCRIPTION_basic", package = "cffr" diff --git a/tests/testthat/test-cff_parse_person.R b/tests/testthat/test-cff_parse_person.R index 952809f5..2e169564 100644 --- a/tests/testthat/test-cff_parse_person.R +++ b/tests/testthat/test-cff_parse_person.R @@ -1,3 +1,8 @@ +test_that("NULL gives NULL", { + expect_null(cff_parse_person(NULL)) + expect_null(cff_parse_person(NA)) +}) + test_that("Parse one person", { p <- person("one", "person") expect_snapshot(cff_parse_person(p)) diff --git a/tests/testthat/test-cff_read.R b/tests/testthat/test-cff_read.R index 2fd047d1..0c437b26 100644 --- a/tests/testthat/test-cff_read.R +++ b/tests/testthat/test-cff_read.R @@ -58,13 +58,13 @@ test_that("Other convertes", { a <- cff(a) expect_s3_class(a, "cff") a <- as.cff(a) - expect_true(is.cff(a)) + expect_true(is_cff(a)) expect_s3_class(a, "cff") expect_message(noadd <- cff(address = "New York", version = 5)) - expect_true(is.cff(noadd)) - expect_false(is.cff(list(a = 1, b = 2))) - expect_true(is.cff(as.cff(list(a = 1, b = 2)))) + expect_true(is_cff(noadd)) + expect_false(is_cff(list(a = 1, b = 2))) + expect_true(is_cff(as.cff(list(a = 1, b = 2)))) }) @@ -107,7 +107,7 @@ test_that("Fuzzy matching of keys on cff", { ) ) - expect_true(is.cff(cffobj)) + expect_true(is_cff(cffobj)) expect_true(cff_validate(cffobj, verbose = FALSE)) expect_snapshot(print_snapshot("Fuzzy keys", cffobj)) diff --git a/tests/testthat/test-cff_to_bibtex.R b/tests/testthat/test-cff_to_bibentry.R similarity index 88% rename from tests/testthat/test-cff_to_bibtex.R rename to tests/testthat/test-cff_to_bibentry.R index 04e804f6..d5438428 100644 --- a/tests/testthat/test-cff_to_bibtex.R +++ b/tests/testthat/test-cff_to_bibentry.R @@ -14,7 +14,7 @@ test_that("Article to bibtex", { ) expect_snapshot(toBibtex(bib)) x <- cff_parse_citation(bib) - bib <- cff_to_bibtex(x) + bib <- cff_to_bibentry(x) expect_snapshot(toBibtex(bib)) }) @@ -42,7 +42,7 @@ test_that("Book to bibtex", { expect_snapshot(toBibtex(bib)) bibparsed <- cff_parse_citation(bib) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -63,7 +63,7 @@ test_that("Booklet to bibtex", { expect_snapshot(toBibtex(bib)) bibparsed <- cff_parse_citation(bib) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -91,7 +91,7 @@ test_that("InBook to bibtex with pages", { expect_snapshot(toBibtex(bib)) bibparsed <- cff_parse_citation(bib) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -110,7 +110,7 @@ test_that("InCollection to bibtex", { expect_snapshot(toBibtex(bib)) bibparsed <- cff_parse_citation(bib) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -135,7 +135,7 @@ test_that("InProceedings to bibtex", { expect_snapshot(toBibtex(bib)) bibparsed <- cff_parse_citation(bib) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -153,7 +153,7 @@ test_that("Manual to bibtex", { expect_snapshot(toBibtex(bib)) bibparsed <- cff_parse_citation(bib) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -172,7 +172,7 @@ test_that("MastersThesis to bibtex", { expect_snapshot(toBibtex(bib)) bibparsed <- cff_parse_citation(bib) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -189,7 +189,7 @@ test_that("PhdThesis to bibtex", { expect_snapshot(toBibtex(bib)) bibparsed <- cff_parse_citation(bib) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -208,7 +208,7 @@ test_that("Proceedings to bibtex", { expect_snapshot(toBibtex(bib)) bibparsed <- cff_parse_citation(bib) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -224,7 +224,7 @@ test_that("TechReport to bibtex", { expect_snapshot(toBibtex(bib)) bibparsed <- cff_parse_citation(bib) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -239,7 +239,7 @@ test_that("Unpublished to bibtex", { expect_snapshot(toBibtex(bib)) bibparsed <- cff_parse_citation(bib) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -264,7 +264,7 @@ test_that("particle names", { expect_snapshot(bibparsed) - bib <- cff_to_bibtex(bibparsed) + bib <- cff_to_bibentry(bibparsed) expect_snapshot(toBibtex(bib)) }) @@ -281,12 +281,12 @@ test_that("From plain cff with a citation", { s$`preferred-citation` <- cff_parse_citation(acit) s$`preferred-citation`$editors <- list(cff_parse_person("A name")) - bib <- cff_to_bibtex(s) + bib <- cff_to_bibentry(s) expect_snapshot(toBibtex(bib)) }) test_that("From plain cff", { - expect_message(bib <- cff_to_bibtex(cff())) + expect_message(bib <- cff_to_bibentry(cff())) expect_snapshot(toBibtex(bib)) }) @@ -295,13 +295,13 @@ test_that("From file", { package = "cffr" ) - bib <- cff_to_bibtex(file) + bib <- cff_to_bibentry(file) expect_snapshot(toBibtex(bib)) }) test_that("NULL", { s <- NULL - expect_null(cff_to_bibtex(s)) + expect_null(cff_to_bibentry(s)) }) @@ -311,7 +311,7 @@ test_that("Test anonymous", { ) - expect_message(back <- cff_to_bibtex(cff_parse_citation(bib))) + expect_message(back <- cff_to_bibentry(cff_parse_citation(bib))) expect_snapshot(toBibtex(back)) @@ -320,7 +320,7 @@ test_that("Test anonymous", { ) - expect_message(back <- cff_to_bibtex(cff_parse_citation(bib))) + expect_message(back <- cff_to_bibentry(cff_parse_citation(bib))) expect_snapshot(toBibtex(back)) bib <- bibentry("misc", @@ -328,7 +328,7 @@ test_that("Test anonymous", { ) - expect_message(back <- cff_to_bibtex(cff_parse_citation(bib))) + expect_message(back <- cff_to_bibentry(cff_parse_citation(bib))) expect_snapshot(toBibtex(back)) bib <- bibentry("proceedings", @@ -337,7 +337,7 @@ test_that("Test anonymous", { ) - expect_silent(back <- cff_to_bibtex(cff_parse_citation(bib))) + expect_silent(back <- cff_to_bibentry(cff_parse_citation(bib))) expect_snapshot(toBibtex(back)) }) @@ -356,7 +356,7 @@ test_that("Fallback month", { # Delete here the month x$month <- NULL - bibback <- cff_to_bibtex(x) + bibback <- cff_to_bibentry(x) expect_snapshot(toBibtex(bibback)) }) @@ -390,7 +390,7 @@ test_that("Test BibLateX entry", { x <- cff_parse_citation(bib) - parsed <- cff_to_bibtex(x) + parsed <- cff_to_bibentry(x) expect_snapshot(toBibtex(parsed)) }) @@ -398,7 +398,7 @@ test_that("Test BibLateX entry", { test_that("Test Fallback year", { x <- cff() - expect_message(msg <- cff_to_bibtex(x)) + expect_message(msg <- cff_to_bibentry(x)) expect_snapshot(toBibtex(msg)) @@ -407,32 +407,32 @@ test_that("Test Fallback year", { expect_true(cff_validate(x, verbose = FALSE)) - parsed <- cff_to_bibtex(x) + parsed <- cff_to_bibentry(x) expect_snapshot(toBibtex(parsed)) }) test_that("Errors", { - expect_silent(b <- cff_to_bibtex("testthat")) + expect_silent(b <- cff_to_bibentry("testthat")) expect_s3_class(b, "bibentry") - expect_error(cff_to_bibtex("testthat", what = "aa")) + expect_error(cff_to_bibentry("testthat", what = "aa")) }) test_that("From package", { skip_if_not_installed("rmarkdown") - base <- cff_to_bibtex("rmarkdown") + base <- cff_to_bibentry("rmarkdown") expect_s3_class(base, "bibentry") expect_length(base, 1) - refs <- cff_to_bibtex("rmarkdown", "references") + refs <- cff_to_bibentry("rmarkdown", "references") expect_s3_class(refs, "bibentry") expect_gte(length(refs), 1) - all <- cff_to_bibtex("rmarkdown", "all") + all <- cff_to_bibentry("rmarkdown", "all") expect_s3_class(all, "bibentry") expect_length(all, length(base) + length(refs)) @@ -441,10 +441,10 @@ test_that("From package", { test_that("NULL references", { basic <- cff() - expect_null(cff_to_bibtex(basic, "references")) + expect_null(cff_to_bibentry(basic, "references")) # Test all - expect_message(l <- cff_to_bibtex(basic, "all")) + expect_message(l <- cff_to_bibentry(basic, "all")) expect_length(l, 1) }) @@ -452,7 +452,7 @@ test_that("NULL references", { test_that("From CITATION.cff", { p <- system.file("examples/smith-et-al.cff", package = "cffr") - base <- cff_to_bibtex(p) + base <- cff_to_bibentry(p) expect_s3_class(base, "bibentry") diff --git a/tests/testthat/test-deprecated.R b/tests/testthat/test-deprecated.R new file mode 100644 index 00000000..7097e013 --- /dev/null +++ b/tests/testthat/test-deprecated.R @@ -0,0 +1,8 @@ +test_that("cff_extract_to_bibtex", { + a_cff <- cff_create("cffr") + + current <- cff_to_bibentry(a_cff) + expect_snapshot(old1 <- cff_extract_to_bibtex(a_cff)) + + expect_identical(current, old1) +}) diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index 800df3c4..a77bfd96 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -24,3 +24,20 @@ test_that("Try cleaning string", { expect_null(clean_str(logical(0))) expect_null(clean_str(list())) }) + +test_that("Use right repo", { + # Use some other repos + repos <- c("https://ropensci.r-universe.dev", "https://cloud.r-project.org") + + final <- detect_repos(repos) + expect_identical(final, c(CRAN = "https://cloud.r-project.org/")) + + # With posit package manager + repos <- c( + CRAN = "https://packagemanager.posit.co/cran/latest", + RPSM = "https://packagemanager.rstudio.com/", + ANOTHER = "https://packagemanager.rspm.com/" + ) + final <- detect_repos(repos) + expect_identical(final, c(CRAN = "https://cloud.r-project.org/")) +}) diff --git a/tests/testthat/test_ci/.gitignore b/tests/testthat/test_ci/.gitignore index a7cc310b..84cb1ec8 100644 --- a/tests/testthat/test_ci/.gitignore +++ b/tests/testthat/test_ci/.gitignore @@ -1,3 +1,4 @@ _snaps CITATION allpackages.csv +results.* diff --git a/tests/testthat/test_ci/README.md b/tests/testthat/test_ci/README.md index 0500a79b..983fc683 100644 --- a/tests/testthat/test_ci/README.md +++ b/tests/testthat/test_ci/README.md @@ -13,21 +13,15 @@ This test validates the `cff` parsing for \>1500 packages: This test is deployed in [GitHub Actions](https://github.com/ropensci/cffr/actions/workflows/test-ci.yaml) and -the results are uploaded as an artifact. We use here Windows and MacOS binaries -for speeding up the process. +the results are uploaded as an report on the action itself. We use here Windows +and MacOS. -As the installations differs across users and machines, the snapshot testing is -expected to fail on a normal run. However, the snapshots are quite useful for -extensive tests and debugging, as well as for capturing corner cases. For that -reason, these tests are no run in **CRAN** or in the regular package development -workflow. - -However, the test can be run locally with +The test can be run locally with ``` r # Load package devtools::load_all() -# Run the tests -testthat::test_dir("tests/testthat/test_ci") +# Run the report +source("tests/testthat/test_ci/test-new.R") ``` diff --git a/tests/testthat/test_ci/test-full_cff.R b/tests/testthat/test_ci/test-full_cff.R index f86a598f..453fe002 100644 --- a/tests/testthat/test_ci/test-full_cff.R +++ b/tests/testthat/test_ci/test-full_cff.R @@ -1,89 +1,97 @@ -test_that("Test ALL installed packages", { - expect_snapshot_output(print_snapshot("Sessioninfo", sessionInfo())) - - installed <- as.data.frame(installed.packages()[, c("Package", "Version")]) - installed <- installed[order(installed$Package), ] - - rownames(installed) <- seq_len(nrow(installed)) - - l <- nrow(installed) - - # Initial set of packages - write.csv(installed, "allpackages.csv", row.names = FALSE) - expect_snapshot_output(print_snapshot("Summary", paste( - "testing a sample of", - nrow(installed), "installed packages" - ))) - message("Sample of ", nrow(installed)) - - res <- c() - withcit <- c() - - for (i in seq_len(nrow(installed))) { - pkg <- installed[i, ]$Package - # Display some advances - message( - "Testing ", i, "/", nrow(installed), - " (", sprintf("%05.02f", i / nrow(installed) * 100), "%)" - ) - cit_path <- file.path(find.package(installed[i, ]$Package), "CITATION") - - - if (file.exists(cit_path)) { - withcit <- c(withcit, TRUE) - } else { - withcit <- c(withcit, FALSE) - } - - # Add cffobj - cffobj <- suppressMessages( - cff_create(pkg, gh_keywords = FALSE, dependencies = FALSE) - ) - - s <- suppressMessages(cff_validate(cffobj)) - - - res <- c(res, s) - } - - - expect_snapshot_output({ - installed$with_citation <- withcit - installed$is_ok <- res - - errors <- installed[installed$is_ok == FALSE, ] - - okrate <- 1 - nrow(errors) / nrow(installed) - - expect_snapshot_output(print_snapshot( - "OK rate", - sprintf("%1.2f%%", 100 * okrate) - )) - - - if (nrow(errors) > 0) { - print_snapshot( - "Errors", - errors - ) - - print_snapshot( - "Error reports for ", - paste(errors$Package, collapse = ", ") - ) - - for (j in seq_len(nrow(errors))) { - pkg <- errors[j, ]$Package - cff <- cff_create(pkg, gh_keywords = FALSE, dependencies = FALSE) - - print_snapshot(paste0(pkg, ": cffr object"), cff) - - print_snapshot("Validation results", cff_validate(cff)) - } - } else { - print_snapshot(obj = "No errors, hooray!") - } - }) - - write.csv(installed, "allpackages.csv", row.names = FALSE) -}) +# ---------------------------------------------------------------- +# DEPRECATED: SEE ./tests/testthat/test_ci/test-new.R file instead +# ---------------------------------------------------------------- + + +# test_that("Test ALL installed packages", { +# expect_snapshot_output(print_snapshot("Sessioninfo", sessionInfo())) +# +# installed <- as.data.frame(installed.packages()[, c("Package", "Version")]) +# installed <- installed[order(installed$Package), ] +# +# end <- match("ctv", installed$Package) + 10 +# installed <- installed[seq_len(end), ] +# +# rownames(installed) <- seq_len(nrow(installed)) +# +# l <- nrow(installed) +# +# # Initial set of packages +# write.csv(installed, "allpackages.csv", row.names = FALSE) +# expect_snapshot_output(print_snapshot("Summary", paste( +# "testing a sample of", +# nrow(installed), "installed packages" +# ))) +# message("Sample of ", nrow(installed)) +# +# res <- c() +# withcit <- c() +# +# for (i in seq_len(nrow(installed))) { +# pkg <- installed[i, ]$Package +# # Display some advances +# message( +# "Testing ", i, "/", nrow(installed), +# " (", sprintf("%05.02f", i / nrow(installed) * 100), "%)" +# ) +# cit_path <- file.path(find.package(installed[i, ]$Package), "CITATION") +# +# +# if (file.exists(cit_path)) { +# withcit <- c(withcit, TRUE) +# } else { +# withcit <- c(withcit, FALSE) +# } +# +# # Add cffobj +# cffobj <- suppressMessages( +# cff_create(pkg, gh_keywords = FALSE, dependencies = FALSE) +# ) +# +# s <- suppressMessages(cff_validate(cffobj)) +# +# +# res <- c(res, s) +# } +# +# +# expect_snapshot_output({ +# installed$with_citation <- withcit +# installed$is_ok <- res +# +# errors <- installed[installed$is_ok == FALSE, ] +# +# okrate <- 1 - nrow(errors) / nrow(installed) +# +# expect_snapshot_output(print_snapshot( +# "OK rate", +# sprintf("%1.2f%%", 100 * okrate) +# )) +# +# +# if (nrow(errors) > 0) { +# print_snapshot( +# "Errors", +# errors +# ) +# +# print_snapshot( +# "Error reports for ", +# paste(errors$Package, collapse = ", ") +# ) +# +# for (j in seq_len(nrow(errors))) { +# pkg <- errors[j, ]$Package +# cff <- cff_create(pkg, gh_keywords = FALSE, dependencies = FALSE) +# +# print_snapshot(paste0(pkg, ": cffr object"), cff) +# +# print_snapshot("Validation results", cff_validate(cff)) +# } +# } else { +# print_snapshot(obj = "No errors, hooray!") +# } +# }) +# +# write.csv(installed, "allpackages.csv", row.names = FALSE) +# }) diff --git a/tests/testthat/test_ci/test-new.R b/tests/testthat/test_ci/test-new.R new file mode 100644 index 00000000..5ea2c93e --- /dev/null +++ b/tests/testthat/test_ci/test-new.R @@ -0,0 +1,149 @@ +library(cffr) +installed <- as.data.frame(installed.packages()[, c("Package", "Version")]) +installed <- installed[order(installed$Package), ] + + +rownames(installed) <- seq_len(nrow(installed)) + +l <- nrow(installed) + +dir_path <- "./tests/testthat/test_ci/" + +message("Testing a sample of ", nrow(installed), " packages") + +res <- c() +withcit <- c() +note <- c() +for (i in seq_len(nrow(installed))) { + pkg <- installed[i, ]$Package + # Display some advances + message( + "Testing ", i, "/", nrow(installed), + " (", sprintf("%05.02f", i / nrow(installed) * 100), "%) [", + installed[i, ]$Package, "]" + ) + cit_path <- file.path(find.package(installed[i, ]$Package), "CITATION") + + + if (file.exists(cit_path)) { + withcit <- c(withcit, TRUE) + } else { + withcit <- c(withcit, FALSE) + } + + # Add cffobj + cffobj <- try( + cff_create(pkg, gh_keywords = FALSE, dependencies = FALSE), + silent = TRUE + ) + + if (inherits(cffobj, "cff")) { + s <- try(cff_validate(cffobj, verbose = FALSE), silent = TRUE) + if (!is.logical(s)) s <- FALSE + + res <- c(res, s) + note <- c(note, "") + } else { + res <- c(res, FALSE) + note <- c(note, "Other errors") + } +} + +installed$with_citation <- withcit +installed$is_ok <- res +installed$note <- note + +# Create report + +options(cli.width = 60) +outmd <- file.path(dir_path, "results.md") +unlink(outmd) + +cat("# Test all files\n\n", file = outmd) +write("## Session info\n", outmd, append = TRUE) +write("

", outmd, append = TRUE) +write("\n```r", outmd, append = TRUE) +conn <- file(outmd, "a") +capture.output(sessioninfo::session_info(), file = conn) +close(conn) +write("```\n", outmd, append = TRUE) +write("
", outmd, append = TRUE) + +errors <- installed[installed$is_ok == FALSE, ] +errother <- errors$Package[errors$note == "Other errors"] +errcff <- setdiff(errors$Package, errother) +errother_df <- installed[installed$Package %in% errother, c(1, 2)] + + + +write("\n## High level summary", outmd, append = TRUE) +write(paste0("\n- I checked ", nrow(installed), " packages"), + outmd, + append = TRUE +) +write(paste0("- Invalid cff in ", length(errcff), " packages"), + outmd, + append = TRUE +) +write(paste0("- I failed to generate cff in ", length(errother), " packages"), + outmd, + append = TRUE +) + +okrate <- 100 * (1 - length(errcff) / (nrow(installed) - length(errother))) +write(paste0("- OK Rate: ", round(okrate, 2), "%"), outmd, append = TRUE) + + +if (nrow(errors) == 0) { + write("\nNo errors, hooray!", outmd, append = TRUE) +} else { + write("\nPackages with errors:", outmd, append = TRUE) + conn <- file(outmd, "a") + capture.output(knitr::kable(errors, row.names = FALSE), + file = conn + ) + close(conn) + + + if (length(errother) > 0) { + pk <- paste0(errother, collapse = ", ") + line <- paste0("\n## Packages with errors not coming from cff") + write(line, outmd, append = TRUE) + conn <- file(outmd, "a") + capture.output(knitr::kable(errother_df, row.names = FALSE), + file = conn + ) + close(conn) + } + + if (length(errcff) > 0) { + write("\n## cff errors reported", outmd, append = TRUE) + # Prepare links + cfflist <- paste0("- [", errcff, "](#", tolower(errcff), ")", + collapse = "\n" + ) + write(cfflist, outmd, append = TRUE) + + for (j in errcff) { + write(paste0("\n### ", j, ""), outmd, append = TRUE) + write("\n#### cff object\n", outmd, append = TRUE) + write("
", outmd, append = TRUE) + write("\n```r", outmd, append = TRUE) + cff <- cff_create(j, gh_keywords = FALSE, dependencies = FALSE) + conn <- file(outmd, "a") + capture.output(print(cff), file = conn) + close(conn) + write("```\n", outmd, append = TRUE) + write("
", outmd, append = TRUE) + + + write("\n#### Validation results", outmd, append = TRUE) + + s <- cff_validate(cff, verbose = FALSE) + df <- attr(s, "errors") + conn <- file(outmd, "a") + capture.output(knitr::kable(df, row.names = FALSE), file = conn) + close(conn) + } + } +} diff --git a/vignettes/REFERENCES.bib b/vignettes/REFERENCES.bib index 6bbbf02a..78eb0a53 100644 --- a/vignettes/REFERENCES.bib +++ b/vignettes/REFERENCES.bib @@ -8,6 +8,16 @@ @misc{biblatexcheatsheet note = {Version Number: 2017-06-24}, date = {2017-06-24} } +@misc{biblatexpack, + title = {The {biblatex} package}, + author = {Philip Kime and Moritz Wemheuer and Philipp Lehman}, + year = 2023, + month = {mar}, + url = {https://osl.ugr.es/CTAN/macros/latex/contrib/biblatex/doc/biblatex.pdf}, + urldate = {2024-02-07}, + note = {Version Number: 3.19}, + date = {2023-03-05} +} @manual{codemetar2021, title = {{codemetar}: Generate '{CodeMeta}' Metadata for {R} Packages}, author = {Carl Boettiger and Maëlle Salmon}, @@ -212,3 +222,14 @@ @manual{codemeta url = {https://CRAN.R-project.org/package=codemeta}, note = {R package version 0.1.1} } +@misc{druskat2019, + title = {{Citation File Format (CFF)} - Specifications}, + author = {Druskat, Stephan and Spaaks, Jurriaan H. and Chue Hong, Neil and Haines, Robert and Baker, James}, + year = 2019, + month = 11, + doi = {10.5281/ZENODO.3515946}, + url = {https://zenodo.org/record/3515946}, + note = {Version 1.0.3-4}, + date = {2019-11-04}, + langid = {en} +} diff --git a/vignettes/bibtex_cff.Rmd b/vignettes/bibtex_cff.Rmd index 05e76077..c86fdeb6 100644 --- a/vignettes/bibtex_cff.Rmd +++ b/vignettes/bibtex_cff.Rmd @@ -2,23 +2,25 @@ title: "BibTeX and CFF" subtitle: A potential crosswalk bibliography: REFERENCES.bib -author:
Diego Hernangómez ORCID logo +author: Diego Hernangómez description: >- This article presents a crosswalk between BibTeX and Citation File Format [@druskat_citation_2021], as it is performed by the cffr package [@hernangomez2021]. abstract: >- - This article presents a crosswalk between BibTeX and Citation File Format - [@druskat_citation_2021], as it is performed by the cffr package - [@hernangomez2021]. Several crosswalk models specific for each BibTeX entry - type [@patashnik1988] are proposed. The article also provide examples using real - BibTeX entries and tips for developers that would like to implement the crosswalk - on different programming languages. + This article introduces a crosswalk between **BibTeX** and the Citation File + Format (CFF) [@druskat_citation_2021], as implemented by the **cffr** package + [@hernangomez2021]. The crosswalk aims to facilitate seamless translation + between these two reference formats. Specifically, it proposes various + crosswalk models tailored to different **BibTeX** entry types + [@patashnik1988]. Additionally, the article includes practical examples using + real **BibTeX** entries and offers tips for developers interested in + implementing this crosswalk across various programming languages. link-citations: yes documentclass: article editor_options: markdown: - wrap: 120 + wrap: 80 output: rmarkdown::html_vignette: toc: true @@ -34,9 +36,18 @@ knitr::opts_chunk$set( comment = "" ) -options(width = 60) +# Load the table of tables + +p2file <- system.file("extdata/crosswalk_tables.csv", package = "cffr") + +table_master <- read.csv(p2file) ``` +## Disclaimer + +*This article was reviewed and updated in 2024, along with the release of +**cffr** v0.6.0.* + ## Citation Please cite this article as: @@ -49,12 +60,14 @@ thisart <- bibentry("article", journal = "The {cffr} package", year = 2022, volume = "Vignettes", + doi = "10.21105/joss.03900", + url = "https://docs.ropensci.org/cffr/articles/bibtex_cff.html" ) cat(" \n") thisart ``` -A BibTeX entry for LaTeX users: +A **BibTeX** entry for LaTeX users: ``` bibtex @article{hernangomez2022, @@ -62,17 +75,21 @@ A BibTeX entry for LaTeX users: author = {Diego Hernangómez}, year = 2022, journal = {The {cffr} package}, - volume = {Vignettes} + volume = {Vignettes}, + doi = {10.21105/joss.03900}, + url = {https://docs.ropensci.org/cffr/articles/bibtex_cff.html} } ``` ## BibTeX and R -[BibTeX](https://en.wikipedia.org/wiki/BibTeX) is a well-known format for storing references created by [Oren -Patashnik](https://en.wikipedia.org/wiki/Oren_Patashnik "Oren Patashnik") and [Leslie -Lamport](https://en.wikipedia.org/wiki/Leslie_Lamport "Leslie Lamport") back in 1985. BibTeX that may be reused by -another software, like [LaTeX](https://en.wikipedia.org/wiki/LaTeX), for adding references to a work. An example -structure of a BibTeX entry would be: +[**BibTeX**](https://en.wikipedia.org/wiki/BibTeX) is a well-known format for +storing references created by [Oren +Patashnik](https://en.wikipedia.org/wiki/Oren_Patashnik "Oren Patashnik") and +[Leslie Lamport](https://en.wikipedia.org/wiki/Leslie_Lamport "Leslie Lamport") +back in 1985. **BibTeX** can be reused by other software, such as +[LaTeX](https://en.wikipedia.org/wiki/LaTeX), to add references to scholarly +works. An example structure of a **BibTeX** entry would be: ``` bibtex @book{einstein1921, @@ -85,10 +102,10 @@ structure of a BibTeX entry would be: } ``` -On this case, the entry (identified as `einstein1921`) would refer to a book. This entry then can be used on a document -and include references to it. - -On **R** [@R_2021], we can replicate this structure using the `bibentry()` and `toBibtex()` functions: +In this case, the entry (identified as `einstein1921`) refers to a book. This +entry can then be used in a document to include references to it. In **R** +[@R_2021], we can replicate this structure using the `bibentry()` and +`toBibtex()` functions: ```{r bibentry, comment="#>"} entry <- bibentry("book", @@ -106,14 +123,16 @@ toBibtex(entry) The final results of the entry as a text string would be parsed as[^1]: -[^1]: By default R Pandoc would generate the cite on the Chicago author-date format [@rmarkdowncookbook2020] +[^1]: By default **R** Pandoc would generate the cite on the Chicago author-date + format [@rmarkdowncookbook2020] ```{r echo=FALSE, results='asis'} entry ``` -Additionally, **cffr** [@hernangomez2021] incorporates a function `cff_from_bibtex()` than can be used to read and -transform BibTeX strings into different formats: +Additionally, the **cffr** package [@hernangomez2021] incorporates a function +`cff_from_bibtex()` that can be used to read and transform **BibTeX** strings +into different formats: ```{r cffbibread,comment="#>"} string <- "@book{einstein1921, @@ -131,362 +150,398 @@ cff_format <- cff_from_bibtex(string) cff_format # To citation R format and bibtex -citation_format <- cff_to_bibtex(cff_format) +citation_format <- cff_to_bibentry(cff_format) class(citation_format) citation_format toBibtex(citation_format) ``` -## BibTeX definitions +## BibTeX Definitions -@patashnik1988 provides a comprehensive explanation of the BibTeX formats. We can distinguish between **Entries** and -**Fields**. +@patashnik1988 provides a comprehensive explanation of the **BibTeX** formats. +Let's distinguish between **Entries** and **Fields**. ### Entries {#entries} -Each entry type defines a different type of work. The 14 entry types defined on BibTeX[^2] are: - -[^2]: Other implementations similar to BibTeX, as [BibLaTeX](https://www.ctan.org/pkg/biblatex), expand the definitions - of entries including other types as **online**, **software** or **dataset**. On BibTeX these entries should be - reclassified to **misc**. - -- **\@article**: An article from a journal or magazine. -- **\@book**: A book with an explicit publisher. -- **\@booklet**: A work that is printed and bound, but without a named publisher or sponsoring institution. -- **\@conference**: The same as **\@inproceedings**, included for Scribe compatibility. -- **\@inbook**: A part of a book, which may be a chapter (or section or whatever) and/or a range of pages. -- **\@incollection**: A part of a book having its own title. -- **\@inproceedings**: An article in a conference proceedings. -- **\@manual**: Technical documentation. -- **\@mastersthesis**: A Master's thesis. -- **\@misc**: Use this type when nothing else fits. -- **\@phdthesis**: A PhD thesis. -- **\@proceedings**: The proceedings of a conference. -- **\@techreport**: A report published by a school or other institution, usually numbered within a series. -- **\@unpublished**: A document having an author and title, but not formally published. - -Regarding the entries, `bibentry()` **R** function does not implement **\@conference** . However, we can replace that -key by **\@inproceedings** given that the definition is identical. - -### Fields - -As in the case of Entries, @patashnik1988 provides also a definition for each of the possible standard BibTeX -fields[^3]. An entry can include other fields that would be ignored on the raw implementation of BibTeX: - -[^3]: As in the case of the entries, other implementations based on BibTeX may recognize additional fields. - -- **address**: Usually the address of the **publisher** or other of **institution**. -- **annote**: An annotation. It is not used by the standard bibliography styles, but may be used by others that - produce an annotated bibliography. -- **author**: The name(s) of the author(s), in the format described in the LaTeX book [@lamport86latex]. -- **booktitle**: Title of a book, part of which is being cited. For **\@book** entries, use the **title** field - instead. -- **chapter**: A chapter (or section or whatever) number. -- **crossref**: The database key of the entry being cross referenced. -- **edition**: The edition of a **\@book**, for example, "Second". This should be an ordinal, and should have the - first letter capitalized, the standard styles convert to lower case when necessary. -- **editor**: Name(s) of editor(s), typed as indicated in the LaTeX book [@lamport86latex]. If there is also an - **author** field, then the editor field gives the editor of the book or collection in which the reference appears. -- **howpublished**: How something strange has been published. The first word should be capitalized. -- **institution**: The sponsoring institution of a technical report. -- **journal**: A journal name. -- **key**: Used for alphabetizing, cross referencing, and creating a label when the **author** information is missing. -- **month**: The month in which the work was published or, for an unpublished work, in which it was written. You - should use the standard three-letter abbreviation, as described in Appendix B.1.3 of the LaTeX book - [@lamport86latex] (i.e. `jan, feb, mar`). -- **note**: Any additional information that can help the reader. The first word should be capitalized. -- **number**: The number of a journal, magazine, technical report, or of a work in a series. An issue of a journal or - magazine is usually identified by its **volume**: and number; the organization that issues a technical report - usually gives it a number; and sometimes books are given numbers in a named series. -- **organization**: The organization that sponsors a **\@conference** or that publishes a manual. -- **pages**: One or more page numbers or range of numbers, such as `42--111` or `7,41,73--97` or `43+`. -- **publisher**: The publisher's name. -- **school**: The name of the school where a thesis was written. -- **series**: The name of a series or set of books. When citing an entire book, the **title** field gives its title - and an optional **series** field gives the name of a series or multi-volume set in which the book is published. -- **title**: The work's title. -- **type**: The type of a technical report, for example, "Research Note". -- **volume**: The volume of a journal or multivolume book. -- **year**: The year of publication or, for an unpublished work, the year it was written. Generally it should consist - of four numerals, such as `1984`. - -There is a strict relation between Entries and Fields on BibTeX. Depending on the type of entries, some fields are -required while others are optional or even ignored. On the following table, required field are flagged as **x** and -optional fields are flagged as **o**. Fields on parenthesis (**(x), (o)**) denotes that there are some degree of -flexibility on the requirement of the field, see @patashnik1988 for more information. +Each entry type defines a different type of work. The 14 entry types defined in +**BibTeX** are: + +1. **\@article**: An article from a journal or magazine. +2. **\@book**: A book with an explicit publisher. +3. **\@booklet**: A work that is printed and bound, but without a named + publisher or sponsoring institution. +4. **\@conference**: Equivalent to **\@inproceedings**, included for + [Scribe](https://en.wikipedia.org/wiki/Scribe_(markup_language)) + compatibility. +5. **\@inbook**: A part of a book, which may be a chapter (or section) and/or a + range of pages. +6. **\@incollection**: A part of a book having its own title. +7. **\@inproceedings**: An article in conference proceedings. +8. **\@manual**: Technical documentation. +9. **\@mastersthesis**: A Master's thesis. +10. **\@misc**: Use this type when nothing else fits. +11. **\@phdthesis**: A PhD thesis. +12. **\@proceedings**: The proceedings of a conference. +13. **\@techreport**: A report published by a school or other institution, + usually numbered within a series. +14. **\@unpublished**: A document having an author and title, but not formally + published. + +Other implementations similar to **BibTeX**, such as **BibLaTeX** +[@biblatexpack], expand the definitions of entries to include other types such +as online resources, software, or datasets. In **BibTeX**, these entries should +be reclassified as **\@misc**. + +In **R**, the `bibentry()` base function does not implement **\@conference**. +However, we can use **\@inproceedings**, instead given that the definition is +identical. + +### Fields {#fields} + +Similar to the **Entries**, @patashnik1988 also provides definitions for each of +the possible standard **BibTeX fields**. While an entry must include certain +required fields, it can also include additional fields that might be ignored in +the raw implementation of **BibTeX**. Let's explore some of these fields: + +1. **address**: Typically represents the address of the **publisher** or + another **institution**. In the case of **\@conference**, + **\@inproceedings** and **\@proceedings** this field indicates where the + conference was held. +2. **annote**: An annotation. Although not used by standard bibliography + styles, it may be relevant for producing annotated bibliographies. +3. **author**: Contains the name(s) of the author(s), following the format + described in the LaTeX book [@lamport86latex]. +4. **booktitle**: Refers to the title of a book, part of which is being cited. + For **\@book** entries, use the **title** field instead. +5. **chapter**: Indicates a chapter (or section) number. +6. **crossref**: Refers to the database key of the entry being + cross-referenced. +7. **edition**: Specifies the edition of a **\@book**, e.g., `"Second"`. The + ordinal should have the first letter capitalized; standard styles convert to + lowercase when necessary. +8. **editor**: Contains the name(s) of editor(s), following the conventions in + the LaTeX book [@lamport86latex]. If there is also an **author** field, the + **editor** field specifies the editor of the book or collection where the + reference appears. +9. **howpublished**: Describes how something unusual has been published. The + first word should be capitalized. +10. **institution**: Represents the sponsoring institution of a technical + report. +11. **journal**: Refers to the name of a journal. +12. **key**: Used for alphabetizing, cross-referencing, and creating a label + when **author** information is missing. +13. **month**: Indicates the month in which the work was published or, for an + unpublished work, when it was written. Use the standard three-letter + abbreviation (e.g., `jan`, `feb`, `mar`) as described in **Appendix B.1.3** + of the LaTeX book [@lamport86latex]. +14. **note**: Provides any additional information that can assist the reader. + The first word should be capitalized. +15. **number**: Represents the number of a journal, magazine, technical report, + or a work in a series. An issue of a journal or magazine is usually + identified by its **volume** and number. Organizations issuing technical + reports often assign them numbers, and sometimes books are given numbers + within a named series. +16. **organization**: Refers to the organization that sponsors a + **\@conference** or publishes a manual. +17. **pages**: Specifies one or more page numbers or a range of numbers (e.g., + `42--111` or `7,41,73--97` or `43+`). +18. **publisher**: Indicates the publisher's name. +19. **school**: Provides the name of the school where a thesis was written. +20. **series**: Specifies the name of a series or set of books. When citing an + entire book, the **title** field gives its title, and an optional **series** + field provides the name of a series or multi-volume set in which the book is + published. +21. **title**: Represents the work's title. +22. **type**: Describes the type of a technical report (e.g., "Research Note"). +23. **volume**: Refers to the volume of a journal or multi-volume book. +24. **year**: Indicates the year of publication or, for an unpublished work, the + year it was written. Generally, it should consist of four numerals (e.g., + `1984`). + +As in the case of the **Entries**, other implementations such as **BibLaTeX** +recognize additional fields. + +In **BibTeX**, there exists a strict relationship between **Entries** and +**Fields**. Depending on the type of entry, certain fields are required, while +others are optional or even ignored. + +The following table summarizes the relationship between **Entries** and +**Fields** in **BibTeX**. Required fields are flagged as **x**, and optional +fields are flagged as **o**. For more detailed information, refer to +@patashnik1988. ```{r entry_fields1, echo=FALSE} -bibtex_field_entry <- read.csv( - system.file("extdata/bibtex_field_entry.csv", - package = "cffr" - ), - sep = "," +df_table <- table_master[table_master$table == "entry_fields", -1] + +nms <- c( + "**field**", "**\\@article**", "**\\@book**", "**\\@booklet**", + "**\\@inbook**", "**\\@incollection**", "**\\@conference, \\@inproceedings**", + "**\\@manual**", "**\\@mastersthesis, phdthesis**", "**\\@misc**", + "**\\@proceedings**", "**\\@techreport**", "**\\@unpublished**" ) -t1 <- bibtex_field_entry[, c(1:7)] + +df_table[is.na(df_table)] <- "" +row.names(df_table) <- NULL +t1 <- df_table[, c(1:7)] +nm1 <- nms[1:7] knitr::kable(t1, - col.names = gsub("\\.", ",", names(t1)), - align = c("l", rep("c", 6)), - caption = "BibTeX, required fields by entry" + col.names = nm1, row.names = NA, align = c("l", rep("c", 6)), + caption = "**BibTeX**, required fields by entry" ) ``` ```{r entry_fields2, echo=FALSE} -t2 <- bibtex_field_entry[, c(1, 8:13)] - +t2 <- df_table[, c(1, 8:13)] +nm2 <- nms[c(1, 8:13)] knitr::kable(t2, - col.names = gsub("\\.", ",", names(t2)), - align = c("l", rep("c", 6)), - caption = "(cont) BibTeX, required fields by entry" + col.names = nm2, row.names = NA, align = c("l", rep("c", 6)), + caption = "(cont) **BibTeX**, required fields by entry" ) ``` -It can be observed that just a subset of fields is required in any of the Entries. For example, **title**, **year** and -**author** are either required or optional on almost every entry, while **crossref**, **annote** or **key** are never -required. +It can be seen that only a subset of fields is necessary for any entry. For +instance, **title**, **year**, and **author** are either required or optional in +almost every entry, whereas **crossref**, **annote**, or **key** are never +mandatory. ## Citation File Format -[Citation File Format (CFF](https://citation-file-format.github.io/)) [@druskat_citation_2021] are plain text files with -human- and machine-readable citation information for software (and datasets). Among the [valid keys of -CFF](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#valid-keys) there are two -keys, `preferred-citation` and `references` of special interest for citing and referring to related works[^4]: - -[^4]: See [Guide to Citation File Format schema version - 1.2.0](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#preferred-citation). - -- **`preferred-citation`**: A reference to another work that should be cited instead of the software or dataset - itself. - -- **`references`**: Reference(s) to other creative works. Similar to a list of references in a paper, references of - the software or dataset may include other software (dependencies), or other research products that the software or - dataset builds on, but not work describing the software or dataset. - -These two keys are expected to be -[`definition.reference`](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#definitionsreference) -objects, therefore they may contain the following keys: +[Citation File Format (CFF](https://citation-file-format.github.io/)) +[@druskat_citation_2021] consists of plain text files containing both human- and +machine-readable citation information for software and datasets. Within +[CFF]{.underline}, there are two important keys: `preferred-citation` and +`references`, which play a crucial role in citing and referring to related +works: + +- `preferred-citation`: Refers to another work that should be cited instead of + the software or dataset itself. +- `references`: Includes reference(s) to other creative works related to the + software or dataset. Similar to a list of references in a scholarly paper, + these references may encompass papers describing the abstract concepts of + the software or algorithms implemented in the software version. + +These two keys are expected to be `definition.reference objects`, as defined in +the [Guide to Citation File Format schema version +1.2.0](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#preferred-citation), +and they may contain the following keys: ```{r refkeys, echo=FALSE, message=FALSE, warning=FALSE, results='asis'} library(cffr) # Fill with whites -l <- c(cff_schema_definitions_refs(), rep("", 4)) +init <- paste0("[", cff_schema_definitions_refs(), "]{.underline}") + +l <- c(init, rep("", 4)) refkeys <- matrix(l, ncol = 5, byrow = TRUE) knitr::kable(refkeys, - caption = "Valid keys on CFF `definition-reference` objects" + row.names = NA, + caption = "Valid keys on [CFF]{underline} `definition-reference` objects" +) +``` + +These keys are equivalent to the **BibTeX** [fields](#fields), with the +exception of the key [type]{.underline}. In [CFF]{.underline}, this key defines +the type of work[^2], making it analogous to the **BibTeX** [entries](#0). + +[^2]: See a complete list of possible values of [CFF]{.underline} + [type]{.underline} in [Appendix B](#appendix_cff_type). + +## Proposed Crosswalk + +The **cffr** package [@hernangomez2021] provides utilities for converting +**BibTeX** entries (via the **R** base function `bibentry()`) to +[CFF]{.underline} files and vice versa. This section describes how the +conversion between both formats has been implemented. The crosswalk is partially +based on @Haines_Ruby_CFF_Library_2021[^3]. + +[^3]: Note that this software performs only the conversion from + [CFF]{.underline} to **BibTeX**, however **cffr** can perform the conversion + in both directions. + +In the following two sections, I present an overview of the proposed mapping +between the **Entries** and **Fields** of **BibTeX** and the [CFF]{.underline} +keys. After this initial mapping, I propose further transformations to enhance +compatibility between both systems using different [Entry Models](#entrymodels). + +For better clarity, when a field is in **bold** (e.g., **\@book, edition**), it +corresponds to **BibTeX**, and when the field is [underlined]{.underline} (e.g., +[book, edition]{.underline}), it corresponds to [CFF]{.underline}. + +### Entry/Type Crosswalk + +For converting general **BibTeX** entries to [CFF]{.underline} +[types]{.underline}, the following crosswalk is proposed: + +```{r entry_bib2cff, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "entry_bib2cff", c(2:4)] +df_table[is.na(df_table)] <- "" +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +row.names(df_table) <- NULL + +knitr::kable(df_table, + col.names = c("**BibTeX** Entry", "[**CFF key: type**]{.underline}", "Notes"), + row.names = NA, + caption = "Entry/Type crosswalk: From **BibTeX** to [CFF]{.underline}" +) +``` + +The previous crosswalk has the following specifications: + +- **\@book**, **\@inbook**, and **\@incollection** are closely related in + **BibTeX**[^4]. While **\@inbook** and **\@incollection** both reference + parts of a **\@book**, the former is used for citing sections, chapters, + pages, or other specific parts, whereas the latter is used for citing parts + with a specific title. Since [CFF]{.underline} allows keys `type:book` and + `collection-type: book`, we may utilize a combination of these fields to tag + each entry type in [CFF]{.underline} accordingly. +- **\@mastersthesis** and **\@phdthesis** would be tagged using a combination + of `type:thesis` and `thesis-type`. + +[^4]: Note that **BibLaTeX** [@biblatexpack] handles **\@inbook** differently, + see [Appendix A](#appendix_inbook). + +Additionally, considering that [CFF]{.underline} allows for a wide range of +values[^5] for the [type]{.underline} field, the following conversion would be +applied from [CFF]{.underline} to **BibTeX**: + +[^5]: See [Appendix B](#appendix_cff_type) for all possible values. Information + extracted from @druskat2019. + +```{r entry_cff2bib, echo=FALSE,results='asis'} +df_table <- table_master[table_master$table == "entry_cff2bib", c(2:4)] +df_table[is.na(df_table)] <- "" +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +row.names(df_table) <- NULL + +knitr::kable(df_table, + col.names = c("[**CFF key: type**]{.underline}", "**BibTeX** Entry", "Notes"), + caption = "Entry/Type crosswalk: From [CFF]{.underline} to **BibTeX**" +) +``` + +### Fields/Key Crosswalk + +There is a significant similarity between the definitions and names of certain +**BibTeX** fields and [CFF]{.underline} keys. While the equivalence is +straightforward in some cases, there are instances where certain keys need to be +processed depending on the **entry** type. + +```{r fields_bib2cff, echo=FALSE,results='asis'} +df_table <- table_master[table_master$table == "fields_bib2cff", c(2:4)] +df_table[is.na(df_table)] <- "" +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +row.names(df_table) <- NULL + +knitr::kable(df_table, + col.names = c("**BibTeX Field**", "[CFF key]{.underline}", "Notes"), + caption = "**BibTeX** - [CFF]{.underline} Field/Key crosswalk" +) +``` + +We provide more detail on some of the mappings presented in the table above: + +- Some fields are not mapped because there is no clear equivalence with + [CFF]{.underline} keys (such as **annote**, **crossref**, and **key**). + Regarding the **type** field, the [CFF]{.underline} key [type]{.underline} + corresponds to the identifier of the work (similar to an entry in + **BibTeX**), therefore, **BibTeX type** won't be mapped. These fields are + always optional in **BibTeX**. + +- For the **address** field, its intended use in **BibTeX** varies depending + on the entry type (e.g., for **\@inproceedings**, it denotes the **address** + of the **conference**, while for **\@mastersthesis/\@phdthesis**, is the + **address** of the **school**, etc.). Mapping between **BibTeX** and + [CFF]{.underline} becomes more complex when related to institutions, + resulting in varying final mappings in [CFF]{.underline}. When converting + from [CFF]{.underline} to **BibTeX**, we propose to follow the same + entry-based logic, using the key [location]{.underline} as a fallback value + when converting to **address**. + +- In relation with this complexity mentioned above, **institution, + organization** and **school** would be mapped to [institution]{.underline}. + +- **series** would be mapped to [collection-title]{.underline} only on those + entries that does not requires **booktitle**. In practice, this means that + collection-title would correspond to **booktitle** for **incollection** and + **inproceedings**, and in the rest of cases it would correspond to series. A + consequence of this is that series information would be lost for + incollection and inproceedings, but on those cases is an optional field. + +- Regarding **series**, it would be mapped to [collection-title]{.underline} + only for those entries that do not require **booktitle**. In practice, this + means that [collection-title]{.underline} would correspond to **booktitle** + for **\@incollection** and **\@inproceedings**, while in other cases it + would correspond to **series**. As a consequence, **series** information + would be lost for **\@incollection** and **\@inproceedings**, but in those + cases, it is an optional field. + +- When converting from [CFF]{.underline} to **BibTeX**, we propose to use + [date-published]{.underline} as a fallback for extracting **month** and + **year** fields. + +- When **pages** is provided as a range separated by `--`, i.e, **pages = + {3--5}** would be parsed as [start: 3]{.underline}, [end: 5]{.underline} in + [CFF]{.underline}. + +Additionally, there are other [CFF]{.underline} keys that correspond to +**BibLaTeX** fields. We propose to include these fields in the crosswalk[^6], +even though they are not part of the core **BibTeX** fields definition. + +[^6]: See @biblatexcheatsheet for a preview of the accepted **BibLaTeX** fields. + +```{r fields_biblatex2cff, echo=FALSE,results='asis'} +df_table <- table_master[table_master$table == "fields_biblatex2cff", c(2:3)] +df_table[is.na(df_table)] <- "" +# fix links +df_table$f2 <- gsub("link_to_entry_models", "#entrymodels", df_table$f2) +row.names(df_table) <- NULL + +knitr::kable(df_table, + col.names = c("**BibLaTeX Field**", "[CFF key]{.underline}"), + caption = "**BibLaTeX** - [CFF]{.underline} Field/Key crosswalk" ) ``` -These keys are the equivalent to the fields of BibTeX (see [Fields]), with the exception of the key **type**. On CFF, -this key defines the type of work[^5], therefore this is the equivalent to the BibTeX entries (see [Entries](#entries)). - -[^5]: See a complete list of possible values of CFF type on the [Guide to Citation File Format schema version - 1.2.0](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#definitionsreferencetype). - -## Proposed crosswalk - -The **cffr** package [@hernangomez2021] provides utilities from converting BibTeX entries (via the **R** base function -`bibentry()`) to CFF files and vice-versa. This section describes how the conversion between both formats have been -implemented. This crosswalk is based partially on @Haines_Ruby_CFF_Library_2021[^6]. - -[^6]: Note that this software performs only the conversion from CFF to BibTeX, however **cffr** can perform the - conversion in both directions. - -On the following two section I present an overview of the proposed mapping between the Entries and Fields of BibTeX and -the CFF keys. After this initial mapping, I propose further transformations to improve the compatibility between both -systems using different [Entry Models]. - -For a better understanding of this paper, when a field is in **bold** (i.e. **\@book**, **edition**) the field -correspond to **BibTex** and when the field is [underlined]{.underline} (i.e. [book]{.underline}, [edition]{.underline}) -the field correspond to [CFF]{.underline}. - -### Entry/Type crosswalk - -For converting general **BibTeX** entries to [CFF]{.underline} types, the following crosswalk is proposed: - -+----------------------------+-----------------------------------------------------------+----------------------------+ -| BibTeX Entry | [**Value of CFF key: type**]{.underline} | Notes | -+============================+===========================================================+============================+ -| **\@article** | [article]{.underline} | | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@book** | [book]{.underline} | | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@booklet** | [pamphlet]{.underline} | | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@conference** | [conference-paper]{.underline} | | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@inbook** | [book]{.underline} | See [Entry Models] | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@incollection** | [generic]{.underline} | See [Entry Models] | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@inproceedings** | [conference-paper]{.underline} | | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@manual** | [manual]{.underline} | | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@mastersthesis** | [thesis]{.underline} | See [Entry Models] | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@misc** | [generic]{.underline} | | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@phdthesis** | [thesis]{.underline} | See [Entry Models] | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@proceedings** | [proceedings]{.underline} | | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@techreport** | [report]{.underline} | | -+----------------------------+-----------------------------------------------------------+----------------------------+ -| **\@unpublished** | [unpublished]{.underline} | | -+----------------------------+-----------------------------------------------------------+----------------------------+ - -: Entry/Type crosswalk: From **BibTeX** to [CFF]{.underline} - -Also, given that CFF provides with a [wide range of allowed -values](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#definitionsreferencetype) -on type, the following conversion would be performed from [CFF]{.underline} to **BibTeX**: - -+------------------------------------+---------------------------------+---------------------------------------------+ -| [Value of CFF key: | BibTeX Entry | Notes | -| type]{.underline} | | | -+====================================+=================================+=============================================+ -| [book]{.underline} | **\@book** **/ \@inbook** | See [Entry Models] | -+------------------------------------+---------------------------------+---------------------------------------------+ -| [conference]{.underline} | **\@inproceedings** | | -+------------------------------------+---------------------------------+---------------------------------------------+ -| [conference-paper]{.underline} | **\@inproceedings** | | -+------------------------------------+---------------------------------+---------------------------------------------+ -| [magazine-article]{.underline} | **\@article** | | -+------------------------------------+---------------------------------+---------------------------------------------+ -| [manual]{.underline} | **\@manual** | | -+------------------------------------+---------------------------------+---------------------------------------------+ -| [newspaper-article]{.underline} | **\@article** | | -+------------------------------------+---------------------------------+---------------------------------------------+ -| [pamphlet]{.underline} | **\@booklet** | | -+------------------------------------+---------------------------------+---------------------------------------------+ -| [proceedings]{.underline} | **\@proceedings** | | -+------------------------------------+---------------------------------+---------------------------------------------+ -| [report]{.underline} | **\@techreport** | | -+------------------------------------+---------------------------------+---------------------------------------------+ -| [thesis]{.underline} | **\@mastersthesis / | See [Entry Models] | -| | \@phdthesis** | | -+------------------------------------+---------------------------------+---------------------------------------------+ -| [unpublished]{.underline} | **\@unpublished** | | -+------------------------------------+---------------------------------+---------------------------------------------+ -| [generic]{.underline} | **\@misc / \@incollection** | Under specific conditions, see [Entry | -| | | Models] | -+------------------------------------+---------------------------------+---------------------------------------------+ -| \ | **\@misc** | | -+------------------------------------+---------------------------------+---------------------------------------------+ - -: Entry/Type crosswalk: From [CFF]{.underline} to **BibTeX** - -### Fields/Key crosswalk - -There is a large degree of similarity between the definition and names of some **BibTeX** fields and [CFF]{.underline} -keys. On the following cases, the equivalence is almost straightforward: - -| BibTeX Field | [CFF key]{.underline} | -|------------------|-----------------------------------------| -| **address** | See [Entry Models] | -| ***annote*** | \- | -| **author** | [authors]{.underline} | -| **booktitle** | [collection-title]{.underline} | -| **chapter** | [section]{.underline} | -| ***crossref*** | \- | -| **edition** | [edition]{.underline} | -| **editor** | [editors]{.underline} | -| **howpublished** | [medium]{.underline} | -| **institution** | See [Entry Models] | -| **journal** | [journal]{.underline} | -| ***key*** | \- | -| **month** | [month]{.underline} | -| **note** | [notes]{.underline} | -| **number** | [issue]{.underline} | -| **organization** | See [Entry Models] | -| **pages** | [start]{.underline} & [end]{.underline} | -| **publisher** | [publisher]{.underline} | -| **school** | See [Entry Models] | -| **series** | See [Entry Models] | -| **title** | [title]{.underline} | -| ***type*** | \- | -| **volume** | [volume]{.underline} | -| **year** | [year]{.underline} | - -: BibTeX - CFF Field/Key crosswalk - -Additionally, there are other additional CFF keys that have a correspondence with BibLaTeX fields. We propose also to -include these fields on the crosswalk[^7], although they are not part of the core BibTeX fields definition. - -[^7]: See @biblatexcheatsheet for a preview of the accepted BibLaTeX fields. - -| BibLaTeX Field | [CFF key]{.underline} | -|----------------|------------------------------| -| **abstract** | [abstract]{.underline} | -| **date** | [date-published]{.underline} | -| **doi** | [doi]{.underline} | -| **file** | [filename]{.underline} | -| **isbn** | [isbn]{.underline} | -| **issn** | [issn]{.underline} | -| **issuetitle** | [issue-title]{.underline} | -| **pagetotal** | [pages]{.underline} | -| **translator** | [translators]{.underline} | -| **url** | [url]{.underline} | -| **urldate** | [date-accessed]{.underline} | -| **version** | [version]{.underline} | - -: BibLaTeX - CFF Field/Key crosswalk - -## Entry Models - -This section presents the specific mapping proposed for each of the BibTeX entries, providing further information on how -each field is treated. Examples are adapted from the [xampl.bib](https://tug.org/texmf-docs/bibtex/xampl.bib) file -provided with the bibtex package [@patashnik]. - -### article +## Entry Models {#entrymodels} + +This section presents the specific mapping proposed for each of the **BibTeX** +entries, providing further information on how each field is treated. Examples +are adapted from the [xampl.bib](https://tug.org/texmf-docs/bibtex/xampl.bib) +file provided with the **bibtex** package [@patashnik]. + +### \@article {#article} The crosswalk of **\@article** does not require any special treatment. -+------------------------+------------------------------------------+------------------------------------------------+ -| BibTeX | [CFF]{.underline} | Note | -+========================+==========================================+================================================+ -| **\@article** | [type: article]{.underline} | When converting CFF to BibTeX, [type | -| | | magazine-article]{.underline} and | -| | | [newspaper-article]{.underline} are converted | -| | | to **\@article**. | -+------------------------+------------------------------------------+------------------------------------------------+ -| **author\*** | [authors]{.underline} | | -+------------------------+------------------------------------------+------------------------------------------------+ -| **title\*** | [title]{.underline} | | -+------------------------+------------------------------------------+------------------------------------------------+ -| **journal\*** | [journal]{.underline} | | -+------------------------+------------------------------------------+------------------------------------------------+ -| **year\*** | [year]{.underline} | | -+------------------------+------------------------------------------+------------------------------------------------+ -| **volume** | [volume]{.underline} | | -+------------------------+------------------------------------------+------------------------------------------------+ -| **number** | [issue]{.underline} | | -+------------------------+------------------------------------------+------------------------------------------------+ -| **pages** | [start]{.underline} and | Separated by `--`, i.e, **pages = {3\--5}** | -| | [end]{.underline} | would be parsed as: | -| | | | -| | | - [start: 3]{.underline} | -| | | | -| | | - [end: 5]{.underline} | -+------------------------+------------------------------------------+------------------------------------------------+ -| **month** | [month]{.underline} | As a fallback, **month** could be extracted | -| | | also from **date** (BibLaTeX field) or | -| | | [date-published]{.underline} | -+------------------------+------------------------------------------+------------------------------------------------+ -| **note** | [notes]{.underline} | | -+------------------------+------------------------------------------+------------------------------------------------+ - -: **\@article** Model +```{r model_article, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "model_article", c(2:4)] +df_table[is.na(df_table)] <- "" + +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +df_table$f3 <- gsub("link_to_article", "#article", df_table$f3) +df_table$f3 <- gsub("link_to_booklet", "#booklet", df_table$f3) +df_table$f3 <- gsub("link_to_book", "#book-inbook", df_table$f3) + +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("**BibTeX**", "[CFF]{.underline}", "Notes"), + caption = "**\\@article** Model" +) +``` **Examples** -[*BibTeX entry*]{.underline} +**BibTeX entry** ``` bibtex @article{article-full, @@ -502,7 +557,7 @@ The crosswalk of **\@article** does not require any special treatment. } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE} bib <- "@article{article-full, @@ -519,69 +574,53 @@ bib <- "@article{article-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r echo=FALSE} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) -``` - -### book/inbook - -In terms of field required on BibTeX, the only difference between **\@book** and **\@inbook** is that the latter -requires also a **chapter** or **pages**, while for **\@book** these fields are not even optional. So we propose here to -identify an **\@inbook** on CFF as a [book]{.underline} with [section]{.underline} and -[start]{.underline}-[end]{.underline} fields (CFF). - -Another specificity is that **series** field is mapped to [collection-title]{.underline} and **address** is mapped as -the [address]{.underline} of the [publisher]{.underline} (CFF). - -+----------------------+---------------------------+------------------------------------------------------------------+ -| BibTeX | [CFF]{.underline} | Note | -+======================+===========================+==================================================================+ -| **\@book** | [type: book]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **\@inbook** | [type: book]{.underline} | For identifying an **\@inbook** in CFF, assess if | -| | | [section]{.underline} or [start/end]{.underline} information is | -| | | available | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **author\*** | [authors]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **editor\*** | [editors]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **title\*** | [title]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **publisher\*** | [publisher]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **year\*** | [year]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **chapter\*** | [section]{.underline} | Only required on **\@inbook** | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **pages\*** | [start]{.underline} and | Only required on **\@inbook** | -| | [end]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **volume** | [volume]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **number** | [issue]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **series** | [coll | | -| | ection-title]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **address** | [address]{.underline} | As a fallback, the field [location]{.underline} can be used | -| | property of | | -| | [publisher]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **edition** | [edition]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **month** | [month]{.underline} | See **Note** on [article] | -+----------------------+---------------------------+------------------------------------------------------------------+ -| **note** | [notes]{.underline} | | -+----------------------+---------------------------+------------------------------------------------------------------+ - -: **\@book/\@inbook** Model - -**Examples: book** - -[*BibTeX entry*]{.underline} +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) +``` + +### \@book / \@inbook {#book-inbook} + +In terms of the fields required in BibTeX, the primary difference between +**\@book** and **\@inbook** is that **\@inbook** requires a **chapter** or +**page** field, while **\@book** does not even allow these fields as optional. +Therefore, we propose that an **\@inbook** entry in [CFF]{.underline} be treated +as a **\@book** with the following supplementary fields: + +1. [section]{.underline}: To denote the specific **chapter** within the book. +2. [start-end]{.underline}: To indicate the range of **pages** covered by the + section. + +Additionally, note that in [CFF]{.underline}, the **series** field corresponds +to [collection-title]{.underline}, and the **address** field represents the +[publisher]{.underline}'s [address]{.underline}. By last, the key +[collection-type]{.underline} would be populated with [book-series]{.underline}. + +```{r model_book, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "model_book", c(2:4)] +df_table[is.na(df_table)] <- "" + +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +df_table$f3 <- gsub("link_to_article", "#article", df_table$f3) +df_table$f3 <- gsub("link_to_booklet", "#booklet", df_table$f3) +df_table$f3 <- gsub("link_to_book", "#book-inbook", df_table$f3) + +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("**BibTeX**", "[CFF]{.underline}", "Notes"), + caption = "**\\@book / \\@inbook** Model" +) +``` + +There are notable differences in how **BibTeX** and **BibLaTeX** handle the +**\@inbook** entry (further discussed in the [Appendix A](#appendix_inbook)). We +propose to treat a **BibLaTeX \@inbook** as a **BibTeX \@incollection.** + +**Examples: \@book** + +**BibTeX entry** ``` bibtex @book{book-full, @@ -598,7 +637,7 @@ the [address]{.underline} of the [publisher]{.underline} (CFF). } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE} bib <- "@book{book-full, @@ -617,15 +656,15 @@ bib <- "@book{book-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r, echo=FALSE} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) ``` -**Examples: inbook** +**Examples: \@inbook** -[*BibTeX entry*]{.underline} +**BibTeX entry** ``` bibtex @inbook{inbook-full, @@ -645,7 +684,7 @@ toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE,} bib <- "@inbook{inbook-full, @@ -667,47 +706,36 @@ bib <- "@inbook{inbook-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r echo=FALSE,} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) ``` -### booklet +### \@booklet {#booklet} In **\@booklet** **address** is mapped to [location]{.underline}. -+---------------------+---------------------+--------------------------------------------------------------------------+ -| BibTeX | [CFF]{.underline} | Note | -+=====================+=====================+==========================================================================+ -| **\@booklet** | [type: | | -| | pa | | -| | mphlet]{.underline} | | -+---------------------+---------------------+--------------------------------------------------------------------------+ -| **title\*** | [title]{.underline} | | -+---------------------+---------------------+--------------------------------------------------------------------------+ -| **author\*** | [a | | -| | uthors]{.underline} | | -+---------------------+---------------------+--------------------------------------------------------------------------+ -| **howpublished** | [ | | -| | medium]{.underline} | | -+---------------------+---------------------+--------------------------------------------------------------------------+ -| **address** | [lo | | -| | cation]{.underline} | | -+---------------------+---------------------+--------------------------------------------------------------------------+ -| **month** | [month]{.underline} | See **Note** on [article] | -+---------------------+---------------------+--------------------------------------------------------------------------+ -| **year** | [year]{.underline} | As a fallback, **year** could be extracted also from **date** (BibLaTeX | -| | | field)/ [date-published]{.underline} | -+---------------------+---------------------+--------------------------------------------------------------------------+ -| **note** | [notes]{.underline} | | -+---------------------+---------------------+--------------------------------------------------------------------------+ - -: **\@booklet** Model +```{r model_booklet, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "model_booklet", c(2:4)] +df_table[is.na(df_table)] <- "" + +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +df_table$f3 <- gsub("link_to_article", "#article", df_table$f3) +df_table$f3 <- gsub("link_to_booklet", "#booklet", df_table$f3) +df_table$f3 <- gsub("link_to_book", "#book-inbook", df_table$f3) + +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("**BibTeX**", "[CFF]{.underline}", "Notes"), + caption = "**\\@booklet** Model" +) +``` **Examples** -[*BibTeX entry*]{.underline} +**BibTeX entry** ``` bibtex @booklet{booklet-full, @@ -721,7 +749,7 @@ In **\@booklet** **address** is mapped to [location]{.underline}. } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE, } bib <- "@booklet{booklet-full, @@ -737,61 +765,38 @@ bib <- "@booklet{booklet-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r echo=FALSE, } -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) -``` - -### conference/inproceedings - -Note that in this case, **organization** is mapped to [institution]{.underline}, as BibTeX does not prescribe the use of -**institution** on these entries. - -+---------------------------+----------------------------+-------------------------------------------------------------+ -| BibTeX | CFF | Note | -+===========================+============================+=============================================================+ -| **\@conference / | [type: | CFF entries with [type; conference]{.underline} are mapped | -| \@inproceedings** | con | back to **\@inproceedings**. | -| | ference-paper]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **author\*** | [authors]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **title\*** | [title]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **booktitle\*** | [col | | -| | lection-title]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **year\*** | [year]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **editor** | [editors]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **volume** | [volume]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **number** | [issue]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **series** | [conference]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **pages** | [start]{.underline} and | See **Note** on [article] | -| | [end]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **address** | [location]{.underline} | As a fallback, [address]{.underline} property of | -| | | [conference]{.underline} can be used | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **month** | [month]{.underline} | See **Note** on [article] | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **organization** | [institution]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **publisher** | [publisher]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ -| **note** | [notes]{.underline} | | -+---------------------------+----------------------------+-------------------------------------------------------------+ - -: **\@conference/\@inproceedings** Model +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) +``` + +### \@conference / \@inproceedings {#conf_inproc} + +Note that in this case, **organization** is mapped to [institution]{.underline}. +Additionally, **series** would be ignored as there is not clear mapping on +[CFF]{.underline} for this field. + +```{r model_inproceedings, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "model_inproceedings", c(2:4)] +df_table[is.na(df_table)] <- "" + +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +df_table$f3 <- gsub("link_to_article", "#article", df_table$f3) +df_table$f3 <- gsub("link_to_booklet", "#booklet", df_table$f3) +df_table$f3 <- gsub("link_to_book", "#book-inbook", df_table$f3) + +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("**BibTeX**", "[CFF]{.underline}", "Notes"), + caption = "**\\@conference / \\@inproceedings** Model" +) +``` **Examples** -[*BibTeX entry*]{.underline} +**BibTeX entry** ``` bibtex @inproceedings{inproceedings-full, @@ -810,7 +815,7 @@ Note that in this case, **organization** is mapped to [institution]{.underline}, } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE,} bib <- "@inproceedings{inproceedings-full, @@ -831,63 +836,42 @@ bib <- "@inproceedings{inproceedings-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r echo=FALSE,} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) -``` - -### incollection - -As **booktitle** is a required field, we propose to map that field to [collection-title]{.underline} and the -[type]{.underline} to [generic]{.underline}. Therefore, an **\@incollection** is a [type: generic]{.underline} with a -[collection-title]{.underline} key. - -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **BibTeX** | [CFF]{.underline} | Note | -+=========================+=================================================+=========================================+ -| **\@incollection** | [type: generic]{.underline} | Including a | -| | | [collection-title]{.underline} value | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **author\*** | [authors]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **title\*** | [title]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **booktitle\*** | [collection-title]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **publisher\*** | [publisher]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **year\*** | [year]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **editor** | [editors]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **volume** | [volume]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **number** | [issue]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **series** | [series]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **type** | \- | Ignored | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **chapter** | [section]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **pages** | [start]{.underline} and [end]{.underline} | See **Note** on [article] | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **address** | [address]{.underline} property of | See **Note** on [book/inbook] | -| | [publisher]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **edition** | [edition]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **month** | [month]{.underline} | See **Note** on [article] | -+-------------------------+-------------------------------------------------+-----------------------------------------+ -| **note** | [notes]{.underline} | | -+-------------------------+-------------------------------------------------+-----------------------------------------+ - -: **\@incollection** Model +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) +``` + +### \@incollection {#incol} + +As **booktitle** is a required field, we propose to map that field to +[collection-title]{.underline} and the [type]{.underline} to +[generic]{.underline}. Therefore, an **\@incollection** is a [type: +generic]{.underline} with a [collection-title]{.underline} key. + +Additionally, **series** and **type** would be ignored as there is not clear +mapping on [CFF]{.underline} for this field. + +```{r model_incollection, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "model_incollection", c(2:4)] +df_table[is.na(df_table)] <- "" + +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +df_table$f3 <- gsub("link_to_article", "#article", df_table$f3) +df_table$f3 <- gsub("link_to_booklet", "#booklet", df_table$f3) +df_table$f3 <- gsub("link_to_book", "#book-inbook", df_table$f3) + +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("**BibTeX**", "[CFF]{.underline}", "Notes"), + caption = "**\\@incollection** Model" +) +``` **Examples** -[*BibTeX entry*]{.underline} +**BibTeX entry** ``` bibtex @incollection{incollection-full, @@ -909,7 +893,7 @@ As **booktitle** is a required field, we propose to map that field to [collectio } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE,} bib <- "@incollection{incollection-full, @@ -933,46 +917,40 @@ bib <- "@incollection{incollection-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r echo=FALSE,} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) -``` - -### manual - -As in the case of [conference/inproceedings], **organization** is mapped to [institution]{.underline}. - -+----------------------------+--------------------------------------------+-------------------------------------------+ -| **BibTeX** | [CFF]{.underline} | Note | -+============================+============================================+===========================================+ -| **\@manual** | [type: manual]{.underline} | | -+----------------------------+--------------------------------------------+-------------------------------------------+ -| **title\*** | [title]{.underline} | | -+----------------------------+--------------------------------------------+-------------------------------------------+ -| **author** | [authors]{.underline} | | -+----------------------------+--------------------------------------------+-------------------------------------------+ -| **organization** | [institution]{.underline} | | -+----------------------------+--------------------------------------------+-------------------------------------------+ -| **address** | [location]{.underline} | | -+----------------------------+--------------------------------------------+-------------------------------------------+ -| **edition** | [edition]{.underline} | | -+----------------------------+--------------------------------------------+-------------------------------------------+ -| **month** | [month]{.underline} | See **Note** on [article] | -+----------------------------+--------------------------------------------+-------------------------------------------+ -| **year** | [year]{.underline} | See **Note** on [booklet] | -+----------------------------+--------------------------------------------+-------------------------------------------+ -| **note** | [notes]{.underline} | | -+----------------------------+--------------------------------------------+-------------------------------------------+ - -: **\@manual** Model +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) +``` + +### \@manual + +As in the case of [**\@conference** / **\@inproceedings**](#conf_inproc), +**organization** is mapped to [institution]{.underline}. + +```{r model_manual, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "model_manual", c(2:4)] +df_table[is.na(df_table)] <- "" + +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +df_table$f3 <- gsub("link_to_article", "#article", df_table$f3) +df_table$f3 <- gsub("link_to_booklet", "#booklet", df_table$f3) +df_table$f3 <- gsub("link_to_book", "#book-inbook", df_table$f3) + +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("**BibTeX**", "[CFF]{.underline}", "Notes"), + caption = "**\\@manual** Model" +) +``` **Examples** -[*BibTeX entry*]{.underline} +**BibTeX entry** -Note that **month** can't be parsed to a single integer in the range `1--12` as required on CFF, so it is not parsed to -avoid validation errors. +Note that **month** can't be parsed to a single integer in the range `1--12` as +required on CFF, so it is not parsed to avoid validation errors. ``` bibtex @manual{manual-full, @@ -987,7 +965,7 @@ avoid validation errors. } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE,} bib <- "@manual{manual-full, @@ -1004,52 +982,44 @@ bib <- "@manual{manual-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r echo=FALSE,} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) -``` - -### mastersthesis/phdthesis - -In terms of field required on BibTeX, it is identical for both **\@mastersthesis** and **\@phdthesis.** - -We propose here to identify each type of thesis using the field [thesis-type]{.underline} (CFF). So if -[thesis-type]{.underline} contains a [regex pattern](https://regex101.com/r/mBWfbs/1) `(?i)(phd)` it would be recognized -as **\@phdthesis**. - -+------------------------+------------------------------------------+-------------------------------------------------+ -| BibTeX | [CFF]{.underline} | Note | -+========================+==========================================+=================================================+ -| **\@mastersthesis** | [type: thesis]{.underline} | Use also [thesis-type]{.underline} for | -| | | identifying the thesis type. | -+------------------------+------------------------------------------+-------------------------------------------------+ -| **\@phdthesis** | [type: thesis]{.underline} | Use also [thesis-type]{.underline} for | -| | | identifying the thesis type. | -+------------------------+------------------------------------------+-------------------------------------------------+ -| **author\*** | [authors]{.underline} | | -+------------------------+------------------------------------------+-------------------------------------------------+ -| **title\*** | [title]{.underline} | | -+------------------------+------------------------------------------+-------------------------------------------------+ -| **school\*** | [institution]{.underline} | | -+------------------------+------------------------------------------+-------------------------------------------------+ -| **year\*** | [year]{.underline} | | -+------------------------+------------------------------------------+-------------------------------------------------+ -| **type** | | | -+------------------------+------------------------------------------+-------------------------------------------------+ -| **address** | [address]{.underline} property of | See **Note** on [book/inbook] | -| | [institution]{.underline} | | -+------------------------+------------------------------------------+-------------------------------------------------+ -| **month** | [month]{.underline} | See **Note** on [article] | -+------------------------+------------------------------------------+-------------------------------------------------+ -| **note** | [notes]{.underline} | | -+------------------------+------------------------------------------+-------------------------------------------------+ - -: **\@mastersthesis/phdthesis** Model - -**Examples: mastersthesis** - -[*BibTeX entry*]{.underline} +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) +``` + +### \@mastersthesis / \@phdthesis + +In terms of field required on BibTeX, it is identical for both +**\@mastersthesis** and **\@phdthesis.** + +We propose here to identify each type of thesis using the key +[thesis-type]{.underline} So if [thesis-type]{.underline} contains a [regex +pattern](https://regex101.com/r/mBWfbs/1) `(?i)(phd)` it would be recognized as +**\@phdthesis**. + +Additionally, **school** would be mapped to [institution]{.underline}. + +```{r model_thesis, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "model_thesis", c(2:4)] +df_table[is.na(df_table)] <- "" + +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +df_table$f3 <- gsub("link_to_article", "#article", df_table$f3) +df_table$f3 <- gsub("link_to_booklet", "#booklet", df_table$f3) +df_table$f3 <- gsub("link_to_book", "#book-inbook", df_table$f3) + +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("**BibTeX**", "[CFF]{.underline}", "Notes"), + caption = "**\\@mastersthesis / \\@phdthesis** Model" +) +``` + +**Examples: \@mastersthesis** + +**BibTeX entry** ``` bibtex @mastersthesis{mastersthesis-full, @@ -1064,7 +1034,7 @@ as **\@phdthesis**. } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE} bib <- "@mastersthesis{mastersthesis-full, @@ -1081,15 +1051,15 @@ bib <- "@mastersthesis{mastersthesis-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r, echo=FALSE} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) ``` -**Examples: phdthesis** +**Examples: \@phdthesis** -[*BibTeX entry*]{.underline} +**BibTeX entry** ``` bibtex @phdthesis{phdthesis-full, @@ -1104,7 +1074,7 @@ toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE,} bib <- "@phdthesis{phdthesis-full, @@ -1121,42 +1091,42 @@ bib <- "@phdthesis{phdthesis-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r echo=FALSE,} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) ``` -### misc +### \@misc -The crosswalk of **\@misc** does not require any special treatment. This entry does not require any field. +The crosswalk of **\@misc** does not require any special treatment. This +**entry** does not require any **field**. -Note also that it is mapped to [type: generic]{.underline} as [incollection], but in this case **booktitle** is not even -an option, so the proposed definition should cover both **\@misc** and **\@incollection** without problems. +Note also that it is mapped to [type: generic]{.underline} as +[**\@incollection**](#incol), but in this case **booktitle** is not even an +option, so the proposed definition should cover both **\@misc** and +**\@incollection** without problems. -+----------------------------+---------------------------------------------+------------------------------------------+ -| **BibTeX** | [CFF]{.underline} | Note | -+============================+=============================================+==========================================+ -| **\@misc** | [type: generic]{.underline} | | -+----------------------------+---------------------------------------------+------------------------------------------+ -| **author** | [authors]{.underline} | | -+----------------------------+---------------------------------------------+------------------------------------------+ -| **title** | [title]{.underline} | | -+----------------------------+---------------------------------------------+------------------------------------------+ -| **howpublished** | [medium]{.underline} | | -+----------------------------+---------------------------------------------+------------------------------------------+ -| **month** | [month]{.underline} | See **Note** on [article] | -+----------------------------+---------------------------------------------+------------------------------------------+ -| **year** | [year]{.underline} | See **Note** on [booklet] | -+----------------------------+---------------------------------------------+------------------------------------------+ -| **note** | [notes]{.underline} | | -+----------------------------+---------------------------------------------+------------------------------------------+ +```{r model_misc, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "model_misc", c(2:4)] +df_table[is.na(df_table)] <- "" -: **\@misc** Model +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +df_table$f3 <- gsub("link_to_article", "#article", df_table$f3) +df_table$f3 <- gsub("link_to_booklet", "#booklet", df_table$f3) +df_table$f3 <- gsub("link_to_book", "#book-inbook", df_table$f3) + +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("**BibTeX**", "[CFF]{.underline}", "Notes"), + caption = "**\\@misc** Model" +) +``` **Examples** -[*BibTeX entry*]{.underline} +**BibTeX entry** ``` bibtex @misc{misc-full, @@ -1169,7 +1139,7 @@ an option, so the proposed definition should cover both **\@misc** and **\@incol } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE,} bib <- "@misc{misc-full, @@ -1184,61 +1154,45 @@ bib <- "@misc{misc-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r echo=FALSE,} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) ``` -### proceedings +### \@proceedings -The proposed model is similar to [conference/inproceedings]. Note that **\@proceedings** does not prescribe a **author** -field. On this cases, as [authors]{.underline} is required on CFF, we would use *anonymous*[^8] when converting to CFF -and omit it on the conversion back to CFF. +The proposed model is consistent with [**\@conference** / +**\@inproceedings**](#conf_inproc). Note that **\@proceedings** does not +prescribe a **author** field. On this cases, as [authors]{.underline} is +required on [CFF]{.underline}, we would use *anonymous*[^7] when converting to +[CFF]{.underline} and omit it on the conversion from [CFF]{.underline} to +**BibTeX**. -[^8]: As proposed on [*How to deal with unknown individual +[^7]: As proposed on [*How to deal with unknown individual authors?*](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md#how-to-deal-with-unknown-individual-authors), **(Guide to Citation File Format schema version 1.2.0)** -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| BibTeX | [CFF]{.underline} | Note | -+=======================+=======================+====================================================================+ -| **\@proceedings** | [type: | | -| | pro | | -| | ceedings]{.underline} | | -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| **title\*** | [title]{.underline} | | -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| **year\*** | [year]{.underline} | | -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| **editor** | [editors]{.underline} | | -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| **volume** | [volume]{.underline} | | -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| **number** | [issue]{.underline} | | -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| **series** | [co | | -| | nference]{.underline} | | -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| **address** | [ | As a fallback, [address]{.underline} property of | -| | location]{.underline} | [conference]{.underline} can be used | -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| **month** | [month]{.underline} | See **Note** on [article] | -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| **organization** | [ins | | -| | titution]{.underline} | | -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| **publisher** | [p | | -| | ublisher]{.underline} | | -+-----------------------+-----------------------+--------------------------------------------------------------------+ -| **note** | [notes]{.underline} | | -+-----------------------+-----------------------+--------------------------------------------------------------------+ - -: **\@conference/\@inproceedings** Model +```{r model_proceedings, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "model_proceedings", c(2:4)] +df_table[is.na(df_table)] <- "" + +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +df_table$f3 <- gsub("link_to_article", "#article", df_table$f3) +df_table$f3 <- gsub("link_to_booklet", "#booklet", df_table$f3) +df_table$f3 <- gsub("link_to_book", "#book-inbook", df_table$f3) + +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("**BibTeX**", "[CFF]{.underline}", "Notes"), + caption = "**\\@proceedings** Model" +) +``` **Examples** -[*BibTeX entry*]{.underline} +**BibTeX entry** ``` bibtex @proceedings{proceedings-full, @@ -1274,44 +1228,36 @@ bib <- "@proceedings{proceedings-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r echo=FALSE,} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) -``` - -### techreport - -+-------------------------+-------------------------------------------------------------+-----------------------------+ -| **BibTeX** | [CFF]{.underline} | Note | -+=========================+=============================================================+=============================+ -| **\@techreport** | [type: report]{.underline} | | -+-------------------------+-------------------------------------------------------------+-----------------------------+ -| **author\*** | [authors]{.underline} | | -+-------------------------+-------------------------------------------------------------+-----------------------------+ -| **title\*** | [title]{.underline} | | -+-------------------------+-------------------------------------------------------------+-----------------------------+ -| **institution\*** | [institution]{.underline} | | -+-------------------------+-------------------------------------------------------------+-----------------------------+ -| **year\*** | [year]{.underline} | | -+-------------------------+-------------------------------------------------------------+-----------------------------+ -| **type** | \- | Ignored | -+-------------------------+-------------------------------------------------------------+-----------------------------+ -| **number** | [issue]{.underline} | | -+-------------------------+-------------------------------------------------------------+-----------------------------+ -| **address** | [address]{.underline} property of [institution]{.underline} | See **Note** on | -| | | [book/inbook] | -+-------------------------+-------------------------------------------------------------+-----------------------------+ -| **month** | [month]{.underline} | See **Note** on [article] | -+-------------------------+-------------------------------------------------------------+-----------------------------+ -| **note** | [notes]{.underline} | | -+-------------------------+-------------------------------------------------------------+-----------------------------+ - -: **\@techreport** Model +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) +``` + +### \@techreport + +The crosswalk of **\@techreport** does not require any special treatment. + +```{r model_techreport, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "model_techreport", c(2:4)] +df_table[is.na(df_table)] <- "" + +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +df_table$f3 <- gsub("link_to_article", "#article", df_table$f3) +df_table$f3 <- gsub("link_to_booklet", "#booklet", df_table$f3) +df_table$f3 <- gsub("link_to_book", "#book-inbook", df_table$f3) + +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("**BibTeX**", "[CFF]{.underline}", "Notes"), + caption = "**\\@techreport** Model" +) +``` **Examples** -[*BibTeX entry*]{.underline} +**BibTeX entry** ``` bibtex @techreport{techreport-full, @@ -1327,7 +1273,7 @@ toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE,} bib <- "@techreport{techreport-full, @@ -1345,35 +1291,36 @@ bib <- "@techreport{techreport-full, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** ```{r echo=FALSE,} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) ``` -### unpublished +### \@unpublished + +The crosswalk of **\@unpublished** does not require any special treatment. + +```{r model_unpublished, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "model_unpublished", c(2:4)] +df_table[is.na(df_table)] <- "" -+----------------------------+------------------------------------------------+---------------------------------------+ -| **BibTeX** | [CFF]{.underline} | Note | -+============================+================================================+=======================================+ -| **\@unpublished** | [type: unpublished]{.underline} | | -+----------------------------+------------------------------------------------+---------------------------------------+ -| **author\*** | [authors]{.underline} | | -+----------------------------+------------------------------------------------+---------------------------------------+ -| **title\*** | [title]{.underline} | | -+----------------------------+------------------------------------------------+---------------------------------------+ -| **note\*** | [notes]{.underline} | | -+----------------------------+------------------------------------------------+---------------------------------------+ -| **month** | [month]{.underline} | See **Note** on [article] | -+----------------------------+------------------------------------------------+---------------------------------------+ -| **year** | [year]{.underline} | See **Note** on [booklet] | -+----------------------------+------------------------------------------------+---------------------------------------+ +# fix links +df_table$f3 <- gsub("link_to_entry_models", "#entrymodels", df_table$f3) +df_table$f3 <- gsub("link_to_article", "#article", df_table$f3) +df_table$f3 <- gsub("link_to_booklet", "#booklet", df_table$f3) +df_table$f3 <- gsub("link_to_book", "#book-inbook", df_table$f3) -: **\@unpublished** Model +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("**BibTeX**", "[CFF]{.underline}", "Notes"), + caption = "**\\@unpublished** Model" +) +``` **Examples** -[*BibTeX entry*]{.underline} +**BibTeX entry** ``` bibtex @unpublished{unpublished-minimal, @@ -1383,7 +1330,7 @@ toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) } ``` -[*CFF entry*]{.underline} +[CFF entry]{.underline} ```{r echo=FALSE,} bib <- "@unpublished{unpublished-minimal, @@ -1395,10 +1342,98 @@ bib <- "@unpublished{unpublished-minimal, cff_from_bibtex(bib) ``` -[*From CFF to BibTeX*]{.underline} +From [CFF]{.underline} to **BibTeX** + +```{r echo=FALSE,} +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) +``` + +## Appendix A: **\@inbook** in BibTeX and BibLaTeX {#appendix_inbook} + +The definition of **\@inbook** and **\@incollection** in **BibTeX** +[@patashnik1988] is as follows: + +> - **\@inbook**: A part of a book, which may be a chapter (or section) and/or +> a range of pages. Required fields: author or editor, title, chapter and/or +> pages, publisher, year (...) +> +> - **\@incollection**: A part of a book having its own title. Required +> fields: author, title, booktitle, publisher, year (...) + +Whereas **BibLaTeX** [@biblatexpack] specifies: + +> - **\@inbook:** A part of a book which forms a self-contained unit with its +> own title. Note that the [profile]{.underline} of this entry type is +> [different from standard BibTeX]{.underline}, see § 2.3.1. Required +> fields: author, title, booktitle, year/date (...). + +When considering required fields, an important difference is **booktitle** +requirement in **BibLaTeX**. Notably, **BibTeX \@incollection** requires also +this field. Moreover, both **BibTeX \@incollection** and **BibLaTeX \@inbook** +emphasize its reference to *"a part of a book (...) with its own title"*. + +In this document, the proposed crosswalk ensures full compatibility with +**BibTeX**. Hence, we propose to consider a **BibLaTeX \@inbook** entry as +equivalent to a **BibTeX \@incollection**, given the congruence in their +definitions and field requirements. + +**Examples** + +**BibTeX entry** + +``` bibtex +@inbook{inbook-biblatex, + author = {Yihui Xie and Christophe Dervieux and Emily Riederer}, + title = {Bibliographies and citations}, + booktitle = {{R} Markdown Cookbook}, + date = {2023-12-30}, + publisher = {Chapman and Hall/CRC}, + address = {Boca Raton, Florida}, + series = {The {R} Series}, + isbn = 9780367563837, + url = {https://bookdown.org/yihui/rmarkdown-cookbook}, + chapter = {4.5} +} +``` + +[CFF entry]{.underline} + +```{r echo=FALSE,} +bib <- "@inbook{inbook-biblatex, + author = {Yihui Xie and Christophe Dervieux and Emily Riederer}, + title = {Bibliographies and citations}, + booktitle = {{R} Markdown Cookbook}, + date = {2023-12-30}, + publisher = {Chapman and Hall/CRC}, + address = {Boca Raton, Florida}, + series = {The {R} Series}, + isbn = 9780367563837, + url = {https://bookdown.org/yihui/rmarkdown-cookbook}, + chapter = {4.5} +}" + +cff_from_bibtex(bib) +``` + +From [CFF]{.underline} to **BibTeX** ```{r echo=FALSE,} -toBibtex(cff_to_bibtex(cff_from_bibtex(bib))) +toBibtex(cff_to_bibentry(cff_from_bibtex(bib))) +``` + +## Appendix B: [CFF key:type]{.underline} values {#appendix_cff_type} + +From @druskat2019 Table 4: Complete list of [CFF]{.underline} reference types. + +```{r cff_types, echo=FALSE, results='asis'} +df_table <- table_master[table_master$table == "cff_types", c(2:3)] +df_table[is.na(df_table)] <- "" +row.names(df_table) <- NULL +knitr::kable(df_table, + col.names = c("Reference type string", "Description"), + row.names = NA, + caption = "Complete list of [CFF]{.underline} reference types." +) ``` ## References diff --git a/vignettes/cffr.Rmd b/vignettes/cffr.Rmd index c6b97152..030c065a 100644 --- a/vignettes/cffr.Rmd +++ b/vignettes/cffr.Rmd @@ -254,7 +254,7 @@ simplified as: allkeys <- list( "url" = "https://ropensci.org/", "version" = "0.0.1", - "repository" = "https://github.com/user/repo", + "repository" = "https://github.com/ropensci/cffr", # If the field is already present, it would be overridden title = "Modifying a 'cff' object", authors = newauthors, diff --git a/vignettes/crosswalk.Rmd b/vignettes/crosswalk.Rmd index 0acf2d20..e1cb1741 100644 --- a/vignettes/crosswalk.Rmd +++ b/vignettes/crosswalk.Rmd @@ -3,7 +3,7 @@ title: "From R to CFF" subtitle: "Crosswalk" description: > A comprehenshive description of the internal mappings performed by `cffr`. -author: Diego Hernangómez ORCID logo +author: Diego Hernangómez bibliography: REFERENCES.bib link-citations: yes output: