@manuscripts/transform 1.5.3 → 1.5.4

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");
@@ -51,9 +52,16 @@ const parseJATSFront = async (front) => {
51
52
  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
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 titles = {
57
+ objectType: json_schema_1.ObjectTypes.Titles,
58
+ _id: (0, id_1.generateID)(json_schema_1.ObjectTypes.Titles),
59
+ title: title ? inlineContentsFromJATSTitle(title) : undefined,
60
+ subtitle: subtitle ? inlineContentsFromJATSTitle(subtitle) : undefined,
61
+ runningTitle: runningTitle
55
62
  ? inlineContentsFromJATSTitle(runningTitle)
56
- : undefined }, jats_front_parser_1.jatsFrontParser.parseCounts(articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('counts')));
63
+ : undefined,
64
+ };
57
65
  const { affiliations, affiliationIDs } = jats_front_parser_1.jatsFrontParser.parseAffiliationNodes([
58
66
  ...front.querySelectorAll('article-meta > contrib-group > aff'),
59
67
  ]);
@@ -73,6 +81,7 @@ const parseJATSFront = async (front) => {
73
81
  const manuscript = Object.assign(Object.assign(Object.assign({}, (0, builders_1.buildManuscript)()), manuscriptMeta), history);
74
82
  return {
75
83
  models: generateModelIDs([
84
+ titles,
76
85
  manuscript,
77
86
  ...footnotes,
78
87
  ...correspondingList,
@@ -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 titles = (0, project_bundle_1.findTitles)(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 (titles.title) {
319
320
  const element = this.document.createElement('article-title');
320
- this.setTitleContent(element, manuscript.title);
321
+ this.setTitleContent(element, titles.title);
321
322
  titleGroup.appendChild(element);
322
323
  }
323
- if (manuscript.subtitle) {
324
+ if (titles.subtitle) {
324
325
  const element = this.document.createElement('subtitle');
325
- this.setTitleContent(element, manuscript.subtitle);
326
+ this.setTitleContent(element, titles.subtitle);
326
327
  titleGroup.appendChild(element);
327
328
  }
328
- if (manuscript.runningTitle) {
329
+ if (titles.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, titles.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
  affiliations_section: () => '',
602
604
  contributors_section: () => '',
603
605
  table_element_footer: () => ['table-wrap-foot', 0],
@@ -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);
@@ -140,6 +141,7 @@ __exportStar(require("./nodes/affiliation"), exports);
140
141
  __exportStar(require("./nodes/meta_section"), exports);
141
142
  __exportStar(require("./nodes/contributor"), exports);
142
143
  __exportStar(require("./nodes/table_element_footer"), exports);
144
+ __exportStar(require("./nodes/title"), exports);
143
145
  __exportStar(require("./nodes/affiliations_section"), exports);
144
146
  __exportStar(require("./nodes/contributors_section"), exports);
145
147
  exports.schema = new prosemirror_model_1.Schema({
@@ -216,6 +218,7 @@ exports.schema = new prosemirror_model_1.Schema({
216
218
  meta_section: meta_section_1.metaSection,
217
219
  contributor: contributor_1.contributor,
218
220
  table_element_footer: table_element_footer_1.tableElementFooter,
221
+ title: title_1.title,
219
222
  affiliations_section: affiliations_section_1.affiliationsSection,
220
223
  contributors_section: contributors_section_1.contributorsSection,
221
224
  },
@@ -17,7 +17,7 @@
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.manuscript = void 0;
19
19
  exports.manuscript = {
20
- content: '(section | sections)+ meta_section',
20
+ content: 'title* (section | sections)+ meta_section',
21
21
  attrs: {
22
22
  id: { default: '' },
23
23
  },
@@ -0,0 +1,29 @@
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 tracked_insert tracked_delete',
22
+ attrs: {
23
+ id: { default: '' },
24
+ dataTracked: { default: null },
25
+ },
26
+ group: 'block element',
27
+ parseDOM: [{ tag: 'div' }],
28
+ toDOM: () => ['div', 0],
29
+ };
@@ -18,7 +18,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
18
18
  return (mod && mod.__esModule) ? mod : { "default": mod };
19
19
  };
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.buildElementsOrder = exports.auxiliaryObjectTypes = exports.buildStatusLabel = exports.buildJournal = exports.buildAttribution = exports.buildInlineStyle = exports.buildContributorRole = exports.buildContribution = exports.buildHighlightMarker = exports.buildHighlight = exports.buildColor = exports.buildParagraph = exports.buildSection = exports.buildCorresp = exports.buildFootnotesOrder = exports.buildFootnote = exports.buildInlineMathFragment = exports.buildValidation = exports.buildNote = exports.buildComment = exports.buildUserProfileAffiliation = exports.buildSupplementaryMaterial = exports.buildAffiliation = exports.buildFigure = exports.buildLibraryCollection = exports.buildManuscriptKeyword = exports.buildKeywordGroup = exports.buildKeyword = exports.buildCitation = exports.buildEmbeddedCitationItem = exports.buildAuxiliaryObjectReference = exports.buildBibliographicDate = exports.buildBibliographicName = exports.buildBibliographyItem = exports.buildContributor = exports.buildManuscript = exports.buildProject = exports.DEFAULT_PAGE_LAYOUT = exports.DEFAULT_BUNDLE = void 0;
21
+ exports.buildTitles = exports.buildElementsOrder = exports.auxiliaryObjectTypes = exports.buildStatusLabel = exports.buildJournal = exports.buildAttribution = exports.buildInlineStyle = exports.buildContributorRole = exports.buildContribution = exports.buildHighlightMarker = exports.buildHighlight = exports.buildColor = exports.buildParagraph = exports.buildSection = exports.buildCorresp = exports.buildFootnotesOrder = exports.buildFootnote = exports.buildInlineMathFragment = exports.buildValidation = exports.buildNote = exports.buildComment = exports.buildUserProfileAffiliation = exports.buildSupplementaryMaterial = exports.buildAffiliation = exports.buildFigure = exports.buildLibraryCollection = exports.buildManuscriptKeyword = exports.buildKeywordGroup = exports.buildKeyword = exports.buildCitation = exports.buildEmbeddedCitationItem = exports.buildAuxiliaryObjectReference = exports.buildBibliographicDate = exports.buildBibliographicName = exports.buildBibliographyItem = exports.buildContributor = exports.buildManuscript = exports.buildProject = exports.DEFAULT_PAGE_LAYOUT = exports.DEFAULT_BUNDLE = void 0;
22
22
  const json_schema_1 = require("@manuscripts/json-schema");
23
23
  const w3c_xmlserializer_1 = __importDefault(require("w3c-xmlserializer"));
24
24
  const schema_1 = require("../schema");
@@ -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) => ({
@@ -291,3 +290,9 @@ const buildElementsOrder = (elementType) => ({
291
290
  elements: [],
292
291
  });
293
292
  exports.buildElementsOrder = buildElementsOrder;
293
+ const buildTitles = (title) => ({
294
+ _id: (0, id_1.generateID)(json_schema_1.ObjectTypes.Titles),
295
+ objectType: json_schema_1.ObjectTypes.Titles,
296
+ title: title || '',
297
+ });
298
+ exports.buildTitles = buildTitles;
@@ -35,6 +35,7 @@ const debug_1 = __importDefault(require("debug"));
35
35
  const prosemirror_model_1 = require("prosemirror-model");
36
36
  const errors_1 = require("../errors");
37
37
  const schema_1 = require("../schema");
38
+ const builders_1 = require("./builders");
38
39
  const highlight_markers_1 = require("./highlight-markers");
39
40
  const id_1 = require("./id");
40
41
  const object_types_1 = require("./object-types");
@@ -115,6 +116,11 @@ class Decoder {
115
116
  rootSectionNodes.unshift(node);
116
117
  }
117
118
  }
119
+ createTitleNode() {
120
+ const titles = (0, exports.getModelsByType)(this.modelMap, json_schema_1.ObjectTypes.Titles)[0] ||
121
+ (0, builders_1.buildTitles)();
122
+ return this.decode(titles);
123
+ }
118
124
  createRootSectionNodes() {
119
125
  let rootSections = getSections(this.modelMap).filter((section) => !section.path || section.path.length <= 1);
120
126
  rootSections = this.addGeneratedLabels(rootSections);
@@ -147,6 +153,14 @@ class Decoder {
147
153
  constructor(modelMap, allowMissingElements = false) {
148
154
  this.comments = new Map();
149
155
  this.creators = {
156
+ [json_schema_1.ObjectTypes.Titles]: (data) => {
157
+ const model = data;
158
+ return this.parseContents(model.title, 'div', undefined, {
159
+ topNode: schema_1.schema.nodes.title.create({
160
+ id: model._id,
161
+ }),
162
+ });
163
+ },
150
164
  [json_schema_1.ObjectTypes.BibliographyElement]: (data) => {
151
165
  var _a;
152
166
  const model = data;
@@ -631,9 +645,14 @@ class Decoder {
631
645
  };
632
646
  this.getModel = (id) => this.modelMap.get(id);
633
647
  this.createArticleNode = (manuscriptID) => {
648
+ const titlesNode = this.createTitleNode();
634
649
  const rootSectionNodes = this.createRootSectionNodes();
635
650
  const metaSectionNode = this.createMetaSectionNode();
636
- const contents = [...rootSectionNodes, metaSectionNode];
651
+ const contents = [
652
+ titlesNode,
653
+ ...rootSectionNodes,
654
+ metaSectionNode,
655
+ ];
637
656
  return schema_1.schema.nodes.manuscript.create({
638
657
  id: manuscriptID || this.getManuscriptID(),
639
658
  }, contents);
@@ -263,6 +263,12 @@ function figureElementEncoder(node) {
263
263
  };
264
264
  }
265
265
  const encoders = {
266
+ title: (node) => ({
267
+ title: (0, exports.inlineContents)(node),
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 titles = (0, project_bundle_1.findTitles)(this.modelMap);
155
156
  if (!manuscript) {
156
157
  throw new Error('Manuscript not found in project modelMap');
157
158
  }
@@ -170,14 +171,14 @@ class HTMLTransformer {
170
171
  }
171
172
  const articleMeta = this.document.createElement('div');
172
173
  front.appendChild(articleMeta);
173
- const articleTitle = this.document.createElement('h1');
174
- if (manuscript.title) {
175
- articleTitle.innerHTML = manuscript.title;
174
+ const title = this.document.createElement('h1');
175
+ if (titles.title) {
176
+ title.innerHTML = titles.title;
176
177
  }
177
178
  if (journal === null || journal === void 0 ? void 0 : journal.title) {
178
- articleTitle.setAttribute('data-journal', journal.title);
179
+ title.setAttribute('data-journal', journal.title);
179
180
  }
180
- articleMeta.appendChild(articleTitle);
181
+ articleMeta.appendChild(title);
181
182
  if (manuscript.DOI) {
182
183
  const articleID = this.document.createElement('article-id');
183
184
  articleID.setAttribute('pub-id-type', 'doi');
@@ -32,7 +32,7 @@ const textSnippet = (node, max = 100) => {
32
32
  text += ' ';
33
33
  }
34
34
  });
35
- return text.substr(0, max);
35
+ return text.substring(0, max);
36
36
  };
37
37
  const snippetOfNodeType = (node, nodeType) => {
38
38
  for (const child of (0, utils_1.iterateChildren)(node, true)) {
@@ -43,8 +43,10 @@ const snippetOfNodeType = (node, nodeType) => {
43
43
  return null;
44
44
  };
45
45
  const nodeTitle = (node) => {
46
- const nodes = node.type.schema.nodes;
46
+ const nodes = schema_1.schema.nodes;
47
47
  switch (node.type) {
48
+ case nodes.manuscript:
49
+ return snippetOfNodeType(node, nodes.title);
48
50
  case nodes.section:
49
51
  case nodes.bibliography_section:
50
52
  case nodes.footnotes_section:
@@ -72,9 +74,9 @@ const nodeTitle = (node) => {
72
74
  };
73
75
  exports.nodeTitle = nodeTitle;
74
76
  const nodeTitlePlaceholder = (nodeType) => {
75
- const nodes = nodeType.schema.nodes;
77
+ const nodes = schema_1.schema.nodes;
76
78
  switch (nodeType) {
77
- case nodes.title:
79
+ case nodes.manuscript:
78
80
  return 'Untitled Manuscript';
79
81
  case nodes.section:
80
82
  return 'Untitled Section';
@@ -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.Titles],
60
61
  [schema_1.schema.nodes.contributors_section, json_schema_1.ObjectTypes.Section],
61
62
  [schema_1.schema.nodes.affiliations_section, json_schema_1.ObjectTypes.Section],
62
63
  ]);
@@ -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.findTitles = 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,24 @@ 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.Titles);
75
+ const findTitles = (modelMap) => {
76
+ for (const model of modelMap.values()) {
77
+ if (isTitle(model)) {
78
+ return model;
79
+ }
80
+ }
81
+ const defaultTitle = {
82
+ _id: 'MPTitles:8EB79C14-9F61-483A-902F-A0B8EF5973C1',
83
+ createdAt: 1538472121.690101,
84
+ updatedAt: 1538472121.690101,
85
+ objectType: 'MPTitles',
86
+ title: 'main title',
87
+ subtitle: 'subtitle',
88
+ runningTitle: 'running title',
89
+ manuscriptID: 'MPManuscript:E3830344-E77B-42BA-BD77-3E95489712A0',
90
+ containerID: 'MPProject:1',
91
+ };
92
+ return defaultTitle;
93
+ };
94
+ exports.findTitles = findTitles;
@@ -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';
@@ -48,9 +49,16 @@ export const parseJATSFront = async (front) => {
48
49
  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
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 titles = {
54
+ objectType: ObjectTypes.Titles,
55
+ _id: generateID(ObjectTypes.Titles),
56
+ title: title ? inlineContentsFromJATSTitle(title) : undefined,
57
+ subtitle: subtitle ? inlineContentsFromJATSTitle(subtitle) : undefined,
58
+ runningTitle: runningTitle
52
59
  ? inlineContentsFromJATSTitle(runningTitle)
53
- : undefined }, jatsFrontParser.parseCounts(articleMeta === null || articleMeta === void 0 ? void 0 : articleMeta.querySelector('counts')));
60
+ : undefined,
61
+ };
54
62
  const { affiliations, affiliationIDs } = jatsFrontParser.parseAffiliationNodes([
55
63
  ...front.querySelectorAll('article-meta > contrib-group > aff'),
56
64
  ]);
@@ -70,6 +78,7 @@ export const parseJATSFront = async (front) => {
70
78
  const manuscript = Object.assign(Object.assign(Object.assign({}, buildManuscript()), manuscriptMeta), history);
71
79
  return {
72
80
  models: generateModelIDs([
81
+ titles,
73
82
  manuscript,
74
83
  ...footnotes,
75
84
  ...correspondingList,
@@ -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, findTitles, } 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 titles = findTitles(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 (titles.title) {
312
313
  const element = this.document.createElement('article-title');
313
- this.setTitleContent(element, manuscript.title);
314
+ this.setTitleContent(element, titles.title);
314
315
  titleGroup.appendChild(element);
315
316
  }
316
- if (manuscript.subtitle) {
317
+ if (titles.subtitle) {
317
318
  const element = this.document.createElement('subtitle');
318
- this.setTitleContent(element, manuscript.subtitle);
319
+ this.setTitleContent(element, titles.subtitle);
319
320
  titleGroup.appendChild(element);
320
321
  }
321
- if (manuscript.runningTitle) {
322
+ if (titles.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, titles.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
  affiliations_section: () => '',
595
597
  contributors_section: () => '',
596
598
  table_element_footer: () => ['table-wrap-foot', 0],
@@ -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';
@@ -123,6 +124,7 @@ export * from './nodes/affiliation';
123
124
  export * from './nodes/meta_section';
124
125
  export * from './nodes/contributor';
125
126
  export * from './nodes/table_element_footer';
127
+ export * from './nodes/title';
126
128
  export * from './nodes/affiliations_section';
127
129
  export * from './nodes/contributors_section';
128
130
  export const schema = new Schema({
@@ -199,6 +201,7 @@ export const schema = new Schema({
199
201
  meta_section: metaSection,
200
202
  contributor: contributor,
201
203
  table_element_footer: tableElementFooter,
204
+ title: title,
202
205
  affiliations_section: affiliationsSection,
203
206
  contributors_section: contributorsSection,
204
207
  },
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  export const manuscript = {
17
- content: '(section | sections)+ meta_section',
17
+ content: 'title* (section | sections)+ meta_section',
18
18
  attrs: {
19
19
  id: { default: '' },
20
20
  },
@@ -0,0 +1,26 @@
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 tracked_insert tracked_delete',
19
+ attrs: {
20
+ id: { default: '' },
21
+ dataTracked: { default: null },
22
+ },
23
+ group: 'block element',
24
+ parseDOM: [{ tag: 'div' }],
25
+ toDOM: () => ['div', 0],
26
+ };
@@ -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),
@@ -249,3 +248,8 @@ export const buildElementsOrder = (elementType) => ({
249
248
  elementType: elementType,
250
249
  elements: [],
251
250
  });
251
+ export const buildTitles = (title) => ({
252
+ _id: generateID(ObjectTypes.Titles),
253
+ objectType: ObjectTypes.Titles,
254
+ title: title || '',
255
+ });
@@ -29,6 +29,7 @@ import debug from 'debug';
29
29
  import { DOMParser } from 'prosemirror-model';
30
30
  import { MissingElement } from '../errors';
31
31
  import { schema, } from '../schema';
32
+ import { buildTitles } from './builders';
32
33
  import { insertHighlightMarkers } from './highlight-markers';
33
34
  import { generateNodeID } from './id';
34
35
  import { ExtraObjectTypes, hasObjectType, isCommentAnnotation, isManuscript, } from './object-types';
@@ -105,6 +106,11 @@ export class Decoder {
105
106
  rootSectionNodes.unshift(node);
106
107
  }
107
108
  }
109
+ createTitleNode() {
110
+ const titles = getModelsByType(this.modelMap, ObjectTypes.Titles)[0] ||
111
+ buildTitles();
112
+ return this.decode(titles);
113
+ }
108
114
  createRootSectionNodes() {
109
115
  let rootSections = getSections(this.modelMap).filter((section) => !section.path || section.path.length <= 1);
110
116
  rootSections = this.addGeneratedLabels(rootSections);
@@ -137,6 +143,14 @@ export class Decoder {
137
143
  constructor(modelMap, allowMissingElements = false) {
138
144
  this.comments = new Map();
139
145
  this.creators = {
146
+ [ObjectTypes.Titles]: (data) => {
147
+ const model = data;
148
+ return this.parseContents(model.title, 'div', undefined, {
149
+ topNode: schema.nodes.title.create({
150
+ id: model._id,
151
+ }),
152
+ });
153
+ },
140
154
  [ObjectTypes.BibliographyElement]: (data) => {
141
155
  var _a;
142
156
  const model = data;
@@ -621,9 +635,14 @@ export class Decoder {
621
635
  };
622
636
  this.getModel = (id) => this.modelMap.get(id);
623
637
  this.createArticleNode = (manuscriptID) => {
638
+ const titlesNode = this.createTitleNode();
624
639
  const rootSectionNodes = this.createRootSectionNodes();
625
640
  const metaSectionNode = this.createMetaSectionNode();
626
- const contents = [...rootSectionNodes, metaSectionNode];
641
+ const contents = [
642
+ titlesNode,
643
+ ...rootSectionNodes,
644
+ metaSectionNode,
645
+ ];
627
646
  return schema.nodes.manuscript.create({
628
647
  id: manuscriptID || this.getManuscriptID(),
629
648
  }, contents);
@@ -255,6 +255,12 @@ function figureElementEncoder(node) {
255
255
  };
256
256
  }
257
257
  const encoders = {
258
+ title: (node) => ({
259
+ title: inlineContents(node),
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, findTitles } 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 titles = findTitles(this.modelMap);
149
150
  if (!manuscript) {
150
151
  throw new Error('Manuscript not found in project modelMap');
151
152
  }
@@ -164,14 +165,14 @@ export class HTMLTransformer {
164
165
  }
165
166
  const articleMeta = this.document.createElement('div');
166
167
  front.appendChild(articleMeta);
167
- const articleTitle = this.document.createElement('h1');
168
- if (manuscript.title) {
169
- articleTitle.innerHTML = manuscript.title;
168
+ const title = this.document.createElement('h1');
169
+ if (titles.title) {
170
+ title.innerHTML = titles.title;
170
171
  }
171
172
  if (journal === null || journal === void 0 ? void 0 : journal.title) {
172
- articleTitle.setAttribute('data-journal', journal.title);
173
+ title.setAttribute('data-journal', journal.title);
173
174
  }
174
- articleMeta.appendChild(articleTitle);
175
+ articleMeta.appendChild(title);
175
176
  if (manuscript.DOI) {
176
177
  const articleID = this.document.createElement('article-id');
177
178
  articleID.setAttribute('pub-id-type', 'doi');
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { iterateChildren } from '../lib/utils';
17
- import { isHighlightMarkerNode } from '../schema';
17
+ import { isHighlightMarkerNode, schema } from '../schema';
18
18
  import { nodeNames } from './node-names';
19
19
  const textSnippet = (node, max = 100) => {
20
20
  let text = '';
@@ -29,7 +29,7 @@ const textSnippet = (node, max = 100) => {
29
29
  text += ' ';
30
30
  }
31
31
  });
32
- return text.substr(0, max);
32
+ return text.substring(0, max);
33
33
  };
34
34
  const snippetOfNodeType = (node, nodeType) => {
35
35
  for (const child of iterateChildren(node, true)) {
@@ -40,8 +40,10 @@ const snippetOfNodeType = (node, nodeType) => {
40
40
  return null;
41
41
  };
42
42
  export const nodeTitle = (node) => {
43
- const nodes = node.type.schema.nodes;
43
+ const nodes = schema.nodes;
44
44
  switch (node.type) {
45
+ case nodes.manuscript:
46
+ return snippetOfNodeType(node, nodes.title);
45
47
  case nodes.section:
46
48
  case nodes.bibliography_section:
47
49
  case nodes.footnotes_section:
@@ -68,9 +70,9 @@ export const nodeTitle = (node) => {
68
70
  }
69
71
  };
70
72
  export const nodeTitlePlaceholder = (nodeType) => {
71
- const nodes = nodeType.schema.nodes;
73
+ const nodes = schema.nodes;
72
74
  switch (nodeType) {
73
- case nodes.title:
75
+ case nodes.manuscript:
74
76
  return 'Untitled Manuscript';
75
77
  case nodes.section:
76
78
  return 'Untitled Section';
@@ -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.Titles],
57
58
  [schema.nodes.contributors_section, ObjectTypes.Section],
58
59
  [schema.nodes.affiliations_section, ObjectTypes.Section],
59
60
  ]);
@@ -63,3 +63,23 @@ 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.Titles);
67
+ export const findTitles = (modelMap) => {
68
+ for (const model of modelMap.values()) {
69
+ if (isTitle(model)) {
70
+ return model;
71
+ }
72
+ }
73
+ const defaultTitle = {
74
+ _id: 'MPTitles:8EB79C14-9F61-483A-902F-A0B8EF5973C1',
75
+ createdAt: 1538472121.690101,
76
+ updatedAt: 1538472121.690101,
77
+ objectType: 'MPTitles',
78
+ title: 'main title',
79
+ subtitle: 'subtitle',
80
+ runningTitle: 'running title',
81
+ manuscriptID: 'MPManuscript:E3830344-E77B-42BA-BD77-3E95489712A0',
82
+ containerID: 'MPProject:1',
83
+ };
84
+ return defaultTitle;
85
+ };
@@ -68,6 +68,7 @@ export * from './nodes/affiliation';
68
68
  export * from './nodes/meta_section';
69
69
  export * from './nodes/contributor';
70
70
  export * from './nodes/table_element_footer';
71
+ export * from './nodes/title';
71
72
  export * from './nodes/affiliations_section';
72
73
  export * from './nodes/contributors_section';
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
+ title: 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' | 'contributor' | 'table_element_footer' | 'affiliations_section' | 'contributors_section';
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' | 'contributor' | 'table_element_footer' | 'title' | 'affiliations_section' | 'contributors_section';
21
21
  export type ManuscriptSchema = Schema<Nodes, Marks>;
22
22
  export type ManuscriptEditorState = EditorState;
23
23
  export type ManuscriptEditorView = EditorView;
@@ -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 { Affiliation, Attribution, AuxiliaryObjectReference, BibliographicDate, BibliographicName, BibliographyItem, Citation, CitationItem, Color, CommentAnnotation, Contribution, Contributor, ContributorRole, Corresponding, ElementsOrder, EmbeddedModel, Figure, Footnote, FootnotesOrder, Highlight, HighlightMarker, InlineMathFragment, InlineStyle, Journal, Keyword, KeywordGroup, LibraryCollection, Manuscript, ManuscriptKeyword, ManuscriptNote, ObjectTypes, ParagraphElement, Project, RequirementsValidation, RequirementsValidationData, Section, StatusLabel, Supplement, UserProfileAffiliation } from '@manuscripts/json-schema';
16
+ import { Affiliation, Attribution, AuxiliaryObjectReference, BibliographicDate, BibliographicName, BibliographyItem, Citation, CitationItem, Color, CommentAnnotation, Contribution, Contributor, ContributorRole, Corresponding, ElementsOrder, EmbeddedModel, Figure, Footnote, FootnotesOrder, Highlight, HighlightMarker, InlineMathFragment, InlineStyle, Journal, Keyword, KeywordGroup, LibraryCollection, Manuscript, ManuscriptKeyword, ManuscriptNote, ObjectTypes, ParagraphElement, Project, RequirementsValidation, RequirementsValidationData, Section, StatusLabel, Supplement, Titles, UserProfileAffiliation } from '@manuscripts/json-schema';
17
17
  import { FootnotesOrderIndexList } from './footnotes-order';
18
18
  import { CommentSelector, ManuscriptModel, ModelAttachment } from './models';
19
19
  export declare const DEFAULT_BUNDLE = "MPBundle:www-zotero-org-styles-nature";
@@ -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>;
@@ -70,3 +70,4 @@ export declare const buildStatusLabel: (name: string) => Build<StatusLabel>;
70
70
  export type AuxiliaryObjects = 'MPFigureElement' | 'MPTableElement' | 'MPListingElement' | 'MPEquationElement';
71
71
  export declare const auxiliaryObjectTypes: Set<import("prosemirror-model").NodeType>;
72
72
  export declare const buildElementsOrder: (elementType: AuxiliaryObjects) => Build<ElementsOrder>;
73
+ export declare const buildTitles: (title?: string) => Build<Titles>;
@@ -30,6 +30,7 @@ export declare class Decoder {
30
30
  private handleMissingRootSectionNodes;
31
31
  private createAffiliationSectionNode;
32
32
  private createContributorSectionNode;
33
+ private createTitleNode;
33
34
  private createRootSectionNodes;
34
35
  private createCommentsNode;
35
36
  private getComments;
@@ -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, Titles } 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 findTitles: (modelMap: Map<string, Model>) => Titles;
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.5.3",
4
+ "version": "1.5.4",
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.1",
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
+ }