# Introduction to plume

The goal of the plume package is to make the handling and formatting of author data for scientific writing in R Markdown and Quarto easy and painless.

## Example data

We’ll use the data sets `encyclopedists` and `encyclopedists_fr` to explore the different functionalities of the package. These data sets contain information on four famous authors of the “Encyclopédie”, published in France in the 18th century. `encyclopedists_fr` is the French translation of `encyclopedists` and will be used to illustrate how to handle custom variable names. Both data sets are documented in `?encyclopedists`.

    encyclopedists
    #> # A tibble: 4 × 10
    #>   given_name     family_name        email  phone orcid supervision writing note
    #>   <chr>          <chr>              <chr>  <chr> <chr>       <dbl>   <dbl> <chr>
    #> 1 Denis          Diderot            dider… +1234 0000…           1       1 born…
    #> 2 Jean-Jacques   Rousseau           rouss… <NA>  0000…          NA       1 <NA>
    #> 3 François-Marie Arouet             aroue… <NA>  <NA>           NA       1 also…
    #> 4 Jean           Le Rond d'Alembert alemb… <NA>  0000…           1       1 born…
    #> # ℹ 2 more variables: affiliation_1 <chr>, affiliation_2 <chr>

## Creating a `plume` object

plume provides two R6 classes, namely `Plume` and `PlumeQuarto`. To create a `plume` object, simply write the name of the class you want to use followed by the `new()` method. plume classes take a data frame or tibble as input data. The input data must have at least two columns, one for given names and another for family names.

    Plume$new(encyclopedists)
    #> # A tibble: 4 × 11
    #>      id given_name     family_name literal_name initials email phone orcid note
    #>   <int> <chr>          <chr>       <chr>        <chr>    <chr> <chr> <chr> <chr>
    #> 1     1 Denis          Diderot     Denis Dider… DD       dide… +1234 0000… born…
    #> 2     2 Jean-Jacques   Rousseau    Jean-Jacque… J-JR     rous… <NA>  0000… <NA>
    #> 3     3 François-Marie Arouet      François-Ma… F-MA     arou… <NA>  <NA>  also…
    #> 4     4 Jean           Le Rond d'… Jean Le Ron… JLRd'A   alem… <NA>  0000… born…
    #> # ℹ 2 more variables: affiliation <list>, role <list>

## Available names

The default variables handled by plume classes are organised into six categories:

Primaries: variables required to create a `plume` object.

Name | Plume | PlumeQuarto
--- | --- | ---
given_name |  |
family_name |  |

Secondaries: optional variables that can be provided in the input data.

Name | Plume | PlumeQuarto
--- | --- | ---
email |  |
phone |  |
fax |  |
url |  |
number |  |
dropping_particle |  |
acknowledgements |  |

Nestables: optional variables that can be provided in the input data to pass multiple independent values to authors. Nestable variables must start with the same prefix. E.g. `affiliation_1`, `affiliation_2`, …, `affiliation_n` to pass several affiliations to authors.

Name | Plume | PlumeQuarto
--- | --- | ---
affiliation |  |
role |  |
note |  |

Constants: optional names that can be provided in the input data. These names are standardised and must be provided as is.

Name | Plume | PlumeQuarto
--- | --- | ---
orcid |  |
conceptualization |  |
data_curation |  |
analysis |  |
funding |  |
investigation |  |
methodology |  |
administration |  |
resources |  |
software |  |
supervision |  |
validation |  |
visualization |  |
writing |  |
editing |  |

Internals: variables created internally. These variables don’t need to be provided in the input data and are ignored if supplied. You shouldn’t worry much about these variables unless you want to customise names or extend plume classes with new default names.

Name | Plume | PlumeQuarto
--- | --- | ---
id |  |
initials |  |
literal_name |  |
corresponding |  |
contributor_rank |  |
deceased |  |
equal_contributor |  |

Meta: `PlumeQuarto`-specific variables used to pass extra information that doesn’t fit in other categories. Meta columns must start with the prefix `meta-` and are followed by a custom name (e.g. `meta-custom_name`). You should only use these variables to pass data that are template specific. See Quarto’s arbitrary-metadata section for details.

## Using custom names

