@manuscripts/transform 1.0.1 → 1.1.0-LEAN-2070

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.
@@ -24,6 +24,7 @@ import { caption } from './nodes/caption';
24
24
  import { captionTitle } from './nodes/caption_title';
25
25
  import { citation } from './nodes/citation';
26
26
  import { comment } from './nodes/comment';
27
+ import { commentList } from './nodes/comment_list';
27
28
  import { crossReference } from './nodes/cross_reference';
28
29
  import { doc } from './nodes/doc';
29
30
  import { equation } from './nodes/equation';
@@ -39,6 +40,7 @@ import { hardBreak } from './nodes/hard_break';
39
40
  import { highlightMarker } from './nodes/highlight_marker';
40
41
  import { inlineEquation } from './nodes/inline_equation';
41
42
  import { inlineFootnote } from './nodes/inline_footnote';
43
+ import { keyword } from './nodes/keyword';
42
44
  import { keywordsElement } from './nodes/keywords_element';
43
45
  import { keywordsSection } from './nodes/keywords_section';
44
46
  import { link } from './nodes/link';
@@ -64,6 +66,7 @@ import { tocSection } from './nodes/toc_section';
64
66
  export * from './groups';
65
67
  export * from './types';
66
68
  export * from './nodes/comment';
69
+ export * from './nodes/comment_list';
67
70
  export * from './nodes/attribution';
68
71
  export * from './nodes/bibliography_item';
69
72
  export * from './nodes/bibliography_element';
@@ -87,6 +90,7 @@ export * from './nodes/hard_break';
87
90
  export * from './nodes/highlight_marker';
88
91
  export * from './nodes/inline_equation';
89
92
  export * from './nodes/inline_footnote';
93
+ export * from './nodes/keyword';
90
94
  export * from './nodes/keywords_element';
91
95
  export * from './nodes/keywords_section';
92
96
  export * from './nodes/link';
