75 | ```
76 |
77 | `PlumeQuarto` lets you push author metadata in YAML files or the YAML
78 | header of any `.qmd` file using the `to_yaml()` method.
79 |
80 | Consider the following example:
81 |
82 | ---
83 | title: Encyclopédie
84 | ---
85 |
86 | Qui scribit bis legit
87 |
88 | ``` r
89 | aut <- PlumeQuarto$new(
90 | encyclopedists,
91 | file = "file.qmd"
92 | )
93 | aut$set_corresponding_authors(1, 4)
94 | aut$to_yaml()
95 | ```
96 |
97 | ---
98 | title: Encyclopédie
99 | author:
100 | - id: aut1
101 | name:
102 | given: Denis
103 | family: Diderot
104 | email: diderot@encyclopediste.fr
105 | phone: '+1234'
106 | orcid: 0000-0000-0000-0001
107 | note: born in 1713 in Langres
108 | attributes:
109 | corresponding: true
110 | roles:
111 | - Supervision
112 | - Writing - original draft
113 | affiliations:
114 | - ref: aff1
115 | - id: aut2
116 | name:
117 | given: Jean-Jacques
118 | family: Rousseau
119 | email: rousseau@encyclopediste.fr
120 | orcid: 0000-0000-0000-0002
121 | attributes:
122 | corresponding: false
123 | roles:
124 | - Writing - original draft
125 | affiliations:
126 | - ref: aff2
127 | - id: aut3
128 | name:
129 | given: François-Marie
130 | family: Arouet
131 | email: arouet@encyclopediste.fr
132 | note: also known as Voltaire
133 | attributes:
134 | corresponding: false
135 | roles:
136 | - Writing - original draft
137 | affiliations:
138 | - ref: aff2
139 | - id: aut4
140 | name:
141 | given: Jean
142 | family: Le Rond d'Alembert
143 | email: alembert@encyclopediste.fr
144 | orcid: 0000-0000-0000-0003
145 | note: born in 1717 in Paris
146 | attributes:
147 | corresponding: true
148 | roles:
149 | - Supervision
150 | - Writing - original draft
151 | affiliations:
152 | - ref: aff1
153 | - ref: aff3
154 | affiliations:
155 | - id: aff1
156 | name: Université de Paris
157 | - id: aff2
158 | name: Lycée Louis-le-Grand
159 | - id: aff3
160 | name: Collège des Quatre-Nations
161 | ---
162 |
163 | Qui scribit bis legit
164 |
165 | Alternatively, you can generate author information as character strings
166 | using `Plume`:
167 |
168 | ``` r
169 | aut <- Plume$new(encyclopedists)
170 | aut$set_corresponding_authors(diderot, .by = "family_name")
171 |
172 | aut$get_author_list(suffix = "^a,^cn")
173 | #> Denis Diderot^1,^\*†
174 | #> Jean-Jacques Rousseau^2^
175 | #> François-Marie Arouet^2^‡
176 | #> Jean Le Rond d'Alembert^1,3^§
177 |
178 | aut$get_contact_details()
179 | #> diderot@encyclopediste.fr (Denis Diderot)
180 |
181 | aut$get_affiliations()
182 | #> ^1^Université de Paris
183 | #> ^2^Lycée Louis-le-Grand
184 | #> ^3^Collège des Quatre-Nations
185 |
186 | aut$get_notes()
187 | #> ^†^born in 1713 in Langres
188 | #> ^‡^also known as Voltaire
189 | #> ^§^born in 1717 in Paris
190 |
191 | aut$get_contributions()
192 | #> Supervision: D.D. and J.L.R.d'A.
193 | #> Writing - original draft: D.D., J.-J.R., F.-M.A. and J.L.R.d'A.
194 |
195 | aut2 <- Plume$new(
196 | encyclopedists,
197 | roles = c(
198 | supervision = "supervised the project",
199 | writing = "contributed to the Encyclopédie"
200 | ),
201 | symbols = list(affiliation = letters)
202 | )
203 |
204 | aut2$get_author_list("^a^")
205 | #> Denis Diderot^a^
206 | #> Jean-Jacques Rousseau^b^
207 | #> François-Marie Arouet^b^
208 | #> Jean Le Rond d'Alembert^a,c^
209 |
210 | aut2$get_contributions(roles_first = FALSE, divider = " ")
211 | #> D.D. and J.L.R.d'A. supervised the project
212 | #> D.D., J.-J.R., F.-M.A. and J.L.R.d'A. contributed to the Encyclopédie
213 | ```
214 |
215 | ## Acknowledgements
216 |
217 | Thanks to:
218 |
219 | - [Richard J. Telford](https://github.com/richardjtelford) for his
220 | advice that helped me conceive this package.
221 |
222 | - [Maëlle Salmon](https://github.com/maelle) and [Gábor
223 | Csárdi](https://github.com/gaborcsardi) for their help when I was
224 | stuck with unit tests, roxygen2 or pkgdown.
225 |
--------------------------------------------------------------------------------
/_pkgdown.yml:
--------------------------------------------------------------------------------
1 | url: https://arnaudgallou.github.io/plume/
2 | template:
3 | bootstrap: 5
4 | package: cygne
5 | includes:
6 | after_body: >
7 |
9 | reference:
10 | - title: Classes
11 | contents:
12 | - PlumeQuarto
13 | - Plume
14 | - title: Helpers
15 | contents:
16 | - as_lines
17 | - credit_roles
18 | - enumerate
19 | - everyone
20 | - icn_orcid
21 | - plm_template
22 | - sequential
23 | - set_default_names
24 | - title: Built-in datasets
25 | contents:
26 | - encyclopedists
27 | - encyclopedists_fr
28 | articles:
29 | - title: Get started
30 | navbar: ~
31 | contents:
32 | - plume
33 | - plume-workflow
34 | - working-in-other-languages
35 | - comprehensive-affiliation-schema
36 | development:
37 | mode: auto
38 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | comment: false
2 |
3 | coverage:
4 | status:
5 | project:
6 | default:
7 | target: auto
8 | threshold: 1%
9 | informational: true
10 | patch:
11 | default:
12 | target: auto
13 | threshold: 1%
14 | informational: true
15 |
--------------------------------------------------------------------------------
/cran-comments.md:
--------------------------------------------------------------------------------
1 | ## R CMD check results
2 |
3 | 0 errors | 0 warnings | 0 notes
4 |
--------------------------------------------------------------------------------
/data-raw/encyclopedists.R:
--------------------------------------------------------------------------------
1 | make_emails <- function(x) {
2 | out <- gsub(".+\\b(\\w+)$", "\\1", x, perl = TRUE)
3 | out <- tolower(out)
4 | paste0(out, "@encyclopediste.fr")
5 | }
6 |
7 | encyclopedists <- tibble::tibble(
8 | given_name = c("Denis", "Jean-Jacques", "François-Marie", "Jean"),
9 | family_name = c("Diderot", "Rousseau", "Arouet", "Le Rond d'Alembert"),
10 | email = make_emails(family_name),
11 | phone = c("+1234", NA, NA, NA),
12 | orcid = c(paste0("0000-0000-0000-000", 1:2), NA, "0000-0000-0000-0003"),
13 | supervision = c(1, NA, NA, 1),
14 | writing = 1,
15 | note = c(
16 | "born in 1713 in Langres",
17 | NA,
18 | "also known as Voltaire",
19 | "born in 1717 in Paris"
20 | ),
21 | affiliation_1 = c(
22 | "Université de Paris",
23 | rep("Lycée Louis-le-Grand", 2L),
24 | "Université de Paris"
25 | ),
26 | affiliation_2 = c(NA, NA, NA, "Collège des Quatre-Nations"),
27 | )
28 |
29 | encyclopedists_fr <- encyclopedists |>
30 | dplyr::rename(
31 | prénom = given_name,
32 | nom = family_name,
33 | courriel = email,
34 | téléphone = phone,
35 | rédaction = writing
36 | ) |>
37 | dplyr::mutate(note = c(
38 | "né en 1713 à Langres",
39 | NA,
40 | "dit Voltaire",
41 | "né en 1717 à Paris"
42 | ))
43 |
44 | usethis::use_data(encyclopedists, encyclopedists_fr, overwrite = TRUE)
45 |
--------------------------------------------------------------------------------
/data/encyclopedists.rda:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaudgallou/plume/d507781b9cbf12c565e9b88b4b8a636543ff6279/data/encyclopedists.rda
--------------------------------------------------------------------------------
/data/encyclopedists_fr.rda:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaudgallou/plume/d507781b9cbf12c565e9b88b4b8a636543ff6279/data/encyclopedists_fr.rda
--------------------------------------------------------------------------------
/inst/icons/orcid-bw.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaudgallou/plume/d507781b9cbf12c565e9b88b4b8a636543ff6279/inst/icons/orcid-bw.pdf
--------------------------------------------------------------------------------
/inst/icons/orcid-bw.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
11 |
12 |
14 |
16 |
17 |
--------------------------------------------------------------------------------
/inst/icons/orcid.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/arnaudgallou/plume/d507781b9cbf12c565e9b88b4b8a636543ff6279/inst/icons/orcid.pdf
--------------------------------------------------------------------------------
/inst/icons/orcid.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
9 |
10 |
11 |
12 |
14 |
16 |
17 |
--------------------------------------------------------------------------------
/man/PlumeHandler.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/plume-handler.R
3 | \name{PlumeHandler}
4 | \alias{PlumeHandler}
5 | \title{PlumeHandler class}
6 | \description{
7 | Internal class processing and shaping tabular data into a
8 | \code{plume} object.
9 | }
10 | \keyword{internal}
11 | \section{Super class}{
12 | \code{plume::NameHandler} -> \code{PlumeHandler}
13 | }
14 | \section{Methods}{
15 | \subsection{Public methods}{
16 | \itemize{
17 | \item \href{#method-PlumeHandler-new}{\code{PlumeHandler$new()}}
18 | \item \href{#method-PlumeHandler-print}{\code{PlumeHandler$print()}}
19 | \item \href{#method-PlumeHandler-get_plume}{\code{PlumeHandler$get_plume()}}
20 | \item \href{#method-PlumeHandler-get_roles}{\code{PlumeHandler$get_roles()}}
21 | \item \href{#method-PlumeHandler-clone}{\code{PlumeHandler$clone()}}
22 | }
23 | }
24 | \if{html}{\out{ }}
25 | \if{html}{\out{ }}
26 | \if{latex}{\out{\hypertarget{method-PlumeHandler-new}{}}}
27 | \subsection{Method \code{new()}}{
28 | \subsection{Usage}{
29 | \if{html}{\out{}}\preformatted{PlumeHandler$new(
30 | data,
31 | names,
32 | roles,
33 | credit_roles,
34 | initials_given_name,
35 | family_name_first = FALSE,
36 | interword_spacing = TRUE
37 | )}\if{html}{\out{
}}
38 | }
39 |
40 | }
41 | \if{html}{\out{ }}
42 | \if{html}{\out{ }}
43 | \if{latex}{\out{\hypertarget{method-PlumeHandler-print}{}}}
44 | \subsection{Method \code{print()}}{
45 | \subsection{Usage}{
46 | \if{html}{\out{}}\preformatted{PlumeHandler$print()}\if{html}{\out{
}}
47 | }
48 |
49 | }
50 | \if{html}{\out{ }}
51 | \if{html}{\out{ }}
52 | \if{latex}{\out{\hypertarget{method-PlumeHandler-get_plume}{}}}
53 | \subsection{Method \code{get_plume()}}{
54 | \subsection{Usage}{
55 | \if{html}{\out{}}\preformatted{PlumeHandler$get_plume()}\if{html}{\out{
}}
56 | }
57 |
58 | }
59 | \if{html}{\out{ }}
60 | \if{html}{\out{ }}
61 | \if{latex}{\out{\hypertarget{method-PlumeHandler-get_roles}{}}}
62 | \subsection{Method \code{get_roles()}}{
63 | \subsection{Usage}{
64 | \if{html}{\out{}}\preformatted{PlumeHandler$get_roles()}\if{html}{\out{
}}
65 | }
66 |
67 | }
68 | \if{html}{\out{ }}
69 | \if{html}{\out{ }}
70 | \if{latex}{\out{\hypertarget{method-PlumeHandler-clone}{}}}
71 | \subsection{Method \code{clone()}}{
72 | The objects of this class are cloneable with this method.
73 | \subsection{Usage}{
74 | \if{html}{\out{}}\preformatted{PlumeHandler$clone(deep = FALSE)}\if{html}{\out{
}}
75 | }
76 |
77 | \subsection{Arguments}{
78 | \if{html}{\out{}}
79 | \describe{
80 | \item{\code{deep}}{Whether to make a deep clone.}
81 | }
82 | \if{html}{\out{
}}
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/man/PlumeQuarto.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/plume-quarto.R
3 | \name{PlumeQuarto}
4 | \alias{PlumeQuarto}
5 | \title{PlumeQuarto class}
6 | \description{
7 | Class that pushes author metadata in YAML files or the YAML
8 | header of Quarto files.
9 | }
10 | \examples{
11 | # Create a simple temporary file with a YAML header
12 | # containing a title
13 | tmp_file <- tempfile(fileext = ".qmd")
14 | readr::write_lines("---\ntitle: Encyclopédie\n---", tmp_file)
15 |
16 | # View the temporary file
17 | cat(readr::read_file(tmp_file))
18 |
19 | # Create a PlumeQuarto instance using the temporary file
20 | # you've just created
21 | aut <- PlumeQuarto$new(
22 | encyclopedists,
23 | file = tmp_file
24 | )
25 |
26 | # And push author data to the YAML header
27 | aut$to_yaml()
28 |
29 | cat(readr::read_file(tmp_file))
30 |
31 | # Pushing again with new data updates the YAML
32 | # header accordingly
33 | aut <- PlumeQuarto$new(
34 | dplyr::slice(encyclopedists, 2),
35 | file = tmp_file
36 | )
37 | aut$to_yaml()
38 |
39 | cat(readr::read_file(tmp_file))
40 |
41 | # Clean up the temporary file
42 | unlink(tmp_file)
43 | }
44 | \section{Super classes}{
45 | \code{plume::NameHandler} -> \code{\link[plume:PlumeHandler]{plume::PlumeHandler}} -> \code{\link[plume:StatusSetter]{plume::StatusSetter}} -> \code{\link[plume:StatusSetterPlumeQuarto]{plume::StatusSetterPlumeQuarto}} -> \code{PlumeQuarto}
46 | }
47 | \section{Methods}{
48 | \subsection{Public methods}{
49 | \itemize{
50 | \item \href{#method-PlumeQuarto-new}{\code{PlumeQuarto$new()}}
51 | \item \href{#method-PlumeQuarto-to_yaml}{\code{PlumeQuarto$to_yaml()}}
52 | \item \href{#method-PlumeQuarto-clone}{\code{PlumeQuarto$clone()}}
53 | }
54 | }
55 | \if{html}{\out{
56 | Inherited methods
57 |
66 |
67 | }}
68 | \if{html}{\out{ }}
69 | \if{html}{\out{ }}
70 | \if{latex}{\out{\hypertarget{method-PlumeQuarto-new}{}}}
71 | \subsection{Method \code{new()}}{
72 | Create a \code{PlumeQuarto} object.
73 | \subsection{Usage}{
74 | \if{html}{\out{}}\preformatted{PlumeQuarto$new(
75 | data,
76 | file,
77 | names = NULL,
78 | roles = credit_roles(),
79 | credit_roles = FALSE,
80 | initials_given_name = FALSE,
81 | by = NULL
82 | )}\if{html}{\out{
}}
83 | }
84 |
85 | \subsection{Arguments}{
86 | \if{html}{\out{}}
87 | \describe{
88 | \item{\code{data}}{A data frame containing author-related data.}
89 |
90 | \item{\code{file}}{A \code{.qmd}, \code{.yml} or \code{.yaml} file to insert author data into.}
91 |
92 | \item{\code{names}}{A vector of key-value pairs specifying custom names to use,
93 | where keys are default names and values their respective replacements.}
94 |
95 | \item{\code{roles}}{A vector of key-value pairs defining roles where keys
96 | identify columns and values describe the actual roles to use.}
97 |
98 | \item{\code{credit_roles}}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}}
99 |
100 | It is now recommended to use \code{roles = credit_roles()} to use the
101 | \href{https://credit.niso.org}{Contributor Roles Taxonomy}.}
102 |
103 | \item{\code{initials_given_name}}{Should the initials of given names be used?}
104 |
105 | \item{\code{by}}{A character string defining the default variable used to assign
106 | specific metadata to authors in all \verb{set_*()} methods. By default, uses
107 | authors' id.}
108 | }
109 | \if{html}{\out{
}}
110 | }
111 | \subsection{Returns}{
112 | A \code{PlumeQuarto} object.
113 | }
114 | }
115 | \if{html}{\out{ }}
116 | \if{html}{\out{ }}
117 | \if{latex}{\out{\hypertarget{method-PlumeQuarto-to_yaml}{}}}
118 | \subsection{Method \code{to_yaml()}}{
119 | Push or update author information in a YAML file or YAML
120 | header. The generated YAML complies with Quarto's
121 | \href{https://quarto.org/docs/journals/authors.html}{author and affiliations schemas}.
122 | \subsection{Usage}{
123 | \if{html}{\out{}}\preformatted{PlumeQuarto$to_yaml()}\if{html}{\out{
}}
124 | }
125 |
126 | \subsection{Details}{
127 | If missing, \code{to_yaml()} inserts author information into the desired file.
128 | Otherwise, the function replaces old \code{author} and \code{affiliations} values
129 | with the ones provided in the input data.
130 | }
131 |
132 | \subsection{Returns}{
133 | The input \code{file} invisibly.
134 | }
135 | }
136 | \if{html}{\out{ }}
137 | \if{html}{\out{ }}
138 | \if{latex}{\out{\hypertarget{method-PlumeQuarto-clone}{}}}
139 | \subsection{Method \code{clone()}}{
140 | The objects of this class are cloneable with this method.
141 | \subsection{Usage}{
142 | \if{html}{\out{}}\preformatted{PlumeQuarto$clone(deep = FALSE)}\if{html}{\out{
}}
143 | }
144 |
145 | \subsection{Arguments}{
146 | \if{html}{\out{}}
147 | \describe{
148 | \item{\code{deep}}{Whether to make a deep clone.}
149 | }
150 | \if{html}{\out{
}}
151 | }
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/man/StatusSetter.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/status-setter.R
3 | \name{StatusSetter}
4 | \alias{StatusSetter}
5 | \title{StatusSetter class}
6 | \description{
7 | Internal class that manages authors' status.
8 | }
9 | \keyword{internal}
10 | \section{Super classes}{
11 | \code{plume::NameHandler} -> \code{\link[plume:PlumeHandler]{plume::PlumeHandler}} -> \code{StatusSetter}
12 | }
13 | \section{Methods}{
14 | \subsection{Public methods}{
15 | \itemize{
16 | \item \href{#method-StatusSetter-new}{\code{StatusSetter$new()}}
17 | \item \href{#method-StatusSetter-set_corresponding_authors}{\code{StatusSetter$set_corresponding_authors()}}
18 | \item \href{#method-StatusSetter-clone}{\code{StatusSetter$clone()}}
19 | }
20 | }
21 | \if{html}{\out{
22 | Inherited methods
23 |
28 |
29 | }}
30 | \if{html}{\out{ }}
31 | \if{html}{\out{ }}
32 | \if{latex}{\out{\hypertarget{method-StatusSetter-new}{}}}
33 | \subsection{Method \code{new()}}{
34 | \subsection{Usage}{
35 | \if{html}{\out{}}\preformatted{StatusSetter$new(..., by)}\if{html}{\out{
}}
36 | }
37 |
38 | }
39 | \if{html}{\out{ }}
40 | \if{html}{\out{ }}
41 | \if{latex}{\out{\hypertarget{method-StatusSetter-set_corresponding_authors}{}}}
42 | \subsection{Method \code{set_corresponding_authors()}}{
43 | Set corresponding authors.
44 | \subsection{Usage}{
45 | \if{html}{\out{}}\preformatted{StatusSetter$set_corresponding_authors(..., .by = NULL, by = deprecated())}\if{html}{\out{
}}
46 | }
47 |
48 | \subsection{Arguments}{
49 | \if{html}{\out{}}
50 | \describe{
51 | \item{\code{...}}{One or more unquoted expressions separated by commas.
52 | Expressions matching values in the column defined by \code{by}/\code{.by}
53 | determine corresponding authors. Matching of values is case-
54 | insensitive.}
55 |
56 | \item{\code{.by}}{Variable used to set corresponding authors. By default, uses
57 | authors' id.}
58 |
59 | \item{\code{by}}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}}
60 |
61 | Please use the \code{.by} parameter instead.}
62 | }
63 | \if{html}{\out{
}}
64 | }
65 | \subsection{Returns}{
66 | The class instance.
67 | }
68 | }
69 | \if{html}{\out{ }}
70 | \if{html}{\out{ }}
71 | \if{latex}{\out{\hypertarget{method-StatusSetter-clone}{}}}
72 | \subsection{Method \code{clone()}}{
73 | The objects of this class are cloneable with this method.
74 | \subsection{Usage}{
75 | \if{html}{\out{}}\preformatted{StatusSetter$clone(deep = FALSE)}\if{html}{\out{
}}
76 | }
77 |
78 | \subsection{Arguments}{
79 | \if{html}{\out{}}
80 | \describe{
81 | \item{\code{deep}}{Whether to make a deep clone.}
82 | }
83 | \if{html}{\out{
}}
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/man/StatusSetterPlume.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/status-setter.R
3 | \name{StatusSetterPlume}
4 | \alias{StatusSetterPlume}
5 | \title{StatusSetterPlume class}
6 | \description{
7 | Internal class extending \code{StatusSetter} for \code{Plume}.
8 | }
9 | \keyword{internal}
10 | \section{Super classes}{
11 | \code{plume::NameHandler} -> \code{\link[plume:PlumeHandler]{plume::PlumeHandler}} -> \code{\link[plume:StatusSetter]{plume::StatusSetter}} -> \code{StatusSetterPlume}
12 | }
13 | \section{Methods}{
14 | \subsection{Public methods}{
15 | \itemize{
16 | \item \href{#method-StatusSetterPlume-set_main_contributors}{\code{StatusSetterPlume$set_main_contributors()}}
17 | \item \href{#method-StatusSetterPlume-clone}{\code{StatusSetterPlume$clone()}}
18 | }
19 | }
20 | \if{html}{\out{
21 | Inherited methods
22 |
29 |
30 | }}
31 | \if{html}{\out{ }}
32 | \if{html}{\out{ }}
33 | \if{latex}{\out{\hypertarget{method-StatusSetterPlume-set_main_contributors}{}}}
34 | \subsection{Method \code{set_main_contributors()}}{
35 | Force one or more contributors' names to appear first in the
36 | contribution list.
37 | \subsection{Usage}{
38 | \if{html}{\out{}}\preformatted{StatusSetterPlume$set_main_contributors(..., .roles = NULL, .by = NULL)}\if{html}{\out{
}}
39 | }
40 |
41 | \subsection{Arguments}{
42 | \if{html}{\out{}}
43 | \describe{
44 | \item{\code{...}}{One or more unquoted expressions separated by commas.
45 | Expressions matching values in the column defined by \code{by}/\code{.by}
46 | determine main contributors. Expressions can be named after any role to
47 | set different main contributors to different roles at once, in which
48 | case the \code{.roles} parameter only applies roles that are not already set
49 | to unnamed expressions. Matching of values is case-insensitive.}
50 |
51 | \item{\code{.roles}}{Roles to assign main contributors to. If \code{.roles} is a
52 | named vector, only the names will be used.}
53 |
54 | \item{\code{.by}}{Variable used to specify which authors are main contributors.
55 | By default, uses authors' id.}
56 | }
57 | \if{html}{\out{
}}
58 | }
59 | \subsection{Returns}{
60 | The class instance.
61 | }
62 | }
63 | \if{html}{\out{ }}
64 | \if{html}{\out{ }}
65 | \if{latex}{\out{\hypertarget{method-StatusSetterPlume-clone}{}}}
66 | \subsection{Method \code{clone()}}{
67 | The objects of this class are cloneable with this method.
68 | \subsection{Usage}{
69 | \if{html}{\out{}}\preformatted{StatusSetterPlume$clone(deep = FALSE)}\if{html}{\out{
}}
70 | }
71 |
72 | \subsection{Arguments}{
73 | \if{html}{\out{}}
74 | \describe{
75 | \item{\code{deep}}{Whether to make a deep clone.}
76 | }
77 | \if{html}{\out{
}}
78 | }
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/man/StatusSetterPlumeQuarto.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/status-setter.R
3 | \name{StatusSetterPlumeQuarto}
4 | \alias{StatusSetterPlumeQuarto}
5 | \title{StatusSetterPlumeQuarto class}
6 | \description{
7 | Internal class extending \code{StatusSetter} for \code{PlumeQuarto}.
8 | }
9 | \keyword{internal}
10 | \section{Super classes}{
11 | \code{plume::NameHandler} -> \code{\link[plume:PlumeHandler]{plume::PlumeHandler}} -> \code{\link[plume:StatusSetter]{plume::StatusSetter}} -> \code{StatusSetterPlumeQuarto}
12 | }
13 | \section{Methods}{
14 | \subsection{Public methods}{
15 | \itemize{
16 | \item \href{#method-StatusSetterPlumeQuarto-set_cofirst_authors}{\code{StatusSetterPlumeQuarto$set_cofirst_authors()}}
17 | \item \href{#method-StatusSetterPlumeQuarto-set_equal_contributor}{\code{StatusSetterPlumeQuarto$set_equal_contributor()}}
18 | \item \href{#method-StatusSetterPlumeQuarto-set_deceased}{\code{StatusSetterPlumeQuarto$set_deceased()}}
19 | \item \href{#method-StatusSetterPlumeQuarto-clone}{\code{StatusSetterPlumeQuarto$clone()}}
20 | }
21 | }
22 | \if{html}{\out{
23 | Inherited methods
24 |
31 |
32 | }}
33 | \if{html}{\out{ }}
34 | \if{html}{\out{ }}
35 | \if{latex}{\out{\hypertarget{method-StatusSetterPlumeQuarto-set_cofirst_authors}{}}}
36 | \subsection{Method \code{set_cofirst_authors()}}{
37 | Set co-first authors.
38 | \subsection{Usage}{
39 | \if{html}{\out{}}\preformatted{StatusSetterPlumeQuarto$set_cofirst_authors(..., .by = NULL)}\if{html}{\out{
}}
40 | }
41 |
42 | \subsection{Arguments}{
43 | \if{html}{\out{}}
44 | \describe{
45 | \item{\code{...}}{One or more unquoted expressions separated by commas.
46 | Expressions matching values in the column defined by \code{by}/\code{.by}
47 | determine co-first authors. Matching of values is case-insensitive.}
48 |
49 | \item{\code{.by}}{Variable used to specify which authors contributed equally to
50 | the work. By default, uses authors' id.}
51 | }
52 | \if{html}{\out{
}}
53 | }
54 | \subsection{Returns}{
55 | The class instance.
56 | }
57 | }
58 | \if{html}{\out{ }}
59 | \if{html}{\out{ }}
60 | \if{latex}{\out{\hypertarget{method-StatusSetterPlumeQuarto-set_equal_contributor}{}}}
61 | \subsection{Method \code{set_equal_contributor()}}{
62 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}}
63 |
64 | This method has been deprecated in favour of \code{set_cofirst_authors()}.
65 | \subsection{Usage}{
66 | \if{html}{\out{}}\preformatted{StatusSetterPlumeQuarto$set_equal_contributor(
67 | ...,
68 | .by = NULL,
69 | by = deprecated()
70 | )}\if{html}{\out{
}}
71 | }
72 |
73 | \subsection{Arguments}{
74 | \if{html}{\out{}}
75 | \describe{
76 | \item{\code{...}}{One or more unquoted expressions separated by commas.
77 | Expressions matching values in the column defined by \code{by}/\code{.by}
78 | determine equal contributors. Matching of values is case-insensitive.}
79 |
80 | \item{\code{.by}}{Variable used to specify which authors are equal contributors.
81 | By default, uses authors' id.}
82 |
83 | \item{\code{by}}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}}
84 |
85 | Please use the \code{.by} parameter instead.}
86 | }
87 | \if{html}{\out{
}}
88 | }
89 | \subsection{Returns}{
90 | The class instance.
91 | }
92 | }
93 | \if{html}{\out{ }}
94 | \if{html}{\out{ }}
95 | \if{latex}{\out{\hypertarget{method-StatusSetterPlumeQuarto-set_deceased}{}}}
96 | \subsection{Method \code{set_deceased()}}{
97 | Set deceased authors.
98 | \subsection{Usage}{
99 | \if{html}{\out{}}\preformatted{StatusSetterPlumeQuarto$set_deceased(..., .by = NULL, by = deprecated())}\if{html}{\out{
}}
100 | }
101 |
102 | \subsection{Arguments}{
103 | \if{html}{\out{}}
104 | \describe{
105 | \item{\code{...}}{One or more unquoted expressions separated by commas.
106 | Expressions matching values in the column defined by \code{by}/\code{.by}
107 | determine deceased authors. Matching of values is case-insensitive.}
108 |
109 | \item{\code{.by}}{Variable used to specify whether an author is deceased or not.
110 | By default, uses authors' id.}
111 |
112 | \item{\code{by}}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}}
113 |
114 | Please use the \code{.by} parameter instead.}
115 | }
116 | \if{html}{\out{
}}
117 | }
118 | \subsection{Returns}{
119 | The class instance.
120 | }
121 | }
122 | \if{html}{\out{ }}
123 | \if{html}{\out{ }}
124 | \if{latex}{\out{\hypertarget{method-StatusSetterPlumeQuarto-clone}{}}}
125 | \subsection{Method \code{clone()}}{
126 | The objects of this class are cloneable with this method.
127 | \subsection{Usage}{
128 | \if{html}{\out{}}\preformatted{StatusSetterPlumeQuarto$clone(deep = FALSE)}\if{html}{\out{
}}
129 | }
130 |
131 | \subsection{Arguments}{
132 | \if{html}{\out{}}
133 | \describe{
134 | \item{\code{deep}}{Whether to make a deep clone.}
135 | }
136 | \if{html}{\out{
}}
137 | }
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/man/as_lines.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/as-lines.R
3 | \name{as_lines}
4 | \alias{as_lines}
5 | \title{Print vector elements on multiple lines}
6 | \usage{
7 | as_lines(...)
8 | }
9 | \arguments{
10 | \item{...}{Objects to print.}
11 | }
12 | \value{
13 | \code{NULL} invisibly.
14 | }
15 | \description{
16 | Thin wrapper around \code{\link[=cat]{cat()}} to display vector elements on
17 | multiple lines when rendering an R Markdown or Quarto document. This is
18 | primarily intended to be used with \code{\link{Plume}}'s methods to output each
19 | returned element on its own line.
20 | }
21 | \examples{
22 | aut <- Plume$new(encyclopedists)
23 | as_lines(aut$get_affiliations())
24 | }
25 |
--------------------------------------------------------------------------------
/man/credit_roles.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/credit-roles.R
3 | \name{credit_roles}
4 | \alias{credit_roles}
5 | \title{CRediT roles}
6 | \usage{
7 | credit_roles(oxford_spelling = TRUE)
8 | }
9 | \arguments{
10 | \item{oxford_spelling}{Should the suffix -ize/-ization be used?}
11 | }
12 | \value{
13 | A named vector.
14 | }
15 | \description{
16 | Helper function returning the 14 contributor roles of the
17 | \href{https://credit.niso.org}{Contributor Roles Taxonomy} (CRediT). This function is the default argument of the
18 | \code{roles} and \code{role_cols} parameters in plume classes and \code{\link[=plm_template]{plm_template()}},
19 | respectively.
20 | }
21 | \examples{
22 | credit_roles()
23 | }
24 |
--------------------------------------------------------------------------------
/man/encyclopedists.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/data-encyclopedists.R
3 | \docType{data}
4 | \name{encyclopedists}
5 | \alias{encyclopedists}
6 | \alias{encyclopedists_fr}
7 | \title{Famous encyclopedists}
8 | \format{
9 | A tibble with 4 rows and 10 variables:
10 | \describe{
11 | \item{given_name,prénom}{authors' given names}
12 | \item{family_name,nom}{authors' family names}
13 | \item{email,courriel}{authors' email addresses}
14 | \item{phone,téléphone}{authors' phone numbers}
15 | \item{orcid}{authors' ORCID}
16 | \item{affiliation_1,affiliation_2}{authors' affiliations}
17 | \item{supervision}{authors that supervised the project}
18 | \item{writing,rédaction}{authors involved in the writing}
19 | \item{note}{special notes about authors}
20 | }
21 | }
22 | \usage{
23 | encyclopedists
24 |
25 | encyclopedists_fr
26 | }
27 | \description{
28 | Data on four famous authors of the Encyclopédie (originally "Encyclopédie, ou
29 | dictionnaire raisonné des sciences, des arts et des métiers") published in
30 | France in the second half of the 18th century. The data set is available in
31 | English (\code{encyclopedists}) and French (\code{encyclopedists_fr}).
32 | }
33 | \examples{
34 | encyclopedists
35 |
36 | encyclopedists_fr
37 | }
38 | \keyword{datasets}
39 |
--------------------------------------------------------------------------------
/man/enumerate.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/enumerate.R
3 | \name{enumerate}
4 | \alias{enumerate}
5 | \title{Enumerate vector elements}
6 | \usage{
7 | enumerate(x, sep = ", ", last = " and ")
8 | }
9 | \arguments{
10 | \item{x}{A character vector.}
11 |
12 | \item{sep}{Separator used to separate the terms.}
13 |
14 | \item{last}{Separator used to separate the last two items if \code{x} has at least
15 | 2 items.}
16 | }
17 | \value{
18 | A character string with the same class as \code{x}.
19 | }
20 | \description{
21 | Wrapper around \code{\link[glue:glue_collapse]{glue_collapse()}} using
22 | \code{sep = ", "} and \code{last = " and "} as default arguments.
23 | }
24 | \examples{
25 | aut <- Plume$new(encyclopedists)
26 | aut$get_author_list() |> enumerate()
27 | }
28 |
--------------------------------------------------------------------------------
/man/everyone.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/context-selectors.R
3 | \name{everyone}
4 | \alias{everyone}
5 | \alias{everyone_but}
6 | \title{Select all authors or exclude some from a selection}
7 | \usage{
8 | everyone()
9 |
10 | everyone_but(...)
11 | }
12 | \arguments{
13 | \item{...}{One or more unquoted expressions separated by commas. Expressions
14 | matching values in the column defined by the \code{by}/\code{.by} parameters of
15 | \verb{set_*()} methods are used to set a given status to authors. Matching of
16 | values is case-insensitive.}
17 | }
18 | \description{
19 | Selection helpers to use in conjonction with status setter
20 | methods (i.e. methods that assign a status to authors with either \code{TRUE}
21 | or \code{FALSE}):
22 | \itemize{
23 | \item \code{\link[=everyone]{everyone()}} select all authors.
24 | \item \code{\link[=everyone_but]{everyone_but()}} \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} this function was
25 | deprecated as I believe it is not necessary since not more than a couple of
26 | authors should normally be given a particular status.
27 | }
28 | }
29 | \examples{
30 | aut <- Plume$new(encyclopedists)
31 |
32 | aut$set_corresponding_authors(everyone())
33 | aut$get_plume() |> dplyr::select(1:3, corresponding)
34 | }
35 | \keyword{internal}
36 |
--------------------------------------------------------------------------------
/man/figures/lifecycle-archived.svg:
--------------------------------------------------------------------------------
1 | lifecycle lifecycle archived archived
--------------------------------------------------------------------------------
/man/figures/lifecycle-defunct.svg:
--------------------------------------------------------------------------------
1 | lifecycle lifecycle defunct defunct
--------------------------------------------------------------------------------
/man/figures/lifecycle-deprecated.svg:
--------------------------------------------------------------------------------
1 | lifecycle lifecycle deprecated deprecated
--------------------------------------------------------------------------------
/man/figures/lifecycle-experimental.svg:
--------------------------------------------------------------------------------
1 | lifecycle lifecycle experimental experimental
--------------------------------------------------------------------------------
/man/figures/lifecycle-maturing.svg:
--------------------------------------------------------------------------------
1 | lifecycle lifecycle maturing maturing
--------------------------------------------------------------------------------
/man/figures/lifecycle-questioning.svg:
--------------------------------------------------------------------------------
1 | lifecycle lifecycle questioning questioning
--------------------------------------------------------------------------------
/man/figures/lifecycle-stable.svg:
--------------------------------------------------------------------------------
1 | lifecycle lifecycle stable stable
--------------------------------------------------------------------------------
/man/figures/lifecycle-superseded.svg:
--------------------------------------------------------------------------------
1 | lifecycle lifecycle superseded superseded
--------------------------------------------------------------------------------
/man/icn_orcid.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/icon.R
3 | \name{icn_orcid}
4 | \alias{icn_orcid}
5 | \title{Create an ORCID icon}
6 | \usage{
7 | icn_orcid(size = 16, bw = FALSE)
8 | }
9 | \arguments{
10 | \item{size}{Size of the icon (in pixels).}
11 |
12 | \item{bw}{Should the black and white version of the icon be used?}
13 | }
14 | \value{
15 | A plume icon, i.e. an object with S3 class \code{plm_icon}.
16 | }
17 | \description{
18 | Create an ORCID icon for use with the \code{\link{Plume}} class.
19 | }
20 | \examples{
21 | aut <- Plume$new(encyclopedists, orcid_icon = icn_orcid(bw = TRUE))
22 | }
23 |
--------------------------------------------------------------------------------
/man/orcid.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/icon.R
3 | \name{orcid}
4 | \alias{orcid}
5 | \title{ORCID icon}
6 | \usage{
7 | orcid(size = 16, bw = FALSE)
8 | }
9 | \arguments{
10 | \item{size}{Size of the icon (in pixels).}
11 |
12 | \item{bw}{Should the black and white version of the icon be used?}
13 | }
14 | \value{
15 | A plume icon.
16 | }
17 | \description{
18 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}}
19 |
20 | Please use \code{\link[=icn_orcid]{icn_orcid()}} instead.
21 | }
22 | \keyword{internal}
23 |
--------------------------------------------------------------------------------
/man/plm_template.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/plm-template.R
3 | \name{plm_template}
4 | \alias{plm_template}
5 | \title{Create a table template for plume classes}
6 | \usage{
7 | plm_template(minimal = TRUE, role_cols = credit_roles(), credit_roles = FALSE)
8 | }
9 | \arguments{
10 | \item{minimal}{If \code{TRUE}, returns an empty tibble with the following columns:
11 | \code{given_name}, \code{family_name}, \code{email}, \code{orcid}, \code{affiliation} and \code{note}.
12 | Otherwise the function returns a template with all columns that can be
13 | supplied to plume classes that are not \code{PlumeQuarto}-specific.}
14 |
15 | \item{role_cols}{A vector of names defining role columns to create. If the
16 | vector contains key-value pairs, columns will be named after the keys.}
17 |
18 | \item{credit_roles}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}}
19 |
20 | It is now recommended to use \code{role_cols = credit_roles()} to use the
21 | \href{https://credit.niso.org}{Contributor Roles Taxonomy}.}
22 | }
23 | \value{
24 | An empty tibble.
25 | }
26 | \description{
27 | This helper function allows you to generate an empty
28 | \code{\link[tibble:tibble]{tibble}} that you can use as a template to supply
29 | author data.
30 | }
31 | \examples{
32 | plm_template()
33 |
34 | plm_template(role_cols = paste0("role_", 1:5))
35 | }
36 |
--------------------------------------------------------------------------------
/man/plume-package.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/plume-package.R
3 | \docType{package}
4 | \name{plume-package}
5 | \alias{plume}
6 | \alias{plume-package}
7 | \title{plume: A Simple Author Handler for Scientific Writing}
8 | \description{
9 | Handles and formats author information in scientific writing in 'R Markdown' and 'Quarto'. 'plume' provides easy-to-use and flexible tools for injecting author metadata in 'YAML' headers as well as generating author and contribution lists (among others) as strings from tabular data.
10 | }
11 | \seealso{
12 | Useful links:
13 | \itemize{
14 | \item \url{https://arnaudgallou.github.io/plume/}
15 | \item \url{https://github.com/arnaudgallou/plume}
16 | \item Report bugs at \url{https://github.com/arnaudgallou/plume/issues}
17 | }
18 |
19 | }
20 | \author{
21 | \strong{Maintainer}: Arnaud Gallou \email{arangacas@gmail.com} (\href{https://orcid.org/0000-0002-1002-4247}{ORCID}) [copyright holder]
22 |
23 | }
24 | \keyword{internal}
25 |
--------------------------------------------------------------------------------
/man/sequential.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/sequential.R
3 | \name{sequential}
4 | \alias{sequential}
5 | \title{Control the sequencing behaviour of character vectors}
6 | \usage{
7 | sequential(x)
8 | }
9 | \arguments{
10 | \item{x}{A character vector.}
11 | }
12 | \value{
13 | A character vector with parent S3 class \code{sequential}.
14 | }
15 | \description{
16 | Modifier function used to generate logical sequences of
17 | characters.
18 | }
19 | \examples{
20 | aut <- Plume$new(
21 | tibble::tibble(
22 | given_name = "X",
23 | family_name = "Y",
24 | affiliation = 1:60
25 | ),
26 | symbols = list(affiliation = sequential(letters))
27 | )
28 |
29 | aut$get_affiliations(sep = ": ", superscript = FALSE)
30 | }
31 |
--------------------------------------------------------------------------------
/man/set_default_names.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/set-default-names.R
3 | \name{set_default_names}
4 | \alias{set_default_names}
5 | \title{Set new default names to a plume subclass}
6 | \usage{
7 | set_default_names(..., .plume_quarto = FALSE)
8 | }
9 | \arguments{
10 | \item{...}{Key-value pairs where keys are default names and values their
11 | respective replacements.}
12 |
13 | \item{.plume_quarto}{Are you setting new names for \code{\link{PlumeQuarto}}?}
14 | }
15 | \value{
16 | A named list.
17 | }
18 | \description{
19 | This helper function allows you to set new default names to a
20 | plume subclass, e.g. to set default names to a language other than English.
21 | }
22 | \details{
23 | Available names are:
24 |
25 | \code{id}, \code{initials}, \code{literal_name}, \code{corresponding}, \code{role}, \code{contributor_rank}, \code{given_name}, \code{family_name}, \code{orcid}, \code{email}, \code{phone}, \code{fax}, \code{url}, \code{affiliation}, \code{note}.
26 |
27 | Using \code{.plume_quarto = TRUE} adds \code{deceased}, \code{equal_contributor}, \code{number},
28 | \code{dropping_particle} and \code{acknowledgements}.
29 | }
30 | \examples{
31 | # Extending `Plume` with default names in French
32 | PlumeFr <- R6::R6Class(
33 | classname = "PlumeFr",
34 | inherit = Plume,
35 | private = list(
36 | plume_names = set_default_names(
37 | initials = "initiales",
38 | literal_name = "nom_complet",
39 | corresponding = "correspondant",
40 | given_name = "prénom",
41 | family_name = "nom",
42 | email = "courriel",
43 | phone = "téléphone"
44 | )
45 | )
46 | )
47 |
48 | PlumeFr$new(encyclopedists_fr)
49 | }
50 |
--------------------------------------------------------------------------------
/plume.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: Sweave
13 | LaTeX: pdfLaTeX
14 |
15 | AutoAppendNewline: Yes
16 | StripTrailingWhitespace: Yes
17 |
18 | BuildType: Package
19 | PackageUseDevtools: Yes
20 | PackageInstallArgs: --no-multiarch --with-keep.source
21 |
--------------------------------------------------------------------------------
/tests/testthat.R:
--------------------------------------------------------------------------------
1 | library(testthat)
2 | library(plume)
3 |
4 | test_check("plume")
5 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/credit-roles.md:
--------------------------------------------------------------------------------
1 | # credit_roles() returns CRediT roles
2 |
3 | Code
4 | credit_roles()
5 | Output
6 | conceptualization data_curation
7 | "Conceptualization" "Data curation"
8 | analysis funding
9 | "Formal analysis" "Funding acquisition"
10 | investigation methodology
11 | "Investigation" "Methodology"
12 | administration resources
13 | "Project administration" "Resources"
14 | software supervision
15 | "Software" "Supervision"
16 | validation visualization
17 | "Validation" "Visualization"
18 | writing editing
19 | "Writing - original draft" "Writing - review & editing"
20 |
21 | ---
22 |
23 | Code
24 | credit_roles(oxford_spelling = FALSE)
25 | Output
26 | conceptualisation data_curation
27 | "Conceptualisation" "Data curation"
28 | analysis funding
29 | "Formal analysis" "Funding acquisition"
30 | investigation methodology
31 | "Investigation" "Methodology"
32 | administration resources
33 | "Project administration" "Resources"
34 | software supervision
35 | "Software" "Supervision"
36 | validation visualisation
37 | "Validation" "Visualisation"
38 | writing editing
39 | "Writing - original draft" "Writing - review & editing"
40 |
41 | # credit_roles() gives meaningful error messages
42 |
43 | Code
44 | credit_roles(oxford_spelling = 1)
45 | Condition
46 | Error in `credit_roles()`:
47 | ! `oxford_spelling` must be `TRUE` or `FALSE`.
48 |
49 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/defunct.md:
--------------------------------------------------------------------------------
1 | # defunct functionalities generate informative errors
2 |
3 | Code
4 | aut <- PlumeQuarto$new(basic_df, temp_file())
5 | aut$set_equal_contributor(1)
6 | Condition
7 | Error:
8 | ! `set_equal_contributor()` was deprecated in plume 0.2.0 and is now defunct.
9 | i Please use `set_cofirst_authors()` instead.
10 | Code
11 | aut <- Plume$new(basic_df)
12 | aut$set_corresponding_authors(zip, by = "given_name")
13 | Condition
14 | Error:
15 | ! The `by` argument of `set_corresponding_author()` was deprecated in plume 0.2.0 and is now defunct.
16 | i Please use the `.by` argument instead.
17 | Code
18 | aut$get_author_list(format = "a")
19 | Condition
20 | Error:
21 | ! The `format` argument of `get_author_list()` was deprecated in plume 0.2.1 and is now defunct.
22 | i Please use the `suffix` argument instead.
23 | Code
24 | Plume$new(data.frame(given_name = "X", family_name = "Y", role = "a"))
25 | Condition
26 | Error:
27 | ! Defining explicit roles in the input data was deprecated in plume 0.2.0 and is now defunct.
28 | i Please use the `roles` argument of `new()` instead.
29 | i See .
30 | Code
31 | Plume$new(basic_df, credit_roles = TRUE)
32 | Condition
33 | Error:
34 | ! The `credit_roles` argument of `new()` was deprecated in plume 0.2.0 and is now defunct.
35 | i Please use `roles = credit_roles()` instead.
36 | Code
37 | plm_template(credit_roles = TRUE)
38 | Condition
39 | Error:
40 | ! The `credit_roles` argument of `plm_template()` was deprecated in plume 0.2.0 and is now defunct.
41 | i Please use `role_cols = credit_roles()` instead.
42 | Code
43 | everyone_but()
44 | Condition
45 | Error:
46 | ! `everyone_but()` was deprecated in plume 0.2.0 and is now defunct.
47 |
48 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/deprecated.md:
--------------------------------------------------------------------------------
1 | # deprecated functionalities generate informative errors
2 |
3 | Code
4 | aut <- Plume$new(basic_df)
5 | aut$set_corresponding_authors(1)
6 | aut$get_contact_details(format = "{name} {details}")
7 | Condition
8 | Warning:
9 | The `format` argument of `get_contact_details()` is deprecated as of plume 0.2.6.
10 | i Please use the `template` argument instead.
11 | Output
12 | Zip Zap zipzap@test.com
13 | Code
14 | orcid()
15 | Condition
16 | Warning:
17 | `orcid()` was deprecated in plume 0.2.6.
18 | i Please use `icn_orcid()` instead.
19 | Output
20 |
21 |
22 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/get-author-list.md:
--------------------------------------------------------------------------------
1 | # get_author_list() makes ORCID icons
2 |
3 | Code
4 | aut$get_author_list("o")
5 | Output
6 | Zip Zap[\hspace{3pt}{height=16px}\hspace{3pt}](https://orcid.org/0000-0000-0000-0001)
7 | Ric Rac[\hspace{3pt}{height=16px}\hspace{3pt}](https://orcid.org/0000-0000-0000-0002)
8 | Pim-Pam Pom
9 |
10 | # get_author_list() gives meaningful error messages
11 |
12 | Code
13 | (expect_error(aut$get_author_list(1)))
14 | Output
15 |
16 | Error in `aut$get_author_list()`:
17 | ! `suffix` must be a character string.
18 | Code
19 | (expect_error(aut$get_author_list("aa")))
20 | Output
21 |
22 | Error in `aut$get_author_list()`:
23 | ! `suffix` must have unique keys.
24 | Code
25 | (expect_error(aut$get_author_list("az")))
26 | Output
27 |
28 | Error in `aut$get_author_list()`:
29 | ! `suffix` must only contain any of `a`, `c`, `n`, `o`, `^` or `,`.
30 | Code
31 | (expect_error(aut$get_author_list("ac")))
32 | Output
33 |
34 | Error in `aut$get_author_list()`:
35 | ! Column `corresponding` doesn't exist.
36 | i Did you forget to assign corresponding authors?
37 | i Use `set_corresponding_authors()` to set corresponding authors.
38 | Code
39 | (expect_error(aut$get_author_list("o")))
40 | Output
41 |
42 | Error in `aut$get_author_list()`:
43 | ! Invalid ORCID identifier found: `0000`.
44 | i ORCID identifiers must have 16 digits, separated by a hyphen every 4 digits.
45 | i The last character of the identifiers must be a digit or `X`.
46 |
47 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/get-contact-details.md:
--------------------------------------------------------------------------------
1 | # get_conctact_details() gives meaningful error messages
2 |
3 | Code
4 | (expect_error(aut$get_contact_details("foo")))
5 | Output
6 |
7 | Error in `aut$get_contact_details()`:
8 | ! `template` must be a glue specification.
9 | Code
10 | (expect_error(aut$get_contact_details("{foo}")))
11 | Output
12 |
13 | Error in `aut$get_contact_details()`:
14 | ! Invalid variable `foo`.
15 | i `template` must use variables `name` and/or `details`.
16 | Code
17 | (expect_error(aut$get_contact_details()))
18 | Output
19 |
20 | Error in `aut$get_contact_details()`:
21 | ! Column `corresponding` doesn't exist.
22 | i Did you forget to assign corresponding authors?
23 | i Use `set_corresponding_authors()` to set corresponding authors.
24 | Code
25 | (expect_error(aut$get_contact_details(email = 1)))
26 | Output
27 |
28 | Error in `aut$get_contact_details()`:
29 | ! `email` must be `TRUE` or `FALSE`.
30 | Code
31 | (expect_error(aut$get_contact_details(sep = NULL)))
32 | Output
33 |
34 | Error in `aut$get_contact_details()`:
35 | ! `sep` must be a character string.
36 | Code
37 | (expect_error(aut$get_contact_details(sep = "")))
38 | Output
39 |
40 | Error in `aut$get_contact_details()`:
41 | ! `sep` must be a non-empty string.
42 | Code
43 | aut$set_corresponding_authors(1)
44 | (expect_error(aut$get_contact_details(fax = TRUE)))
45 | Output
46 |
47 | Error in `aut$get_contact_details()`:
48 | ! Column `fax` doesn't exist.
49 |
50 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/get-contributions.md:
--------------------------------------------------------------------------------
1 | # get_contributions() gives meaningful error messages
2 |
3 | Code
4 | (expect_error(aut$get_contributions(roles_first = "")))
5 | Output
6 |
7 | Error in `aut$get_contributions()`:
8 | ! `roles_first` must be `TRUE` or `FALSE`.
9 | Code
10 | (expect_error(aut$get_contributions(by_author = "")))
11 | Output
12 |
13 | Error in `aut$get_contributions()`:
14 | ! `by_author` must be `TRUE` or `FALSE`.
15 | Code
16 | (expect_error(aut$get_contributions(alphabetical_order = "")))
17 | Output
18 |
19 | Error in `aut$get_contributions()`:
20 | ! `alphabetical_order` must be `TRUE` or `FALSE`.
21 | Code
22 | (expect_error(aut$get_contributions(dotted_initials = "")))
23 | Output
24 |
25 | Error in `aut$get_contributions()`:
26 | ! `dotted_initials` must be `TRUE` or `FALSE`.
27 | Code
28 | (expect_error(aut$get_contributions(literal_names = "")))
29 | Output
30 |
31 | Error in `aut$get_contributions()`:
32 | ! `literal_names` must be `TRUE` or `FALSE`.
33 | Code
34 | (expect_error(aut$get_contributions(sep = 1)))
35 | Output
36 |
37 | Error in `aut$get_contributions()`:
38 | ! `sep` must be a character string.
39 | Code
40 | (expect_error(aut$get_contributions(sep_last = 1)))
41 | Output
42 |
43 | Error in `aut$get_contributions()`:
44 | ! `sep_last` must be a character string.
45 | Code
46 | (expect_error(aut$get_contributions(divider = 1)))
47 | Output
48 |
49 | Error in `aut$get_contributions()`:
50 | ! `divider` must be a character string.
51 |
52 | ---
53 |
54 | Code
55 | aut$get_contributions()
56 | Condition
57 | Error in `aut$get_contributions()`:
58 | ! Column `role` doesn't exist.
59 |
60 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/get-footnotes.md:
--------------------------------------------------------------------------------
1 | # get_affiliations()/get_notes() give meaningful error messages
2 |
3 | Code
4 | (expect_error(aut$get_affiliations(sep = 1)))
5 | Output
6 |
7 | Error in `aut$get_affiliations()`:
8 | ! `sep` must be a character string.
9 | Code
10 | (expect_error(aut$get_affiliations(superscript = "")))
11 | Output
12 |
13 | Error in `aut$get_affiliations()`:
14 | ! `superscript` must be `TRUE` or `FALSE`.
15 | Code
16 | (expect_error(aut$get_notes(sep = 1)))
17 | Output
18 |
19 | Error in `aut$get_notes()`:
20 | ! `sep` must be a character string.
21 | Code
22 | (expect_error(aut$get_notes(superscript = "")))
23 | Output
24 |
25 | Error in `aut$get_notes()`:
26 | ! `superscript` must be `TRUE` or `FALSE`.
27 |
28 | ---
29 |
30 | Code
31 | (expect_error(aut$get_affiliations()))
32 | Output
33 |
34 | Error in `aut$get_affiliations()`:
35 | ! Column `affiliation` doesn't exist.
36 | Code
37 | (expect_error(aut$get_notes()))
38 | Output
39 |
40 | Error in `aut$get_notes()`:
41 | ! Column `note` doesn't exist.
42 |
43 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/get-orcids.md:
--------------------------------------------------------------------------------
1 | # get_orcids() returns authors' ORCID
2 |
3 | Code
4 | aut$get_orcids()
5 | Output
6 | Zip Zap[\hspace{3pt}{height=16px}\hspace{3pt}](https://orcid.org/0000-0000-0000-0001)
7 | Ric Rac[\hspace{3pt}{height=16px}\hspace{3pt}](https://orcid.org/0000-0000-0000-0002)
8 |
9 | ---
10 |
11 | Code
12 | aut$get_orcids(sep = " - ")
13 | Output
14 | Zip Zap - [\hspace{3pt}{height=16px}\hspace{3pt}](https://orcid.org/0000-0000-0000-0001)
15 | Ric Rac - [\hspace{3pt}{height=16px}\hspace{3pt}](https://orcid.org/0000-0000-0000-0002)
16 |
17 | ---
18 |
19 | Code
20 | aut$get_orcids(icon = FALSE)
21 | Output
22 | Zip Zap
23 | Ric Rac
24 |
25 | ---
26 |
27 | Code
28 | aut$get_orcids(icon = FALSE, compact = TRUE)
29 | Output
30 | Zip Zap[0000-0000-0000-0001](https://orcid.org/0000-0000-0000-0001)
31 | Ric Rac[0000-0000-0000-0002](https://orcid.org/0000-0000-0000-0002)
32 |
33 | # get_orcids() gives meaningful error messages
34 |
35 | Code
36 | (expect_error(aut$get_orcids(compact = 1)))
37 | Output
38 |
39 | Error in `aut$get_orcids()`:
40 | ! `compact` must be `TRUE` or `FALSE`.
41 | Code
42 | (expect_error(aut$get_orcids(icon = 1)))
43 | Output
44 |
45 | Error in `aut$get_orcids()`:
46 | ! `icon` must be `TRUE` or `FALSE`.
47 | Code
48 | (expect_error(aut$get_orcids(sep = 1)))
49 | Output
50 |
51 | Error in `aut$get_orcids()`:
52 | ! `sep` must be a character string.
53 |
54 | ---
55 |
56 | Code
57 | aut$get_orcids(icon = FALSE)
58 | Condition
59 | Error in `aut$get_orcids()`:
60 | ! Invalid ORCID identifier found: `0000`.
61 | i ORCID identifiers must have 16 digits, separated by a hyphen every 4 digits.
62 | i The last character of the identifiers must be a digit or `X`.
63 |
64 | ---
65 |
66 | Code
67 | aut$get_orcids()
68 | Condition
69 | Error in `aut$get_orcids()`:
70 | ! Column `orcid` doesn't exist.
71 |
72 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/icon.md:
--------------------------------------------------------------------------------
1 | # icn_orcid() makes orcid icon metadata
2 |
3 | Code
4 | read_rendered_md()
5 | Output
6 | ---
7 | title: test
8 | ---
9 |
10 | ``` r
11 | str(attributes(icn_orcid()))
12 | ```
13 |
14 | List of 5
15 | $ class : chr "plm_icon"
16 | $ size : num 16
17 | $ filename: chr "orcid.pdf"
18 | $ style : chr ""
19 | $ spacing : chr "\\hspace{3pt}"
20 |
21 | ``` r
22 | str(attributes(icn_orcid(size = 24)))
23 | ```
24 |
25 | List of 5
26 | $ class : chr "plm_icon"
27 | $ size : num 24
28 | $ filename: chr "orcid.pdf"
29 | $ style : chr ""
30 | $ spacing : chr "\\hspace{4pt}"
31 |
32 | ``` r
33 | str(attributes(icn_orcid(bw = TRUE)))
34 | ```
35 |
36 | List of 5
37 | $ class : chr "plm_icon"
38 | $ size : num 16
39 | $ filename: chr "orcid-bw.pdf"
40 | $ style : chr ""
41 | $ spacing : chr "\\hspace{3pt}"
42 |
43 | ---
44 |
45 | Code
46 | read_rendered_md()
47 | Output
48 | ---
49 | title: test
50 | ---
51 |
52 | ``` r
53 | str(attributes(icn_orcid()))
54 | ```
55 |
56 | List of 5
57 | $ class : chr "plm_icon"
58 | $ size : num 16
59 | $ filename: chr "orcid.svg"
60 | $ style : chr " style='margin: 0 4px; vertical-align: baseline'"
61 | $ spacing : chr ""
62 |
63 | ``` r
64 | str(attributes(icn_orcid(size = 24)))
65 | ```
66 |
67 | List of 5
68 | $ class : chr "plm_icon"
69 | $ size : num 24
70 | $ filename: chr "orcid.svg"
71 | $ style : chr " style='margin: 0 6px; vertical-align: baseline'"
72 | $ spacing : chr ""
73 |
74 | ``` r
75 | str(attributes(icn_orcid(bw = TRUE)))
76 | ```
77 |
78 | List of 5
79 | $ class : chr "plm_icon"
80 | $ size : num 16
81 | $ filename: chr "orcid-bw.svg"
82 | $ style : chr " style='margin: 0 4px; vertical-align: baseline'"
83 | $ spacing : chr ""
84 |
85 | # icn_orcid() gives meaningful error messages
86 |
87 | Code
88 | (expect_error(icn_orcid(size = NULL)))
89 | Output
90 |
91 | Error in `icn_orcid()`:
92 | ! `size` must be a numeric vector.
93 | Code
94 | (expect_error(icn_orcid(bw = 1)))
95 | Output
96 |
97 | Error in `icn_orcid()`:
98 | ! `bw` must be `TRUE` or `FALSE`.
99 |
100 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/initialize.md:
--------------------------------------------------------------------------------
1 | # initialize() gives meaningful error messages
2 |
3 | Code
4 | (expect_error(Plume$new(list(x = 1))))
5 | Output
6 |
7 | Error in `initialize()`:
8 | ! `data` must be a data frame or tibble.
9 | Code
10 | (expect_error(Plume$new(data.frame(family_name = "x"))))
11 | Output
12 |
13 | Error in `initialize()`:
14 | ! Column `given_name` doesn't exist.
15 | Code
16 | (expect_error(Plume$new(data.frame(given_name = "x", family_name = ""))))
17 | Output
18 |
19 | Error in `initialize()`:
20 | ! Missing author name found in position 1.
21 | i All authors must have a given and family name.
22 | Code
23 | (expect_error(Plume$new(data.frame(given_name = "x"))))
24 | Output
25 |
26 | Error in `initialize()`:
27 | ! Column `family_name` doesn't exist.
28 | Code
29 | (expect_error(Plume$new(basic_df, names = list(given_name = "prénom"))))
30 | Output
31 |
32 | Error in `initialize()`:
33 | ! `names` must be a character vector.
34 | Code
35 | (expect_error(Plume$new(basic_df, names = "prénom")))
36 | Output
37 |
38 | Error in `initialize()`:
39 | ! All `names` inputs must be named.
40 | Code
41 | (expect_error(Plume$new(basic_df, names = c(given_name = "prénom", family_name = "prénom")))
42 | )
43 | Output
44 |
45 | Error in `initialize()`:
46 | ! `names` must have unique input values.
47 | Code
48 | (expect_error(Plume$new(basic_df, names = c(given_name = "prénom", given_name = "nom")))
49 | )
50 | Output
51 |
52 | Error in `initialize()`:
53 | ! `names` must have unique input names.
54 | Code
55 | (expect_error(Plume$new(basic_df, symbols = c(note = letters))))
56 | Output
57 |
58 | Error in `initialize()`:
59 | ! `symbols` must be a list.
60 | Code
61 | (expect_error(Plume$new(basic_df, symbols = list(note = NULL, note = NULL))))
62 | Output
63 |
64 | Error in `initialize()`:
65 | ! `symbols` must have unique input names.
66 | Code
67 | (expect_error(Plume$new(basic_df, orcid_icon = NULL)))
68 | Output
69 |
70 | Error in `initialize()`:
71 | ! Invalid `orcid_icon` input.
72 | i Use `icn_orcid()` to set the ORCID icon.
73 | Code
74 | (expect_error(Plume$new(basic_df, initials_given_name = 1)))
75 | Output
76 |
77 | Error in `initialize()`:
78 | ! `initials_given_name` must be `TRUE` or `FALSE`.
79 | Code
80 | (expect_error(Plume$new(basic_df, family_name_first = 1)))
81 | Output
82 |
83 | Error in `initialize()`:
84 | ! `family_name_first` must be `TRUE` or `FALSE`.
85 | Code
86 | (expect_error(Plume$new(basic_df, credit_roles = 1)))
87 | Output
88 |
89 | Error in `initialize()`:
90 | ! `credit_roles` must be `TRUE` or `FALSE`.
91 | Code
92 | (expect_error(Plume$new(basic_df, interword_spacing = 1)))
93 | Output
94 |
95 | Error in `initialize()`:
96 | ! `interword_spacing` must be `TRUE` or `FALSE`.
97 | Code
98 | (expect_error(Plume$new(basic_df, roles = 1)))
99 | Output
100 |
101 | Error in `initialize()`:
102 | ! `roles` must be a character vector.
103 | Code
104 | (expect_error(Plume$new(basic_df, roles = "foo")))
105 | Output
106 |
107 | Error in `initialize()`:
108 | ! All `roles` inputs must be named.
109 | Code
110 | (expect_error(Plume$new(basic_df, roles = c(role = "foo", role = "bar"))))
111 | Output
112 |
113 | Error in `initialize()`:
114 | ! `roles` must have unique input names.
115 | Code
116 | (expect_error(Plume$new(basic_df, roles = c(role = "foo", role_2 = "foo"))))
117 | Output
118 |
119 | Error in `initialize()`:
120 | ! `roles` must have unique input values.
121 | Code
122 | (expect_error(PlumeQuarto$new(basic_df, file = 1)))
123 | Output
124 |
125 | Error in `initialize()`:
126 | ! `file` must be a character string.
127 | Code
128 | (expect_error(PlumeQuarto$new(basic_df, file = "")))
129 | Output
130 |
131 | Error in `initialize()`:
132 | ! `file` must be a non-empty string.
133 | Code
134 | (expect_error(PlumeQuarto$new(basic_df, file = "test.rmd")))
135 | Output
136 |
137 | Error in `initialize()`:
138 | ! `file` must be a `.qmd`, `.yml` or `.yaml` file.
139 | Code
140 | (expect_error(PlumeQuarto$new(basic_df, file = "~/test.qmd")))
141 | Output
142 |
143 | Error in `initialize()`:
144 | ! `~/test.qmd` doesn't exist.
145 | Code
146 | (expect_error(PlumeQuarto$new(basic_df, temp_file(), by = 1)))
147 | Output
148 |
149 | Error in `initialize()`:
150 | ! `by` must be a character string.
151 | Code
152 | (expect_error(PlumeQuarto$new(basic_df, temp_file(), by = "")))
153 | Output
154 |
155 | Error in `initialize()`:
156 | ! `by` must be a non-empty string.
157 | Code
158 | (expect_error(PlumeQuarto$new(basic_df, temp_file(), by = "foo")))
159 | Output
160 |
161 | Error in `initialize()`:
162 | ! Column `foo` doesn't exist.
163 |
164 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/plm-template.md:
--------------------------------------------------------------------------------
1 | # plm_template() gives meaningful error messages
2 |
3 | Code
4 | (expect_error(plm_template(minimal = 1)))
5 | Output
6 |
7 | Error in `plm_template()`:
8 | ! `minimal` must be `TRUE` or `FALSE`.
9 | Code
10 | (expect_error(plm_template(role_cols = 1)))
11 | Output
12 |
13 | Error in `plm_template()`:
14 | ! `role_cols` must be a character vector.
15 | Code
16 | (expect_error(plm_template(role_cols = c("foo", "foo"))))
17 | Output
18 |
19 | Error in `plm_template()`:
20 | ! `role_cols` must have unique input values.
21 |
22 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/sequential.md:
--------------------------------------------------------------------------------
1 | # sequential() gives meaningful error messages
2 |
3 | Code
4 | sequential(1)
5 | Condition
6 | Error in `sequential()`:
7 | ! `x` must be a character vector.
8 |
9 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/set-default-names.md:
--------------------------------------------------------------------------------
1 | # set_default_names() sets new plume names
2 |
3 | Code
4 | str(nms)
5 | Output
6 | List of 4
7 | $ internals :List of 6
8 | ..$ id : chr "id"
9 | ..$ initials : chr "initiales"
10 | ..$ literal_name : chr "nom_complet"
11 | ..$ corresponding : chr "correspondant"
12 | ..$ role : chr "role"
13 | ..$ contributor_rank: chr "rang_contributeur"
14 | $ primaries :List of 2
15 | ..$ given_name : chr "prénom"
16 | ..$ family_name: chr "nom"
17 | $ secondaries:List of 5
18 | ..$ orcid: chr "orcid"
19 | ..$ email: chr "courriel"
20 | ..$ phone: chr "téléphone"
21 | ..$ fax : chr "fax"
22 | ..$ url : chr "url"
23 | $ nestables :List of 2
24 | ..$ affiliation: chr "affiliation"
25 | ..$ note : chr "note"
26 |
27 | # set_default_names() gives meaningful error messages
28 |
29 | Code
30 | (expect_error(set_default_names()))
31 | Output
32 |
33 | Error in `set_default_names()`:
34 | ! `...` must not be empty.
35 | Code
36 | (expect_error(set_default_names(1)))
37 | Output
38 |
39 | Error in `set_default_names()`:
40 | ! `...` must be a character vector.
41 | Code
42 | (expect_error(set_default_names("a")))
43 | Output
44 |
45 | Error in `set_default_names()`:
46 | ! All `...` inputs must be named.
47 | Code
48 | (expect_error(set_default_names(x = "a", y = "a")))
49 | Output
50 |
51 | Error in `set_default_names()`:
52 | ! `...` must have unique input values.
53 | Code
54 | (expect_error(set_default_names(x = "a", x = "b")))
55 | Output
56 |
57 | Error in `set_default_names()`:
58 | ! `...` must have unique input names.
59 | Code
60 | (expect_error(set_default_names(given_name = "nom", .plume_quarto = 1)))
61 | Output
62 |
63 | Error in `set_default_names()`:
64 | ! `.plume_quarto` must be `TRUE` or `FALSE`.
65 |
66 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/set-main-contributors.md:
--------------------------------------------------------------------------------
1 | # set_ranks() gives meaningful error messages
2 |
3 | Code
4 | (expect_error(aut$set_main_contributors()))
5 | Output
6 |
7 | Error in `aut$set_main_contributors()`:
8 | ! `...` must not be empty.
9 | Code
10 | (expect_error(aut$set_main_contributors(1, .roles = 1)))
11 | Output
12 |
13 | Error in `aut$set_main_contributors()`:
14 | ! `.roles` must be a character vector.
15 | Code
16 | (expect_error(aut$set_main_contributors(1, .roles = c("x", "x"))))
17 | Output
18 |
19 | Error in `aut$set_main_contributors()`:
20 | ! `.roles` must have unique input values.
21 | Code
22 | (expect_error(aut$set_main_contributors(1, .by = 1)))
23 | Output
24 |
25 | Error in `aut$set_main_contributors()`:
26 | ! `.by` must be a character string.
27 |
28 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/set-status.md:
--------------------------------------------------------------------------------
1 | # set_*() methods give meaningful error messages
2 |
3 | Code
4 | (expect_error(aut$set_corresponding_authors()))
5 | Output
6 |
7 | Error in `aut$set_corresponding_authors()`:
8 | ! `...` must not be empty.
9 | Code
10 | (expect_error(aut$set_corresponding_authors(a, .by = "foo")))
11 | Output
12 |
13 | Error in `aut$set_corresponding_authors()`:
14 | ! Column `foo` doesn't exist.
15 | Code
16 | (expect_error(aut$set_corresponding_authors(a, .by = "")))
17 | Output
18 |
19 | Error in `aut$set_corresponding_authors()`:
20 | ! `.by` must be a non-empty string.
21 | Code
22 | (expect_error(aut$set_corresponding_authors(a, .by = 1)))
23 | Output
24 |
25 | Error in `aut$set_corresponding_authors()`:
26 | ! `.by` must be a character string.
27 | Code
28 | (expect_error(aut$set_corresponding_authors(x <- y)))
29 | Output
30 |
31 | Error in `aut$set_corresponding_authors()`:
32 | ! Can't match elements with `x <- y`.
33 | Code
34 | (expect_error(aut$set_cofirst_authors(a, .by = "foo")))
35 | Output
36 |
37 | Error in `aut$set_cofirst_authors()`:
38 | ! Column `foo` doesn't exist.
39 | Code
40 | (expect_error(aut$set_cofirst_authors(a, .by = "")))
41 | Output
42 |
43 | Error in `aut$set_cofirst_authors()`:
44 | ! `.by` must be a non-empty string.
45 | Code
46 | (expect_error(aut$set_cofirst_authors(a, .by = 1)))
47 | Output
48 |
49 | Error in `aut$set_cofirst_authors()`:
50 | ! `.by` must be a character string.
51 | Code
52 | (expect_error(aut$set_deceased(a, .by = "foo")))
53 | Output
54 |
55 | Error in `aut$set_deceased()`:
56 | ! Column `foo` doesn't exist.
57 | Code
58 | (expect_error(aut$set_deceased(a, .by = "")))
59 | Output
60 |
61 | Error in `aut$set_deceased()`:
62 | ! `.by` must be a non-empty string.
63 | Code
64 | (expect_error(aut$set_deceased(a, .by = 1)))
65 | Output
66 |
67 | Error in `aut$set_deceased()`:
68 | ! `.by` must be a character string.
69 |
70 | # everyone*() selectors error if used in a wrong context
71 |
72 | Code
73 | everyone()
74 | Condition
75 | Error in `everyone()`:
76 | ! `everyone()` must be used within a *status setter* method.
77 |
78 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/to-yaml.md:
--------------------------------------------------------------------------------
1 | # to_yaml() injects authors and affiliations into a `.qmd`
2 |
3 | Code
4 | read_test_file(tmp_file)
5 | Output
6 | ---
7 | title: test
8 | author:
9 | - id: aut1
10 | name:
11 | given: Zip
12 | family: Zap
13 | email: zipzap@test.com
14 | phone: '+1234'
15 | orcid: 0000-0000-0000-0001
16 | note: a. c
17 | attributes:
18 | corresponding: true
19 | roles:
20 | - Formal analysis
21 | - Writing - original draft
22 | affiliations:
23 | - ref: aff1
24 | - ref: aff2
25 | - id: aut2
26 | name:
27 | given: Ric
28 | family: Rac
29 | email: ricrac@test.com
30 | orcid: 0000-0000-0000-0002
31 | attributes:
32 | corresponding: false
33 | roles:
34 | - Formal analysis
35 | affiliations:
36 | - ref: aff3
37 | - id: aut3
38 | name:
39 | given: Pim-Pam
40 | family: Pom
41 | email: pimpampom@test.com
42 | note: b
43 | attributes:
44 | corresponding: false
45 | roles:
46 | - Formal analysis
47 | affiliations:
48 | - ref: aff1
49 | - ref: aff4
50 | affiliations:
51 | - id: aff1
52 | name: a
53 | - id: aff2
54 | name: b
55 | - id: aff3
56 | name: c
57 | - id: aff4
58 | name: d
59 | ---
60 |
61 | ```{r}
62 | #| echo: false
63 | x <- 1
64 | ```
65 |
66 | ---
67 |
68 | Code
69 | read_test_file(tmp_file)
70 | Output
71 | ---
72 | title: test
73 | author:
74 | - id: aut1
75 | name:
76 | given: Pim-Pam
77 | family: Pom
78 | email: pimpampom@test.com
79 | note: b
80 | attributes:
81 | corresponding: true
82 | roles:
83 | - Formal analysis
84 | affiliations:
85 | - ref: aff1
86 | - ref: aff2
87 | - id: aut2
88 | name:
89 | given: Ric
90 | family: Rac
91 | email: ricrac@test.com
92 | orcid: 0000-0000-0000-0002
93 | attributes:
94 | corresponding: false
95 | roles:
96 | - Formal analysis
97 | affiliations:
98 | - ref: aff3
99 | - id: aut3
100 | name:
101 | given: Zip
102 | family: Zap
103 | email: zipzap@test.com
104 | phone: '+1234'
105 | orcid: 0000-0000-0000-0001
106 | note: a. c
107 | attributes:
108 | corresponding: false
109 | roles:
110 | - Formal analysis
111 | - Writing - original draft
112 | affiliations:
113 | - ref: aff2
114 | - ref: aff4
115 | affiliations:
116 | - id: aff1
117 | name: d
118 | - id: aff2
119 | name: a
120 | - id: aff3
121 | name: c
122 | - id: aff4
123 | name: b
124 | ---
125 |
126 | ```{r}
127 | #| echo: false
128 | x <- 1
129 | ```
130 |
131 | ---
132 |
133 | Code
134 | read_test_file(tmp_file)
135 | Output
136 | ---
137 | title: test
138 | author:
139 | - name:
140 | given: Zip
141 | family: Zap
142 | affiliations:
143 | - ref: aff1
144 | - ref: aff2
145 | - ref: aff3
146 | affiliations:
147 | - id: aff1
148 | name: a
149 | department: b
150 | city: c
151 | postal-code: d
152 | - id: aff2
153 | name: f
154 | department: g
155 | city: e
156 | - id: aff3
157 | name: h
158 | ---
159 |
160 | ```{r}
161 | #| echo: false
162 | x <- 1
163 | ```
164 |
165 | # to_yaml() doesn't add the `affiliations` schema if there're no affiliations
166 |
167 | Code
168 | read_test_file(tmp_file)
169 | Output
170 | ---
171 | author:
172 | - name:
173 | given: Zip
174 | family: Zap
175 | ---
176 |
177 | # to_yaml() pushes data to empty YAML headers
178 |
179 | Code
180 | read_test_file(tmp_file)
181 | Output
182 | ---
183 | author:
184 | - name:
185 | given: Zip
186 | family: Zap
187 | metadata:
188 | meta-foo: bar
189 | ---
190 |
191 | # to_yaml() preserves line breaks preceding `---` (#37)
192 |
193 | Code
194 | read_test_file(tmp_file)
195 | Output
196 | ---
197 | author:
198 | - name:
199 | given: Zip
200 | family: Zap
201 | ---
202 | Lorem ipsum
203 | ---
204 |
205 | # to_yaml() writes in a separate header to preserve strippable data (#56)
206 |
207 | Code
208 | read_test_file(tmp_file)
209 | Output
210 | ---
211 | author:
212 | - name:
213 | given: Zip
214 | family: Zap
215 | ---
216 | ---
217 | title: test # this is a title
218 | foo: >
219 | Lorem ipsum
220 | Vivamus quis
221 | ---
222 |
223 | # to_yaml() can push data into YAML files
224 |
225 | Code
226 | read_test_file(tmp_file)
227 | Output
228 | title: foo
229 | author:
230 | - name:
231 | given: Zip
232 | family: Zap
233 |
234 | # to_yaml() properly handles authors with no roles (#81)
235 |
236 | Code
237 | read_test_file(tmp_file)
238 | Output
239 | title: foo
240 | author:
241 | - id: aut1
242 | name:
243 | given: A
244 | family: A
245 | roles:
246 | - Formal analysis
247 | - Writing - original draft
248 | - id: aut2
249 | name:
250 | given: B
251 | family: B
252 | roles: {}
253 |
254 | # to_yaml() errors if no YAML headers is found
255 |
256 | Code
257 | aut$to_yaml()
258 | Condition
259 | Error in `aut$to_yaml()`:
260 | ! No YAML headers found.
261 | i YAML headers must be at the beginning of the document.
262 | i YAML headers must start and end with three hyphens.
263 |
264 | # to_yaml() errors if an invalid ORCID identifier is found
265 |
266 | Code
267 | aut$to_yaml()
268 | Condition
269 | Error in `aut$to_yaml()`:
270 | ! Invalid ORCID identifier found: `0000`.
271 | i ORCID identifiers must have 16 digits, separated by a hyphen every 4 digits.
272 | i The last character of the identifiers must be a digit or `X`.
273 |
274 |
--------------------------------------------------------------------------------
/tests/testthat/helper-plume.R:
--------------------------------------------------------------------------------
1 | basic_df <- tibble(
2 | given_name = c("Zip", "Ric", "Pim-Pam"),
3 | family_name = c("Zap", "Rac", "Pom"),
4 | literal_name = paste(given_name, family_name),
5 | initials = c("ZZ", "RR", "P-PP"),
6 | affiliation = c("a", "c", "d"),
7 | affiliation2 = c("b", NA, "a"),
8 | analysis = rep(1, 3),
9 | writing = c(1, NA, NA),
10 | note = c("a", NA, "b"),
11 | note2 = c("c", NA, NA),
12 | email = paste0(c("zipzap", "ricrac", "pimpampom"), "@test.com"),
13 | phone = c("+1234", NA, NA),
14 | orcid = c(
15 | "0000-0000-0000-0001",
16 | "0000-0000-0000-0002",
17 | NA
18 | ),
19 | )
20 |
21 | temp_file <- function() {
22 | withr::local_tempfile(
23 | lines = "---\n---",
24 | fileext = ".qmd",
25 | .local_envir = rlang::caller_env()
26 | )
27 | }
28 |
29 | dedent <- function(string) {
30 | indent <- sub("(?s)\\S*\n(\\s*).+", "\\1", string, perl = TRUE)
31 | out <- gsub(paste0("(?m)^", indent), "", string, perl = TRUE)
32 | trimws(out)
33 | }
34 |
35 | read_test_file <- function(file) {
36 | cat(readr::read_file(file))
37 | }
38 |
39 | scrub_icon_path <- function(x) {
40 | path_regex <- "(?<=\\()(?:[A-Z]:)?\\/.+\\/(?=[\\w-]+\\.(?:pdf|svg)\\))"
41 | sub(path_regex, "", x, perl = TRUE)
42 | }
43 |
44 | pull_nested_var <- function(cls, nested_var, pull) {
45 | out <- unnest(cls$get_plume(), cols = all_of(nested_var))
46 | out[[pull]]
47 | }
48 |
--------------------------------------------------------------------------------
/tests/testthat/test-as-lines.R:
--------------------------------------------------------------------------------
1 | test_that("as_lines() prints vector elements on distinct lines", {
2 | expect_output(as_lines("a", "b"), "a\\R{2}b", perl = TRUE)
3 | })
4 |
--------------------------------------------------------------------------------
/tests/testthat/test-credit-roles.R:
--------------------------------------------------------------------------------
1 | test_that("credit_roles() returns CRediT roles", {
2 | expect_snapshot(credit_roles())
3 | expect_snapshot(credit_roles(oxford_spelling = FALSE))
4 | })
5 |
6 | # Errors ----
7 |
8 | test_that("credit_roles() gives meaningful error messages", {
9 | expect_snapshot({
10 | credit_roles(oxford_spelling = 1)
11 | }, error = TRUE)
12 | })
13 |
--------------------------------------------------------------------------------
/tests/testthat/test-defunct.R:
--------------------------------------------------------------------------------
1 | test_that("defunct functionalities generate informative errors", {
2 | expect_snapshot(error = TRUE, {
3 | aut <- PlumeQuarto$new(basic_df, temp_file())
4 | aut$set_equal_contributor(1)
5 |
6 | aut <- Plume$new(basic_df)
7 | aut$set_corresponding_authors(zip, by = "given_name")
8 | aut$get_author_list(format = "a")
9 |
10 | Plume$new(data.frame(
11 | given_name = "X",
12 | family_name = "Y",
13 | role = "a"
14 | ))
15 |
16 | Plume$new(basic_df, credit_roles = TRUE)
17 |
18 | plm_template(credit_roles = TRUE)
19 |
20 | everyone_but()
21 | })
22 | })
23 |
--------------------------------------------------------------------------------
/tests/testthat/test-deprecated.R:
--------------------------------------------------------------------------------
1 | test_that("deprecated functionalities generate informative errors", {
2 | expect_snapshot({
3 | aut <- Plume$new(basic_df)
4 |
5 | aut$set_corresponding_authors(1)
6 | aut$get_contact_details(format = "{name} {details}")
7 |
8 | orcid()
9 | })
10 | })
11 |
--------------------------------------------------------------------------------
/tests/testthat/test-get-author-list.R:
--------------------------------------------------------------------------------
1 | test_that("get_author_list() returns author list", {
2 | aut <- Plume$new(basic_df)
3 | aut$set_corresponding_authors(1, 3)
4 |
5 | expect_s3_class(aut$get_author_list(), "plm")
6 | expect_equal(
7 | aut$get_author_list(NULL),
8 | c("Zip Zap", "Ric Rac", "Pim-Pam Pom")
9 | )
10 | expect_equal(
11 | aut$get_author_list(""),
12 | c("Zip Zap", "Ric Rac", "Pim-Pam Pom")
13 | )
14 |
15 | affix_to_authors <- function(...) {
16 | paste0(basic_df$literal_name, ...)
17 | }
18 |
19 | .a <- c("1,2", "3", "1,4")
20 | .c <- c("\\*", "", "\\*")
21 | .n <- c("†,‡", "", "§")
22 |
23 | expect_equal(
24 | aut$get_author_list("a"),
25 | affix_to_authors(.a)
26 | )
27 | expect_equal(
28 | aut$get_author_list("c"),
29 | affix_to_authors(.c)
30 | )
31 | expect_equal(
32 | aut$get_author_list("n"),
33 | affix_to_authors(.n)
34 | )
35 | expect_equal(
36 | aut$get_author_list("anc"),
37 | affix_to_authors(.a, .n, .c)
38 | )
39 | expect_equal(
40 | aut$get_author_list("cna"),
41 | affix_to_authors(.c, .n, .a)
42 | )
43 | expect_equal(
44 | aut$get_author_list("^ac^n"),
45 | affix_to_authors("^", .a, .c, "^", .n)
46 | )
47 |
48 | .seps <- c(",", "", ",")
49 |
50 | expect_equal(
51 | aut$get_author_list("a,c"),
52 | affix_to_authors(.a, .seps, .c)
53 | )
54 | expect_equal(
55 | aut$get_author_list("^a,^c"),
56 | affix_to_authors("^", .a, .seps, "^", .c)
57 | )
58 | expect_equal(
59 | aut$get_author_list("c^,a^"),
60 | affix_to_authors(.c, "^", .seps, .a, "^")
61 | )
62 |
63 | expect_equal(
64 | aut$get_author_list("a,,c"),
65 | affix_to_authors(.a, .seps, .c)
66 | )
67 | expect_equal(
68 | aut$get_author_list("^^ac^^"),
69 | affix_to_authors("^", .a, .c, "^")
70 | )
71 |
72 | .hats <- c("^", "", "^")
73 |
74 | expect_equal(
75 | aut$get_author_list("^a^c^n^"),
76 | affix_to_authors("^", .a, .hats, .c, .hats, .n, "^")
77 | )
78 |
79 | # overrides default symbols
80 |
81 | aut <- Plume$new(basic_df, symbols = list(
82 | affiliation = letters,
83 | corresponding = "#",
84 | note = NULL
85 | ))
86 | aut$set_corresponding_authors(1, 3)
87 |
88 | .a <- c("a,b", "c", "a,d")
89 | .c <- c("#", "", "#")
90 | .n <- c("1,2", "", "3")
91 |
92 | expect_equal(
93 | aut$get_author_list("anc"),
94 | affix_to_authors(.a, .n, .c)
95 | )
96 |
97 | # using custom names
98 |
99 | aut <- Plume$new(
100 | data.frame(given_name = "X", family_name = "Y", aff = "a", aff2 = "b"),
101 | names = c(affiliation = "aff")
102 | )
103 |
104 | expect_equal(
105 | aut$get_author_list("a"),
106 | "X Y1,2"
107 | )
108 | })
109 |
110 | test_that("get_author_list() makes ORCID icons", {
111 | aut <- Plume$new(basic_df)
112 | expect_snapshot(aut$get_author_list("o"), transform = scrub_icon_path)
113 | })
114 |
115 | # Errors ----
116 |
117 | test_that("get_author_list() gives meaningful error messages", {
118 | basic_df["orcid"] <- c(NA, "0000", NA)
119 | aut <- Plume$new(basic_df)
120 |
121 | expect_snapshot({
122 | (expect_error(
123 | aut$get_author_list(1)
124 | ))
125 | (expect_error(
126 | aut$get_author_list("aa")
127 | ))
128 | (expect_error(
129 | aut$get_author_list("az")
130 | ))
131 | (expect_error(
132 | aut$get_author_list("ac")
133 | ))
134 | (expect_error(
135 | aut$get_author_list("o")
136 | ))
137 | })
138 | })
139 |
--------------------------------------------------------------------------------
/tests/testthat/test-get-contact-details.R:
--------------------------------------------------------------------------------
1 | test_that("get_contact_details() returns contact details of corresponding authors", {
2 | aut <- Plume$new(basic_df)
3 | aut$set_corresponding_authors(1, 2)
4 |
5 | expect_s3_class(aut$get_contact_details(), "plm")
6 |
7 | literal_names <- c("Zip Zap", "Ric Rac")
8 | emails <- c("zipzap@test.com", "ricrac@test.com")
9 |
10 | expect_equal(
11 | aut$get_contact_details(),
12 | paste0(emails, " (", literal_names, ")")
13 | )
14 | expect_equal(
15 | aut$get_contact_details("{name}: {details}"),
16 | paste(literal_names, emails, sep = ": ")
17 | )
18 | expect_equal(
19 | aut$get_contact_details("{details}"),
20 | emails
21 | )
22 | expect_equal(
23 | aut$get_contact_details(phone = TRUE),
24 | paste0(emails, c(", +1234", ""), " (", literal_names, ")")
25 | )
26 | expect_equal(
27 | aut$get_contact_details(phone = TRUE, sep = "; "),
28 | paste0(emails, c("; +1234", ""), " (", literal_names, ")")
29 | )
30 | expect_equal(
31 | aut$get_contact_details(email = FALSE, phone = TRUE),
32 | "+1234 (Zip Zap)"
33 | )
34 | })
35 |
36 | test_that("get_contact_details() returns `NULL` if all booleans are `FALSE`", {
37 | aut <- Plume$new(basic_df)
38 | aut$set_corresponding_authors(1)
39 | expect_null(aut$get_contact_details(email = FALSE))
40 | })
41 |
42 | # Errors ----
43 |
44 | test_that("get_conctact_details() gives meaningful error messages", {
45 | aut <- Plume$new(basic_df)
46 |
47 | expect_snapshot({
48 | (expect_error(
49 | aut$get_contact_details("foo")
50 | ))
51 | (expect_error(
52 | aut$get_contact_details("{foo}")
53 | ))
54 | (expect_error(
55 | aut$get_contact_details()
56 | ))
57 | (expect_error(
58 | aut$get_contact_details(email = 1)
59 | ))
60 | (expect_error(
61 | aut$get_contact_details(sep = NULL)
62 | ))
63 | (expect_error(
64 | aut$get_contact_details(sep = "")
65 | ))
66 |
67 | aut$set_corresponding_authors(1)
68 |
69 | (expect_error(
70 | aut$get_contact_details(fax = TRUE)
71 | ))
72 | })
73 | })
74 |
--------------------------------------------------------------------------------
/tests/testthat/test-get-contributions.R:
--------------------------------------------------------------------------------
1 | test_that("get_contributions() return authors' contributions", {
2 | aut <- Plume$new(basic_df, roles = c(analysis = "a", writing = "b"))
3 |
4 | expect_s3_class(aut$get_contributions(), "plm")
5 |
6 | # contributors-roles combinations
7 |
8 | expect_equal(
9 | aut$get_contributions(roles_first = FALSE, by_author = TRUE),
10 | c("Z.Z.: a and b", "R.R.: a", "P.-P.P.: a")
11 | )
12 | expect_equal(
13 | aut$get_contributions(roles_first = TRUE, by_author = TRUE),
14 | c("a and b: Z.Z.", "a: R.R.", "a: P.-P.P.")
15 | )
16 | expect_equal(
17 | aut$get_contributions(roles_first = FALSE, by_author = FALSE),
18 | c("Z.Z., R.R. and P.-P.P.: a", "Z.Z.: b")
19 | )
20 | expect_equal(
21 | aut$get_contributions(roles_first = TRUE, by_author = FALSE),
22 | c("a: Z.Z., R.R. and P.-P.P.", "b: Z.Z.")
23 | )
24 |
25 | # other arguments
26 |
27 | expect_equal(
28 | aut$get_contributions(by_author = FALSE, divider = " "),
29 | c("a Z.Z., R.R. and P.-P.P.", "b Z.Z.")
30 | )
31 | expect_equal(
32 | aut$get_contributions(by_author = FALSE, alphabetical_order = TRUE),
33 | c("a: P.-P.P., R.R. and Z.Z.", "b: Z.Z.")
34 | )
35 | expect_equal(
36 | aut$get_contributions(by_author = FALSE, sep = "; "),
37 | c("a: Z.Z.; R.R. and P.-P.P.", "b: Z.Z.")
38 | )
39 | expect_equal(
40 | aut$get_contributions(by_author = FALSE, sep_last = " & "),
41 | c("a: Z.Z., R.R. & P.-P.P.", "b: Z.Z.")
42 | )
43 | expect_equal(
44 | aut$get_contributions(by_author = FALSE, dotted_initials = FALSE),
45 | c("a: ZZ, RR and P-PP", "b: ZZ")
46 | )
47 | expect_equal(
48 | aut$get_contributions(by_author = FALSE, literal_names = TRUE),
49 | c("a: Zip Zap, Ric Rac and Pim-Pam Pom", "b: Zip Zap")
50 | )
51 | })
52 |
53 | test_that("get_contributions() returns `NULL` if no contributions", {
54 | aut <- Plume$new(data.frame(
55 | given_name = "Zip",
56 | family_name = "Zap",
57 | analysis = ""
58 | ))
59 | expect_null(aut$get_contributions())
60 | })
61 |
62 | test_that("get_contributions() rearranges authors only (#18)", {
63 | aut <- Plume$new(
64 | data.frame(
65 | given_name = c("Zip", "Pim"),
66 | family_name = c("Zap", "Pam"),
67 | role_1 = c(1, NA),
68 | role_2 = c(1, 1)
69 | ),
70 | roles = c(role_1 = "z", role_2 = "a")
71 | )
72 |
73 | expect_equal(
74 | aut$get_contributions(alphabetical_order = TRUE),
75 | c("z: Z.Z.", "a: P.P. and Z.Z.")
76 | )
77 | expect_equal(
78 | aut$get_contributions(by_author = TRUE, alphabetical_order = TRUE),
79 | c("z and a: Z.Z.", "a: P.P.")
80 | )
81 | })
82 |
83 | test_that("get_contributions() handles namesakes (#15)", {
84 | aut <- Plume$new(
85 | data.frame(
86 | given_name = c("Zip", "Zip"),
87 | family_name = c("Zap", "Zap"),
88 | role_1 = c(1, NA),
89 | role_2 = c(1, 1)
90 | ),
91 | roles = c(role_1 = "a", role_2 = "b")
92 | )
93 |
94 | expect_equal(
95 | aut$get_contributions(roles_first = FALSE),
96 | c("Z.Z.: a", "Z.Z. and Z.Z.: b")
97 | )
98 | expect_equal(
99 | aut$get_contributions(roles_first = FALSE, by_author = TRUE),
100 | c("Z.Z.: a and b", "Z.Z.: b")
101 | )
102 | })
103 |
104 | test_that("get_contributions() reorders CRediT roles alphabetically", {
105 | aut <- Plume$new(data.frame(
106 | given_name = c("Zip", "Ric"),
107 | family_name = c("Zap", "Rac"),
108 | writing = c(1, NA),
109 | analysis = c(NA, 1)
110 | ), roles = credit_roles())
111 |
112 | expect_equal(
113 | aut$get_contributions(),
114 | c("Formal analysis: R.R.", "Writing - original draft: Z.Z.")
115 | )
116 | })
117 |
118 | test_that("author order is preserved when using CRediT and `by_author` (#50)", {
119 | aut <- Plume$new(data.frame(
120 | given_name = c("Z", "A"),
121 | family_name = c("Z", "A"),
122 | writing = c(1, NA),
123 | analysis = c(NA, 1)
124 | ))
125 | expect_equal(
126 | aut$get_contributions(roles_first = FALSE, by_author = TRUE),
127 | c("Z.Z.: Writing - original draft", "A.A.: Formal analysis")
128 | )
129 | })
130 |
131 | test_that("set_main_contributors() ranks contributors", {
132 | aut <- Plume$new(
133 | data.frame(
134 | given_name = c("C", "B", "A"),
135 | family_name = c("C", "B", "A"),
136 | writing = rep(1, 3),
137 | analysis = rep(1, 3)
138 | ),
139 | roles = c(writing = "Writing", analysis = "Analysis")
140 | )
141 |
142 | aut$set_main_contributors(3, 2, .roles = "writing")
143 | expect_equal(
144 | aut$get_contributions(),
145 | c("Writing: A.A., B.B. and C.C.", "Analysis: C.C., B.B. and A.A.")
146 | )
147 |
148 | aut$set_main_contributors(2, .roles = "writing")
149 | expect_equal(
150 | aut$get_contributions(alphabetical_order = TRUE),
151 | c("Writing: B.B., A.A. and C.C.", "Analysis: A.A., B.B. and C.C.")
152 | )
153 |
154 | aut$set_main_contributors(writing = c(3, 2))
155 | expect_equal(
156 | aut$get_contributions(),
157 | c("Writing: A.A., B.B. and C.C.", "Analysis: C.C., B.B. and A.A.")
158 | )
159 |
160 | aut$set_main_contributors(3, .roles = c("writing", "analysis", "test"))
161 | expect_equal(
162 | aut$get_contributions(),
163 | c("Writing: A.A., C.C. and B.B.", "Analysis: A.A., C.C. and B.B.")
164 | )
165 |
166 | aut$set_main_contributors(writing = aa, analysis = bb, .by = "initials")
167 | expect_equal(
168 | aut$get_contributions(),
169 | c("Writing: A.A., C.C. and B.B.", "Analysis: B.B., C.C. and A.A.")
170 | )
171 |
172 | aut$set_main_contributors(
173 | writing = c(aa, bb), analysis = bb,
174 | .by = "initials"
175 | )
176 | expect_equal(
177 | aut$get_contributions(),
178 | c("Writing: A.A., B.B. and C.C.", "Analysis: B.B., C.C. and A.A.")
179 | )
180 | })
181 |
182 | # Errors ----
183 |
184 | test_that("get_contributions() gives meaningful error messages", {
185 | aut <- Plume$new(basic_df)
186 |
187 | expect_snapshot({
188 | (expect_error(
189 | aut$get_contributions(roles_first = "")
190 | ))
191 | (expect_error(
192 | aut$get_contributions(by_author = "")
193 | ))
194 | (expect_error(
195 | aut$get_contributions(alphabetical_order = "")
196 | ))
197 | (expect_error(
198 | aut$get_contributions(dotted_initials = "")
199 | ))
200 | (expect_error(
201 | aut$get_contributions(literal_names = "")
202 | ))
203 | (expect_error(
204 | aut$get_contributions(sep = 1)
205 | ))
206 | (expect_error(
207 | aut$get_contributions(sep_last = 1)
208 | ))
209 | (expect_error(
210 | aut$get_contributions(divider = 1)
211 | ))
212 | })
213 |
214 | aut <- Plume$new(data.frame(given_name = "A", family_name = "B"))
215 | expect_snapshot(aut$get_contributions(), error = TRUE)
216 | })
217 |
--------------------------------------------------------------------------------
/tests/testthat/test-get-footnotes.R:
--------------------------------------------------------------------------------
1 | test_that("get_affiliations/notes() return affiliations/notes", {
2 | aut <- Plume$new(basic_df)
3 |
4 | expect_s3_class(aut$get_notes(), "plm")
5 |
6 | expect_equal(
7 | aut$get_affiliations(),
8 | c("^1^a", "^2^b", "^3^c", "^4^d")
9 | )
10 | expect_equal(
11 | aut$get_affiliations(superscript = FALSE),
12 | c("1a", "2b", "3c", "4d")
13 | )
14 | expect_equal(
15 | aut$get_affiliations(sep = ": ", superscript = FALSE),
16 | c("1: a", "2: b", "3: c", "4: d")
17 | )
18 |
19 | aut <- Plume$new(basic_df, symbols = list(affiliation = letters))
20 |
21 | expect_equal(aut$get_affiliations(), c("^a^a", "^b^b", "^c^c", "^d^d"))
22 | expect_equal(aut$get_notes(), c("^†^a", "^‡^c", "^§^b"))
23 | })
24 |
25 | test_that("get_affiliations/notes() return `NULL` if no affiliations/notes", {
26 | aut <- Plume$new(data.frame(
27 | given_name = "Zip",
28 | family_name = "Zap",
29 | note = ""
30 | ))
31 | expect_null(aut$get_notes())
32 | })
33 |
34 | # Errors ----
35 |
36 | test_that("get_affiliations()/get_notes() give meaningful error messages", {
37 | aut <- Plume$new(basic_df)
38 |
39 | expect_snapshot({
40 | (expect_error(
41 | aut$get_affiliations(sep = 1)
42 | ))
43 | (expect_error(
44 | aut$get_affiliations(superscript = "")
45 | ))
46 | (expect_error(
47 | aut$get_notes(sep = 1)
48 | ))
49 | (expect_error(
50 | aut$get_notes(superscript = "")
51 | ))
52 | })
53 |
54 | aut <- Plume$new(data.frame(given_name = "A", family_name = "B"))
55 |
56 | expect_snapshot({
57 | (expect_error(
58 | aut$get_affiliations()
59 | ))
60 | (expect_error(
61 | aut$get_notes()
62 | ))
63 | })
64 | })
65 |
--------------------------------------------------------------------------------
/tests/testthat/test-get-orcids.R:
--------------------------------------------------------------------------------
1 | test_that("get_orcids() returns authors' ORCID", {
2 | aut <- Plume$new(basic_df)
3 |
4 | expect_s3_class(aut$get_orcids(), "plm")
5 |
6 | expect_snapshot(aut$get_orcids(), transform = scrub_icon_path)
7 | expect_snapshot(aut$get_orcids(sep = " - "), transform = scrub_icon_path)
8 | expect_snapshot(aut$get_orcids(icon = FALSE))
9 | expect_snapshot(aut$get_orcids(icon = FALSE, compact = TRUE))
10 | })
11 |
12 | # Errors ----
13 |
14 | test_that("get_orcids() gives meaningful error messages", {
15 | aut <- Plume$new(basic_df)
16 |
17 | expect_snapshot({
18 | (expect_error(
19 | aut$get_orcids(compact = 1)
20 | ))
21 | (expect_error(
22 | aut$get_orcids(icon = 1)
23 | ))
24 | (expect_error(
25 | aut$get_orcids(sep = 1)
26 | ))
27 | })
28 |
29 | basic_df$orcid <- c(NA, "0000", NA)
30 | aut <- Plume$new(basic_df)
31 | expect_snapshot(aut$get_orcids(icon = FALSE), error = TRUE)
32 |
33 | aut <- Plume$new(data.frame(given_name = "A", family_name = "B"))
34 | expect_snapshot(aut$get_orcids(), error = TRUE)
35 | })
36 |
--------------------------------------------------------------------------------
/tests/testthat/test-icon.R:
--------------------------------------------------------------------------------
1 | test_that("printing a `plm_icon` object returns a formatted output", {
2 | expect_output(print(icn_orcid()), "")
3 | })
4 |
5 | test_that("icn_orcid() makes orcid icon metadata", {
6 | skip_if(!rmarkdown::pandoc_available(), "pandoc is not available")
7 |
8 | render <- partial(rmarkdown::render, clean = FALSE, quiet = TRUE)
9 |
10 | read_rendered_md <- function() {
11 | read_test_file(list.files(pattern = "\\.md$"))
12 | }
13 |
14 | withr::with_tempdir({
15 | tmp_file <- withr::local_tempfile(lines = dedent("
16 | ---
17 | title: test
18 | ---
19 | ```{r results = 'asis'}
20 | str(attributes(icn_orcid()))
21 | str(attributes(icn_orcid(size = 24)))
22 | str(attributes(icn_orcid(bw = TRUE)))
23 | ```
24 | "), fileext = ".Rmd", tmpdir = getwd())
25 |
26 | # pdf
27 | # use rtf_document to speed up test runs
28 | render(tmp_file, output_format = "rtf_document")
29 | expect_snapshot(read_rendered_md())
30 |
31 | # svg
32 | render(tmp_file, output_format = "html_document")
33 | expect_snapshot(read_rendered_md())
34 | })
35 | })
36 |
37 | # Errors ----
38 |
39 | test_that("icn_orcid() gives meaningful error messages", {
40 | expect_snapshot({
41 | (expect_error(
42 | icn_orcid(size = NULL)
43 | ))
44 | (expect_error(
45 | icn_orcid(bw = 1)
46 | ))
47 | })
48 | })
49 |
--------------------------------------------------------------------------------
/tests/testthat/test-plm-template.R:
--------------------------------------------------------------------------------
1 | test_that("plm_template() returns a table template", {
2 | df <- plm_template(role_cols = NULL)
3 |
4 | expect_equal(nrow(df), 0L)
5 |
6 | nms_minimal <- c(
7 | "given_name", "family_name", "email", "orcid",
8 | "affiliation_1", "affiliation_2", "note"
9 | )
10 | nms_minimal_crt <- c(nms_minimal, names(credit_roles()))
11 |
12 | expect_named(df, nms_minimal, ignore.order = TRUE)
13 | expect_named(
14 | plm_template(role_cols = credit_roles()),
15 | nms_minimal_crt,
16 | ignore.order = TRUE
17 | )
18 |
19 | df <- plm_template(minimal = FALSE, role_cols = NULL)
20 | nms_minimal_all <- c(nms_minimal, "phone", "fax", "url")
21 |
22 | expect_named(df, nms_minimal_all, ignore.order = TRUE)
23 | })
24 |
25 | test_that("role columns are of type numeric", {
26 | get_numeric_cols <- function(tbl) {
27 | names(tbl)[sapply(tbl, is.numeric)]
28 | }
29 |
30 | df <- plm_template(role_cols = "foo")
31 | expect_equal(get_numeric_cols(df), "foo")
32 |
33 | df <- plm_template(role_cols = c(a = "foo"))
34 | expect_equal(get_numeric_cols(df), "a")
35 | })
36 |
37 | # Errors ----
38 |
39 | test_that("plm_template() gives meaningful error messages", {
40 | expect_snapshot({
41 | (expect_error(
42 | plm_template(minimal = 1)
43 | ))
44 | (expect_error(
45 | plm_template(role_cols = 1)
46 | ))
47 | (expect_error(
48 | plm_template(role_cols = c("foo", "foo"))
49 | ))
50 | })
51 | })
52 |
--------------------------------------------------------------------------------
/tests/testthat/test-print.R:
--------------------------------------------------------------------------------
1 | test_that("printing a plume object is identical to cat()", {
2 | aut <- Plume$new(data.frame(given_name = "X", family_name = "Y"))
3 | expect_output(print(aut$get_author_list()), "X Y")
4 | })
5 |
--------------------------------------------------------------------------------
/tests/testthat/test-sequential.R:
--------------------------------------------------------------------------------
1 | test_that("sequences of characters are properly generated", {
2 | df <- data.frame(given_name = "X", family_name = "Y", affiliation = 1:55)
3 | aut <- Plume$new(df, symbols = list(affiliation = letters))
4 |
5 | .h <- paste0("X Y", c("a", "b", "c", "d", "e", "f"))
6 |
7 | expect_equal(head(aut$get_author_list("a")), .h)
8 | expect_equal(
9 | tail(aut$get_author_list("a")),
10 | paste0("X Y", c("xx", "yy", "zz", "aaa", "bbb", "ccc"))
11 | )
12 |
13 | aut <- Plume$new(df, symbols = list(affiliation = sequential(letters)))
14 |
15 | expect_equal(head(aut$get_author_list("a")), .h)
16 | expect_equal(
17 | tail(aut$get_author_list("a")),
18 | paste0("X Y", c("ax", "ay", "az", "ba", "bb", "bc"))
19 | )
20 | })
21 |
22 | # Errors ----
23 |
24 | test_that("sequential() gives meaningful error messages", {
25 | expect_snapshot(sequential(1), error = TRUE)
26 | })
27 |
--------------------------------------------------------------------------------
/tests/testthat/test-set-default-names.R:
--------------------------------------------------------------------------------
1 | test_that("set_default_names() sets new plume names", {
2 | nms <- set_default_names(
3 | initials = "initiales",
4 | literal_name = "nom_complet",
5 | corresponding = "correspondant",
6 | contributor_rank = "rang_contributeur",
7 | given_name = "prénom",
8 | family_name = "nom",
9 | email = "courriel",
10 | phone = "téléphone"
11 | )
12 |
13 | expect_snapshot(str(nms))
14 |
15 | nms <- set_default_names(
16 | equal_contributor = "contribution_égale",
17 | .plume_quarto = FALSE
18 | )
19 |
20 | expect_null(list_fetch(nms, "equal_contributor")[[1]])
21 |
22 | nms <- set_default_names(
23 | equal_contributor = "contribution_égale",
24 | .plume_quarto = TRUE
25 | )
26 |
27 | expect_equal(
28 | list_fetch(nms, "equal_contributor")[[1]],
29 | "contribution_égale"
30 | )
31 |
32 | nms <- set_default_names(foo = "foo", analysis = "bar")
33 |
34 | expect_equal(nms, .names_plume)
35 | })
36 |
37 | # Errors ----
38 |
39 | test_that("set_default_names() gives meaningful error messages", {
40 | expect_snapshot({
41 | (expect_error(set_default_names()))
42 | (expect_error(set_default_names(1)))
43 | (expect_error(set_default_names("a")))
44 | (expect_error(set_default_names(x = "a", y = "a")))
45 | (expect_error(set_default_names(x = "a", x = "b")))
46 | (expect_error(set_default_names(given_name = "nom", .plume_quarto = 1)))
47 | })
48 | })
49 |
--------------------------------------------------------------------------------
/tests/testthat/test-set-main-contributors.R:
--------------------------------------------------------------------------------
1 | test_that("ranking contributors makes a `contributor_rank` column", {
2 | aut <- Plume$new(basic_df)
3 | aut$set_main_contributors(1, .roles = "analysis")
4 |
5 | expect_named(
6 | aut$get_plume()$role[[1]],
7 | c("role", "contributor_rank")
8 | )
9 | })
10 |
11 | test_that("set_main_contributors() ranks contributors", {
12 | aut <- Plume$new(basic_df)
13 | aut$set_main_contributors(2, 3, .roles = "analysis")
14 |
15 | expect_equal(
16 | pull_nested_var(aut, "role", "contributor_rank"),
17 | c(3, NA, 1, NA, 2, NA)
18 | )
19 | })
20 |
21 | test_that("`.roles` applies to any unnamed expression (#65)", {
22 | aut <- Plume$new(data.frame(
23 | given_name = LETTERS[1:3],
24 | family_name = LETTERS[1:3],
25 | analysis = 1,
26 | writing = 1
27 | ))
28 |
29 | aut$set_main_contributors(analysis = 3, 2, 3, .roles = "writing")
30 | expect_equal(
31 | pull_nested_var(aut, "role", "contributor_rank"),
32 | c(2, 3, 2, 1, 1, 2)
33 | )
34 |
35 | aut$set_main_contributors(analysis = 3, 2, 3, .roles = c(writing = "foo"))
36 | expect_equal(
37 | pull_nested_var(aut, "role", "contributor_rank"),
38 | c(2, 3, 2, 1, 1, 2)
39 | )
40 | })
41 |
42 | test_that("named expressions have the priority over `.roles`", {
43 | aut <- Plume$new(basic_df)
44 | aut$set_main_contributors(analysis = 3, 2, .roles = "analysis")
45 |
46 | expect_equal(
47 | pull_nested_var(aut, "role", "contributor_rank"),
48 | c(2, NA, 2, NA, 1, NA)
49 | )
50 | })
51 |
52 | # Errors ----
53 |
54 | test_that("set_ranks() gives meaningful error messages", {
55 | aut <- Plume$new(basic_df)
56 |
57 | expect_snapshot({
58 | (expect_error(aut$set_main_contributors()))
59 | (expect_error(aut$set_main_contributors(1, .roles = 1)))
60 | (expect_error(aut$set_main_contributors(1, .roles = c("x", "x"))))
61 | (expect_error(aut$set_main_contributors(1, .by = 1)))
62 | })
63 | })
64 |
--------------------------------------------------------------------------------
/tests/testthat/test-set-status.R:
--------------------------------------------------------------------------------
1 | test_that("sets status to selected authors", {
2 | aut <- PlumeQuarto$new(basic_df, temp_file())
3 |
4 | # set_corresponding_authors
5 |
6 | expect_equal({
7 | aut$set_corresponding_authors(everyone())
8 | aut$get_plume()$corresponding
9 | }, rep(TRUE, 3))
10 |
11 | expect_equal({
12 | aut$set_corresponding_authors(plume::everyone())
13 | aut$get_plume()$corresponding
14 | }, rep(TRUE, 3))
15 |
16 | expect_equal({
17 | aut$set_corresponding_authors(1)
18 | aut$get_plume()$corresponding
19 | }, c(TRUE, FALSE, FALSE))
20 |
21 | expect_equal({
22 | aut$set_corresponding_authors(1, 3)
23 | aut$get_plume()$corresponding
24 | }, c(TRUE, FALSE, TRUE))
25 |
26 | expect_equal({
27 | aut$set_corresponding_authors(zip, .by = "given_name")
28 | aut$get_plume()$corresponding
29 | }, c(TRUE, FALSE, FALSE))
30 |
31 | # set_cofirst_authors
32 |
33 | expect_equal({
34 | aut$set_cofirst_authors(zip, .by = "given_name")
35 | aut$get_plume()$equal_contributor
36 | }, c(TRUE, FALSE, FALSE))
37 |
38 | # set_deceased
39 |
40 | expect_equal({
41 | aut$set_deceased(zip, .by = "given_name")
42 | aut$get_plume()$deceased
43 | }, c(TRUE, FALSE, FALSE))
44 | })
45 |
46 | # Errors ----
47 |
48 | test_that("set_*() methods give meaningful error messages", {
49 | aut <- PlumeQuarto$new(basic_df, temp_file())
50 |
51 | expect_snapshot({
52 | (expect_error(
53 | aut$set_corresponding_authors()
54 | ))
55 | (expect_error(
56 | aut$set_corresponding_authors(a, .by = "foo")
57 | ))
58 | (expect_error(
59 | aut$set_corresponding_authors(a, .by = "")
60 | ))
61 | (expect_error(
62 | aut$set_corresponding_authors(a, .by = 1)
63 | ))
64 | (expect_error(
65 | aut$set_corresponding_authors(x <- y)
66 | ))
67 | (expect_error(
68 | aut$set_cofirst_authors(a, .by = "foo")
69 | ))
70 | (expect_error(
71 | aut$set_cofirst_authors(a, .by = "")
72 | ))
73 | (expect_error(
74 | aut$set_cofirst_authors(a, .by = 1)
75 | ))
76 | (expect_error(
77 | aut$set_deceased(a, .by = "foo")
78 | ))
79 | (expect_error(
80 | aut$set_deceased(a, .by = "")
81 | ))
82 | (expect_error(
83 | aut$set_deceased(a, .by = 1)
84 | ))
85 | })
86 | })
87 |
88 | test_that("everyone*() selectors error if used in a wrong context", {
89 | expect_snapshot(everyone(), error = TRUE)
90 | })
91 |
--------------------------------------------------------------------------------
/tests/testthat/test-to-yaml.R:
--------------------------------------------------------------------------------
1 | test_that("to_yaml() injects authors and affiliations into a `.qmd`", {
2 | tmp_file <- withr::local_tempfile(
3 | lines = "---\ntitle: test\n---\n\n```{r}\n#| echo: false\nx <- 1\n```",
4 | fileext = ".qmd"
5 | )
6 |
7 | aut <- PlumeQuarto$new(basic_df, tmp_file)
8 | aut$set_corresponding_authors(1)
9 | aut$to_yaml()
10 | expect_snapshot(read_test_file(tmp_file))
11 |
12 | aut <- PlumeQuarto$new(basic_df[c(3, 2, 1), ], tmp_file)
13 | aut$set_corresponding_authors(1)
14 | aut$to_yaml()
15 | expect_snapshot(read_test_file(tmp_file))
16 |
17 | aut <- PlumeQuarto$new(data.frame(
18 | given_name = "Zip", family_name = "Zap",
19 | affiliation1 = "name=a department=b city=c postal-code=d",
20 | affiliation2 = "city=e name=f department=g",
21 | affiliation3 = "h"
22 | ), tmp_file)
23 | aut$to_yaml()
24 | expect_snapshot(read_test_file(tmp_file))
25 | })
26 |
27 | test_that("to_yaml() doesn't add the `affiliations` schema if there're no affiliations", {
28 | tmp_file <- withr::local_tempfile(
29 | lines = dedent("
30 | ---
31 | affiliations:
32 | - name: a
33 | ---
34 | "),
35 | fileext = ".qmd"
36 | )
37 |
38 | aut <- PlumeQuarto$new(
39 | data.frame(given_name = "Zip", family_name = "Zap"),
40 | tmp_file
41 | )
42 | aut$to_yaml()
43 |
44 | expect_snapshot(read_test_file(tmp_file))
45 | })
46 |
47 | test_that("to_yaml() pushes data to empty YAML headers", {
48 | tmp_file <- withr::local_tempfile(lines = "---\n---", fileext = ".qmd")
49 |
50 | aut <- PlumeQuarto$new(tibble(
51 | given_name = "Zip",
52 | family_name = "Zap",
53 | `meta-foo` = "bar"
54 | ), tmp_file)
55 | aut$to_yaml()
56 |
57 | expect_snapshot(read_test_file(tmp_file))
58 | })
59 |
60 | test_that("to_yaml() exits before pushing new header if invalid YAML", {
61 | tmp_file <- withr::local_tempfile(
62 | lines = "---\ntitle: test\n--\n\nLorem ipsum\n\n---",
63 | fileext = ".qmd"
64 | )
65 |
66 | old <- readr::read_file(tmp_file)
67 |
68 | aut <- PlumeQuarto$new(basic_df, tmp_file)
69 | try(aut$to_yaml(), silent = TRUE)
70 |
71 | new <- readr::read_file(tmp_file)
72 |
73 | expect_equal(old, new)
74 | })
75 |
76 | test_that("to_yaml() preserves line breaks preceding `---` (#37)", {
77 | tmp_file <- withr::local_tempfile(
78 | lines = "---\n---\nLorem ipsum\n---",
79 | fileext = ".qmd"
80 | )
81 |
82 | aut <- PlumeQuarto$new(
83 | data.frame(given_name = "Zip", family_name = "Zap"),
84 | tmp_file
85 | )
86 | aut$to_yaml()
87 |
88 | expect_snapshot(read_test_file(tmp_file))
89 | })
90 |
91 | test_that("to_yaml() writes in a separate header to preserve strippable data (#56)", {
92 | tmp_file <- withr::local_tempfile(
93 | lines = dedent("
94 | ---
95 | title: test # this is a title
96 | foo: >
97 | Lorem ipsum
98 | Vivamus quis
99 | ---
100 | "),
101 | fileext = ".qmd"
102 | )
103 |
104 | aut <- PlumeQuarto$new(
105 | data.frame(given_name = "Zip", family_name = "Zap"),
106 | tmp_file
107 | )
108 |
109 | expect_warning(
110 | aut$to_yaml(),
111 | "Writing author metadata in a separate YAML header"
112 | )
113 | expect_snapshot(read_test_file(tmp_file))
114 | })
115 |
116 | test_that("to_yaml() can push data into YAML files", {
117 | tmp_file <- withr::local_tempfile(
118 | lines = "title: foo",
119 | fileext = ".yaml"
120 | )
121 |
122 | aut <- PlumeQuarto$new(
123 | data.frame(given_name = "Zip", family_name = "Zap"),
124 | tmp_file
125 | )
126 | aut$to_yaml()
127 |
128 | expect_snapshot(read_test_file(tmp_file))
129 | })
130 |
131 | test_that("to_yaml() properly handles authors with no roles (#81)", {
132 | tmp_file <- withr::local_tempfile(
133 | lines = "title: foo",
134 | fileext = ".yaml"
135 | )
136 |
137 | aut <- PlumeQuarto$new(
138 | data.frame(
139 | given_name = c("A", "B"),
140 | family_name = c("A", "B"),
141 | writing = c(1, NA),
142 | analysis = c(1, NA)
143 | ),
144 | tmp_file
145 | )
146 | aut$to_yaml()
147 |
148 | expect_snapshot(read_test_file(tmp_file))
149 | })
150 |
151 | # Errors ----
152 |
153 | test_that("to_yaml() errors if no YAML headers is found", {
154 | tmp_file <- withr::local_tempfile(
155 | lines = "---\ntitle: test---",
156 | fileext = ".qmd"
157 | )
158 | aut <- PlumeQuarto$new(basic_df, tmp_file)
159 |
160 | expect_snapshot(aut$to_yaml(), error = TRUE)
161 | })
162 |
163 | test_that("to_yaml() errors if an invalid ORCID identifier is found ", {
164 | aut <- PlumeQuarto$new(
165 | data.frame(given_name = "X", family_name = "Y", orcid = "0000"),
166 | temp_file()
167 | )
168 | expect_snapshot(aut$to_yaml(), error = TRUE)
169 | })
170 |
--------------------------------------------------------------------------------
/vignettes/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 | *.R
3 |
--------------------------------------------------------------------------------
/vignettes/comprehensive-affiliation-schema.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Comprehensive affiliation schema"
3 | output: rmarkdown::html_vignette
4 | vignette: >
5 | %\VignetteIndexEntry{Comprehensive affiliation schema}
6 | %\VignetteEngine{knitr::rmarkdown}
7 | %\VignetteEncoding{UTF-8}
8 | ---
9 |
10 | ```{r, include = FALSE}
11 | knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
12 | library(plume)
13 | ```
14 |
15 | Quarto provides a complete [affiliation schema](https://quarto.org/docs/journals/authors.html#affiliations-schema) to define affiliations in more detail.
16 |
17 | To generate comprehensive affiliations in plume, you can specify affiliation items in the input data using the following syntax `key_1=item_1 key_2=item_2 key_n=item_n`. `PlumeQuarto` will automatically parse affiliations and assign each item to its respective key.
18 |
19 | Affiliations with no or unrecognised keys are assigned to the `name` key.
20 |
21 | ```{r}
22 | author <- tibble::tibble(
23 | given_name = "René",
24 | family_name = "Descartes",
25 | affiliation1 = "Collège royal Henri-le-Grand",
26 | affiliation2 = "
27 | city=Poitiers
28 | name=Université de Poitiers
29 | address=15 Rue de l'Hôtel Dieu
30 | country=Kingdom of France
31 | ",
32 | affiliation3 = "name=Academia Franekerensis country=The Netherlands city=Franeker"
33 | )
34 | ```
35 |
36 | ```{r, include = FALSE}
37 | tmp_file <- withr::local_tempfile(
38 | lines = "---\ntitle: Cogito ergo sum\n---",
39 | fileext = ".qmd"
40 | )
41 | aut <- PlumeQuarto$new(author, tmp_file)
42 | ```
43 |
44 | ```{r, eval = FALSE}
45 | aut <- PlumeQuarto$new(author, file = "file.qmd")
46 | aut$to_yaml()
47 | ```
48 |
49 | The above will produce the following YAML header:
50 |
51 | ```{r, echo = FALSE, comment = ""}
52 | aut$to_yaml()
53 | cat(readr::read_file(tmp_file))
54 | ```
55 |
--------------------------------------------------------------------------------
/vignettes/plume-workflow.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "plume workflow"
3 | output: rmarkdown::html_vignette
4 | vignette: >
5 | %\VignetteIndexEntry{plume workflow}
6 | %\VignetteEngine{knitr::rmarkdown}
7 | %\VignetteEncoding{UTF-8}
8 | ---
9 |
10 | ```{r include = FALSE}
11 | knitr::opts_chunk$set(
12 | collapse = TRUE,
13 | comment = "#>"
14 | )
15 | ```
16 |
17 | ## Data
18 |
19 | plume is designed to work with spreadsheets, which makes it easy to store, maintain and share data with co-authors. I recommend using [Google Sheets](https://docs.google.com/spreadsheets/) to take advantage of the R interface provided by the [googlesheets4](https://googlesheets4.tidyverse.org) package.
20 |
21 | First, you'll need to create a spreadsheet. `plm_template()` provides a default template for that purpose.
22 |
23 | ```{r eval = FALSE}
24 | library(googlesheets4)
25 |
26 | gs4_create(
27 | name = "authors",
28 | sheets = plm_template()
29 | )
30 | ```
31 |
32 | The above will create a sheet named `authors` with the columns defined by `plm_template()`.
33 |
34 | Enter your information and share the sheet with your collaborators so they can add theirs too.
35 |
36 | Note that if it's the first time you use googlesheets4, you'll need to grant the package permission to work with Google Sheets. You can read more about googlesheets4 authentication [here](https://googlesheets4.tidyverse.org/reference/gs4_auth.html).
37 |
38 | Once the sheet is online, use `read_sheet()` to read it in R.
39 |
40 | ```{r eval = FALSE}
41 | read_sheet(gs4_find("authors"))
42 | ```
43 |
44 | ## Set up
45 |
46 | ### Plume
47 |
48 | If you use `Plume`, put the code directly in your R Markdown or Quarto document as shown in the example below:
49 |
50 | ````{verbatim}
51 | ---
52 | title: An awesome publication
53 | execute:
54 | echo: false
55 | ---
56 |
57 | ```{r}
58 | #| label: setup
59 | #| include: false
60 |
61 | library(googlesheets4)
62 | library(plume)
63 |
64 | tbl_authors <- read_sheet(gs4_find("sheet_name"))
65 |
66 | aut <- Plume$new(tbl_authors)
67 | aut$set_corresponding_authors(1)
68 | ```
69 |
70 | `r aut$get_author_list("^a,^co")`
71 |
72 | ```{r}
73 | #| results: asis
74 | aut$get_affiliations() |> cat(sep = "\n\n")
75 | ```
76 |
77 | \*Correspondence to: `r aut$get_contact_details()`
78 |
79 | ## Main text
80 |
81 | Lorem ipsum...
82 |
83 | ## Contributions
84 |
85 | ```{r}
86 | #| results: asis
87 | aut$get_contributions() |> cat(sep = "; ")
88 | ```
89 | ````
90 |
91 | To modify author data, simply edit the spreadsheet. All author information in the document will update automatically the next time you render it.
92 |
93 | ### PlumeQuarto
94 |
95 | If you use `PlumeQuarto` to inject author information in a Quarto document, you'll have to pass the data from a separate R script.
96 |
97 | ```{r, eval = FALSE}
98 | library(googlesheets4)
99 | library(plume)
100 |
101 | tbl_authors <- read_sheet(gs4_find("sheet_name"))
102 |
103 | aut <- PlumeQuarto$new(tbl_authors, file = "file.qmd")
104 | aut$set_corresponding_authors(1)
105 | aut$to_yaml()
106 | ```
107 |
108 | Remember to run the script everytime the spreadsheet is updated to implement the changes in your document.
109 |
--------------------------------------------------------------------------------
/vignettes/working-in-other-languages.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Working in other languages"
3 | output: rmarkdown::html_vignette
4 | vignette: >
5 | %\VignetteIndexEntry{Working in other languages}
6 | %\VignetteEngine{knitr::rmarkdown}
7 | %\VignetteEncoding{UTF-8}
8 | ---
9 |
10 | ```{r, include = FALSE}
11 | knitr::opts_chunk$set(
12 | collapse = TRUE,
13 | comment = "#>"
14 | )
15 | library(plume)
16 | ```
17 |
18 | If you work in a language other than English, you can extend plume classes with default names in your desired language. plume provides `set_default_names()` to help you set new default names.
19 |
20 | E.g. to extend `Plume` with default names in French:
21 |
22 | ```{r}
23 | PlumeFr <- R6::R6Class(
24 | classname = "PlumeFr",
25 | inherit = Plume,
26 | private = list(
27 | plume_names = set_default_names(
28 | initials = "initiales",
29 | literal_name = "nom_complet",
30 | corresponding = "correspondant",
31 | given_name = "prénom",
32 | family_name = "nom",
33 | email = "courriel",
34 | phone = "téléphone"
35 | )
36 | )
37 | )
38 | ```
39 |
40 | ```{r}
41 | PlumeFr$new(encyclopedists_fr)
42 | ```
43 |
44 | You can also overwrite the default arguments of some methods to match your language. I recommend doing it in the `public` argument of the class definition. For the purpose of this example, I'll use the `set()` method instead. For example, to change `divider` and `sep_last` to ` : ` and ` et ` in `get_contributions()`:
45 |
46 | ```{r}
47 | PlumeFr$set("public", "get_contributions", function(
48 | roles_first = TRUE,
49 | by_author = FALSE,
50 | alphabetical_order = FALSE,
51 | dotted_initials = TRUE,
52 | literal_names = FALSE,
53 | divider = " : ",
54 | sep = ", ",
55 | sep_last = " et "
56 | ) {
57 | super$get_contributions(
58 | roles_first, by_author, alphabetical_order, dotted_initials,
59 | literal_names, divider, sep, sep_last
60 | )
61 | })
62 | ```
63 |
64 | ```{r}
65 | aut <- PlumeFr$new(
66 | encyclopedists_fr,
67 | roles = c(supervision = "Supervision", rédaction = "Rédaction")
68 | )
69 | aut$get_contributions()
70 | ```
71 |
--------------------------------------------------------------------------------