@manuscripts/transform 1.3.11 → 1.3.12-LEAN-2880-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.
@@ -410,7 +410,7 @@ const nodes = [
410
410
  {
411
411
  tag: 'fn-group',
412
412
  node: 'footnotes_element',
413
- context: 'footnotes_section/',
413
+ context: 'footnotes_section/|table_element_footer/',
414
414
  getAttrs: (node) => {
415
415
  const element = node;
416
416
  return {
@@ -421,19 +421,18 @@ const nodes = [
421
421
  },
422
422
  {
423
423
  tag: 'table-wrap-foot',
424
- node: 'footnotes_element',
424
+ node: 'table_element_footer',
425
425
  getAttrs: (node) => {
426
426
  const element = node;
427
427
  return {
428
428
  id: element.getAttribute('id'),
429
- kind: 'table_footnote',
430
429
  };
431
430
  },
432
431
  },
433
432
  {
434
433
  tag: 'fn',
435
434
  node: 'footnote',
436
- context: 'footnotes_element/',
435
+ context: 'footnotes_element/|table_element_footer/',
437
436
  getAttrs: (node) => {
438
437
  const element = node;
439
438
  return {
@@ -240,7 +240,7 @@ exports.jatsBodyTransformations = {
240
240
  backmatterContainer.append(section);
241
241
  }
242
242
  }
243
- const footnotes = [...doc.querySelectorAll('fn')];
243
+ const footnotes = [...doc.querySelectorAll('fn:not(table-wrap-foot fn)')];
244
244
  const footnotesSection = doc.querySelector('sec[sec-type="endnotes"]');
245
245
  const footnotesSectionGroup = footnotesSection === null || footnotesSection === void 0 ? void 0 : footnotesSection.querySelector('fn-group');
246
246
  const containingGroup = footnotesSectionGroup || createElement('fn-group');
@@ -598,6 +598,7 @@ class JATSExporter {
598
598
  this.createSerializer = () => {
599
599
  const getModel = (id) => id ? this.modelMap.get(id) : undefined;
600
600
  const nodes = {
601
+ table_element_footer: () => ['table-wrap-foot', 0],
601
602
  contributor_list: () => '',
602
603
  contributor: () => '',
603
604
  affiliation_list: () => '',
@@ -870,7 +871,7 @@ class JATSExporter {
870
871
  section_title_plain: () => ['title', 0],
871
872
  table: (node) => ['table', { id: normalizeID(node.attrs.id) }, 0],
872
873
  table_element: (node) => {
873
- const element = createFigureElement(node, 'table-wrap', node.type.schema.nodes.table);
874
+ const element = createTableElement(node);
874
875
  element.setAttribute('position', 'anchor');
875
876
  return element;
876
877
  },
@@ -909,12 +910,27 @@ class JATSExporter {
909
910
  tracked_delete: () => ['del'],
910
911
  };
911
912
  this.serializer = new prosemirror_model_1.DOMSerializer(nodes, marks);
912
- const createFigureElement = (node, nodeName, contentNodeType, figType) => {
913
+ const processChildNodes = (element, node, contentNodeType) => {
914
+ node.forEach((childNode) => {
915
+ if (childNode.type === contentNodeType) {
916
+ if (childNode.attrs.id) {
917
+ element.appendChild(this.serializeNode(childNode));
918
+ }
919
+ }
920
+ else if (childNode.type === node.type.schema.nodes.paragraph) {
921
+ element.appendChild(this.serializeNode(childNode));
922
+ }
923
+ else if (childNode.type === node.type.schema.nodes.missing_figure) {
924
+ element.appendChild(this.serializeNode(childNode));
925
+ }
926
+ });
927
+ };
928
+ const createElement = (node, nodeName) => {
913
929
  const element = this.document.createElement(nodeName);
914
930
  element.setAttribute('id', normalizeID(node.attrs.id));
915
- if (figType) {
916
- element.setAttribute('fig-type', figType);
917
- }
931
+ return element;
932
+ };
933
+ const appendLabels = (element, node) => {
918
934
  if (node.attrs.label) {
919
935
  const label = this.document.createElement('label');
920
936
  label.textContent = node.attrs.label;
@@ -928,32 +944,42 @@ class JATSExporter {
928
944
  element.appendChild(label);
929
945
  }
930
946
  }
931
- const figcaptionNode = findChildNodeOfType(node, node.type.schema.nodes.figcaption);
932
- if (figcaptionNode) {
933
- element.appendChild(this.serializeNode(figcaptionNode));
934
- }
935
- const footnotesNode = findChildNodeOfType(node, node.type.schema.nodes.footnotes_element);
936
- if (footnotesNode) {
937
- element.appendChild(this.serializeNode(footnotesNode));
938
- }
939
- node.forEach((childNode) => {
940
- if (childNode.type === contentNodeType) {
941
- if (childNode.attrs.id) {
942
- element.appendChild(this.serializeNode(childNode));
943
- }
944
- }
945
- else if (childNode.type === node.type.schema.nodes.paragraph) {
946
- element.appendChild(this.serializeNode(childNode));
947
- }
948
- else if (childNode.type === node.type.schema.nodes.missing_figure) {
949
- element.appendChild(this.serializeNode(childNode));
950
- }
951
- });
947
+ };
948
+ const appendAttributions = (element, node) => {
952
949
  if (node.attrs.attribution) {
953
950
  const attribution = this.document.createElement('attrib');
954
951
  attribution.textContent = node.attrs.attribution.literal;
955
952
  element.appendChild(attribution);
956
953
  }
954
+ };
955
+ const appendChildNodeOfType = (element, node, type) => {
956
+ const childNode = findChildNodeOfType(node, type);
957
+ if (childNode) {
958
+ element.appendChild(this.serializeNode(childNode));
959
+ }
960
+ };
961
+ const createFigureElement = (node, nodeName, contentNodeType, figType) => {
962
+ const element = createElement(node, nodeName);
963
+ if (figType) {
964
+ element.setAttribute('fig-type', figType);
965
+ }
966
+ appendLabels(element, node);
967
+ appendChildNodeOfType(element, node, node.type.schema.nodes.figcaption);
968
+ appendChildNodeOfType(element, node, node.type.schema.nodes.footnotes_element);
969
+ processChildNodes(element, node, contentNodeType);
970
+ appendAttributions(element, node);
971
+ if ((0, node_types_1.isExecutableNodeType)(node.type)) {
972
+ processExecutableNode(node, element);
973
+ }
974
+ return element;
975
+ };
976
+ const createTableElement = (node) => {
977
+ const nodeName = 'table-wrap';
978
+ const element = createElement(node, nodeName);
979
+ appendLabels(element, node);
980
+ appendChildNodeOfType(element, node, node.type.schema.nodes.figcaption);
981
+ appendChildNodeOfType(element, node, node.type.schema.nodes.table);
982
+ appendChildNodeOfType(element, node, node.type.schema.nodes.table_element_footer);
957
983
  if ((0, node_types_1.isExecutableNodeType)(node.type)) {
958
984
  processExecutableNode(node, element);
959
985
  }
@@ -82,6 +82,7 @@ const section_title_1 = require("./nodes/section_title");
82
82
  const table_1 = require("./nodes/table");
83
83
  const table_col_1 = require("./nodes/table_col");
84
84
  const table_element_1 = require("./nodes/table_element");
85
+ const table_element_footer_1 = require("./nodes/table_element_footer");
85
86
  const table_row_1 = require("./nodes/table_row");
86
87
  const text_1 = require("./nodes/text");
87
88
  const toc_element_1 = require("./nodes/toc_element");
@@ -140,6 +141,7 @@ __exportStar(require("./nodes/affiliation_list"), exports);
140
141
  __exportStar(require("./nodes/meta_section"), exports);
141
142
  __exportStar(require("./nodes/contributor_list"), exports);
142
143
  __exportStar(require("./nodes/contributor"), exports);
144
+ __exportStar(require("./nodes/table_element_footer"), exports);
143
145
  exports.schema = new prosemirror_model_1.Schema({
144
146
  marks: {
145
147
  bold: marks_1.bold,
@@ -215,5 +217,6 @@ exports.schema = new prosemirror_model_1.Schema({
215
217
  affiliation_list: affiliation_list_1.affiliationList,
216
218
  contributor_list: contributor_list_1.contributorList,
217
219
  contributor: contributor_1.contributor,
220
+ table_element_footer: table_element_footer_1.tableElementFooter,
218
221
  },
219
222
  });
@@ -7,9 +7,9 @@ exports.contributor = {
7
7
  role: { default: '' },
8
8
  affiliations: { default: [] },
9
9
  bibliographicName: { default: {} },
10
- userID: { default: '' },
11
- invitationID: { default: '' },
10
+ userID: { default: undefined },
11
+ invitationID: { default: undefined },
12
12
  isCorresponding: { default: undefined },
13
- ORCIDIdentifier: { default: '' },
13
+ ORCIDIdentifier: { default: undefined },
14
14
  },
15
15
  };
@@ -17,7 +17,7 @@
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.tableElement = void 0;
19
19
  exports.tableElement = {
20
- content: '(table | placeholder) figcaption? footnotes_element? (listing | placeholder)',
20
+ content: '(table | placeholder) figcaption? table_element_footer? (listing | placeholder)',
21
21
  attrs: {
22
22
  id: { default: '' },
23
23
  paragraphStyle: { default: '' },
@@ -0,0 +1,26 @@
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.tableElementFooter = void 0;
19
+ exports.tableElementFooter = {
20
+ attrs: {
21
+ id: { default: '' },
22
+ },
23
+ content: '(paragraph | footnotes_element)+',
24
+ group: 'block element',
25
+ toDOM: () => ['table-wrap-foot', 0],
26
+ };
@@ -123,21 +123,7 @@ class Decoder {
123
123
  }
124
124
  extractListing(model) {
125
125
  if (model.listingID) {
126
- const listingModel = this.getModel(model.listingID);
127
- let listing;
128
- if (listingModel) {
129
- listing = this.decode(listingModel);
130
- }
131
- else if (this.allowMissingElements) {
132
- listing = schema_1.schema.nodes.placeholder.create({
133
- id: model.listingID,
134
- label: 'A listing',
135
- });
136
- }
137
- else {
138
- throw new errors_1.MissingElement(model.listingID);
139
- }
140
- return listing;
126
+ return this.createListing(model);
141
127
  }
142
128
  }
143
129
  constructor(modelMap, allowMissingElements = false) {
@@ -282,11 +268,13 @@ class Decoder {
282
268
  }, [equation, figcaption]);
283
269
  },
284
270
  [json_schema_1.ObjectTypes.FootnotesElement]: (data) => {
285
- const model = data;
286
- const collateByKind = model.collateByKind || 'footnote';
271
+ const foonotesElementModel = data;
272
+ const collateByKind = foonotesElementModel.collateByKind || 'footnote';
287
273
  const footnotesOfKind = [];
288
274
  for (const model of this.modelMap.values()) {
289
- if (isFootnote(model) && model.kind === collateByKind) {
275
+ if (isFootnote(model) &&
276
+ model.kind === collateByKind &&
277
+ model.containingObject === foonotesElementModel._id) {
290
278
  const commentNodes = this.createCommentsNode(model);
291
279
  commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
292
280
  const footnote = this.parseContents(model.contents || '<div></div>', undefined, this.getComments(model), {
@@ -300,19 +288,21 @@ class Decoder {
300
288
  }
301
289
  }
302
290
  return schema_1.schema.nodes.footnotes_element.create({
303
- id: model._id,
304
- kind: model.collateByKind,
305
- paragraphStyle: model.paragraphStyle,
291
+ id: foonotesElementModel._id,
292
+ kind: foonotesElementModel.collateByKind,
293
+ paragraphStyle: foonotesElementModel.paragraphStyle,
306
294
  }, footnotesOfKind);
307
295
  },
308
296
  [json_schema_1.ObjectTypes.Footnote]: (data) => {
309
- const model = data;
310
- const commentNodes = this.createCommentsNode(model);
297
+ const footnoteModel = data;
298
+ const commentNodes = this.createCommentsNode(footnoteModel);
311
299
  commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
312
- return schema_1.schema.nodes.footnote.create({
313
- id: model._id,
314
- kind: model.kind,
315
- comments: commentNodes.map((c) => c.attrs.id),
300
+ return this.parseContents(footnoteModel.contents || '<div></div>', undefined, this.getComments(footnoteModel), {
301
+ topNode: schema_1.schema.nodes.footnote.create({
302
+ id: footnoteModel._id,
303
+ kind: footnoteModel.kind,
304
+ comments: commentNodes.map((c) => c.attrs.id),
305
+ }),
316
306
  });
317
307
  },
318
308
  [json_schema_1.ObjectTypes.KeywordsElement]: (data) => {
@@ -436,6 +426,13 @@ class Decoder {
436
426
  throw new Error('Unknown block type');
437
427
  }
438
428
  },
429
+ [json_schema_1.ObjectTypes.TableElementFooter]: (data) => {
430
+ const model = data;
431
+ const content = model.containedObjectIDs.map((id) => this.decode(this.modelMap.get(id)));
432
+ return schema_1.schema.nodes.table_element_footer.create({
433
+ id: model._id,
434
+ }, content);
435
+ },
439
436
  [json_schema_1.ObjectTypes.Section]: (data) => {
440
437
  const model = data;
441
438
  const isKeywordsSection = model.category === 'MPSectionCategory:keywords';
@@ -519,39 +516,16 @@ class Decoder {
519
516
  },
520
517
  [json_schema_1.ObjectTypes.TableElement]: (data) => {
521
518
  const model = data;
522
- const tableModel = this.getModel(model.containedObjectID);
523
- let table;
524
- if (tableModel) {
525
- table = this.decode(tableModel);
526
- }
527
- else if (this.allowMissingElements) {
528
- table = schema_1.schema.nodes.placeholder.create({
529
- id: model.containedObjectID,
530
- label: 'A table',
531
- });
532
- }
533
- else {
534
- throw new errors_1.MissingElement(model.containedObjectID);
535
- }
519
+ const table = this.createTable(model);
520
+ const tableElementFooter = this.createTableElementFooter(model);
536
521
  const figcaption = this.getFigcaption(model);
537
522
  const commentNodes = this.createCommentsNode(model);
538
523
  commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
539
- const content = [table, figcaption];
524
+ const content = tableElementFooter
525
+ ? [table, figcaption, tableElementFooter]
526
+ : [table, figcaption];
540
527
  if (model.listingID) {
541
- const listingModel = this.getModel(model.listingID);
542
- let listing;
543
- if (listingModel) {
544
- listing = this.decode(listingModel);
545
- }
546
- else if (this.allowMissingElements) {
547
- listing = schema_1.schema.nodes.placeholder.create({
548
- id: model.listingID,
549
- label: 'A listing',
550
- });
551
- }
552
- else {
553
- throw new errors_1.MissingElement(model.listingID);
554
- }
528
+ const listing = this.createListing(model);
555
529
  content.push(listing);
556
530
  }
557
531
  else {
@@ -727,6 +701,51 @@ class Decoder {
727
701
  this.modelMap = modelMap;
728
702
  this.allowMissingElements = allowMissingElements;
729
703
  }
704
+ createTable(model) {
705
+ const tableId = model.containedObjectID;
706
+ const tableModel = this.getModel(tableId);
707
+ let table;
708
+ if (tableModel) {
709
+ table = this.decode(tableModel);
710
+ }
711
+ else if (this.allowMissingElements) {
712
+ table = schema_1.schema.nodes.placeholder.create({
713
+ id: tableId,
714
+ label: 'A table',
715
+ });
716
+ }
717
+ else {
718
+ throw new errors_1.MissingElement(tableId);
719
+ }
720
+ return table;
721
+ }
722
+ createTableElementFooter(model) {
723
+ const tableElementFooterID = model.tableElementFooterID;
724
+ if (!tableElementFooterID) {
725
+ return undefined;
726
+ }
727
+ const tableElementFooterModel = this.getModel(tableElementFooterID);
728
+ return tableElementFooterModel
729
+ ? this.decode(tableElementFooterModel)
730
+ : undefined;
731
+ }
732
+ createListing(model) {
733
+ const listingModel = this.getModel(model.listingID);
734
+ let listing;
735
+ if (listingModel) {
736
+ listing = this.decode(listingModel);
737
+ }
738
+ else if (this.allowMissingElements) {
739
+ listing = schema_1.schema.nodes.placeholder.create({
740
+ id: model.listingID,
741
+ label: 'A listing',
742
+ });
743
+ }
744
+ else {
745
+ throw new errors_1.MissingElement(model.listingID);
746
+ }
747
+ return listing;
748
+ }
730
749
  getKeywordGroups() {
731
750
  const kwdGroupNodes = [];
732
751
  const kwdGroupsModels = [
@@ -219,7 +219,7 @@ const containedObjectIDs = (node, nodeTypes) => {
219
219
  const ids = [];
220
220
  for (let i = 0; i < node.childCount; i++) {
221
221
  const childNode = node.child(i);
222
- if (nodeTypes.includes(childNode.type)) {
222
+ if (!nodeTypes || nodeTypes.includes(childNode.type)) {
223
223
  ids.push(childNode.attrs.id);
224
224
  }
225
225
  }
@@ -385,6 +385,9 @@ const encoders = {
385
385
  elementType: 'div',
386
386
  paragraphStyle: node.attrs.paragraphStyle || undefined,
387
387
  }),
388
+ table_element_footer: (node) => ({
389
+ containedObjectIDs: containedObjectIDs(node),
390
+ }),
388
391
  footnotes_section: (node, parent, path, priority) => ({
389
392
  category: (0, section_category_1.buildSectionCategory)(node),
390
393
  priority: priority.value++,
@@ -472,6 +475,7 @@ const encoders = {
472
475
  }),
473
476
  table_element: (node) => ({
474
477
  containedObjectID: attributeOfNodeType(node, 'table', 'id'),
478
+ tableElementFooterID: attributeOfNodeType(node, 'table_element_footer', 'id'),
475
479
  caption: inlineContentOfChildNodeType(node, node.type.schema.nodes.figcaption, node.type.schema.nodes.caption),
476
480
  title: inlineContentOfChildNodeType(node, node.type.schema.nodes.figcaption, node.type.schema.nodes.caption_title, false),
477
481
  elementType: 'table',
@@ -21,6 +21,9 @@ const createOrderedFootnotesIDs = (doc) => {
21
21
  const footnotesRefs = [...doc.querySelectorAll('xref[ref-type="fn"][rid]')];
22
22
  const footnotes = [...doc.querySelectorAll('fn:not([fn-type])')];
23
23
  const authorNotesIDs = [...doc.querySelectorAll('author-notes > fn')].map((an) => an.getAttribute('id'));
24
+ const tableElementFooters = [
25
+ ...doc.querySelectorAll('table-wrap-foot > fn'),
26
+ ].map((footer) => footer.getAttribute('id'));
24
27
  const orderedFootnotesIDs = [];
25
28
  footnotesRefs.forEach((ref) => {
26
29
  const refID = ref.getAttribute('rid');
@@ -32,7 +35,8 @@ const createOrderedFootnotesIDs = (doc) => {
32
35
  const id = footnote.getAttribute('id');
33
36
  if (id &&
34
37
  !authorNotesIDs.includes(id) &&
35
- !orderedFootnotesIDs.includes(id)) {
38
+ !orderedFootnotesIDs.includes(id) &&
39
+ !tableElementFooters.includes(id)) {
36
40
  orderedFootnotesIDs.push(id);
37
41
  }
38
42
  });
@@ -56,6 +56,7 @@ exports.nodeTypesMap = new Map([
56
56
  [schema_1.schema.nodes.meta_section, json_schema_1.ObjectTypes.MetaSection],
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
+ [schema_1.schema.nodes.table_element_footer, json_schema_1.ObjectTypes.TableElementFooter],
59
60
  ]);
60
61
  const isExecutableNodeType = (type) => (0, schema_1.hasGroup)(type, schema_1.GROUP_EXECUTABLE);
61
62
  exports.isExecutableNodeType = isExecutableNodeType;
@@ -404,7 +404,7 @@ const nodes = [
404
404
  {
405
405
  tag: 'fn-group',
406
406
  node: 'footnotes_element',
407
- context: 'footnotes_section/',
407
+ context: 'footnotes_section/|table_element_footer/',
408
408
  getAttrs: (node) => {
409
409
  const element = node;
410
410
  return {
@@ -415,19 +415,18 @@ const nodes = [
415
415
  },
416
416
  {
417
417
  tag: 'table-wrap-foot',
418
- node: 'footnotes_element',
418
+ node: 'table_element_footer',
419
419
  getAttrs: (node) => {
420
420
  const element = node;
421
421
  return {
422
422
  id: element.getAttribute('id'),
423
- kind: 'table_footnote',
424
423
  };
425
424
  },
426
425
  },
427
426
  {
428
427
  tag: 'fn',
429
428
  node: 'footnote',
430
- context: 'footnotes_element/',
429
+ context: 'footnotes_element/|table_element_footer/',
431
430
  getAttrs: (node) => {
432
431
  const element = node;
433
432
  return {
@@ -237,7 +237,7 @@ export const jatsBodyTransformations = {
237
237
  backmatterContainer.append(section);
238
238
  }
239
239
  }
240
- const footnotes = [...doc.querySelectorAll('fn')];
240
+ const footnotes = [...doc.querySelectorAll('fn:not(table-wrap-foot fn)')];
241
241
  const footnotesSection = doc.querySelector('sec[sec-type="endnotes"]');
242
242
  const footnotesSectionGroup = footnotesSection === null || footnotesSection === void 0 ? void 0 : footnotesSection.querySelector('fn-group');
243
243
  const containingGroup = footnotesSectionGroup || createElement('fn-group');
@@ -591,6 +591,7 @@ export class JATSExporter {
591
591
  this.createSerializer = () => {
592
592
  const getModel = (id) => id ? this.modelMap.get(id) : undefined;
593
593
  const nodes = {
594
+ table_element_footer: () => ['table-wrap-foot', 0],
594
595
  contributor_list: () => '',
595
596
  contributor: () => '',
596
597
  affiliation_list: () => '',
@@ -863,7 +864,7 @@ export class JATSExporter {
863
864
  section_title_plain: () => ['title', 0],
864
865
  table: (node) => ['table', { id: normalizeID(node.attrs.id) }, 0],
865
866
  table_element: (node) => {
866
- const element = createFigureElement(node, 'table-wrap', node.type.schema.nodes.table);
867
+ const element = createTableElement(node);
867
868
  element.setAttribute('position', 'anchor');
868
869
  return element;
869
870
  },
@@ -902,12 +903,27 @@ export class JATSExporter {
902
903
  tracked_delete: () => ['del'],
903
904
  };
904
905
  this.serializer = new DOMSerializer(nodes, marks);
905
- const createFigureElement = (node, nodeName, contentNodeType, figType) => {
906
+ const processChildNodes = (element, node, contentNodeType) => {
907
+ node.forEach((childNode) => {
908
+ if (childNode.type === contentNodeType) {
909
+ if (childNode.attrs.id) {
910
+ element.appendChild(this.serializeNode(childNode));
911
+ }
912
+ }
913
+ else if (childNode.type === node.type.schema.nodes.paragraph) {
914
+ element.appendChild(this.serializeNode(childNode));
915
+ }
916
+ else if (childNode.type === node.type.schema.nodes.missing_figure) {
917
+ element.appendChild(this.serializeNode(childNode));
918
+ }
919
+ });
920
+ };
921
+ const createElement = (node, nodeName) => {
906
922
  const element = this.document.createElement(nodeName);
907
923
  element.setAttribute('id', normalizeID(node.attrs.id));
908
- if (figType) {
909
- element.setAttribute('fig-type', figType);
910
- }
924
+ return element;
925
+ };
926
+ const appendLabels = (element, node) => {
911
927
  if (node.attrs.label) {
912
928
  const label = this.document.createElement('label');
913
929
  label.textContent = node.attrs.label;
@@ -921,32 +937,42 @@ export class JATSExporter {
921
937
  element.appendChild(label);
922
938
  }
923
939
  }
924
- const figcaptionNode = findChildNodeOfType(node, node.type.schema.nodes.figcaption);
925
- if (figcaptionNode) {
926
- element.appendChild(this.serializeNode(figcaptionNode));
927
- }
928
- const footnotesNode = findChildNodeOfType(node, node.type.schema.nodes.footnotes_element);
929
- if (footnotesNode) {
930
- element.appendChild(this.serializeNode(footnotesNode));
931
- }
932
- node.forEach((childNode) => {
933
- if (childNode.type === contentNodeType) {
934
- if (childNode.attrs.id) {
935
- element.appendChild(this.serializeNode(childNode));
936
- }
937
- }
938
- else if (childNode.type === node.type.schema.nodes.paragraph) {
939
- element.appendChild(this.serializeNode(childNode));
940
- }
941
- else if (childNode.type === node.type.schema.nodes.missing_figure) {
942
- element.appendChild(this.serializeNode(childNode));
943
- }
944
- });
940
+ };
941
+ const appendAttributions = (element, node) => {
945
942
  if (node.attrs.attribution) {
946
943
  const attribution = this.document.createElement('attrib');
947
944
  attribution.textContent = node.attrs.attribution.literal;
948
945
  element.appendChild(attribution);
949
946
  }
947
+ };
948
+ const appendChildNodeOfType = (element, node, type) => {
949
+ const childNode = findChildNodeOfType(node, type);
950
+ if (childNode) {
951
+ element.appendChild(this.serializeNode(childNode));
952
+ }
953
+ };
954
+ const createFigureElement = (node, nodeName, contentNodeType, figType) => {
955
+ const element = createElement(node, nodeName);
956
+ if (figType) {
957
+ element.setAttribute('fig-type', figType);
958
+ }
959
+ appendLabels(element, node);
960
+ appendChildNodeOfType(element, node, node.type.schema.nodes.figcaption);
961
+ appendChildNodeOfType(element, node, node.type.schema.nodes.footnotes_element);
962
+ processChildNodes(element, node, contentNodeType);
963
+ appendAttributions(element, node);
964
+ if (isExecutableNodeType(node.type)) {
965
+ processExecutableNode(node, element);
966
+ }
967
+ return element;
968
+ };
969
+ const createTableElement = (node) => {
970
+ const nodeName = 'table-wrap';
971
+ const element = createElement(node, nodeName);
972
+ appendLabels(element, node);
973
+ appendChildNodeOfType(element, node, node.type.schema.nodes.figcaption);
974
+ appendChildNodeOfType(element, node, node.type.schema.nodes.table);
975
+ appendChildNodeOfType(element, node, node.type.schema.nodes.table_element_footer);
950
976
  if (isExecutableNodeType(node.type)) {
951
977
  processExecutableNode(node, element);
952
978
  }
@@ -65,6 +65,7 @@ import { sectionTitle } from './nodes/section_title';
65
65
  import { table, tableBody } from './nodes/table';
66
66
  import { tableCol, tableColGroup } from './nodes/table_col';
67
67
  import { tableElement } from './nodes/table_element';
68
+ import { tableElementFooter } from './nodes/table_element_footer';
68
69
  import { tableCell, tableRow } from './nodes/table_row';
69
70
  import { text } from './nodes/text';
70
71
  import { tocElement } from './nodes/toc_element';
@@ -123,6 +124,7 @@ export * from './nodes/affiliation_list';
123
124
  export * from './nodes/meta_section';
124
125
  export * from './nodes/contributor_list';
125
126
  export * from './nodes/contributor';
127
+ export * from './nodes/table_element_footer';
126
128
  export const schema = new Schema({
127
129
  marks: {
128
130
  bold,
@@ -198,5 +200,6 @@ export const schema = new Schema({
198
200
  affiliation_list: affiliationList,
199
201
  contributor_list: contributorList,
200
202
  contributor: contributor,
203
+ table_element_footer: tableElementFooter,
201
204
  },
202
205
  });
@@ -4,9 +4,9 @@ export const contributor = {
4
4
  role: { default: '' },
5
5
  affiliations: { default: [] },
6
6
  bibliographicName: { default: {} },
7
- userID: { default: '' },
8
- invitationID: { default: '' },
7
+ userID: { default: undefined },
8
+ invitationID: { default: undefined },
9
9
  isCorresponding: { default: undefined },
10
- ORCIDIdentifier: { default: '' },
10
+ ORCIDIdentifier: { default: undefined },
11
11
  },
12
12
  };
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  export const tableElement = {
17
- content: '(table | placeholder) figcaption? footnotes_element? (listing | placeholder)',
17
+ content: '(table | placeholder) figcaption? table_element_footer? (listing | placeholder)',
18
18
  attrs: {
19
19
  id: { default: '' },
20
20
  paragraphStyle: { default: '' },
@@ -0,0 +1,23 @@
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 tableElementFooter = {
17
+ attrs: {
18
+ id: { default: '' },
19
+ },
20
+ content: '(paragraph | footnotes_element)+',
21
+ group: 'block element',
22
+ toDOM: () => ['table-wrap-foot', 0],
23
+ };
@@ -113,21 +113,7 @@ export class Decoder {
113
113
  }
114
114
  extractListing(model) {
115
115
  if (model.listingID) {
116
- const listingModel = this.getModel(model.listingID);
117
- let listing;
118
- if (listingModel) {
119
- listing = this.decode(listingModel);
120
- }
121
- else if (this.allowMissingElements) {
122
- listing = schema.nodes.placeholder.create({
123
- id: model.listingID,
124
- label: 'A listing',
125
- });
126
- }
127
- else {
128
- throw new MissingElement(model.listingID);
129
- }
130
- return listing;
116
+ return this.createListing(model);
131
117
  }
132
118
  }
133
119
  constructor(modelMap, allowMissingElements = false) {
@@ -272,11 +258,13 @@ export class Decoder {
272
258
  }, [equation, figcaption]);
273
259
  },
274
260
  [ObjectTypes.FootnotesElement]: (data) => {
275
- const model = data;
276
- const collateByKind = model.collateByKind || 'footnote';
261
+ const foonotesElementModel = data;
262
+ const collateByKind = foonotesElementModel.collateByKind || 'footnote';
277
263
  const footnotesOfKind = [];
278
264
  for (const model of this.modelMap.values()) {
279
- if (isFootnote(model) && model.kind === collateByKind) {
265
+ if (isFootnote(model) &&
266
+ model.kind === collateByKind &&
267
+ model.containingObject === foonotesElementModel._id) {
280
268
  const commentNodes = this.createCommentsNode(model);
281
269
  commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
282
270
  const footnote = this.parseContents(model.contents || '<div></div>', undefined, this.getComments(model), {
@@ -290,19 +278,21 @@ export class Decoder {
290
278
  }
291
279
  }
292
280
  return schema.nodes.footnotes_element.create({
293
- id: model._id,
294
- kind: model.collateByKind,
295
- paragraphStyle: model.paragraphStyle,
281
+ id: foonotesElementModel._id,
282
+ kind: foonotesElementModel.collateByKind,
283
+ paragraphStyle: foonotesElementModel.paragraphStyle,
296
284
  }, footnotesOfKind);
297
285
  },
298
286
  [ObjectTypes.Footnote]: (data) => {
299
- const model = data;
300
- const commentNodes = this.createCommentsNode(model);
287
+ const footnoteModel = data;
288
+ const commentNodes = this.createCommentsNode(footnoteModel);
301
289
  commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
302
- return schema.nodes.footnote.create({
303
- id: model._id,
304
- kind: model.kind,
305
- comments: commentNodes.map((c) => c.attrs.id),
290
+ return this.parseContents(footnoteModel.contents || '<div></div>', undefined, this.getComments(footnoteModel), {
291
+ topNode: schema.nodes.footnote.create({
292
+ id: footnoteModel._id,
293
+ kind: footnoteModel.kind,
294
+ comments: commentNodes.map((c) => c.attrs.id),
295
+ }),
306
296
  });
307
297
  },
308
298
  [ObjectTypes.KeywordsElement]: (data) => {
@@ -426,6 +416,13 @@ export class Decoder {
426
416
  throw new Error('Unknown block type');
427
417
  }
428
418
  },
419
+ [ObjectTypes.TableElementFooter]: (data) => {
420
+ const model = data;
421
+ const content = model.containedObjectIDs.map((id) => this.decode(this.modelMap.get(id)));
422
+ return schema.nodes.table_element_footer.create({
423
+ id: model._id,
424
+ }, content);
425
+ },
429
426
  [ObjectTypes.Section]: (data) => {
430
427
  const model = data;
431
428
  const isKeywordsSection = model.category === 'MPSectionCategory:keywords';
@@ -509,39 +506,16 @@ export class Decoder {
509
506
  },
510
507
  [ObjectTypes.TableElement]: (data) => {
511
508
  const model = data;
512
- const tableModel = this.getModel(model.containedObjectID);
513
- let table;
514
- if (tableModel) {
515
- table = this.decode(tableModel);
516
- }
517
- else if (this.allowMissingElements) {
518
- table = schema.nodes.placeholder.create({
519
- id: model.containedObjectID,
520
- label: 'A table',
521
- });
522
- }
523
- else {
524
- throw new MissingElement(model.containedObjectID);
525
- }
509
+ const table = this.createTable(model);
510
+ const tableElementFooter = this.createTableElementFooter(model);
526
511
  const figcaption = this.getFigcaption(model);
527
512
  const commentNodes = this.createCommentsNode(model);
528
513
  commentNodes.forEach((c) => this.comments.set(c.attrs.id, c));
529
- const content = [table, figcaption];
514
+ const content = tableElementFooter
515
+ ? [table, figcaption, tableElementFooter]
516
+ : [table, figcaption];
530
517
  if (model.listingID) {
531
- const listingModel = this.getModel(model.listingID);
532
- let listing;
533
- if (listingModel) {
534
- listing = this.decode(listingModel);
535
- }
536
- else if (this.allowMissingElements) {
537
- listing = schema.nodes.placeholder.create({
538
- id: model.listingID,
539
- label: 'A listing',
540
- });
541
- }
542
- else {
543
- throw new MissingElement(model.listingID);
544
- }
518
+ const listing = this.createListing(model);
545
519
  content.push(listing);
546
520
  }
547
521
  else {
@@ -717,6 +691,51 @@ export class Decoder {
717
691
  this.modelMap = modelMap;
718
692
  this.allowMissingElements = allowMissingElements;
719
693
  }
694
+ createTable(model) {
695
+ const tableId = model.containedObjectID;
696
+ const tableModel = this.getModel(tableId);
697
+ let table;
698
+ if (tableModel) {
699
+ table = this.decode(tableModel);
700
+ }
701
+ else if (this.allowMissingElements) {
702
+ table = schema.nodes.placeholder.create({
703
+ id: tableId,
704
+ label: 'A table',
705
+ });
706
+ }
707
+ else {
708
+ throw new MissingElement(tableId);
709
+ }
710
+ return table;
711
+ }
712
+ createTableElementFooter(model) {
713
+ const tableElementFooterID = model.tableElementFooterID;
714
+ if (!tableElementFooterID) {
715
+ return undefined;
716
+ }
717
+ const tableElementFooterModel = this.getModel(tableElementFooterID);
718
+ return tableElementFooterModel
719
+ ? this.decode(tableElementFooterModel)
720
+ : undefined;
721
+ }
722
+ createListing(model) {
723
+ const listingModel = this.getModel(model.listingID);
724
+ let listing;
725
+ if (listingModel) {
726
+ listing = this.decode(listingModel);
727
+ }
728
+ else if (this.allowMissingElements) {
729
+ listing = schema.nodes.placeholder.create({
730
+ id: model.listingID,
731
+ label: 'A listing',
732
+ });
733
+ }
734
+ else {
735
+ throw new MissingElement(model.listingID);
736
+ }
737
+ return listing;
738
+ }
720
739
  getKeywordGroups() {
721
740
  const kwdGroupNodes = [];
722
741
  const kwdGroupsModels = [
@@ -211,7 +211,7 @@ const containedObjectIDs = (node, nodeTypes) => {
211
211
  const ids = [];
212
212
  for (let i = 0; i < node.childCount; i++) {
213
213
  const childNode = node.child(i);
214
- if (nodeTypes.includes(childNode.type)) {
214
+ if (!nodeTypes || nodeTypes.includes(childNode.type)) {
215
215
  ids.push(childNode.attrs.id);
216
216
  }
217
217
  }
@@ -377,6 +377,9 @@ const encoders = {
377
377
  elementType: 'div',
378
378
  paragraphStyle: node.attrs.paragraphStyle || undefined,
379
379
  }),
380
+ table_element_footer: (node) => ({
381
+ containedObjectIDs: containedObjectIDs(node),
382
+ }),
380
383
  footnotes_section: (node, parent, path, priority) => ({
381
384
  category: buildSectionCategory(node),
382
385
  priority: priority.value++,
@@ -464,6 +467,7 @@ const encoders = {
464
467
  }),
465
468
  table_element: (node) => ({
466
469
  containedObjectID: attributeOfNodeType(node, 'table', 'id'),
470
+ tableElementFooterID: attributeOfNodeType(node, 'table_element_footer', 'id'),
467
471
  caption: inlineContentOfChildNodeType(node, node.type.schema.nodes.figcaption, node.type.schema.nodes.caption),
468
472
  title: inlineContentOfChildNodeType(node, node.type.schema.nodes.figcaption, node.type.schema.nodes.caption_title, false),
469
473
  elementType: 'table',
@@ -18,6 +18,9 @@ export const createOrderedFootnotesIDs = (doc) => {
18
18
  const footnotesRefs = [...doc.querySelectorAll('xref[ref-type="fn"][rid]')];
19
19
  const footnotes = [...doc.querySelectorAll('fn:not([fn-type])')];
20
20
  const authorNotesIDs = [...doc.querySelectorAll('author-notes > fn')].map((an) => an.getAttribute('id'));
21
+ const tableElementFooters = [
22
+ ...doc.querySelectorAll('table-wrap-foot > fn'),
23
+ ].map((footer) => footer.getAttribute('id'));
21
24
  const orderedFootnotesIDs = [];
22
25
  footnotesRefs.forEach((ref) => {
23
26
  const refID = ref.getAttribute('rid');
@@ -29,7 +32,8 @@ export const createOrderedFootnotesIDs = (doc) => {
29
32
  const id = footnote.getAttribute('id');
30
33
  if (id &&
31
34
  !authorNotesIDs.includes(id) &&
32
- !orderedFootnotesIDs.includes(id)) {
35
+ !orderedFootnotesIDs.includes(id) &&
36
+ !tableElementFooters.includes(id)) {
33
37
  orderedFootnotesIDs.push(id);
34
38
  }
35
39
  });
@@ -53,6 +53,7 @@ export const nodeTypesMap = new Map([
53
53
  [schema.nodes.meta_section, ObjectTypes.MetaSection],
54
54
  [schema.nodes.affiliation, ObjectTypes.Affiliation],
55
55
  [schema.nodes.contributor, ObjectTypes.Contributor],
56
+ [schema.nodes.table_element_footer, ObjectTypes.TableElementFooter],
56
57
  ]);
57
58
  export const isExecutableNodeType = (type) => hasGroup(type, GROUP_EXECUTABLE);
58
59
  export const isElementNodeType = (type) => hasGroup(type, GROUP_ELEMENT);
@@ -69,4 +69,5 @@ export * from './nodes/affiliation_list';
69
69
  export * from './nodes/meta_section';
70
70
  export * from './nodes/contributor_list';
71
71
  export * from './nodes/contributor';
72
+ export * from './nodes/table_element_footer';
72
73
  export declare const schema: Schema<Nodes, Marks>;
@@ -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 TableElementFooterNode extends ManuscriptNode {
22
+ attrs: Attrs;
23
+ }
24
+ export declare const tableElementFooter: NodeSpec;
25
+ 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';
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';
21
21
  export type ManuscriptSchema = Schema<Nodes, Marks>;
22
22
  export type ManuscriptEditorState = EditorState;
23
23
  export type ManuscriptEditorView = EditorView;
@@ -42,5 +42,8 @@ export declare class Decoder {
42
42
  private getKeywords;
43
43
  private getManuscriptID;
44
44
  private getFigcaption;
45
+ private createTable;
46
+ private createTableElementFooter;
47
+ private createListing;
45
48
  private getKeywordGroups;
46
49
  }
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.3.11",
4
+ "version": "1.3.12-LEAN-2880-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.1.1",
32
+ "@manuscripts/json-schema": "^2.1.2",
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
+ }