Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/src/core/author.ts
3557 views
1
/*
2
* author.ts
3
*
4
* Copyright (C) 2020-2022 Posit Software, PBC
5
*/
6
7
import { CSLName } from "./csl.ts";
8
9
export interface Author {
10
name: string | CSLName;
11
affilliation?: Affiliation;
12
url?: string;
13
orcid?: string;
14
}
15
16
export interface Affiliation {
17
name: string;
18
url?: string;
19
}
20
21
const kName = "name";
22
const kGiven = "given";
23
const kFamily = "family";
24
const kDropping = "dropping-particle";
25
const kNonDropping = "non-dropping-particle";
26
const kAffiliation = "affiliation";
27
const kAfilliationUrl = "affiliation-url";
28
const kOrcid = "orcid";
29
const kUrl = "url";
30
31
export function cslNameToString(cslName: string | CSLName) {
32
if (typeof cslName === "string") return cslName;
33
if (cslName.literal) return cslName.literal;
34
const parts: string[] = [];
35
36
if (cslName.given) {
37
parts.push(cslName.given);
38
}
39
40
if (cslName["dropping-particle"]) {
41
parts.push(cslName["dropping-particle"]);
42
}
43
if (cslName["non-dropping-particle"]) {
44
parts.push(cslName["non-dropping-particle"]);
45
}
46
if (cslName.family) {
47
parts.push(cslName.family);
48
}
49
50
return parts.join(" ");
51
}
52
53
export function parseAuthor(authorRaw: unknown, strict?: boolean) {
54
if (!authorRaw) {
55
return undefined;
56
}
57
const parsed: Author[] = [];
58
const authors = Array.isArray(authorRaw) ? authorRaw : [authorRaw];
59
let unrecognized = false;
60
authors.forEach((author) => {
61
if (typeof author === "string") {
62
// Its a string, so make it a name
63
parsed.push({
64
name: author,
65
});
66
} else if (typeof author === "object") {
67
// Parse the author object
68
// Currently this only supports simple 'Distill Style'
69
// authors and affiliations
70
const name = author[kName];
71
if (name) {
72
const auth: Author = {
73
name,
74
};
75
const affilation = author[kAffiliation];
76
if (affilation) {
77
auth.affilliation = { name: affilation };
78
if (author[kAfilliationUrl]) {
79
auth.affilliation.url = author[kAfilliationUrl];
80
}
81
}
82
83
const orcid = author[kOrcid];
84
if (orcid) {
85
auth.orcid = orcid;
86
}
87
88
const url = author[kUrl];
89
if (url) {
90
auth.url = url;
91
}
92
93
parsed.push(auth);
94
} else if (author[kFamily]) {
95
const given = author[kGiven];
96
const family = author[kFamily];
97
const dropping = author[kDropping];
98
const nonDropping = author[kNonDropping];
99
parsed.push({
100
name: {
101
[kGiven]: given,
102
[kFamily]: family,
103
[kDropping]: dropping,
104
[kNonDropping]: nonDropping,
105
},
106
});
107
} else {
108
unrecognized = true;
109
}
110
}
111
});
112
113
// If we didn't know how to parse this author
114
// just stand down - we just don't recognize this.
115
if (strict && unrecognized) {
116
return undefined;
117
} else {
118
return parsed;
119
}
120
}
121
122