# Manipulating Citations with cffr

cffr is a tool whose target audience are R package developers. The main goal of cffr is to create a `CITATION.cff` file using the metadata information of the following files:

- Your `DESCRIPTION` file.
- If available, the citation information located in `inst/CITATION`.

## What is a `CITATION.cff` file?

Citation File Format (CFF) (Druskat et al. 2021) (v1.2.0) are plain text files with human- and machine-readable citation information for software (and datasets). Code developers can include them in their repositories to let others know how to correctly cite their software.

This format is becoming popular within the software citation ecosystem. Recently GitHub, Zenodo and Zotero have included full support of this citation format (Druskat 2021).

GitHub support is of special interest:

— Nat Friedman (@natfriedman) July 27, 2021

See Customize your repository/About CITATION files for more info.

## Creating a `CITATION.cff` file for my R package

With cffr creating a `CITATION.cff` file is quite straightforward. You just need to run `cff_write()`:

    library(cffr)

    cff_write()

    # You are done!

Under the hood, `cff_write()` performs the following tasks:

- It extracts the metadata using `cff_create()`.
- Writes a `CITATION.cff` file using `yaml::write_yaml()`.
- Validates the result using `cff_validate()`.

Congratulations! Now you have a full `CITATION.cff` file for your R package.

## Modifying your `CITATION.cff` file

You can easily customize the `cff` object (a custom class of cffr) using the parsers provided in the package, as well as making use of the `keys` parameter.

We would create a `cff` object using `cff()` (for example purposes only) and we would add or modify contents of it.

### Adding new fields

    newobject <- cff_create(cff())

    # For modifying your auto-generated object, run this line instead:
    # newoobject <- cff_create()

    newobject
    #> cff-version: 1.2.0
    #> message: If you use this software, please cite it using these metadata.
    #> title: My Research Software
    #> authors:
    #> - family-names: Doe
    #>   given-names: John
    #> preferred-citation:
    #>   type: manual
    #>   title: My Research Software
    #>   authors:
    #>   - family-names: Doe
    #>     given-names: John
    #>   year: '2022'

The valid keys of the Citation File Format schema version 1.2.0 can be displayed with `cff_schema_keys()`:

    cff_schema_keys()
    #>  [1] "cff-version"         "message"
    #>  [3] "type"                "license"
    #>  [5] "title"               "version"
    #>  [7] "doi"                 "abstract"
    #>  [9] "authors"             "preferred-citation"
    #> [11] "repository"          "repository-artifact"
    #> [13] "repository-code"     "url"
    #> [15] "date-released"       "contact"
    #> [17] "keywords"            "references"
    #> [19] "commit"              "identifiers"
    #> [21] "license-url"

In this case, we are going to add `url`, `version` and `repository`. We would also overwrite the `title` key. We just need to create a list and pass it to the `keys` argument of `cff_create()`:

    newkeys <- list(
      "url" = "https://ropensci.org/",
      "version" = "0.0.1",
      "repository" = "https://github.com/user/repo",
      # If the field is already present, it would be overridden
      title = "Modifying a 'cff' object"
    )

    modobject <- cff_create(newobject, keys = newkeys)

    modobject
    #> cff-version: 1.2.0
    #> message: If you use this software, please cite it using these metadata.
    #> title: Modifying a 'cff' object
    #> version: 0.0.1
    #> authors:
    #> - family-names: Doe
    #>   given-names: John
    #> preferred-citation:
    #>   type: manual
    #>   title: My Research Software
    #>   authors:
    #>   - family-names: Doe
    #>     given-names: John
    #>   year: '2022'
    #> repository: https://github.com/user/repo
    #> url: https://ropensci.org/

    # Validate against the schema

    cff_validate(modobject)
    #>
    #> cff_validate results-----
    #> Congratulations! This cff object is valid

### Parsing persons and citations

cffr provides two functions that parse `person` objects and `bibentry` objects (See `?person` and `?bibentry`). These objects are included in the utils package and are a core part of the metadata of any R package.

