Skip to content

Commit

Permalink
🤝 Adds collaboration associated with author in frontmatter (#343)
Browse files Browse the repository at this point in the history
  • Loading branch information
dressedfez authored May 31, 2023
1 parent d068df6 commit 97518ca
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 3 deletions.
6 changes: 6 additions & 0 deletions .changeset/friendly-gifts-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'myst-frontmatter': patch
'myst-templates': patch
---

Add collaborations list to myst-frontmatter
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const TEST_AUTHOR: Author = {
email: '[email protected]',
roles: ['Software', 'Validation'],
affiliations: ['example university'],
collaborations: ['example collaboration'],
twitter: '@test',
github: 'test',
website: 'https://example.com',
Expand Down
1 change: 1 addition & 0 deletions packages/myst-frontmatter/src/frontmatter/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface Author {
email?: string;
roles?: AuthorRoles[];
affiliations?: string[];
collaborations?: string[];
twitter?: string;
github?: string;
website?: string;
Expand Down
11 changes: 11 additions & 0 deletions packages/myst-frontmatter/src/frontmatter/validators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ const AUTHOR_KEYS = [
'email',
'roles',
'affiliations',
'collaborations',
'twitter',
'github',
'website',
Expand Down Expand Up @@ -275,6 +276,16 @@ export function validateAuthor(input: any, opts: ValidationOptions) {
return validateString(aff, affiliationsOpts)?.trim();
});
}
if (defined(value.collaborations)) {
const collaborationsOpts = incrementOptions('collaborations', opts);
let collaborations = value.collaborations;
if (typeof collaborations === 'string') {
collaborations = collaborations.split(';');
}
output.collaborations = validateList(collaborations, collaborationsOpts, (col) => {
return validateString(col, collaborationsOpts)?.trim();
});
}
if (defined(value.twitter)) {
output.twitter = validateString(value.twitter, incrementOptions('twitter', opts));
}
Expand Down
24 changes: 23 additions & 1 deletion packages/myst-templates/src/frontmatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,16 @@ function undefinedIfEmpty<T>(array?: T[]): T[] | undefined {
function addIndicesToAuthors(
authors: Author[],
affiliationList: RendererDoc['affiliations'],
collaborationList: RendererDoc['collaborations'],
): RendererAuthor[] {
const affiliationLookup: Record<string, ValueAndIndex> = {};
affiliationList.forEach((affil) => {
affiliationLookup[affil.value] = affil;
});
const collaborationLookup: Record<string, ValueAndIndex> = {};
collaborationList.forEach((col) => {
collaborationLookup[col.value] = col;
});
let correspondingIndex = 0;
return authors.map((auth, index) => {
let corresponding: ValueAndIndex | undefined;
Expand All @@ -39,13 +44,21 @@ function addIndicesToAuthors(
// Affiliations are explicitly undefined if length === 0
affiliations = undefined;
}
let collaborations = auth.collaborations?.map((value) => {
return { ...collaborationLookup[value] };
});
if (!collaborations || collaborations.length === 0) {
// Affiliations are explicitly undefined if length === 0
collaborations = undefined;
}
const [givenName, ...surnameParts] = auth.name?.split(' ') || ['', ''];
const surname = surnameParts.join(' ');
return {
...auth,
...indexAndLetter(index),
corresponding,
affiliations,
collaborations,
given_name: givenName,
surname,
};
Expand All @@ -59,18 +72,27 @@ function affiliationsFromAuthors(authors: Author[]): ValueAndIndex[] {
});
}

function collaborationsFromAuthors(authors: Author[]): ValueAndIndex[] {
const allCollaborations = authors.map((auth) => auth.collaborations || []).flat();
return [...new Set(allCollaborations)].map((value, index) => {
return { value, ...indexAndLetter(index) };
});
}

export function extendFrontmatter(frontmatter: PageFrontmatter): RendererDoc {
const datetime = frontmatter.date ? new Date(frontmatter.date) : new Date();
const affiliations = affiliationsFromAuthors(frontmatter.authors || []);
const collaborations = collaborationsFromAuthors(frontmatter.authors || []);
const doc: RendererDoc = {
...frontmatter,
date: {
day: String(datetime.getDate()),
month: String(datetime.getMonth() + 1),
year: String(datetime.getFullYear()),
},
authors: addIndicesToAuthors(frontmatter.authors || [], affiliations),
authors: addIndicesToAuthors(frontmatter.authors || [], affiliations, collaborations),
affiliations,
collaborations,
bibliography: undefinedIfEmpty(frontmatter.bibliography),
};
return doc;
Expand Down
9 changes: 7 additions & 2 deletions packages/myst-templates/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ export type ValueAndIndex = {
letter: string;
};

export type RendererAuthor = Omit<Author, 'affiliations' | 'corresponding' | 'orcid'> & {
export type RendererAuthor = Omit<
Author,
'affiliations' | 'collaborations' | 'corresponding' | 'orcid'
> & {
affiliations?: ValueAndIndex[];
collaborations?: ValueAndIndex[];
corresponding?: ValueAndIndex;
orcid?: string;
index: number;
Expand All @@ -31,9 +35,10 @@ export type RendererDoc = Omit<PageFrontmatter, 'date' | 'authors'> & {
};
authors: RendererAuthor[];
affiliations: ValueAndIndex[];
collaborations: ValueAndIndex[];
};

export const RENDERER_DOC_KEYS = ['affiliations'].concat(PAGE_FRONTMATTER_KEYS);
export const RENDERER_DOC_KEYS = ['affiliations', 'collaborations'].concat(PAGE_FRONTMATTER_KEYS);

export type TemplatePartDefinition = {
id: string;
Expand Down

0 comments on commit 97518ca

Please sign in to comment.