@manuscripts/transform 1.4.6-LEAN-3209 → 1.4.6-LEAN-2852-5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -16,6 +16,7 @@
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.getElementsOrder = exports.parseJATSArticle = exports.parseJATSBody = exports.parseJATSReferences = exports.parseJATSFront = void 0;
19
+ const json_schema_1 = require("@manuscripts/json-schema");
19
20
  const prosemirror_model_1 = require("prosemirror-model");
20
21
  const errors_1 = require("../../errors");
21
22
  const html_1 = require("../../lib/html");
@@ -48,12 +49,21 @@ const parseJATSFront = async (front) => {
48
49
  const journalMeta = jats_front_parser_1.jatsFrontParser.parseJournal(front.querySelector('journal-meta'));
49
50
  const journal = Object.assign(Object.assign({}, (0, builders_1.buildJournal)()), journalMeta);
50
51
  const articleMeta = front.querySelector('article-meta');
51
- const title = (_a = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('title-group > article-title')) === null || _a === void 0 ? void 0 : _a.innerHTML;
52
+ const articleTitle = (_a = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('title-group > article-title')) === null || _a === void 0 ? void 0 : _a.innerHTML;
52
53
  const subtitle = (_b = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('title-group > subtitle')) === null || _b === void 0 ? void 0 : _b.innerHTML;
53
54
  const runningTitle = (_c = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('title-group > alt-title[alt-title-type="right-running"]')) === null || _c === void 0 ? void 0 : _c.innerHTML;
54
- const manuscriptMeta = Object.assign({ title: title ? inlineContentsFromJATSTitle(title) : undefined, subtitle: subtitle ? inlineContentsFromJATSTitle(subtitle) : undefined, runningTitle: runningTitle
55
+ const manuscriptMeta = Object.assign({}, jats_front_parser_1.jatsFrontParser.parseCounts(articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('counts')));
56
+ const title = {
57
+ objectType: json_schema_1.ObjectTypes.Title,
58
+ _id: (0, id_1.generateID)(json_schema_1.ObjectTypes.Title),
59
+ articleTitle: articleTitle
60
+ ? inlineContentsFromJATSTitle(articleTitle)
61
+ : undefined,
62
+ subtitle: subtitle ? inlineContentsFromJATSTitle(subtitle) : undefined,
63
+ runningTitle: runningTitle
55
64
  ? inlineContentsFromJATSTitle(runningTitle)
56
- : undefined }, jats_front_parser_1.jatsFrontParser.parseCounts(articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('counts')));
65
+ : undefined,
66
+ };
57
67
  const { affiliations, affiliationIDs } = jats_front_parser_1.jatsFrontParser.parseAffiliationNodes([
58
68
  ...front.querySelectorAll('article-meta > contrib-group > aff'),
59
69
  ]);
@@ -74,6 +84,7 @@ const parseJATSFront = async (front) => {
74
84
  return {
75
85
  models: generateModelIDs([
76
86
  manuscript,
87
+ title,
77
88
  ...affiliations,
78
89
  ...authors,
79
90
  ...footnotes,
@@ -238,6 +238,7 @@ class JATSExporter {
238
238
  this.buildFront = (doi, id, links) => {
239
239
  var _a, _b, _c, _d;
240
240
  const manuscript = (0, project_bundle_1.findManuscript)(this.modelMap);
241
+ const title = (0, project_bundle_1.findTitle)(this.modelMap);
241
242
  const front = this.document.createElement('front');
242
243
  const journalMeta = this.document.createElement('journal-meta');
243
244
  front.appendChild(journalMeta);
@@ -315,20 +316,20 @@ class JATSExporter {
315
316
  articleMeta.appendChild(link);
316
317
  }
317
318
  }
318
- if (manuscript.title) {
319
+ if (title.articleTitle) {
319
320
  const element = this.document.createElement('article-title');
320
- this.setTitleContent(element, manuscript.title);
321
+ this.setTitleContent(element, title.articleTitle);
321
322
  titleGroup.appendChild(element);
322
323
  }
323
- if (manuscript.subtitle) {
324
+ if (title.subtitle) {
324
325
  const element = this.document.createElement('subtitle');
325
- this.setTitleContent(element, manuscript.subtitle);
326
+ this.setTitleContent(element, title.subtitle);
326
327
  titleGroup.appendChild(element);
327
328
  }
328
- if (manuscript.runningTitle) {
329
+ if (title.runningTitle) {
329
330
  const element = this.document.createElement('alt-title');
330
331
  element.setAttribute('alt-title-type', 'right-running');
331
- this.setTitleContent(element, manuscript.runningTitle);
332
+ this.setTitleContent(element, title.runningTitle);
332
333
  titleGroup.appendChild(element);
333
334
  }
334
335
  const supplements = [...this.modelMap.values()].filter((model) => model.objectType === json_schema_1.ObjectTypes.Supplement);
@@ -598,6 +599,7 @@ class JATSExporter {
598
599
  this.createSerializer = () => {
599
600
  const getModel = (id) => id ? this.modelMap.get(id) : undefined;
600
601
  const nodes = {
602
+ title: () => '',
601
603
  table_element_footer: () => ['table-wrap-foot', 0],
602
604
  contributor_list: () => '',
603
605
  contributor: () => '',
@@ -1302,7 +1304,7 @@ class JATSExporter {
1302
1304
  authorNotesEl.appendChild(correspondingEl);
1303
1305
  });
1304
1306
  if (authorNotesEl.childNodes.length > 0) {
1305
- articleMeta.insertBefore(authorNotesEl, contribGroup.nextSibling);
1307
+ articleMeta.appendChild(authorNotesEl);
1306
1308
  }
1307
1309
  }
1308
1310
  }
@@ -85,6 +85,7 @@ const table_element_1 = require("./nodes/table_element");
85
85
  const table_element_footer_1 = require("./nodes/table_element_footer");
86
86
  const table_row_1 = require("./nodes/table_row");
87
87
  const text_1 = require("./nodes/text");
88
+ const title_1 = require("./nodes/title");
88
89
  const toc_element_1 = require("./nodes/toc_element");
89
90
  const toc_section_1 = require("./nodes/toc_section");
90
91
  __exportStar(require("./groups"), exports);
@@ -142,6 +143,7 @@ __exportStar(require("./nodes/meta_section"), exports);
142
143
  __exportStar(require("./nodes/contributor_list"), exports);
143
144
  __exportStar(require("./nodes/contributor"), exports);
144
145
  __exportStar(require("./nodes/table_element_footer"), exports);
146
+ __exportStar(require("./nodes/title"), exports);
145
147
  exports.schema = new prosemirror_model_1.Schema({
146
148
  marks: {
147
149
  bold: marks_1.bold,
@@ -218,5 +220,6 @@ exports.schema = new prosemirror_model_1.Schema({
218
220
  contributor_list: contributor_list_1.contributorList,
219
221
  contributor: contributor_1.contributor,
220
222
  table_element_footer: table_element_footer_1.tableElementFooter,
223
+ title: title_1.Title,
221
224
  },
222
225
  });
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ /*!
3
+ * © 2019 Atypon Systems LLC
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.Title = void 0;
19
+ exports.Title = {
20
+ content: 'text*',
21
+ marks: 'italic smallcaps subscript superscript',
22
+ attrs: {
23
+ id: { default: '' },
24
+ articleTitle: { default: '' },
25
+ subtitle: { default: '' },
26
+ runningTitle: { default: '' },
27
+ dataTracked: { default: null },
28
+ },
29
+ group: 'block element',
30
+ parseDOM: [{ tag: 'div' }],
31
+ toDOM: () => ['div', 0],
32
+ };
@@ -35,10 +35,9 @@ const buildProject = (owner) => ({
35
35
  title: '',
36
36
  });
37
37
  exports.buildProject = buildProject;
38
- const buildManuscript = (title = '') => ({
38
+ const buildManuscript = () => ({
39
39
  _id: (0, id_1.generateID)(json_schema_1.ObjectTypes.Manuscript),
40
40
  objectType: json_schema_1.ObjectTypes.Manuscript,
41
- title,
42
41
  });
43
42
  exports.buildManuscript = buildManuscript;
44
43
  const buildContributor = (bibliographicName, role = 'author', priority = 0, userID, invitationID) => ({
@@ -62,6 +62,7 @@ exports.sortSectionsByPriority = sortSectionsByPriority;
62
62
  const getSections = (modelMap) => (0, exports.getModelsByType)(modelMap, json_schema_1.ObjectTypes.Section).sort(exports.sortSectionsByPriority);
63
63
  const getAffiliations = (modelMap) => (0, exports.getModelsByType)(modelMap, json_schema_1.ObjectTypes.Affiliation);
64
64
  const getContributors = (modelMap) => (0, exports.getModelsByType)(modelMap, json_schema_1.ObjectTypes.Contributor);
65
+ const getTitle = (modelMap) => (0, exports.getModelsByType)(modelMap, json_schema_1.ObjectTypes.Title)[0];
65
66
  const isManuscriptNode = (model) => model !== null;
66
67
  exports.isManuscriptNode = isManuscriptNode;
67
68
  const isParagraphElement = (0, object_types_1.hasObjectType)(json_schema_1.ObjectTypes.ParagraphElement);
@@ -71,6 +72,16 @@ const hasParentSection = (id) => (section) => section.path &&
71
72
  section.path.length > 1 &&
72
73
  section.path[section.path.length - 2] === id;
73
74
  class Decoder {
75
+ createTitleNode() {
76
+ const titleModel = getTitle(this.modelMap);
77
+ if (titleModel) {
78
+ const titleNode = this.decode(titleModel);
79
+ return titleNode;
80
+ }
81
+ else {
82
+ return null;
83
+ }
84
+ }
74
85
  createAffiliationListNode() {
75
86
  const affiliationNodes = getAffiliations(this.modelMap)
76
87
  .map((affiliation) => this.decode(affiliation))
@@ -593,6 +604,15 @@ class Decoder {
593
604
  ORCIDIdentifier: model.ORCIDIdentifier,
594
605
  });
595
606
  },
607
+ [json_schema_1.ObjectTypes.Title]: (data) => {
608
+ const model = data;
609
+ return schema_1.schema.nodes.title.create({
610
+ id: model._id,
611
+ articleTitle: model.articleTitle,
612
+ subtitle: model.subtitle,
613
+ runningTitle: model.runningTitle,
614
+ });
615
+ },
596
616
  };
597
617
  this.decode = (model) => {
598
618
  if (!this.creators[model.objectType]) {
@@ -603,9 +623,13 @@ class Decoder {
603
623
  };
604
624
  this.getModel = (id) => this.modelMap.get(id);
605
625
  this.createArticleNode = (manuscriptID) => {
626
+ const articleTitleNode = this.createTitleNode();
606
627
  const rootSectionNodes = this.createRootSectionNodes();
607
628
  const metaSectionNode = this.createMetaSectionNode();
608
629
  const contents = [...rootSectionNodes, metaSectionNode];
630
+ if (articleTitleNode) {
631
+ contents.push(articleTitleNode);
632
+ }
609
633
  return schema_1.schema.nodes.manuscript.create({
610
634
  id: manuscriptID || this.getManuscriptID(),
611
635
  }, contents);
@@ -263,6 +263,12 @@ function figureElementEncoder(node) {
263
263
  };
264
264
  }
265
265
  const encoders = {
266
+ title: (node) => ({
267
+ articleTitle: node.attrs.articleTitle,
268
+ subtitle: node.attrs.subtitle,
269
+ runningTitle: node.attrs.runningTitle,
270
+ _id: node.attrs._id,
271
+ }),
266
272
  bibliography_element: (node) => ({
267
273
  elementType: 'div',
268
274
  contents: '',
@@ -152,6 +152,7 @@ class HTMLTransformer {
152
152
  this.buildFront = () => {
153
153
  const manuscript = (0, project_bundle_1.findManuscript)(this.modelMap);
154
154
  const journal = (0, project_bundle_1.findJournal)(this.modelMap);
155
+ const title = (0, project_bundle_1.findTitle)(this.modelMap);
155
156
  if (!manuscript) {
156
157
  throw new Error('Manuscript not found in project modelMap');
157
158
  }
@@ -171,8 +172,8 @@ class HTMLTransformer {
171
172
  const articleMeta = this.document.createElement('div');
172
173
  front.appendChild(articleMeta);
173
174
  const articleTitle = this.document.createElement('h1');
174
- if (manuscript.title) {
175
- articleTitle.innerHTML = manuscript.title;
175
+ if (title.articleTitle) {
176
+ articleTitle.innerHTML = title.articleTitle;
176
177
  }
177
178
  if (journal === null || journal === void 0 ? void 0 : journal.title) {
178
179
  articleTitle.setAttribute('data-journal', journal.title);
@@ -57,6 +57,7 @@ exports.nodeTypesMap = new Map([
57
57
  [schema_1.schema.nodes.affiliation, json_schema_1.ObjectTypes.Affiliation],
58
58
  [schema_1.schema.nodes.contributor, json_schema_1.ObjectTypes.Contributor],
59
59
  [schema_1.schema.nodes.table_element_footer, json_schema_1.ObjectTypes.TableElementFooter],
60
+ [schema_1.schema.nodes.title, json_schema_1.ObjectTypes.Title],
60
61
  ]);
61
62
  const isExecutableNodeType = (type) => (0, schema_1.hasGroup)(type, schema_1.GROUP_EXECUTABLE);
62
63
  exports.isExecutableNodeType = isExecutableNodeType;
@@ -15,7 +15,7 @@
15
15
  * limitations under the License.
16
16
  */
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
- exports.findManuscriptById = exports.findManuscriptModelByType = exports.findJournal = exports.findManuscript = exports.parseProjectBundle = void 0;
18
+ exports.findTitle = exports.findManuscriptById = exports.findManuscriptModelByType = exports.findJournal = exports.findManuscript = exports.parseProjectBundle = void 0;
19
19
  const json_schema_1 = require("@manuscripts/json-schema");
20
20
  const decode_1 = require("./decode");
21
21
  const object_types_1 = require("./object-types");
@@ -71,3 +71,13 @@ const findManuscriptById = (modelMap, manuscriptID) => {
71
71
  throw new Error(`There is no manuscript found for the following _id (${manuscriptID})`);
72
72
  };
73
73
  exports.findManuscriptById = findManuscriptById;
74
+ const isTitle = (0, object_types_1.hasObjectType)(json_schema_1.ObjectTypes.Title);
75
+ const findTitle = (modelMap) => {
76
+ for (const model of modelMap.values()) {
77
+ if (isTitle(model)) {
78
+ return model;
79
+ }
80
+ }
81
+ throw new Error('No Title found');
82
+ };
83
+ exports.findTitle = findTitle;
@@ -13,6 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
+ import { ObjectTypes, } from '@manuscripts/json-schema';
16
17
  import { DOMParser } from 'prosemirror-model';
17
18
  import { InvalidInput } from '../../errors';
18
19
  import { nodeFromHTML } from '../../lib/html';
@@ -45,12 +46,21 @@ export const parseJATSFront = async (front) => {
45
46
  const journalMeta = jatsFrontParser.parseJournal(front.querySelector('journal-meta'));
46
47
  const journal = Object.assign(Object.assign({}, buildJournal()), journalMeta);
47
48
  const articleMeta = front.querySelector('article-meta');
48
- const title = (_a = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('title-group > article-title')) === null || _a === void 0 ? void 0 : _a.innerHTML;
49
+ const articleTitle = (_a = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('title-group > article-title')) === null || _a === void 0 ? void 0 : _a.innerHTML;
49
50
  const subtitle = (_b = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('title-group > subtitle')) === null || _b === void 0 ? void 0 : _b.innerHTML;
50
51
  const runningTitle = (_c = articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('title-group > alt-title[alt-title-type="right-running"]')) === null || _c === void 0 ? void 0 : _c.innerHTML;
51
- const manuscriptMeta = Object.assign({ title: title ? inlineContentsFromJATSTitle(title) : undefined, subtitle: subtitle ? inlineContentsFromJATSTitle(subtitle) : undefined, runningTitle: runningTitle
52
+ const manuscriptMeta = Object.assign({}, jatsFrontParser.parseCounts(articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('counts')));
53
+ const title = {
54
+ objectType: ObjectTypes.Title,
55
+ _id: generateID(ObjectTypes.Title),
56
+ articleTitle: articleTitle
57
+ ? inlineContentsFromJATSTitle(articleTitle)
58
+ : undefined,
59
+ subtitle: subtitle ? inlineContentsFromJATSTitle(subtitle) : undefined,
60
+ runningTitle: runningTitle
52
61
  ? inlineContentsFromJATSTitle(runningTitle)
53
- : undefined }, jatsFrontParser.parseCounts(articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('counts')));
62
+ : undefined,
63
+ };
54
64
  const { affiliations, affiliationIDs } = jatsFrontParser.parseAffiliationNodes([
55
65
  ...front.querySelectorAll('article-meta > contrib-group > aff'),
56
66
  ]);
@@ -71,6 +81,7 @@ export const parseJATSFront = async (front) => {
71
81
  return {
72
82
  models: generateModelIDs([
73
83
  manuscript,
84
+ title,
74
85
  ...affiliations,
75
86
  ...authors,
76
87
  ...footnotes,
@@ -25,7 +25,7 @@ import { generateAttachmentFilename } from '../transformer/filename';
25
25
  import { buildTargets } from '../transformer/labels';
26
26
  import { isExecutableNodeType, isNodeType } from '../transformer/node-types';
27
27
  import { hasObjectType } from '../transformer/object-types';
28
- import { findManuscript, findManuscriptById, } from '../transformer/project-bundle';
28
+ import { findManuscript, findManuscriptById, findTitle, } from '../transformer/project-bundle';
29
29
  import { chooseJatsFnType, chooseSecType, } from '../transformer/section-category';
30
30
  import { selectVersionIds } from './jats-versions';
31
31
  const warn = debug('manuscripts-transform');
@@ -231,6 +231,7 @@ export class JATSExporter {
231
231
  this.buildFront = (doi, id, links) => {
232
232
  var _a, _b, _c, _d;
233
233
  const manuscript = findManuscript(this.modelMap);
234
+ const title = findTitle(this.modelMap);
234
235
  const front = this.document.createElement('front');
235
236
  const journalMeta = this.document.createElement('journal-meta');
236
237
  front.appendChild(journalMeta);
@@ -308,20 +309,20 @@ export class JATSExporter {
308
309
  articleMeta.appendChild(link);
309
310
  }
310
311
  }
311
- if (manuscript.title) {
312
+ if (title.articleTitle) {
312
313
  const element = this.document.createElement('article-title');
313
- this.setTitleContent(element, manuscript.title);
314
+ this.setTitleContent(element, title.articleTitle);
314
315
  titleGroup.appendChild(element);
315
316
  }
316
- if (manuscript.subtitle) {
317
+ if (title.subtitle) {
317
318
  const element = this.document.createElement('subtitle');
318
- this.setTitleContent(element, manuscript.subtitle);
319
+ this.setTitleContent(element, title.subtitle);
319
320
  titleGroup.appendChild(element);
320
321
  }
321
- if (manuscript.runningTitle) {
322
+ if (title.runningTitle) {
322
323
  const element = this.document.createElement('alt-title');
323
324
  element.setAttribute('alt-title-type', 'right-running');
324
- this.setTitleContent(element, manuscript.runningTitle);
325
+ this.setTitleContent(element, title.runningTitle);
325
326
  titleGroup.appendChild(element);
326
327
  }
327
328
  const supplements = [...this.modelMap.values()].filter((model) => model.objectType === ObjectTypes.Supplement);
@@ -591,6 +592,7 @@ export class JATSExporter {
591
592
  this.createSerializer = () => {
592
593
  const getModel = (id) => id ? this.modelMap.get(id) : undefined;
593
594
  const nodes = {
595
+ title: () => '',
594
596
  table_element_footer: () => ['table-wrap-foot', 0],
595
597
  contributor_list: () => '',
596
598
  contributor: () => '',
@@ -1295,7 +1297,7 @@ export class JATSExporter {
1295
1297
  authorNotesEl.appendChild(correspondingEl);
1296
1298
  });
1297
1299
  if (authorNotesEl.childNodes.length > 0) {
1298
- articleMeta.insertBefore(authorNotesEl, contribGroup.nextSibling);
1300
+ articleMeta.appendChild(authorNotesEl);
1299
1301
  }
1300
1302
  }
1301
1303
  }
@@ -68,6 +68,7 @@ import { tableElement } from './nodes/table_element';
68
68
  import { tableElementFooter } from './nodes/table_element_footer';
69
69
  import { tableCell, tableRow } from './nodes/table_row';
70
70
  import { text } from './nodes/text';
71
+ import { Title } from './nodes/title';
71
72
  import { tocElement } from './nodes/toc_element';
72
73
  import { tocSection } from './nodes/toc_section';
73
74
  export * from './groups';
@@ -125,6 +126,7 @@ export * from './nodes/meta_section';
125
126
  export * from './nodes/contributor_list';
126
127
  export * from './nodes/contributor';
127
128
  export * from './nodes/table_element_footer';
129
+ export * from './nodes/title';
128
130
  export const schema = new Schema({
129
131
  marks: {
130
132
  bold,
@@ -201,5 +203,6 @@ export const schema = new Schema({
201
203
  contributor_list: contributorList,
202
204
  contributor: contributor,
203
205
  table_element_footer: tableElementFooter,
206
+ title: Title,
204
207
  },
205
208
  });
@@ -0,0 +1,29 @@
1
+ /*!
2
+ * © 2019 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ export const Title = {
17
+ content: 'text*',
18
+ marks: 'italic smallcaps subscript superscript',
19
+ attrs: {
20
+ id: { default: '' },
21
+ articleTitle: { default: '' },
22
+ subtitle: { default: '' },
23
+ runningTitle: { default: '' },
24
+ dataTracked: { default: null },
25
+ },
26
+ group: 'block element',
27
+ parseDOM: [{ tag: 'div' }],
28
+ toDOM: () => ['div', 0],
29
+ };
@@ -28,10 +28,9 @@ export const buildProject = (owner) => ({
28
28
  viewers: [],
29
29
  title: '',
30
30
  });
31
- export const buildManuscript = (title = '') => ({
31
+ export const buildManuscript = () => ({
32
32
  _id: generateID(ObjectTypes.Manuscript),
33
33
  objectType: ObjectTypes.Manuscript,
34
- title,
35
34
  });
36
35
  export const buildContributor = (bibliographicName, role = 'author', priority = 0, userID, invitationID) => ({
37
36
  _id: generateID(ObjectTypes.Contributor),
@@ -53,6 +53,7 @@ export const sortSectionsByPriority = (a, b) => a.priority === b.priority ? 0 :
53
53
  const getSections = (modelMap) => getModelsByType(modelMap, ObjectTypes.Section).sort(sortSectionsByPriority);
54
54
  const getAffiliations = (modelMap) => getModelsByType(modelMap, ObjectTypes.Affiliation);
55
55
  const getContributors = (modelMap) => getModelsByType(modelMap, ObjectTypes.Contributor);
56
+ const getTitle = (modelMap) => getModelsByType(modelMap, ObjectTypes.Title)[0];
56
57
  export const isManuscriptNode = (model) => model !== null;
57
58
  const isParagraphElement = hasObjectType(ObjectTypes.ParagraphElement);
58
59
  const isFootnote = hasObjectType(ObjectTypes.Footnote);
@@ -61,6 +62,16 @@ const hasParentSection = (id) => (section) => section.path &&
61
62
  section.path.length > 1 &&
62
63
  section.path[section.path.length - 2] === id;
63
64
  export class Decoder {
65
+ createTitleNode() {
66
+ const titleModel = getTitle(this.modelMap);
67
+ if (titleModel) {
68
+ const titleNode = this.decode(titleModel);
69
+ return titleNode;
70
+ }
71
+ else {
72
+ return null;
73
+ }
74
+ }
64
75
  createAffiliationListNode() {
65
76
  const affiliationNodes = getAffiliations(this.modelMap)
66
77
  .map((affiliation) => this.decode(affiliation))
@@ -583,6 +594,15 @@ export class Decoder {
583
594
  ORCIDIdentifier: model.ORCIDIdentifier,
584
595
  });
585
596
  },
597
+ [ObjectTypes.Title]: (data) => {
598
+ const model = data;
599
+ return schema.nodes.title.create({
600
+ id: model._id,
601
+ articleTitle: model.articleTitle,
602
+ subtitle: model.subtitle,
603
+ runningTitle: model.runningTitle,
604
+ });
605
+ },
586
606
  };
587
607
  this.decode = (model) => {
588
608
  if (!this.creators[model.objectType]) {
@@ -593,9 +613,13 @@ export class Decoder {
593
613
  };
594
614
  this.getModel = (id) => this.modelMap.get(id);
595
615
  this.createArticleNode = (manuscriptID) => {
616
+ const articleTitleNode = this.createTitleNode();
596
617
  const rootSectionNodes = this.createRootSectionNodes();
597
618
  const metaSectionNode = this.createMetaSectionNode();
598
619
  const contents = [...rootSectionNodes, metaSectionNode];
620
+ if (articleTitleNode) {
621
+ contents.push(articleTitleNode);
622
+ }
599
623
  return schema.nodes.manuscript.create({
600
624
  id: manuscriptID || this.getManuscriptID(),
601
625
  }, contents);
@@ -255,6 +255,12 @@ function figureElementEncoder(node) {
255
255
  };
256
256
  }
257
257
  const encoders = {
258
+ title: (node) => ({
259
+ articleTitle: node.attrs.articleTitle,
260
+ subtitle: node.attrs.subtitle,
261
+ runningTitle: node.attrs.runningTitle,
262
+ _id: node.attrs._id,
263
+ }),
258
264
  bibliography_element: (node) => ({
259
265
  elementType: 'div',
260
266
  contents: '',
@@ -23,7 +23,7 @@ import { generateAttachmentFilename } from './filename';
23
23
  import { buildTargets } from './labels';
24
24
  import { isNodeType } from './node-types';
25
25
  import { hasObjectType } from './object-types';
26
- import { findJournal, findManuscript } from './project-bundle';
26
+ import { findJournal, findManuscript, findTitle } from './project-bundle';
27
27
  import { chooseSecType } from './section-category';
28
28
  const chooseNodeName = (element) => {
29
29
  const nodeName = element.nodeName.toLowerCase();
@@ -146,6 +146,7 @@ export class HTMLTransformer {
146
146
  this.buildFront = () => {
147
147
  const manuscript = findManuscript(this.modelMap);
148
148
  const journal = findJournal(this.modelMap);
149
+ const title = findTitle(this.modelMap);
149
150
  if (!manuscript) {
150
151
  throw new Error('Manuscript not found in project modelMap');
151
152
  }
@@ -165,8 +166,8 @@ export class HTMLTransformer {
165
166
  const articleMeta = this.document.createElement('div');
166
167
  front.appendChild(articleMeta);
167
168
  const articleTitle = this.document.createElement('h1');
168
- if (manuscript.title) {
169
- articleTitle.innerHTML = manuscript.title;
169
+ if (title.articleTitle) {
170
+ articleTitle.innerHTML = title.articleTitle;
170
171
  }
171
172
  if (journal === null || journal === void 0 ? void 0 : journal.title) {
172
173
  articleTitle.setAttribute('data-journal', journal.title);
@@ -54,6 +54,7 @@ export const nodeTypesMap = new Map([
54
54
  [schema.nodes.affiliation, ObjectTypes.Affiliation],
55
55
  [schema.nodes.contributor, ObjectTypes.Contributor],
56
56
  [schema.nodes.table_element_footer, ObjectTypes.TableElementFooter],
57
+ [schema.nodes.title, ObjectTypes.Title],
57
58
  ]);
58
59
  export const isExecutableNodeType = (type) => hasGroup(type, GROUP_EXECUTABLE);
59
60
  export const isElementNodeType = (type) => hasGroup(type, GROUP_ELEMENT);
@@ -63,3 +63,12 @@ export const findManuscriptById = (modelMap, manuscriptID) => {
63
63
  }
64
64
  throw new Error(`There is no manuscript found for the following _id (${manuscriptID})`);
65
65
  };
66
+ const isTitle = hasObjectType(ObjectTypes.Title);
67
+ export const findTitle = (modelMap) => {
68
+ for (const model of modelMap.values()) {
69
+ if (isTitle(model)) {
70
+ return model;
71
+ }
72
+ }
73
+ throw new Error('No Title found');
74
+ };
@@ -70,4 +70,5 @@ export * from './nodes/meta_section';
70
70
  export * from './nodes/contributor_list';
71
71
  export * from './nodes/contributor';
72
72
  export * from './nodes/table_element_footer';
73
+ export * from './nodes/title';
73
74
  export declare const schema: Schema<Nodes, Marks>;
@@ -0,0 +1,28 @@
1
+ /*!
2
+ * © 2019 Atypon Systems LLC
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+ import { NodeSpec } from 'prosemirror-model';
17
+ import { ManuscriptNode } from '../types';
18
+ interface Attrs {
19
+ id: string;
20
+ articleTitle: string;
21
+ subtitle: string;
22
+ runningTitle: string;
23
+ }
24
+ export interface TitleNode extends ManuscriptNode {
25
+ attrs: Attrs;
26
+ }
27
+ export declare const Title: NodeSpec;
28
+ export {};
@@ -17,7 +17,7 @@ import { Fragment, Mark as ProsemirrorMark, MarkType, Node as ProsemirrorNode, N
17
17
  import { EditorState, NodeSelection, Plugin, TextSelection, Transaction } from 'prosemirror-state';
18
18
  import { EditorView, NodeView } from 'prosemirror-view';
19
19
  export type Marks = 'bold' | 'code' | 'italic' | 'smallcaps' | 'strikethrough' | 'styled' | 'subscript' | 'superscript' | 'underline' | 'tracked_insert' | 'tracked_delete';
20
- export type Nodes = 'attribution' | 'bibliography_item' | 'bibliography_element' | 'bibliography_section' | 'blockquote_element' | 'bullet_list' | 'caption' | 'caption_title' | 'comment' | 'comment_list' | 'citation' | 'cross_reference' | 'doc' | 'equation' | 'equation_element' | 'figcaption' | 'figure' | 'graphical_abstract_section' | 'figure_element' | 'footnote' | 'footnotes_element' | 'footnotes_section' | 'hard_break' | 'highlight_marker' | 'inline_equation' | 'inline_footnote' | 'keyword' | 'keywords_element' | 'keywords_group' | 'keywords_section' | 'link' | 'list_item' | 'listing' | 'listing_element' | 'manuscript' | 'missing_figure' | 'ordered_list' | 'paragraph' | 'placeholder' | 'placeholder_element' | 'pullquote_element' | 'section' | 'section_label' | 'section_title' | 'section_title_plain' | 'table' | 'table_body' | 'table_cell' | 'table_element' | 'table_row' | 'table_colgroup' | 'table_col' | 'text' | 'toc_element' | 'toc_section' | 'affiliation' | 'meta_section' | 'affiliation_list' | 'contributor_list' | 'contributor' | 'table_element_footer';
20
+ export type Nodes = 'attribution' | 'bibliography_item' | 'bibliography_element' | 'bibliography_section' | 'blockquote_element' | 'bullet_list' | 'caption' | 'caption_title' | 'comment' | 'comment_list' | 'citation' | 'cross_reference' | 'doc' | 'equation' | 'equation_element' | 'figcaption' | 'figure' | 'graphical_abstract_section' | 'figure_element' | 'footnote' | 'footnotes_element' | 'footnotes_section' | 'hard_break' | 'highlight_marker' | 'inline_equation' | 'inline_footnote' | 'keyword' | 'keywords_element' | 'keywords_group' | 'keywords_section' | 'link' | 'list_item' | 'listing' | 'listing_element' | 'manuscript' | 'missing_figure' | 'ordered_list' | 'paragraph' | 'placeholder' | 'placeholder_element' | 'pullquote_element' | 'section' | 'section_label' | 'section_title' | 'section_title_plain' | 'table' | 'table_body' | 'table_cell' | 'table_element' | 'table_row' | 'table_colgroup' | 'table_col' | 'text' | 'toc_element' | 'toc_section' | 'affiliation' | 'meta_section' | 'affiliation_list' | 'contributor_list' | 'contributor' | 'table_element_footer' | 'title';
21
21
  export type ManuscriptSchema = Schema<Nodes, Marks>;
22
22
  export type ManuscriptEditorState = EditorState;
23
23
  export type ManuscriptEditorView = EditorView;
@@ -28,7 +28,7 @@ export type BuildEmbedded<T extends EmbeddedModel, O> = Pick<T, Exclude<keyof T,
28
28
  objectType: O;
29
29
  };
30
30
  export declare const buildProject: (owner: string) => Build<Project>;
31
- export declare const buildManuscript: (title?: string) => Build<Manuscript>;
31
+ export declare const buildManuscript: () => Build<Manuscript>;
32
32
  export type ContributorRoleType = 'author';
33
33
  export declare const buildContributor: (bibliographicName: BibliographicName, role?: ContributorRoleType, priority?: number, userID?: string, invitationID?: string) => Build<Contributor>;
34
34
  export declare const buildBibliographyItem: (data: Partial<Build<BibliographyItem>>) => Build<BibliographyItem>;
@@ -25,6 +25,7 @@ export declare class Decoder {
25
25
  private readonly allowMissingElements;
26
26
  private comments;
27
27
  private creators;
28
+ private createTitleNode;
28
29
  private createAffiliationListNode;
29
30
  private createContributorListNode;
30
31
  private createMetaSectionNode;
@@ -13,7 +13,7 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { Journal, Manuscript, Model, ObjectTypes } from '@manuscripts/json-schema';
16
+ import { Journal, Manuscript, Model, ObjectTypes, Title } from '@manuscripts/json-schema';
17
17
  import { ManuscriptModel } from './models';
18
18
  export interface ProjectBundle {
19
19
  version: string;
@@ -27,3 +27,4 @@ export declare const findManuscript: (modelMap: Map<string, Model>) => Manuscrip
27
27
  export declare const findJournal: (modelMap: Map<string, Model>) => Journal | null;
28
28
  export declare const findManuscriptModelByType: <T extends ManuscriptModel>(modelMap: Map<string, Model>, manuscript: Manuscript, objectType: ObjectTypes) => T | undefined;
29
29
  export declare const findManuscriptById: (modelMap: Map<string, Model>, manuscriptID: string) => Manuscript;
30
+ export declare const findTitle: (modelMap: Map<string, Model>) => Title;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@manuscripts/transform",
3
3
  "description": "ProseMirror transformer for Manuscripts applications",
4
- "version": "1.4.6-LEAN-3209",
4
+ "version": "1.4.6-LEAN-2852-5",
5
5
  "repository": "github:Atypon-OpenSource/manuscripts-transform",
6
6
  "license": "Apache-2.0",
7
7
  "main": "dist/cjs",
@@ -29,7 +29,7 @@
29
29
  "version": "yarn build"
30
30
  },
31
31
  "dependencies": {
32
- "@manuscripts/json-schema": "^2.2.0",
32
+ "@manuscripts/json-schema": "2.2.0-LEAN-2852-3",
33
33
  "debug": "^4.3.4",
34
34
  "jszip": "^3.10.1",
35
35
  "mathjax-full": "^3.2.2",
@@ -82,4 +82,4 @@
82
82
  "prosemirror-state": "^1.4.2",
83
83
  "prosemirror-view": "^1.29.1"
84
84
  }
85
- }
85
+ }