plume lets you use custom variable names. Simply provide the `names` parameter a named vector when instantiating a plume class, where keys are default names and values their respective replacements.

    Plume$new(
      encyclopedists_fr,
      names = c(
        given_name = "prénom",
        family_name = "nom",
        literal_name = "nom_complet",
        email = "courriel",
        initials = "initiales"
      )
    )
    #> # A tibble: 4 × 10
    #>      id prénom         nom      nom_complet initiales courriel orcid role  note
    #>   <int> <chr>          <chr>    <chr>       <chr>     <chr>    <chr> <chr> <chr>
    #> 1     1 Denis          Diderot  Denis Dide… DD        diderot… 0000… Supe… né e…
    #> 2     2 Jean-Jacques   Rousseau Jean-Jacqu… J-JR      roussea… 0000… <NA>  <NA>
    #> 3     3 François-Marie Arouet   François-M… F-MA      arouet@… <NA>  <NA>  dit …
    #> 4     4 Jean           Le Rond… Jean Le Ro… JLRd'A    alember… 0000… Supe… né e…
    #> # ℹ 1 more variable: affiliation <list>

## Defining roles and contributors

You can add roles by creating specific role columns in the input data and indicate contributors using `1`:

    #> # A tibble: 4 × 4
    #>   given_name     family_name        supervision writing
    #>   <chr>          <chr>                    <dbl>   <dbl>
    #> 1 Denis          Diderot                      1       1
    #> 2 Jean-Jacques   Rousseau                    NA       1
    #> 3 François-Marie Arouet                      NA       1
    #> 4 Jean           Le Rond d'Alembert           1       1

plume uses the Contributor Roles Taxonomy (CRediT) by default (assuming the input data contains the appropriate columns). You can specify your own roles via the `roles` parameter when creating a `plume` object. The `roles` parameter takes a vector of key-value pairs where keys identify role columns and values define the actual roles to use.

    Plume$new(data, roles = c(
      supervision = "supervised the project",
      writing = "contributed to the writing"
    ))

## Assigning status to authors

plume provides 4 methods to set particular status to authors:

Name | Plume | PlumeQuarto
--- | --- | ---
set_corresponding_authors() |  |
set_main_contributors() |  |
set_cofirst_authors() |  |
set_deceased() |  |

By default, `set_*()` methods assign values by authors’ id. You can change this behaviour at the object or method level using the `by`/`.by` parameters.

Note that these methods are case insensitive.

    aut <- Plume$new(dplyr::select(encyclopedists, given_name, family_name))

    aut$set_corresponding_authors(dd, "j-jr", .by = "initials")
    aut
    #> # A tibble: 4 × 6
    #>      id given_name     family_name        literal_name    initials corresponding
    #>   <int> <chr>          <chr>              <chr>           <chr>    <lgl>
    #> 1     1 Denis          Diderot            Denis Diderot   DD       TRUE
    #> 2     2 Jean-Jacques   Rousseau           Jean-Jacques R… J-JR     TRUE
    #> 3     3 François-Marie Arouet             François-Marie… F-MA     FALSE
    #> 4     4 Jean           Le Rond d'Alembert Jean Le Rond d… JLRd'A   FALSE

Use `everyone()` to assign `TRUE` to all authors:

    aut$set_corresponding_authors(everyone())
    aut
    #> # A tibble: 4 × 6
    #>      id given_name     family_name        literal_name    initials corresponding
    #>   <int> <chr>          <chr>              <chr>           <chr>    <lgl>
    #> 1     1 Denis          Diderot            Denis Diderot   DD       TRUE
    #> 2     2 Jean-Jacques   Rousseau           Jean-Jacques R… J-JR     TRUE
    #> 3     3 François-Marie Arouet             François-Marie… F-MA     TRUE
    #> 4     4 Jean           Le Rond d'Alembert Jean Le Rond d… JLRd'A   TRUE

## Pushing data into YAML headers

`PlumeQuarto` allows you to inject author metadata directly into the YAML header of `.qmd` files.

Consider the following Quarto document:

    ---
    title: Encyclopédie
    ---

    Qui scribit bis legit

You can push information from the input data into the YAML header using the `to_yaml()` method:

    aut <- PlumeQuarto$new(
      dplyr::slice(encyclopedists, 1, 4),
      file = "file.qmd"
    )
    aut$to_yaml()

    ---
    title: Encyclopédie
    author:
      - id: aut1
        name:
          given: Denis
          family: Diderot
        email: diderot@encyclopediste.fr
        phone: '+1234'
        orcid: 0000-0000-0000-0001
        note: born in 1713 in Langres
        roles:
          - supervision
          - writing - original draft
        affiliations:
          - ref: aff1
      - id: aut2
        name:
          given: Jean
          family: Le Rond d'Alembert
        email: alembert@encyclopediste.fr
        orcid: 0000-0000-0000-0003
        note: born in 1717 in Paris
        roles:
          - supervision
          - writing - original draft
        affiliations:
          - ref: aff1
          - ref: aff2
    affiliations:
      - id: aff1
        name: Université de Paris
      - id: aff2
        name: Collège des Quatre-Nations
    ---

    Qui scribit bis legit

