---
title: "Manipulating citations with cffr"
description: Learn how to modify `cff` objects.
toc: true
bibliography: REFERENCES.bib
link-citations: true
vignette: >
  %\VignetteIndexEntry{Manipulating citations with cffr}
  %\VignetteEngine{quarto::html}
  %\VignetteEncoding{UTF-8}
knitr:
  opts_chunk:
    collapse: true
    comment: "#>"
    warning: false
    message: true
---

```{r}
#| include: false
library(cffr)
```

**cffr** is designed for **R** package developers. Its main goal is to create a
`CITATION.cff` file using metadata from the following files:

- Your `DESCRIPTION` file.
- Your `inst/CITATION` file, when available.

## What is a `CITATION.cff` file?

A `CITATION.cff` file follows the [Citation File Format
(CFF)](https://citation-file-format.github.io/) [@druskat_citation_2021]
(v1.2.0). It contains human- and machine-readable citation metadata for software
and datasets. Developers can include it in a repository to explain how to cite
their software.

This format is increasingly used in the software citation ecosystem.
[**GitHub**](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-citation-files),
[**Zenodo**](https://citation-file-format.github.io/#/supported-by-zenodo-) and
[**Zotero**](https://citation-file-format.github.io/#/supported-by-zotero-) support
this citation format [@druskat_stephan_making_2021].

**GitHub** support is of special interest:

<figure>

![GitHub citation support announcement](tweet-1.png){.quarto-figure
.quarto-figure-center fig-align="center" width="400"}

```{=html}
<figcaption class="blockquote-footer">Nat Friedman (@natfriedman) July 27, 2021</figcaption>
</figure>
```

See [**GitHub**'s guide to CITATION
files](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-citation-files)
for more information.

## Creating a `CITATION.cff` file for your R package

Creating a `CITATION.cff` file with **cffr** is straightforward. You only need
to run `cff_write()`:

```{r}
#| label: setup
#| eval: false
library(cffr)

cff_write()

# Done.
```

Under the hood, `cff_write()` performs these tasks:

- Extracts the metadata using `cff_create()`.
- Optionally modifies it with `cff_modify()`.
- Writes a `CITATION.cff` file.
- Validates the result using `cff_validate()`.

You now have a complete `CITATION.cff` file for your **R** package.

## Modifying your `CITATION.cff` file

You can customize a `cff` object using `cff_modify()`, the package's coercion
methods and the `keys` argument.

For demonstration, we create a `cff` object using `cff()` and then add or modify
its contents.

### Adding new keys

```{r}
#| label: newfields
newobject <- cff()

newobject
```

You can display the valid keys from the [Citation File Format schema version
1.2.0](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md)
with `cff_schema_keys()`:

```{r}
#| label: validkeys
cff_schema_keys()
```

In this case, we add `url`, `version` and `repository`. We also overwrite the
`title` key by passing these arguments to `cff_modify()`:

```{r}
#| label: modify
modobject <- cff_modify(
  newobject,
  url = "https://ropensci.org/",
  version = "0.0.1",
  repository = "https://github.com/ropensci/cffr",
  # If the key is already present, it is overridden.
  title = "Modifying a 'cff' object"
)

modobject

# Validate against the schema.

cff_validate(modobject)
```

### Persons and references

`as_cff_person()` converts `person` objects and `as_cff()` converts `bibentry`
objects to metadata that follows the [Citation File Format
schema](https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md).

Following the previous example, we first add a new author. To do that, we need
to extract the current package authors and append the converted person:

```{r}
#| label: includeauthor
# Valid person keys.

cff_schema_definitions_person()

# 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

# Convert to `cff`.
chiquito_cff <- as_cff_person(chiquito)
chiquito_cff

# Append to previous authors.

newauthors <- c(modobject$authors, chiquito_cff)
newauthors

newauthorobject <- cff_modify(modobject, authors = newauthors)

newauthorobject

cff_validate(newauthorobject)
```

Next, we add `references` to the `cff` object. This example adds two references,
one created with `bibentry()` and another with `citation()`:

```{r}
#| label: parsingcits
# Valid reference keys.

cff_schema_definitions_refs()

# Automatic coercion from another **R** package.
base_r <- citation("base")

bib <- bibentry(
  "Book",
  title = "This is a book",
  author = "Lisa Lee",
  year = 1980,
  publisher = "McGraw Hill",
  volume = 2
)

refs <- c(base_r, bib)

refs

# Convert to `cff`.

refs_cff <- as_cff(refs)

refs_cff
```

As with the `person` example, we modify the `cff` object:

```{r}
#| label: references
finalobject <- cff_modify(newauthorobject, references = refs_cff)

finalobject

cff_validate(finalobject)
```

### Write the modified `CITATION.cff` file

The result can be written with `cff_write()`:

```{r}
#| label: write
# Create a temporary output file.
tmp <- tempfile(fileext = ".cff")

see_res <- cff_write(finalobject, outfile = tmp)

cat(readLines(tmp), sep = "\n")
```

Finally, we can read the created `CITATION.cff` file using `cff_read()`:

```{r}
#| label: read
reading <- cff_read(tmp)

reading
```

Note that `cff_write()` also has the `keys` argument, so the workflow can be
simplified to:

```{r}
allkeys <- list(
  "url" = "https://ropensci.org/",
  "version" = "0.0.1",
  "repository" = "https://github.com/ropensci/cffr",
  # If the key is already present, it is overridden.
  title = "Modifying a 'cff' object",
  authors = newauthors,
  references = refs_cff
)

tmp2 <- tempfile(fileext = ".cff")

res <- cff_write(cff(), outfile = tmp2, keys = allkeys)

res
```

```{r}
#| include: false
# Clean temporary files.
unlink(tmp)
unlink(tmp2)
```

## References