Following the previous example, we are going to add a new author first. For doing that, we need first to extract the current author of the package and append the parsed person:

    # Valid person keys

    cff_schema_definitions_person()
    #>  [1] "address"       "affiliation"   "alias"
    #>  [4] "city"          "country"       "email"
    #>  [7] "family-names"  "fax"           "given-names"
    #> [10] "name-particle" "name-suffix"   "orcid"
    #> [13] "post-code"     "region"        "tel"
    #> [16] "website"

    # Create the person

    chiquito <- person("Gregorio",
      "Sánchez Fernández",
      email = "fake@email2.com",
      comment = c(
        alias = "Chiquito de la Calzada",
        city = "Malaga",
        country = "ES",
        ORCID = "0000-0000-0000-0001"
      )
    )

    chiquito
    #> [1] "Gregorio Sánchez Fernández <fake@email2.com> (Chiquito de la Calzada, Malaga, ES, <https://orcid.org/0000-0000-0000-0001>)"

    # Parse it
    chiquito_parsed <- cff_parse_person(chiquito)
    chiquito_parsed
    #> family-names: Sánchez Fernández
    #> given-names: Gregorio
    #> email: fake@email2.com
    #> alias: Chiquito de la Calzada
    #> city: Malaga
    #> country: ES
    #> orcid: https://orcid.org/0000-0000-0000-0001

    # Append to previous authors

    # Needs to be append as a list
    newauthors <- c(modobject$authors, list(chiquito_parsed))
    newauthors
    #> - family-names: Doe
    #>   given-names: John
    #> - family-names: Sánchez Fernández
    #>   given-names: Gregorio
    #>   email: fake@email2.com
    #>   alias: Chiquito de la Calzada
    #>   city: Malaga
    #>   country: ES
    #>   orcid: https://orcid.org/0000-0000-0000-0001

    newauthorobject <- cff_create(modobject, keys = list(authors = newauthors))

    newauthorobject
    #> cff-version: 1.2.0
    #> message: If you use this software, please cite it using these metadata.
    #> title: Modifying a 'cff' object
    #> version: 0.0.1
    #> authors:
    #> - family-names: Doe
    #>   given-names: John
    #> - family-names: Sánchez Fernández
    #>   given-names: Gregorio
    #>   email: fake@email2.com
    #>   alias: Chiquito de la Calzada
    #>   city: Malaga
    #>   country: ES
    #>   orcid: https://orcid.org/0000-0000-0000-0001
    #> preferred-citation:
    #>   type: manual
    #>   title: My Research Software
    #>   authors:
    #>   - family-names: Doe
    #>     given-names: John
    #>   year: '2022'
    #> repository: https://github.com/user/repo
    #> url: https://ropensci.org/

    cff_validate(newauthorobject)
    #>
    #> cff_validate results-----
    #> Congratulations! This cff object is valid

Now, we may want to add `references` to our data. cffr supports two types of references:

- References created with `bibentry()`
- References extracted from packages using `citation()`

On the following example, we would add two references, one of each type:

    # Valid reference keys

    cff_schema_definitions_refs()
    #>  [1] "abbreviation"        "abstract"
    #>  [3] "authors"             "collection-doi"
    #>  [5] "collection-title"    "collection-type"
    #>  [7] "commit"              "conference"
    #>  [9] "contact"             "copyright"
    #> [11] "data-type"           "database-provider"
    #> [13] "database"            "date-accessed"
    #> [15] "date-downloaded"     "date-published"
    #> [17] "date-released"       "department"
    #> [19] "doi"                 "edition"
    #> [21] "editors"             "editors-series"
    #> [23] "end"                 "entry"
    #> [25] "filename"            "format"
    #> [27] "identifiers"         "institution"
    #> [29] "isbn"                "issn"
    #> [31] "issue"               "issue-date"
    #> [33] "issue-title"         "journal"
    #> [35] "keywords"            "languages"
    #> [37] "license"             "license-url"
    #> [39] "loc-end"             "loc-start"
    #> [41] "location"            "medium"
    #> [43] "month"               "nihmsid"
    #> [45] "notes"               "number"
    #> [47] "number-volumes"      "pages"
    #> [49] "patent-states"       "pmcid"
    #> [51] "publisher"           "recipients"
    #> [53] "repository"          "repository-artifact"
    #> [55] "repository-code"     "scope"
    #> [57] "section"             "senders"
    #> [59] "start"               "status"
    #> [61] "term"                "thesis-type"
    #> [63] "title"               "translators"
    #> [65] "type"                "url"
    #> [67] "version"             "volume"
    #> [69] "volume-title"        "year"
    #> [71] "year-original"

    # Auto parsed from another R package
    base_r <- cff_parse_citation(citation("base"))

    base_r
    #> type: manual
    #> title: 'R: A Language and Environment for Statistical Computing'
    #> authors:
    #> - name: R Core Team
    #> location:
    #>   name: Vienna, Austria
    #> year: '2021'
    #> url: https://www.R-project.org/
    #> institution:
    #>   name: R Foundation for Statistical Computing

    # Create with bibentry

    bib <- bibentry("Book",
      title = "This is a book",
      author = "Lisa Lee",
      year = 1980,
      publisher = "McGraw Hill",
      volume = 2
    )
    bib
    #> Lee L (1980). _This is a book_, volume 2. McGraw
    #> Hill.

    # Now parse it

    bookparsed <- cff_parse_citation(bib)

    bookparsed
    #> type: book
    #> title: This is a book
    #> authors:
    #> - family-names: Lee
    #>   given-names: Lisa
    #> year: '1980'
    #> publisher:
    #>   name: McGraw Hill
    #> volume: '2'