Authors are listed in the order they’re defined in the input data.

If the YAML header already has an `author` and `affiliations` keys, `to_yaml()` replaces old values with new ones.

    aut <- PlumeQuarto$new(
      dplyr::slice(encyclopedists, 2),
      file = "file.qmd"
    )
    aut$to_yaml()

    ---
    title: Encyclopédie
    author:
      - name:
          given: Jean-Jacques
          family: Rousseau
        email: rousseau@encyclopediste.fr
        orcid: 0000-0000-0000-0002
        roles:
          - writing - original draft
        affiliations:
          - ref: aff1
    affiliations:
      - id: aff1
        name: Lycée Louis-le-Grand
    ---

    Qui scribit bis legit

## Getting author information

`get_*()` methods (available through the `Plume` class) format author information as character vectors. This is useful if you want to output author data in a document without using journal templates.

### Author lists

`get_author_list()` generates author lists. You can control the formatting of author suffixes (symbols linking authors to affiliations, notes and other metadata) using the `suffix` parameter. `suffix` takes a character string as argument and allows you to choose which symbol categories to suffix authors with, using the following keys:

- `a` for affiliations

- `c` for corresponding authors

- `n` for notes

- `o` for ORCIDs

The order of the keys determines the order of symbol categories.

    aut <- Plume$new(encyclopedists)
    aut$set_corresponding_authors(everyone())

    aut$get_author_list(suffix = "ac")
    #> Denis Diderot1\*
    #> Jean-Jacques Rousseau2\*
    #> François-Marie Arouet2\*
    #> Jean Le Rond d'Alembert1,3\*

    aut$get_author_list(suffix = "ca")
    #> Denis Diderot\*1
    #> Jean-Jacques Rousseau\*2
    #> François-Marie Arouet\*2
    #> Jean Le Rond d'Alembert\*1,3

In addition, you can use `^` to superscript and `,` to separate symbols:

    aut$set_corresponding_authors(1, 4)

    aut$get_author_list("^a,^cn")
    #> Denis Diderot^1,^\*†
    #> Jean-Jacques Rousseau^2^
    #> François-Marie Arouet^2^‡
    #> Jean Le Rond d'Alembert^1,3,^\*§

Use `suffix = NULL` or `suffix = ""` to ignore suffixes:

    aut$get_author_list(suffix = NULL)
    #> Denis Diderot
    #> Jean-Jacques Rousseau
    #> François-Marie Arouet
    #> Jean Le Rond d'Alembert

### Affiliations & notes

`get_affiliations()` and `get_notes()` return authors’ affiliations and notes.

    aut$get_affiliations()
    #> ^1^Université de Paris
    #> ^2^Lycée Louis-le-Grand
    #> ^3^Collège des Quatre-Nations

    aut$get_notes(sep = ": ", superscript = FALSE)
    #> †: born in 1713 in Langres
    #> ‡: also known as Voltaire
    #> §: born in 1717 in Paris

### ORCIDs

`get_orcids()` returns authors with their respective ORCID.

    aut$get_orcids(icon = FALSE, sep = " ")
    #> Denis Diderot <https://orcid.org/0000-0000-0000-0001>
    #> Jean-Jacques Rousseau <https://orcid.org/0000-0000-0000-0002>
    #> Jean Le Rond d'Alembert <https://orcid.org/0000-0000-0000-0003>

### Contact details

You can get contact details of corresponding authors using the `get_contact_details()` method:

    aut$get_contact_details()
    #> diderot@encyclopediste.fr (Denis Diderot)
    #> alembert@encyclopediste.fr (Jean Le Rond d'Alembert)

    aut$get_contact_details(phone = TRUE)
    #> diderot@encyclopediste.fr, +1234 (Denis Diderot)
    #> alembert@encyclopediste.fr (Jean Le Rond d'Alembert)

    aut$get_contact_details(format = "{name}: {details}")
    #> Denis Diderot: diderot@encyclopediste.fr
    #> Jean Le Rond d'Alembert: alembert@encyclopediste.fr

