Skip to content

Commit 809edd0

Browse files
fwkochrowanc1
andauthored
Abstract from parts and funding for preprints (#17)
Co-authored-by: Rowan Cockett <rowanc1@gmail.com>
1 parent 89e4436 commit 809edd0

5 files changed

Lines changed: 69 additions & 31 deletions

File tree

.changeset/eighty-nails-press.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"crossref-utils": patch
3+
---
4+
5+
Support abstract part

src/cli/deposit.ts

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
loadProject,
1414
parseMyst,
1515
processProject,
16+
resolveFrontmatterParts,
1617
selectors,
1718
} from 'myst-cli';
1819
import type { ISession } from 'myst-cli';
@@ -85,7 +86,9 @@ export async function depositArticleFromSource(session: ISession, depositSource:
8586
} else {
8687
fileContents.forEach(({ mdast }) => {
8788
if (abstractPart) return;
88-
abstractPart = extractPart(mdast, 'abstract');
89+
abstractPart = extractPart(mdast, 'abstract', {
90+
frontmatterParts: resolveFrontmatterParts(session, projectFrontmatter),
91+
});
8992
});
9093
}
9194
fileContents.forEach(({ references }) => {
@@ -108,7 +111,9 @@ export async function depositArticleFromSource(session: ISession, depositSource:
108111
? projectFrontmatter?.subtitle ?? undefined
109112
: frontmatter?.subtitle;
110113
frontmatter = { ...fileContent.frontmatter, title, subtitle };
111-
abstractPart = extractPart(fileContent.mdast, 'abstract');
114+
abstractPart = extractPart(fileContent.mdast, 'abstract', {
115+
frontmatterParts: resolveFrontmatterParts(session, frontmatter),
116+
});
112117
fileContent.references.cite?.order.forEach((key) => {
113118
const value = fileContent.references.cite?.data[key].doi;
114119
if (value) dois[key] = value;
@@ -117,6 +122,7 @@ export async function depositArticleFromSource(session: ISession, depositSource:
117122
}
118123

119124
let abstract: Element | undefined;
125+
const description = (frontmatter?.description || projectFrontmatter?.description)?.trim();
120126
if (abstractPart) {
121127
transformXrefToLink(abstractPart);
122128
transformCiteToText(abstractPart);
@@ -128,6 +134,20 @@ export async function depositArticleFromSource(session: ISession, depositSource:
128134
{ name: 'jats:abstract' },
129135
jats.map((e) => element2JatsUnist(e)),
130136
) as Element;
137+
} else if (description) {
138+
// Use the project description as the fallback for the abstract
139+
abstractPart = {
140+
type: 'root',
141+
children: [{ type: 'paragraph', children: [{ type: 'text', value: description }] }],
142+
};
143+
transformNewlineToSpace(abstractPart);
144+
const serializer = new JatsSerializer(new VFile(), abstractPart as any);
145+
const jats = serializer.render(true).elements();
146+
abstract = u(
147+
'element',
148+
{ name: 'jats:abstract' },
149+
jats.map((e) => element2JatsUnist(e)),
150+
) as Element;
131151
}
132152
return { frontmatter: frontmatter ?? {}, dois, abstract, configFile };
133153
}
@@ -612,7 +632,7 @@ export async function deposit(session: ISession, opts: DepositOptions) {
612632
throw new Error('preprint deposit may only use a single article');
613633
}
614634
const { frontmatter, dois, abstract } = depositArticles[0];
615-
body = preprintFromMyst(frontmatter, dois, abstract);
635+
body = preprintFromMyst(session, frontmatter, dois, abstract);
616636
}
617637
const batch = new DoiBatch(
618638
{ id: opts.id ?? uuid(), depositor: { name, email }, registrant },

src/funding.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { Award, ProjectFrontmatter } from 'myst-frontmatter';
22
import type { Fundref } from './types.js';
33
import type { ISession } from 'myst-cli-utils';
4+
import { e, t } from './utils.js';
45

56
export function fundrefFromMyst(
67
session: ISession,
@@ -35,3 +36,29 @@ export function fundrefFromMyst(
3536
return { sources, awardNumbers };
3637
});
3738
}
39+
40+
export function createFundingXml(funding?: Fundref[]) {
41+
if (!funding || funding.length === 0) return null;
42+
return e(
43+
'fr:program',
44+
{ name: 'fundref' },
45+
funding.map((fundingItem) => {
46+
if (!fundingItem.sources.length) {
47+
throw new Error('Fundref entry must have at least one source');
48+
}
49+
return e('fr:assertion', { name: 'fundgroup' }, [
50+
...fundingItem.sources.map((source) => {
51+
return e('fr:assertion', { name: 'funder_name' }, [
52+
t(source.name),
53+
...source.identifiers.map((id) => {
54+
return e('fr:assertion', { name: 'funder_identifier' }, id);
55+
}),
56+
]);
57+
}),
58+
...fundingItem.awardNumbers.map((awardNumber) => {
59+
return e('fr:assertion', { name: 'award_number' }, awardNumber);
60+
}),
61+
]);
62+
}),
63+
);
64+
}

src/journal.ts

Lines changed: 5 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import type { Element } from 'xast';
2-
import { e, t } from './utils.js';
2+
import { e } from './utils.js';
33
import type { JournalArticle, JournalIssue, JournalMetadata } from './types.js';
44
import { publicationDateXml } from './dates.js';
55
import type { ProjectFrontmatter } from 'myst-frontmatter';
66
import { contributorsXmlFromMystAuthors } from './contributors.js';
77
import { normalize } from 'doi-utils';
8-
import { fundrefFromMyst } from './funding.js';
8+
import { createFundingXml, fundrefFromMyst } from './funding.js';
99
import type { ISession } from 'myst-cli-utils';
1010

1111
/**
@@ -172,32 +172,9 @@ export function journalArticleXml({
172172
children.push(e('pages', pageChildren));
173173
}
174174
// publisher_item
175-
if (funding?.length) {
176-
children.push(
177-
e(
178-
'fr:program',
179-
{ name: 'fundref' },
180-
funding.map((fundingItem) => {
181-
if (!fundingItem.sources.length) {
182-
throw new Error('Fundref entry must have at least one source');
183-
}
184-
return e('fr:assertion', { name: 'fundgroup' }, [
185-
...fundingItem.sources.map((source) => {
186-
return e('fr:assertion', { name: 'funder_name' }, [
187-
t(source.name),
188-
...source.identifiers.map((id) => {
189-
return e('fr:assertion', { name: 'funder_identifier' }, id);
190-
}),
191-
]);
192-
}),
193-
...fundingItem.awardNumbers.map((awardNumber) => {
194-
return e('fr:assertion', { name: 'award_number' }, awardNumber);
195-
}),
196-
]);
197-
}),
198-
),
199-
);
200-
}
175+
const fundingXml = createFundingXml(funding);
176+
if (fundingXml) children.push(fundingXml);
177+
201178
if (license) {
202179
children.push(
203180
e('ai:program', { name: 'AccessIndicators' }, [

src/preprint.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import type { ProjectFrontmatter } from 'myst-frontmatter';
55
import { normalize } from 'doi-utils';
66
import { contributorsXmlFromMystAuthors } from './contributors.js';
77
import { dateXml } from './dates.js';
8+
import { createFundingXml, fundrefFromMyst } from './funding.js';
9+
import type { ISession } from 'myst-cli';
810

911
/**
1012
* Create posted content xml
@@ -19,6 +21,7 @@ export function preprintXml({
1921
title,
2022
subtitle,
2123
abstract,
24+
funding,
2225
doi_data,
2326
citations,
2427
license,
@@ -35,6 +38,10 @@ export function preprintXml({
3538
children.push(e('titles', titles));
3639
children.push(posted_date);
3740
if (abstract) children.push(abstract);
41+
42+
const fundingXml = createFundingXml(funding);
43+
if (fundingXml) children.push(fundingXml);
44+
3845
if (license) {
3946
children.push(
4047
e('ai:program', { name: 'AccessIndicators' }, [
@@ -85,6 +92,7 @@ export function preprintXml({
8592
}
8693

8794
export function preprintFromMyst(
95+
session: ISession,
8896
myst: ProjectFrontmatter,
8997
citations?: Record<string, string>,
9098
abstract?: Element,
@@ -98,6 +106,7 @@ export function preprintFromMyst(
98106
date: typeof date === 'string' ? new Date(date) : undefined,
99107
license: license?.content?.url,
100108
abstract,
109+
funding: fundrefFromMyst(session, myst),
101110
};
102111
if (license && license.content?.CC) {
103112
// Only put in CC licenses at this time

0 commit comments

Comments
 (0)