Now the process is similar to the example with `person`: we append both references (as lists) and add them to our object:

    refkeys <- list(references = c(list(base_r), list(bookparsed)))

    refkeys
    #> $references
    #> $references[[1]]
    #> type: manual
    #> title: 'R: A Language and Environment for Statistical Computing'
    #> authors:
    #> - name: R Core Team
    #> location:
    #>   name: Vienna, Austria
    #> year: '2021'
    #> url: https://www.R-project.org/
    #> institution:
    #>   name: R Foundation for Statistical Computing
    #>
    #> $references[[2]]
    #> type: book
    #> title: This is a book
    #> authors:
    #> - family-names: Lee
    #>   given-names: Lisa
    #> year: '1980'
    #> publisher:
    #>   name: McGraw Hill
    #> volume: '2'

    finalobject <- cff_create(newauthorobject, keys = refkeys)

    finalobject
    #> cff-version: 1.2.0
    #> message: If you use this software, please cite it using these metadata.
    #> title: Modifying a 'cff' object
    #> version: 0.0.1
    #> authors:
    #> - family-names: Doe
    #>   given-names: John
    #> - family-names: Sánchez Fernández
    #>   given-names: Gregorio
    #>   email: fake@email2.com
    #>   alias: Chiquito de la Calzada
    #>   city: Malaga
    #>   country: ES
    #>   orcid: https://orcid.org/0000-0000-0000-0001
    #> preferred-citation:
    #>   type: manual
    #>   title: My Research Software
    #>   authors:
    #>   - family-names: Doe
    #>     given-names: John
    #>   year: '2022'
    #> repository: https://github.com/user/repo
    #> url: https://ropensci.org/
    #> references:
    #> - type: manual
    #>   title: 'R: A Language and Environment for Statistical Computing'
    #>   authors:
    #>   - name: R Core Team
    #>   location:
    #>     name: Vienna, Austria
    #>   year: '2021'
    #>   url: https://www.R-project.org/
    #>   institution:
    #>     name: R Foundation for Statistical Computing
    #> - type: book
    #>   title: This is a book
    #>   authors:
    #>   - family-names: Lee
    #>     given-names: Lisa
    #>   year: '1980'
    #>   publisher:
    #>     name: McGraw Hill
    #>   volume: '2'

    cff_validate(finalobject)
    #>
    #> cff_validate results-----
    #> Congratulations! This cff object is valid

### Create your modified `CITATION.cff` file

The results can be written with `cff_write()`:

    # For example
    tmp <- tempfile(fileext = ".cff")

    see_res <- cff_write(finalobject, outfile = tmp)
    #> C:\Users\diego\AppData\Local\Temp\Rtmp2hb9MO\file60a422db677a.cff generated
    #>
    #> cff_validate results-----
    #> Congratulations! This .cff file is valid

    see_res
    #> cff-version: 1.2.0
    #> message: If you use this software, please cite it using these metadata.
    #> title: Modifying a 'cff' object
    #> version: 0.0.1
    #> authors:
    #> - family-names: Doe
    #>   given-names: John
    #> - family-names: Sánchez Fernández
    #>   given-names: Gregorio
    #>   email: fake@email2.com
    #>   alias: Chiquito de la Calzada
    #>   city: Malaga
    #>   country: ES
    #>   orcid: https://orcid.org/0000-0000-0000-0001
    #> preferred-citation:
    #>   type: manual
    #>   title: My Research Software
    #>   authors:
    #>   - family-names: Doe
    #>     given-names: John
    #>   year: '2022'
    #> repository: https://github.com/user/repo
    #> url: https://ropensci.org/
    #> references:
    #> - type: manual
    #>   title: 'R: A Language and Environment for Statistical Computing'
    #>   authors:
    #>   - name: R Core Team
    #>   location:
    #>     name: Vienna, Austria
    #>   year: '2021'
    #>   url: https://www.R-project.org/
    #>   institution:
    #>     name: R Foundation for Statistical Computing
    #> - type: book
    #>   title: This is a book
    #>   authors:
    #>   - family-names: Lee
    #>     given-names: Lisa
    #>   year: '1980'
    #>   publisher:
    #>     name: McGraw Hill
    #>   volume: '2'

