Skip to content

Commit

Permalink
Merge pull request #13 from elifesciences/pub-year-volume
Browse files Browse the repository at this point in the history
Pub year volume
  • Loading branch information
will-byrne authored Jul 31, 2023
2 parents f17b450 + 9a0e640 commit 2c25b2b
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 13 deletions.
12 changes: 10 additions & 2 deletions examples/generated/04.reviewed_preprintv1.json
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,15 @@
"item": {
"type": "preprint",
"doi": "10.7554/eLife.80494.1",
"versionIdentifier": "1"
"versionIdentifier": "1",
"publicationYear": 2022,
"embodimentOf": {
"type": "manuscript",
"doi": "10.7554/eLife.80494",
"identifier": "80494",
"volumeIdentifier": "11",
"electronicArticleIdentifier": "RP80494"
}
},
"status": "manuscript-published",
"happened": "2022-10-20T00:00:00.000Z"
Expand Down Expand Up @@ -329,4 +337,4 @@
"previous-step": "_:b2"
}
}
}
}
12 changes: 11 additions & 1 deletion src/docmap-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,21 +25,23 @@ import {
Url,
VersionOfRecord,
WebPage,
Work,
} from './docmap';

type Steps = {
'first-step': string,
steps: Map<string, Step>
};

export const generatePreprint = (doi: DOI, published?: Date, url?: Url, version?: string, content?: Manifestation[], license?: string): Preprint => ({
export const generatePreprint = (doi: DOI, published?: Date, url?: Url, version?: string, content?: Manifestation[], license?: string, work?: Work): Preprint => ({
type: ExpressionType.Preprint,
doi,
url,
published,
versionIdentifier: version,
content,
license,
embodimentOf: work,
});

export const generateRevisedPreprint = (doi: DOI, published?: Date, url?: Url, version?: string, content?: Manifestation[]): RevisedPreprint => ({
Expand Down Expand Up @@ -112,6 +114,14 @@ export const generateWebContent = (url: Url): WebPage => ({
url,
});

export const generateWork = (doi?: DOI, identifier?: string, volumeIdentifier?: string, electronicArticleIdentifier?: string): Work => ({
type: 'manuscript',
doi,
identifier,
volumeIdentifier,
electronicArticleIdentifier,
});

export const generatePersonParticipant = (name: string, role: string): Participant => ({
actor: {
name,
Expand Down
19 changes: 19 additions & 0 deletions src/docmap-parser.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -385,4 +385,23 @@ describe('docmap-parser', () => {
expect(parsedData.versions[0].preprint.license).toStrictEqual('http://creativecommons.org/licenses/by/4.0/');
expect(parsedData.versions[0].license).toStrictEqual('http://creativecommons.org/licenses/by/4.0/');
});

it('extracts embodimentOf, if present', () => {
const parsedData = parseDocMap(fixtures.preprintWithWorkAsOutput());

expect(parsedData.manuscript).toStrictEqual({
doi: '10.1101/123456',
volume: '1',
eLocationId: 'RP123456',
});
});

it('extracts partial embodimentOf, if present', () => {
const parsedData = parseDocMap(fixtures.preprintWithPartialWorkAsOutput());

expect(parsedData.manuscript).toStrictEqual({
doi: '10.1101/123456',
eLocationId: 'RP123456',
});
});
});
55 changes: 45 additions & 10 deletions src/docmap-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,30 @@ export type VersionedReviewedPreprint = ReviewedPreprint & {
versionIdentifier: string,
};

export type Manuscript = {
doi?: string,
volume?: string,
eLocationId?: string,
};

export type ManuscriptData = {
id: string,
manuscript?: Manuscript,
versions: VersionedReviewedPreprint[],
};

const getManuscriptFromExpression = (expression: Expression): Manuscript | false => {
if (!expression.embodimentOf) {
return false;
}

return {
doi: expression.embodimentOf.doi,
volume: expression.embodimentOf.volumeIdentifier,
eLocationId: expression.embodimentOf.electronicArticleIdentifier,
};
};

const getPreprintFromExpression = (expression: Expression): Preprint => {
if (!expression.doi) {
throw Error('Cannot identify Expression by DOI');
Expand Down Expand Up @@ -171,13 +190,27 @@ const addPreprintDescribedBy = (expression: Expression, preprintCollection: Arra
return newPreprint;
};

const findAndUpdateOrAddPreprintDescribedBy = (expression: Expression, preprintCollection: Array<ReviewedPreprint>): ReviewedPreprint => {
const findAndUpdateOrAddPreprintDescribedBy = (expression: Expression, preprintCollection: Array<ReviewedPreprint>, manuscript: Manuscript): ReviewedPreprint => {
const foundManuscriptData = getManuscriptFromExpression(expression);
const existingManuscript = manuscript;
if (foundManuscriptData) {
if (foundManuscriptData.doi) {
existingManuscript.doi = foundManuscriptData.doi;
}
if (foundManuscriptData.eLocationId) {
existingManuscript.eLocationId = foundManuscriptData.eLocationId;
}
if (foundManuscriptData.volume) {
existingManuscript.volume = foundManuscriptData.volume;
}
}
const foundPreprint = findPreprintDescribedBy(expression, preprintCollection);
if (!foundPreprint) {
return addPreprintDescribedBy(expression, preprintCollection);
}
// Update fields, default to any data already there.
updateReviewedPreprintFrom(foundPreprint, expression);

return foundPreprint;
};

Expand Down Expand Up @@ -314,36 +347,36 @@ const getAuthorResponse = (step: Step): { preprint: Item, authorResponse: Item }
return (authorResponseOutputs.length === 1 && items.preprintInputs.length === 1) ? { preprint: items.preprintInputs[0], authorResponse: authorResponseOutputs[0] } : false;
};

const parseStep = (step: Step, preprints: Array<ReviewedPreprint>): Array<ReviewedPreprint> => {
const parseStep = (step: Step, preprints: Array<ReviewedPreprint>, manuscript: Manuscript): Array<ReviewedPreprint> => {
const preprintPublishedAssertion = step.assertions.find((assertion) => assertion.status === AssertionStatus.Published);
if (preprintPublishedAssertion) {
// Update type and sent for review date
const preprint = findAndUpdateOrAddPreprintDescribedBy(preprintPublishedAssertion.item, preprints);
const preprint = findAndUpdateOrAddPreprintDescribedBy(preprintPublishedAssertion.item, preprints, manuscript);
preprint.publishedDate = preprintPublishedAssertion.happened ?? preprint.publishedDate;
}

const inferredPublished = getPublishedPreprint(step);
if (inferredPublished) {
findAndUpdateOrAddPreprintDescribedBy(inferredPublished, preprints);
findAndUpdateOrAddPreprintDescribedBy(inferredPublished, preprints, manuscript);
}

const preprintUnderReviewAssertion = step.assertions.find((assertion) => assertion.status === AssertionStatus.UnderReview);
if (preprintUnderReviewAssertion) {
// Update type and sent for review date
const preprint = findAndUpdateOrAddPreprintDescribedBy(preprintUnderReviewAssertion.item, preprints);
const preprint = findAndUpdateOrAddPreprintDescribedBy(preprintUnderReviewAssertion.item, preprints, manuscript);
preprint.sentForReviewDate = preprintUnderReviewAssertion.happened;
}

const inferredRepublished = getRepublishedPreprint(step);
if (inferredRepublished) {
// preprint input, preprint output, but no evaluations = superceed input preprint with output Reviewed Preprint
const preprint = findAndUpdateOrAddPreprintDescribedBy(inferredRepublished.originalExpression, preprints);
const preprint = findAndUpdateOrAddPreprintDescribedBy(inferredRepublished.originalExpression, preprints, manuscript);
republishPreprintAs(inferredRepublished.republishedExpression, preprint);
}

const inferredPeerReviewed = getPeerReviewedPreprint(step);
if (inferredPeerReviewed) {
const preprint = findAndUpdateOrAddPreprintDescribedBy(inferredPeerReviewed.peerReviewedPreprint, preprints);
const preprint = findAndUpdateOrAddPreprintDescribedBy(inferredPeerReviewed.peerReviewedPreprint, preprints, manuscript);
setPeerReviewFrom(step.actions, preprint);
preprint.reviewedDate = preprint.peerReview?.evaluationSummary?.date;

Expand All @@ -355,13 +388,13 @@ const parseStep = (step: Step, preprints: Array<ReviewedPreprint>): Array<Review

const newVersionPreprint = getNewVersionPreprint(step);
if (newVersionPreprint) {
findAndUpdateOrAddPreprintDescribedBy(newVersionPreprint.newVersionExpression, preprints);
findAndUpdateOrAddPreprintDescribedBy(newVersionPreprint.newVersionExpression, preprints, manuscript);
}

// sometimes author response is a separate step, find those and add the author response
const authorResponse = getAuthorResponse(step);
if (authorResponse) {
const preprint = findAndUpdateOrAddPreprintDescribedBy(authorResponse.preprint, preprints);
const preprint = findAndUpdateOrAddPreprintDescribedBy(authorResponse.preprint, preprints, manuscript);
setPeerReviewFrom(step.actions, preprint);
preprint.authorResponseDate = authorResponse.authorResponse.published;
}
Expand Down Expand Up @@ -430,8 +463,9 @@ export const parsePreprintDocMap = (docMap: DocMap | string): ManuscriptData =>
const stepsIterator = getSteps(docMapStruct);
let currentStep = stepsIterator.next().value;
let preprints: Array<ReviewedPreprint> = [];
const manuscript: Manuscript = {};
while (currentStep) {
preprints = parseStep(currentStep, preprints);
preprints = parseStep(currentStep, preprints, manuscript);
currentStep = stepsIterator.next().value;
}

Expand All @@ -442,6 +476,7 @@ export const parsePreprintDocMap = (docMap: DocMap | string): ManuscriptData =>
const { id, versions } = finaliseVersions(preprints);
return {
id,
manuscript,
versions,
};
};
9 changes: 9 additions & 0 deletions src/docmap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export type Expression = {
doi?: DOI,
content?: Manifestation[],
license?: string,
embodimentOf?: Work,
};

export type Manifestation = {
Expand Down Expand Up @@ -115,6 +116,14 @@ export type Assertion = {
happened?: Date,
};

export type Work = {
type: 'manuscript',
doi?: DOI,
identifier?: string,
volumeIdentifier?: string,
electronicArticleIdentifier?: string,
};

export type Step = {
assertions: Assertion[],
inputs: Input[],
Expand Down
15 changes: 15 additions & 0 deletions src/test-fixtures/docmapGenerators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
generateStep,
generateUnderReviewAssertion,
generateWebContent,
generateWork,
} from '../docmap-generator';

const publisher = {
Expand Down Expand Up @@ -46,6 +47,20 @@ export const fixtures = {
return generateDocMap('test', publisher, firstStep);
},

preprintWithWorkAsOutput: (): DocMap => {
const work = generateWork('10.1101/123456', '123456', '1', 'RP123456');
const preprint = generatePreprint('preprint/article1', new Date('2022-03-01'), undefined, undefined, undefined, undefined, work);
const firstStep = generateStep([], [generateAction([], [preprint])], []);
return generateDocMap('test', publisher, firstStep);
},

preprintWithPartialWorkAsOutput: (): DocMap => {
const work = generateWork('10.1101/123456', '123456', undefined, 'RP123456');
const preprint = generatePreprint('preprint/article1', new Date('2022-03-01'), undefined, undefined, undefined, undefined, work);
const firstStep = generateStep([], [generateAction([], [preprint])], []);
return generateDocMap('test', publisher, firstStep);
},

simplePreprintWithUrlAsOutput: (): DocMap => {
const preprint = generatePreprint('preprint/article1', new Date('2022-03-01'), 'https://somewhere.org/preprint/article1');
const firstStep = generateStep([], [generateAction([], [preprint])], []);
Expand Down

0 comments on commit 2c25b2b

Please sign in to comment.