### Contributions

plume provides a convenient way to generate contribution lists using the `get_contributions()` method.

    aut$get_contributions()
    #> Supervision: D.D. and J.L.R.d'A.
    #> Writing - original draft: D.D., J.-J.R., F.-M.A. and J.L.R.d'A.

    aut$get_contributions(
      roles_first = FALSE,
      by_author = TRUE,
      literal_names = TRUE
    )
    #> Denis Diderot: Supervision and Writing - original draft
    #> Jean-Jacques Rousseau: Writing - original draft
    #> François-Marie Arouet: Writing - original draft
    #> Jean Le Rond d'Alembert: Supervision and Writing - original draft

    aut2 <- Plume$new(encyclopedists, roles = c(
      supervision = "supervised the project",
      writing = "contributed to the Encyclopédie"
    ))
    aut2$get_contributions(roles_first = FALSE, divider = " ")
    #> D.D. and J.L.R.d'A. supervised the project
    #> D.D., J.-J.R., F.-M.A. and J.L.R.d'A. contributed to the Encyclopédie

By default, `get_contributions()` lists contributors in the order they’re defined. You can arrange contributors in alphabetical order with `alphabetical_order = TRUE`:

    aut$get_contributions(alphabetical_order = TRUE)
    #> Supervision: D.D. and J.L.R.d'A.
    #> Writing - original draft: D.D., F.-M.A., J.-J.R. and J.L.R.d'A.

It’s possible to force one or more contributors to appear first in any given role by setting main contributors:

    aut$set_main_contributors(supervision = 4, writing = c(3, 2))
    aut$get_contributions()
    #> Supervision: J.L.R.d'A. and D.D.
    #> Writing - original draft: F.-M.A., J.-J.R., D.D. and J.L.R.d'A.

You can assign the same main contributors across multiple roles using the `.roles` parameter. E.g. to set a main contributor across all roles:

    aut$set_main_contributors(jean, .roles = aut$get_roles(), .by = "given_name")
    aut$get_contributions()
    #> Supervision: J.L.R.d'A. and D.D.
    #> Writing - original draft: J.L.R.d'A., D.D., J.-J.R. and F.-M.A.

Note that main contributors have the priority over the alphabetical ordering:

    aut$get_contributions(alphabetical_order = TRUE)
    #> Supervision: J.L.R.d'A. and D.D.
    #> Writing - original draft: J.L.R.d'A., D.D., F.-M.A. and J.-J.R.

The `.roles` parameter only applies to unnamed expressions. This allows you to set the same main contributors across all but a few specific roles at once.

    aut$set_main_contributors(4, 3, supervision = 1, .roles = aut$get_roles())

Here, authors 4 and 3 are the main contributors in all roles but `supervision`, where author 1 is the main contributor.

## Symbols

Default symbols are:

    #> List of 3
    #>  $ affiliation  : NULL
    #>  $ corresponding: chr "\\*"
    #>  $ note         : chr [1:6] "†" "‡" "§" "¶" "#" "\\*\\*"

You can change symbols when creating a `plume` object using the parameter `symbols`.

Use `NULL` to display numbers:

    aut <- Plume$new(
      encyclopedists,
      symbols = list(affiliation = letters, note = NULL)
    )

    aut$get_author_list("^a,n^")
    #> Denis Diderot^a,1^
    #> Jean-Jacques Rousseau^b^
    #> François-Marie Arouet^b,2^
    #> Jean Le Rond d'Alembert^a,c,3^

Use `NULL` as much as possible for symbols using numerous unique items (typically affiliations). If you have to use letters for a given category that has more unique items than letters, you can control the sequencing behaviour using the `sequential()` modifier, as shown below:

    Plume$new(
      encyclopedists,
      symbols = list(affiliation = sequential(letters))
    )

By default, plume repeats elements when all elements in a vector are consumed. Using `sequential()` allows you to display a logical sequence of characters (e.g. `a, b, c, ..., z, aa, ab, ac, ..., az, ba, bb, bc, ...`).

## Outputting as markdown content

To output author data as markdown content, use the chunk option `results: asis` in combination with `cat()`:

    ```{r}
    #| results: asis
    aut$get_contributions() |> cat(sep = "; ")
    ```

Inline chunks output values “as is” by default and can be used as follows:

``r aut$get_author_list()``