@@ -124,6 +128,7 @@ export const schema = new Schema({
124
128
  },
125
129
  nodes: {
126
130
  comment,
131
+ comment_list: commentList,
127
132
  attribution,
128
133
  bibliography_item: bibliographyItem,
129
134
  bibliography_element: bibliographyElement,
@@ -148,6 +153,7 @@ export const schema = new Schema({
148
153
  highlight_marker: highlightMarker,
149
154
  inline_equation: inlineEquation,
150
155
  inline_footnote: inlineFootnote,
156
+ keyword,
151
157
  keywords_element: keywordsElement,
152
158
  keywords_section: keywordsSection,
153
159
  link,
@@ -164,6 +170,7 @@ export const schema = new Schema({
164
170
  section,
165
171
  section_label: sectionLabel,
166
172
  section_title: sectionTitle,
173
+ section_title_plain: sectionTitle,
167
174
  table,
168
175
  table_body: tableBody,
169
176
  table_cell: tableCell,
@@ -0,0 +1,21 @@
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 commentList = {
17
+ content: 'comment*',
18
+ attrs: {
19
+ id: { default: '' },
20
+ },
21
+ };
@@ -0,0 +1,50 @@
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 keyword = {
17
+ atom: true,
18
+ content: 'text*',
19
+ attrs: {
20
+ id: { default: '' },
21
+ contents: { default: '' },
22
+ dataTracked: { default: null },
23
+ comments: { default: null },
24
+ },
25
+ inline: true,
26
+ group: 'inline',
27
+ selectable: false,
28
+ parseDOM: [
29
+ {
30
+ tag: 'span.keyword',
31
+ getAttrs: (node) => {
32
+ const dom = node;
33
+ return {
34
+ id: dom.getAttribute('id'),
35
+ };
36
+ },
37
+ },
38
+ ],
39
+ toDOM: (node) => {
40
+ const keywordNode = node;
41
+ return [
42
+ 'span',
43
+ {
44
+ class: 'keyword',
45
+ id: keywordNode.attrs.id,
46
+ },
47
+ 0,
48
+ ];
49
+ },
50
+ };
@@ -13,15 +13,9 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { nodeFromHTML } from '../../lib/html';
17
- const createBodyElement = (node) => {
18
- const dom = document.createElement('div');
19
- dom.className = 'manuscript-keywords';
20
- dom.id = node.attrs.id;
21
- return dom;
22
- };
23
16
  export const keywordsElement = {
24
17
  atom: true,
18
+ content: 'keyword*',
25
19
  attrs: {
26
20
  id: { default: '' },
27
21
  contents: { default: '' },
@@ -43,7 +37,13 @@ export const keywordsElement = {
43
37
  ],
44
38
  toDOM: (node) => {
45
39
  const keywordsElementNode = node;
46
- return (nodeFromHTML(keywordsElementNode.attrs.contents) ||
47
- createBodyElement(keywordsElementNode));
40
+ return [
41
+ 'div',
42
+ {
43
+ class: 'manuscript-keywords',
44
+ id: keywordsElementNode.attrs.id,
45
+ },
46
+ 0,
47
+ ];
48
48
  },
49
49
  };
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  export const keywordsSection = {
17
- content: 'section_title (keywords_element | placeholder_element)',
17
+ content: 'section_title_plain (keywords_element | placeholder_element)',
18
18
  attrs: {
19
19
  id: { default: '' },
20
20
  dataTracked: { default: null },
@@ -23,13 +23,13 @@ export const keywordsSection = {
23
23
  selectable: false,
24
24
  parseDOM: [
25
25
  {
26
- tag: 'section.keywords',
26
+ tag: 'div.keywords',
27
27
  },
28
28
  ],
29
29
  toDOM: (node) => {
30
30
  const keywordsSectionNode = node;
31
31
  return [
32
- 'section',
32
+ 'div',
33
33
  {
34
34
  id: keywordsSectionNode.attrs.id,
35
35
  class: 'keywords',
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  export const manuscript = {
17
- content: '(section | sections)+',
17
+ content: '(section | sections)+ comment_list*',
18
18
  attrs: {
19
19
  id: { default: '' },
20
20
  },
@@ -54,6 +54,7 @@ const getSections = (modelMap) => getModelsByType(modelMap, ObjectTypes.Section)
54
54
  export const isManuscriptNode = (model) => model !== null;
55
55
  const isParagraphElement = hasObjectType(ObjectTypes.ParagraphElement);
56
56
  const isFootnote = hasObjectType(ObjectTypes.Footnote);
57
+ const isKeyword = hasObjectType(ObjectTypes.Keyword);
57
58
  const hasParentSection = (id) => (section) => section.path &&
58
59
  section.path.length > 1 &&
59
60
  section.path[section.path.length - 2] === id;
@@ -88,6 +89,7 @@ export class Decoder {
88
89
  }
89
90
  }
90
91
  constructor(modelMap, allowMissingElements = false) {
92
+ this.comments = new Map();
91
93
  this.creators = {
92
94
  [ObjectTypes.BibliographyElement]: (data) => {
93
95
  var _a;
@@ -134,12 +136,14 @@ export class Decoder {
134
136
  },
135
137
  [ObjectTypes.Figure]: (data) => {
136
138
  const model = data;
139
+ const commentNodes = this.createCommentsNode(model);
140
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
137
141
  return schema.nodes.figure.create({
138
142
  id: model._id,
139
143
  contentType: model.contentType,
140
144
  src: model.src,
141
145
  position: model.position,
142
- comments: this.createCommentsNode(model),
146
+ comments: commentNodes.map((c) => c.attrs.id),
143
147
  });
144
148
  },
145
149
  [ObjectTypes.FigureElement]: (data) => {
@@ -168,6 +172,8 @@ export class Decoder {
168
172
  figures.push(schema.nodes.figure.createAndFill());
169
173
  }
170
174
  const figcaption = this.getFigcaption(model);
175
+ const commentNodes = this.createCommentsNode(model);
176
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
171
177
  const content = [...paragraphs, ...figures, figcaption];
172
178
  const listing = this.extractListing(model);
173
179
  if (listing) {
@@ -188,7 +194,7 @@ export class Decoder {
188
194
  suppressTitle: Boolean(model.suppressTitle === undefined ? true : model.suppressTitle),
189
195
  attribution: model.attribution,
190
196
  alternatives: model.alternatives,
191
- comments: this.createCommentsNode(model),
197
+ comments: commentNodes.map((c) => c.attrs.id),
192
198
  }, content);
193
199
  },
194
200
  [ObjectTypes.Equation]: (data) => {
@@ -229,11 +235,13 @@ export class Decoder {
229
235
  const footnotesOfKind = [];
230
236
  for (const model of this.modelMap.values()) {
231
237
  if (isFootnote(model) && model.kind === collateByKind) {
238
+ const commentNodes = this.createCommentsNode(model);
239
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
232
240
  const footnote = this.parseContents(model.contents || '<div></div>', undefined, this.getComments(model), {
233
241
  topNode: schema.nodes.footnote.create({
234
242
  id: model._id,
235
243
  kind: model.kind,
236
- comments: this.createCommentsNode(model),
244
+ comments: commentNodes.map((c) => c.attrs.id),
237
245
  }),
238
246
  });
239
247
  footnotesOfKind.push(footnote);
@@ -247,31 +255,41 @@ export class Decoder {
247
255
  },
248
256
  [ObjectTypes.Footnote]: (data) => {
249
257
  const model = data;
258
+ const commentNodes = this.createCommentsNode(model);
259
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
250
260
  return schema.nodes.footnote.create({
251
261
  id: model._id,
252
262
  kind: model.kind,
253
- comments: this.createCommentsNode(model),
263
+ comments: commentNodes.map((c) => c.attrs.id),
254
264
  });
255
265
  },
256
266
  [ObjectTypes.KeywordsElement]: (data) => {
257
267
  const model = data;
268
+ const keywords = this.getKeywords();
258
269
  return schema.nodes.keywords_element.create({
259
270
  id: model._id,
260
- contents: model.contents
261
- ? model.contents.replace(/\s+xmlns=".+?"/, '')
262
- : '',
263
271
  paragraphStyle: model.paragraphStyle,
264
- });
272
+ }, keywords);
273
+ },
274
+ [ObjectTypes.Keyword]: (data) => {
275
+ const model = data;
276
+ return schema.nodes.keyword.create({
277
+ id: model._id,
278
+ contents: model.name,
279
+ comments: this.createCommentsNode(model),
280
+ }, schema.text(model.name));
265
281
  },
266
282
  [ObjectTypes.ListElement]: (data) => {
267
283
  const model = data;
284
+ const commentNodes = this.createCommentsNode(model);
285
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
268
286
  switch (model.elementType) {
269
287
  case 'ol':
270
288
  return this.parseContents(model.contents || '<ol></ol>', undefined, this.getComments(model), {
271
289
  topNode: schema.nodes.ordered_list.create({
272
290
  id: model._id,
273
291
  paragraphStyle: model.paragraphStyle,
274
- comments: this.createCommentsNode(model),
292
+ comments: commentNodes.map((c) => c.attrs.id),
275
293
  }),
276
294
  });
277
295
  case 'ul':
@@ -287,12 +305,14 @@ export class Decoder {
287
305
  },
288
306
  [ObjectTypes.Listing]: (data) => {
289
307
  const model = data;
308
+ const commentNodes = this.createCommentsNode(model);
309
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
290
310
  return schema.nodes.listing.createChecked({
291
311
  id: model._id,
292
312
  contents: model.contents,
293
313
  language: model.language,
294
314
  languageKey: model.languageKey,
295
- comments: this.createCommentsNode(model),
315
+ comments: commentNodes.map((c) => c.attrs.id),
296
316
  });
297
317
  },
298
318
  [ObjectTypes.ListingElement]: (data) => {
@@ -312,11 +332,13 @@ export class Decoder {
312
332
  throw new MissingElement(model.containedObjectID);
313
333
  }
314
334
  const figcaption = this.getFigcaption(model);
335
+ const commentNodes = this.createCommentsNode(model);
336
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
315
337
  return schema.nodes.listing_element.createChecked({
316
338
  id: model._id,
317
339
  suppressCaption: model.suppressCaption,
318
340
  suppressTitle: Boolean(model.suppressTitle === undefined ? true : model.suppressTitle),
319
- comments: this.createCommentsNode(model),
341
+ comments: commentNodes.map((c) => c.attrs.id),
320
342
  }, [listing, figcaption]);
321
343
  },
322
344
  [ObjectTypes.MissingFigure]: (data) => {
@@ -328,12 +350,14 @@ export class Decoder {
328
350
  },
329
351
  [ObjectTypes.ParagraphElement]: (data) => {
330
352
  const model = data;
353
+ const commentNodes = this.createCommentsNode(model);
354
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
331
355
  return this.parseContents(model.contents || '<p></p>', undefined, this.getComments(model), {
332
356
  topNode: schema.nodes.paragraph.create({
333
357
  id: model._id,
334
358
  paragraphStyle: model.paragraphStyle,
335
359
  placeholder: model.placeholderInnerHTML,
336
- comments: this.createCommentsNode(model),
360
+ comments: commentNodes.map((c) => c.attrs.id),
337
361
  }),
338
362
  });
339
363
  },
@@ -392,11 +416,14 @@ export class Decoder {
392
416
  const elementNodes = elements
393
417
  .map(this.decode)
394
418
  .filter(isManuscriptNode);
419
+ const sectionTitle = isKeywordsSection
420
+ ? 'section_title_plain'
421
+ : 'section_title';
395
422
  const sectionTitleNode = model.title
396
423
  ? this.parseContents(model.title, 'h1', this.getComments(model), {
397
- topNode: schema.nodes.section_title.create(),
424
+ topNode: schema.nodes[sectionTitle].create(),
398
425
  })
399
- : schema.nodes.section_title.create();
426
+ : schema.nodes[sectionTitle].create();
400
427
  let sectionLabelNode = undefined;
401
428
  if (model.label) {
402
429
  sectionLabelNode = this.parseContents(model.label, 'label', this.getComments(model), {
@@ -408,6 +435,8 @@ export class Decoder {
408
435
  .map(this.creators[ObjectTypes.Section]);
409
436
  const sectionCategory = model.category || guessSectionCategory(elements);
410
437
  const sectionNodeType = chooseSectionNodeType(sectionCategory);
438
+ const commentNodes = this.createCommentsNode(model);
439
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
411
440
  const content = (sectionLabelNode
412
441
  ? [sectionLabelNode, sectionTitleNode]
413
442
  : [sectionTitleNode])
@@ -419,7 +448,7 @@ export class Decoder {
419
448
  titleSuppressed: model.titleSuppressed,
420
449
  pageBreakStyle: model.pageBreakStyle,
421
450
  generatedLabel: model.generatedLabel,
422
- comments: this.createCommentsNode(model),
451
+ comments: commentNodes.map((c) => c.attrs.id),
423
452
  }, content);
424
453
  if (!sectionNode) {
425
454
  console.error(model);
@@ -429,10 +458,12 @@ export class Decoder {
429
458
  },
430
459
  [ObjectTypes.Table]: (data) => {
431
460
  const model = data;
461
+ const commentNodes = this.createCommentsNode(model);
462
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
432
463
  return this.parseContents(model.contents, undefined, this.getComments(model), {
433
464
  topNode: schema.nodes.table.create({
434
465
  id: model._id,
435
- comments: this.createCommentsNode(model),
466
+ comments: commentNodes.map((c) => c.attrs.id),
436
467
  }),
437
468
  });
438
469
  },
@@ -453,6 +484,8 @@ export class Decoder {
453
484
  throw new MissingElement(model.containedObjectID);
454
485
  }
455
486
  const figcaption = this.getFigcaption(model);
487
+ const commentNodes = this.createCommentsNode(model);
488
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
456
489
  const content = [table, figcaption];
457
490
  if (model.listingID) {
458
491
  const listingModel = this.getModel(model.listingID);
@@ -484,7 +517,7 @@ export class Decoder {
484
517
  suppressHeader: model.suppressHeader,
485
518
  tableStyle: model.tableStyle,
486
519
  paragraphStyle: model.paragraphStyle,
487
- comments: this.createCommentsNode(model),
520
+ comments: commentNodes.map((c) => c.attrs.id),
488
521
  }, content);
489
522
  },
490
523
  [ObjectTypes.TOCElement]: (data) => {
@@ -526,9 +559,29 @@ export class Decoder {
526
559
  id: generateNodeID(schema.nodes.section),
527
560
  }));
528
561
  }
562
+ const keywordsSection = getSections(this.modelMap).filter((section) => section.category === 'MPSectionCategory:keywords');
563
+ const keywords = this.getKeywords();
564
+ if (keywordsSection.length === 0 && keywords.length > 0) {
565
+ const keywordsSection = schema.nodes.keywords_section.createAndFill({
566
+ id: generateNodeID(schema.nodes.keywords_section),
567
+ }, [
568
+ schema.nodes.section_title_plain.create({}, schema.text('Keywords')),
569
+ schema.nodes.keywords_element.create({
570
+ id: generateNodeID(schema.nodes.keywords_element),
571
+ }, keywords),
572
+ ]);
573
+ rootSectionNodes.unshift(keywordsSection);
574
+ }
575
+ const contents = rootSectionNodes;
576
+ if (this.comments.size) {
577
+ const comments = schema.nodes.comment_list.createAndFill({
578
+ id: generateNodeID(schema.nodes.comment_list),
579
+ }, [...this.comments.values()]);
580
+ contents.push(comments);
581
+ }
529
582
  return schema.nodes.manuscript.create({
530
583
  id: manuscriptID || this.getManuscriptID(),
531
- }, rootSectionNodes);
584
+ }, contents);
532
585
  };
533
586
  this.addGeneratedLabels = (sections) => {
534
587
  const nextLableCount = { Appendix: 1 };
@@ -561,10 +614,28 @@ export class Decoder {
561
614
  }
562
615
  const template = document.createElement('template');
563
616
  template.innerHTML = html;
564
- if (!template.content.firstChild) {
617
+ if (!template.content.firstElementChild) {
565
618
  throw new Error('No content could be parsed');
566
619
  }
567
- return parser.parse(template.content.firstChild, options);
620
+ return parser.parse(template.content.firstElementChild, options);
621
+ };
622
+ this.getKeywords = () => {
623
+ const keywordsOfKind = [];
624
+ for (const model of this.modelMap.values()) {
625
+ const commentNodes = this.createCommentsNode(model);
626
+ commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
627
+ if (isKeyword(model)) {
628
+ const keyword = this.parseContents(model.name || '', 'div', this.getComments(model), {
629
+ topNode: schema.nodes.keyword.create({
630
+ id: model._id,
631
+ contents: model.name,
632
+ comments: commentNodes.map((c) => c.attrs.id),
633
+ }),
634
+ });
635
+ keywordsOfKind.push(keyword);
636
+ }
637
+ }
638
+ return keywordsOfKind;
568
639
  };
569
640
  this.getManuscriptID = () => {
570
641
  for (const item of this.modelMap.values()) {
@@ -17,7 +17,7 @@ import { DOMSerializer } from 'prosemirror-model';
17
17
  import serializeToXML from 'w3c-xmlserializer';
18
18
  import { iterateChildren } from '../lib/utils';
19
19
  import { isHighlightMarkerNode, isSectionNode, schema, } from '../schema';
20
- import { buildAttribution, buildComment } from './builders';
20
+ import { buildAttribution } from './builders';
21
21
  import { extractHighlightMarkers, isHighlightableModel, } from './highlight-markers';
22
22
  import { nodeTypesMap } from './node-types';
23
23
  import { buildSectionCategory } from './section-category';
@@ -34,6 +34,10 @@ const footnoteContents = (node) => {
34
34
  });
35
35
  return serializeToXML(output);
36
36
  };
37
+ const keywordContents = (node) => {
38
+ const text = serializer.serializeNode(node).textContent;
39
+ return text === null ? '' : text;
40
+ };
37
41
  export const inlineContents = (node) => serializer.serializeNode(node).innerHTML;
38
42
  export const inlineText = (node) => {
39
43
  const text = serializer.serializeNode(node).textContent;
@@ -385,6 +389,10 @@ const encoders = {
385
389
  SVGRepresentation: node.attrs.SVGRepresentation,
386
390
  SVGGlyphs: svgDefs(node.attrs.SVGRepresentation),
387
391
  }),
392
+ keyword: (node, parent) => ({
393
+ containerID: parent.attrs.id,
394
+ name: keywordContents(node),
395
+ }),
388
396
  keywords_element: (node) => ({
389
397
  contents: elementContents(node),
390
398
  elementType: 'div',
@@ -393,7 +401,7 @@ const encoders = {
393
401
  keywords_section: (node, parent, path, priority) => ({
394
402
  category: buildSectionCategory(node),
395
403
  priority: priority.value++,
396
- title: inlineContentsOfNodeType(node, node.type.schema.nodes.section_title),
404
+ title: inlineContentsOfNodeType(node, node.type.schema.nodes.section_title_plain),
397
405
  path: path.concat([node.attrs.id]),
398
406
  elementIDs: childElements(node)
399
407
  .map((childNode) => childNode.attrs.id)
@@ -493,16 +501,6 @@ export const modelFromNode = (node, parent, path, priority) => {
493
501
  const model = data;
494
502
  if (isHighlightableModel(model)) {
495
503
  extractHighlightMarkers(model, commentAnnotationsMap);
496
- if (node.attrs.comments) {
497
- const commentNodes = node.attrs.comments;
498
- commentNodes
499
- .filter((commentNode) => !commentNode.attrs.selector)
500
- .forEach((c) => {
501
- const commentAnnotation = buildComment(model._id, c.attrs.contents, c.attrs.selector);
502
- commentAnnotation._id = c.attrs.id;
503
- commentAnnotationsMap.set(commentAnnotation._id, commentAnnotation);
504
- });
505
- }
506
504
  }
507
505
  return { model, commentAnnotationsMap };
508
506
  };
@@ -519,6 +517,9 @@ export const encode = (node) => {
519
517
  if (isHighlightMarkerNode(child)) {
520
518
  return;
521
519
  }
520
+ if (child.type === schema.nodes.comment_list) {
521
+ return;
522
+ }
522
523
  if (placeholders.includes(child.type.name)) {
523
524
  return;
524
525
  }
@@ -530,6 +531,14 @@ export const encode = (node) => {
530
531
  commentAnnotationsMap.forEach((val, key) => models.set(key, val));
531
532
  child.forEach(addModel(path.concat(child.attrs.id), child));
532
533
  };
534
+ node.forEach((cNode) => {
535
+ if (cNode.type === schema.nodes.comment_list) {
536
+ cNode.forEach((child) => {
537
+ const { model } = modelFromNode(child, cNode, [], priority);
538
+ models.set(model._id, model);
539
+ });
540
+ }
541
+ });
533
542
  node.forEach(addModel([], node));
534
543
  return models;
535
544
  };
@@ -30,6 +30,7 @@ export const nodeNames = new Map([
30
30
  [schema.nodes.paragraph, 'Paragraph'],
31
31
  [schema.nodes.section, 'Section'],
32
32
  [schema.nodes.section_title, 'Section'],
33
+ [schema.nodes.section_title_plain, 'Section'],
33
34
  [schema.nodes.table, 'Table'],
34
35
  [schema.nodes.table_element, 'Table'],
35
36
  [schema.nodes.blockquote_element, 'Block Quote'],
@@ -35,6 +35,7 @@ export const nodeTypesMap = new Map([
35
35
  [schema.nodes.graphical_abstract_section, ObjectTypes.Section],
36
36
  [schema.nodes.highlight_marker, ObjectTypes.HighlightMarker],
37
37
  [schema.nodes.inline_equation, ObjectTypes.InlineMathFragment],
38
+ [schema.nodes.keyword, ObjectTypes.Keyword],
38
39
  [schema.nodes.keywords_element, ObjectTypes.KeywordsElement],
39
40
  [schema.nodes.keywords_section, ObjectTypes.Section],
40
41
  [schema.nodes.listing, ObjectTypes.Listing],
@@ -48,6 +49,7 @@ export const nodeTypesMap = new Map([
48
49
  [schema.nodes.table_element, ObjectTypes.TableElement],
49
50
  [schema.nodes.toc_element, ObjectTypes.TOCElement],
50
51
  [schema.nodes.toc_section, ObjectTypes.Section],
52
+ [schema.nodes.comment_list, ObjectTypes.MetaSection],
51
53
  ]);
52
54
  export const isExecutableNodeType = (type) => hasGroup(type, GROUP_EXECUTABLE);
53
55
  export const isElementNodeType = (type) => hasGroup(type, GROUP_ELEMENT);
@@ -18,6 +18,7 @@ import { Marks, Nodes } from './types';
18
18
  export * from './groups';
19
19
  export * from './types';
20
20
  export * from './nodes/comment';
21
+ export * from './nodes/comment_list';
21
22
  export * from './nodes/attribution';
22
23
  export * from './nodes/bibliography_item';
23
24
  export * from './nodes/bibliography_element';
@@ -41,6 +42,7 @@ export * from './nodes/hard_break';
41
42
  export * from './nodes/highlight_marker';
42
43
  export * from './nodes/inline_equation';
43
44
  export * from './nodes/inline_footnote';
45
+ export * from './nodes/keyword';
44
46
  export * from './nodes/keywords_element';
45
47
  export * from './nodes/keywords_section';
46
48
  export * from './nodes/link';
@@ -0,0 +1,25 @@
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
+ }
21
+ export interface CommentListNode extends ManuscriptNode {
22
+ attrs: Attrs;
23
+ }
24
+ export declare const commentList: NodeSpec;
25
+ export {};
@@ -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
+ import { CommentNode } from './comment';
19
+ interface Attrs {
20
+ id: string;
21
+ contents: string;
22
+ comments?: CommentNode[];
23
+ }
24
+ export interface KeywordNode extends ManuscriptNode {
25
+ attrs: Attrs;
26
+ }
27
+ export declare const keyword: NodeSpec;
28
+ export {};
@@ -16,9 +16,9 @@
16
16
  import { NodeSpec } from 'prosemirror-model';
17
17
  import { ManuscriptNode } from '../types';
18
18
  interface Attrs {
19
- id: string;
20
19
  contents: string;
21
- paragraphStyle: string;
20
+ id: string;
21
+ paragraphStyle?: string;
22
22
  }
23
23
  export interface KeywordsElementNode extends ManuscriptNode {
24
24
  attrs: Attrs;