And finally we can read our created `CITATION.cff` file using `cff()`:

    reading <- cff(tmp)

    reading
    #> cff-version: 1.2.0
    #> message: If you use this software, please cite it using these metadata.
    #> title: Modifying a 'cff' object
    #> version: 0.0.1
    #> authors:
    #> - family-names: Doe
    #>   given-names: John
    #> - family-names: Sánchez Fernández
    #>   given-names: Gregorio
    #>   email: fake@email2.com
    #>   alias: Chiquito de la Calzada
    #>   city: Malaga
    #>   country: ES
    #>   orcid: https://orcid.org/0000-0000-0000-0001
    #> preferred-citation:
    #>   type: manual
    #>   title: My Research Software
    #>   authors:
    #>   - family-names: Doe
    #>     given-names: John
    #>   year: '2022'
    #> repository: https://github.com/user/repo
    #> url: https://ropensci.org/
    #> references:
    #> - type: manual
    #>   title: 'R: A Language and Environment for Statistical Computing'
    #>   authors:
    #>   - name: R Core Team
    #>   location:
    #>     name: Vienna, Austria
    #>   year: '2021'
    #>   url: https://www.R-project.org/
    #>   institution:
    #>     name: R Foundation for Statistical Computing
    #> - type: book
    #>   title: This is a book
    #>   authors:
    #>   - family-names: Lee
    #>     given-names: Lisa
    #>   year: '1980'
    #>   publisher:
    #>     name: McGraw Hill
    #>   volume: '2'

Note that `cff_write()` also has the `keys` param, so the workflow can be simplified as:

    allkeys <- list(
      "url" = "https://ropensci.org/",
      "version" = "0.0.1",
      "repository" = "https://github.com/user/repo",
      # If the field is already present, it would be overridden
      title = "Modifying a 'cff' object",
      authors = newauthors,
      references = c(list(base_r), list(bookparsed))
    )

    tmp2 <- tempfile(fileext = ".cff")

    res <- cff_write(cff(), outfile = tmp2, keys = allkeys)
    #> C:\Users\diego\AppData\Local\Temp\Rtmp2hb9MO\file60a42e542b6f.cff generated
    #>
    #> cff_validate results-----
    #> Congratulations! This .cff file is valid

    res
    #> cff-version: 1.2.0
    #> message: If you use this software, please cite it using these metadata.
    #> title: Modifying a 'cff' object
    #> version: 0.0.1
    #> authors:
    #> - family-names: Doe
    #>   given-names: John
    #> - family-names: Sánchez Fernández
    #>   given-names: Gregorio
    #>   email: fake@email2.com
    #>   alias: Chiquito de la Calzada
    #>   city: Malaga
    #>   country: ES
    #>   orcid: https://orcid.org/0000-0000-0000-0001
    #> preferred-citation:
    #>   type: manual
    #>   title: My Research Software
    #>   authors:
    #>   - family-names: Doe
    #>     given-names: John
    #>   year: '2022'
    #> repository: https://github.com/user/repo
    #> url: https://ropensci.org/
    #> references:
    #> - type: manual
    #>   title: 'R: A Language and Environment for Statistical Computing'
    #>   authors:
    #>   - name: R Core Team
    #>   location:
    #>     name: Vienna, Austria
    #>   year: '2021'
    #>   url: https://www.R-project.org/
    #>   institution:
    #>     name: R Foundation for Statistical Computing
    #> - type: book
    #>   title: This is a book
    #>   authors:
    #>   - family-names: Lee
    #>     given-names: Lisa
    #>   year: '1980'
    #>   publisher:
    #>     name: McGraw Hill
    #>   volume: '2'

## References

Druskat, Stephan. 2021. “Making Software Citation Easi(er) - The Citation File Format and Its Integrations.” https://doi.org/10.5281/zenodo.5529914.
Druskat, Stephan, Jurriaan H. Spaaks, Neil Chue Hong, Robert Haines, James Baker, Spencer Bliven, Egon Willighagen, David Pérez-Suárez, and Alexander Konovalov. 2021. “Citation File Format.” https://doi.org/10.5281/zenodo.5171937.