@manuscripts/transform 4.5.8 → 4.6.0
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.
- package/dist/cjs/jats/__tests__/jats-exporter.test.js +23 -0
- package/dist/cjs/jats/__tests__/jats-importer.test.js +26 -0
- package/dist/cjs/jats/exporter/JATSExporterBase.js +118 -0
- package/dist/cjs/jats/exporter/jats-exporter.js +224 -342
- package/dist/cjs/jats/exporter/lib.js +62 -0
- package/dist/cjs/jats/importer/jats-dom-parser.js +11 -3
- package/dist/cjs/schema/index.js +4 -1
- package/dist/cjs/schema/migration/migration-scripts/4.5.9.js +30 -0
- package/dist/cjs/schema/migration/migration-scripts/index.js +3 -1
- package/dist/cjs/schema/nodes/bibliography_element.js +0 -1
- package/dist/cjs/schema/nodes/bio.js +24 -0
- package/dist/cjs/schema/nodes/contributor.js +1 -2
- package/dist/cjs/schema/nodes/keywords_element.js +0 -1
- package/dist/cjs/types.js +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/es/jats/__tests__/jats-exporter.test.js +23 -0
- package/dist/es/jats/__tests__/jats-importer.test.js +26 -0
- package/dist/es/jats/exporter/JATSExporterBase.js +114 -0
- package/dist/es/jats/exporter/jats-exporter.js +198 -315
- package/dist/es/jats/exporter/lib.js +55 -0
- package/dist/es/jats/importer/jats-dom-parser.js +11 -3
- package/dist/es/schema/index.js +4 -1
- package/dist/es/schema/migration/migration-scripts/4.5.9.js +28 -0
- package/dist/es/schema/migration/migration-scripts/index.js +3 -1
- package/dist/es/schema/nodes/bibliography_element.js +0 -1
- package/dist/es/schema/nodes/bio.js +20 -0
- package/dist/es/schema/nodes/contributor.js +1 -2
- package/dist/es/schema/nodes/keywords_element.js +0 -1
- package/dist/es/types.js +1 -1
- package/dist/es/version.js +1 -1
- package/dist/types/jats/exporter/JATSExporterBase.d.ts +35 -0
- package/dist/types/jats/exporter/jats-exporter.d.ts +22 -18
- package/dist/types/jats/exporter/lib.d.ts +23 -0
- package/dist/types/schema/index.d.ts +2 -1
- package/dist/types/schema/migration/migration-scripts/4.5.9.d.ts +8 -0
- package/dist/types/schema/migration/migration-scripts/index.d.ts +3 -2
- package/dist/types/schema/nodes/bio.d.ts +10 -0
- package/dist/types/schema/types.d.ts +1 -1
- package/dist/types/types.d.ts +1 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +1 -1
- package/src/jats/__tests__/__fixtures__/jats-import.xml +7 -0
- package/src/jats/__tests__/__snapshots__/jats-importer.test.ts.snap +272 -151
- package/src/jats/__tests__/__snapshots__/jats-roundtrip.test.ts.snap +2 -2
- package/src/jats/__tests__/jats-exporter.test.ts +34 -0
- package/src/jats/__tests__/jats-importer.test.ts +37 -0
- package/src/jats/exporter/JATSExporterBase.ts +164 -0
- package/src/jats/exporter/jats-exporter.ts +212 -380
- package/src/jats/exporter/lib.ts +69 -0
- package/src/jats/importer/jats-dom-parser.ts +15 -5
- package/src/schema/index.ts +4 -1
- package/src/schema/migration/migration-scripts/4.5.9.ts +62 -0
- package/src/schema/migration/migration-scripts/index.ts +3 -1
- package/src/schema/nodes/bibliography_element.ts +0 -1
- package/src/schema/nodes/bio.ts +48 -0
- package/src/schema/nodes/contributor.ts +1 -2
- package/src/schema/nodes/keywords_element.ts +0 -1
- package/src/schema/types.ts +1 -0
- package/src/types.ts +1 -1
- package/src/version.ts +1 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2026 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.chooseRefType = exports.createDefaultIDGenerator = exports.createCounter = exports.normalizeID = void 0;
|
|
19
|
+
const schema_1 = require("../../schema");
|
|
20
|
+
const normalizeID = (id) => id.replace(/:/g, '_');
|
|
21
|
+
exports.normalizeID = normalizeID;
|
|
22
|
+
const createCounter = () => {
|
|
23
|
+
const counts = new Map();
|
|
24
|
+
return {
|
|
25
|
+
increment: (field) => {
|
|
26
|
+
const value = counts.get(field);
|
|
27
|
+
const newValue = value === undefined ? 1 : value + 1;
|
|
28
|
+
counts.set(field, newValue);
|
|
29
|
+
return newValue;
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
exports.createCounter = createCounter;
|
|
34
|
+
const createDefaultIDGenerator = () => {
|
|
35
|
+
const counter = (0, exports.createCounter)();
|
|
36
|
+
return async (element) => {
|
|
37
|
+
const value = String(counter.increment(element.nodeName));
|
|
38
|
+
return `${element.localName}-${value}`;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
exports.createDefaultIDGenerator = createDefaultIDGenerator;
|
|
42
|
+
const chooseRefType = (type) => {
|
|
43
|
+
switch (type) {
|
|
44
|
+
case schema_1.schema.nodes.figure:
|
|
45
|
+
case schema_1.schema.nodes.figure_element:
|
|
46
|
+
return 'fig';
|
|
47
|
+
case schema_1.schema.nodes.footnote:
|
|
48
|
+
return 'fn';
|
|
49
|
+
case schema_1.schema.nodes.table:
|
|
50
|
+
case schema_1.schema.nodes.table_element:
|
|
51
|
+
return 'table';
|
|
52
|
+
case schema_1.schema.nodes.section:
|
|
53
|
+
case schema_1.schema.nodes.abstract:
|
|
54
|
+
return 'sec';
|
|
55
|
+
case schema_1.schema.nodes.equation:
|
|
56
|
+
case schema_1.schema.nodes.equation_element:
|
|
57
|
+
return 'disp-formula';
|
|
58
|
+
case schema_1.schema.nodes.supplement:
|
|
59
|
+
return 'supplementary-material';
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
exports.chooseRefType = chooseRefType;
|
|
@@ -378,7 +378,7 @@ class JATSDOMParser {
|
|
|
378
378
|
const footnoteIDs = [];
|
|
379
379
|
const affiliationIDs = [];
|
|
380
380
|
const correspIDs = [];
|
|
381
|
-
const xrefs = element.querySelectorAll('xref');
|
|
381
|
+
const xrefs = element.querySelectorAll(':scope > xref');
|
|
382
382
|
for (const xref of xrefs) {
|
|
383
383
|
const rid = xref.getAttribute('rid');
|
|
384
384
|
const type = xref.getAttribute('ref-type');
|
|
@@ -416,10 +416,18 @@ class JATSDOMParser {
|
|
|
416
416
|
email: (0, utils_1.getTrimmedTextContent)(element, 'email') || '',
|
|
417
417
|
};
|
|
418
418
|
},
|
|
419
|
-
getContent: () => {
|
|
420
|
-
|
|
419
|
+
getContent: (node) => {
|
|
420
|
+
const bio = node.querySelector('bio');
|
|
421
|
+
if (!bio) {
|
|
422
|
+
return prosemirror_model_1.Fragment.empty;
|
|
423
|
+
}
|
|
424
|
+
return prosemirror_model_1.Fragment.from(this.parse(bio, { topNode: this.schema.nodes.bio.create() }));
|
|
421
425
|
},
|
|
422
426
|
},
|
|
427
|
+
{
|
|
428
|
+
tag: 'bio',
|
|
429
|
+
node: 'bio',
|
|
430
|
+
},
|
|
423
431
|
{
|
|
424
432
|
tag: 'affiliations',
|
|
425
433
|
node: 'affiliations',
|
package/dist/cjs/schema/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*!
|
|
3
|
-
* ©
|
|
3
|
+
* © 2026 Atypon Systems LLC
|
|
4
4
|
*
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
* you may not use this file except in compliance with the License.
|
|
@@ -50,6 +50,7 @@ const backmatter_1 = require("./nodes/backmatter");
|
|
|
50
50
|
const bibliography_element_1 = require("./nodes/bibliography_element");
|
|
51
51
|
const bibliography_item_1 = require("./nodes/bibliography_item");
|
|
52
52
|
const bibliography_section_1 = require("./nodes/bibliography_section");
|
|
53
|
+
const bio_1 = require("./nodes/bio");
|
|
53
54
|
const blockquote_element_1 = require("./nodes/blockquote_element");
|
|
54
55
|
const body_1 = require("./nodes/body");
|
|
55
56
|
const box_element_1 = require("./nodes/box_element");
|
|
@@ -129,6 +130,7 @@ __exportStar(require("./nodes/awards"), exports);
|
|
|
129
130
|
__exportStar(require("./nodes/bibliography_element"), exports);
|
|
130
131
|
__exportStar(require("./nodes/bibliography_item"), exports);
|
|
131
132
|
__exportStar(require("./nodes/bibliography_section"), exports);
|
|
133
|
+
__exportStar(require("./nodes/bio"), exports);
|
|
132
134
|
__exportStar(require("./nodes/blockquote_element"), exports);
|
|
133
135
|
__exportStar(require("./nodes/box_element"), exports);
|
|
134
136
|
__exportStar(require("./nodes/caption"), exports);
|
|
@@ -214,6 +216,7 @@ exports.schema = new prosemirror_model_1.Schema({
|
|
|
214
216
|
bibliography_element: bibliography_element_1.bibliographyElement,
|
|
215
217
|
bibliography_section: bibliography_section_1.bibliographySection,
|
|
216
218
|
blockquote_element: blockquote_element_1.blockquoteElement,
|
|
219
|
+
bio: bio_1.bio,
|
|
217
220
|
list: list_1.list,
|
|
218
221
|
caption: caption_1.caption,
|
|
219
222
|
caption_title: caption_title_1.captionTitle,
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const LEGACY_CONTENTS_NODES = new Set([
|
|
4
|
+
'contributor',
|
|
5
|
+
'bibliography_element',
|
|
6
|
+
'keywords_element',
|
|
7
|
+
]);
|
|
8
|
+
class Migration459 {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.fromVersion = '4.5.8';
|
|
11
|
+
this.toVersion = '4.5.9';
|
|
12
|
+
}
|
|
13
|
+
migrateNode(node) {
|
|
14
|
+
if (LEGACY_CONTENTS_NODES.has(node.type) &&
|
|
15
|
+
node.attrs &&
|
|
16
|
+
'contents' in node.attrs) {
|
|
17
|
+
const attrs = { ...node.attrs };
|
|
18
|
+
delete attrs.contents;
|
|
19
|
+
node = { ...node, attrs };
|
|
20
|
+
}
|
|
21
|
+
if (node.type === 'contributor') {
|
|
22
|
+
const bio = node.content?.filter((child) => child.type === 'bio');
|
|
23
|
+
const migrated = { ...node };
|
|
24
|
+
delete migrated.content;
|
|
25
|
+
return bio?.length ? { ...migrated, content: bio } : migrated;
|
|
26
|
+
}
|
|
27
|
+
return node;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.default = Migration459;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/*!
|
|
3
|
-
* ©
|
|
3
|
+
* © 2026 Atypon Systems LLC
|
|
4
4
|
*
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
6
|
* you may not use this file except in compliance with the License.
|
|
@@ -35,6 +35,7 @@ const _4_3_35_1 = __importDefault(require("./4.3.35"));
|
|
|
35
35
|
const _4_4_2_1 = __importDefault(require("./4.4.2"));
|
|
36
36
|
const _4_4_7_1 = __importDefault(require("./4.4.7"));
|
|
37
37
|
const _4_5_3_1 = __importDefault(require("./4.5.3"));
|
|
38
|
+
const _4_5_9_1 = __importDefault(require("./4.5.9"));
|
|
38
39
|
const migrations = [
|
|
39
40
|
new _1_2_5_1.default(),
|
|
40
41
|
new _2_3_22_1.default(),
|
|
@@ -53,5 +54,6 @@ const migrations = [
|
|
|
53
54
|
new _4_4_2_1.default(),
|
|
54
55
|
new _4_4_7_1.default(),
|
|
55
56
|
new _4_5_3_1.default(),
|
|
57
|
+
new _4_5_9_1.default(),
|
|
56
58
|
];
|
|
57
59
|
exports.default = migrations;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isBioNode = exports.bio = void 0;
|
|
4
|
+
exports.bio = {
|
|
5
|
+
content: 'image_element? paragraph',
|
|
6
|
+
attrs: {
|
|
7
|
+
id: { default: '' },
|
|
8
|
+
dataTracked: { default: null },
|
|
9
|
+
},
|
|
10
|
+
group: 'block',
|
|
11
|
+
toDOM: (node) => {
|
|
12
|
+
const bioNode = node;
|
|
13
|
+
return [
|
|
14
|
+
'div',
|
|
15
|
+
{
|
|
16
|
+
class: 'bio',
|
|
17
|
+
id: bioNode.attrs.id,
|
|
18
|
+
},
|
|
19
|
+
0,
|
|
20
|
+
];
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
const isBioNode = (node) => node.type === node.type.schema.nodes.bio;
|
|
24
|
+
exports.isBioNode = isBioNode;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isContributorNode = exports.contributor = void 0;
|
|
4
4
|
exports.contributor = {
|
|
5
|
-
content: '
|
|
5
|
+
content: 'bio?',
|
|
6
6
|
atom: true,
|
|
7
7
|
attrs: {
|
|
8
8
|
id: { default: '' },
|
|
@@ -23,7 +23,6 @@ exports.contributor = {
|
|
|
23
23
|
priority: { default: undefined },
|
|
24
24
|
creditRoles: { default: [] },
|
|
25
25
|
dataTracked: { default: null },
|
|
26
|
-
contents: { default: '' },
|
|
27
26
|
},
|
|
28
27
|
group: 'block',
|
|
29
28
|
toDOM: (node) => {
|
package/dist/cjs/types.js
CHANGED
package/dist/cjs/version.js
CHANGED
|
@@ -198,4 +198,27 @@ describe('JATS exporter', () => {
|
|
|
198
198
|
expect(fn).not.toBeUndefined();
|
|
199
199
|
}
|
|
200
200
|
});
|
|
201
|
+
test('export contributor bio', async () => {
|
|
202
|
+
const transformer = new JATSExporter();
|
|
203
|
+
const input = await readAndParseFixture('jats-import.xml');
|
|
204
|
+
const node = parseJATSArticle(input, sectionCategories);
|
|
205
|
+
const xml = await transformer.export(node, {
|
|
206
|
+
csl: DEFAULT_CSL_OPTIONS,
|
|
207
|
+
});
|
|
208
|
+
const serialized = serializeToXML(xml);
|
|
209
|
+
const resultDoc = parseXMLWithDTD(serialized);
|
|
210
|
+
expect(resultDoc.errors).toHaveLength(0);
|
|
211
|
+
const contribs = resultDoc.find('//contrib-group/contrib');
|
|
212
|
+
expect(contribs).toHaveLength(2);
|
|
213
|
+
expect(contribs[0].find('bio')).toHaveLength(1);
|
|
214
|
+
expect(contribs[1].find('bio')).toHaveLength(0);
|
|
215
|
+
const graphic = resultDoc.get('//contrib/bio/graphic');
|
|
216
|
+
expect(graphic).not.toBeNull();
|
|
217
|
+
expect(graphic.attr('href')?.value()).toBe('agnete-hornnes.png');
|
|
218
|
+
expect(graphic.find('caption')).toHaveLength(0);
|
|
219
|
+
expect(resultDoc.get('//contrib/bio/graphic/alt-text').text()).toBe('Headshot of Agnete Hviid Hornnes');
|
|
220
|
+
const paragraph = resultDoc.get('//contrib/bio/p');
|
|
221
|
+
expect(paragraph.text()).toBe('Agnete is a Professor of Neurology at Herlev og Gentofte Hospital, specializing in stroke research.');
|
|
222
|
+
expect(resultDoc.get('//contrib/bio/p/italic')?.text()).toBe('Professor of Neurology');
|
|
223
|
+
});
|
|
201
224
|
});
|
|
@@ -58,6 +58,32 @@ describe('JATS importer', () => {
|
|
|
58
58
|
expect(contributorsNode).toHaveLength(0);
|
|
59
59
|
});
|
|
60
60
|
});
|
|
61
|
+
describe('bio', () => {
|
|
62
|
+
it('should parse bio with graphic and paragraph into the contributor node', async () => {
|
|
63
|
+
const jats = await readAndParseFixture('jats-import.xml');
|
|
64
|
+
const node = parseJATSArticle(jats, sectionCategories);
|
|
65
|
+
changeIDs(node);
|
|
66
|
+
const [contributor] = findNodesByType(node, schema.nodes.contributor);
|
|
67
|
+
expect(contributor.childCount).toBe(1);
|
|
68
|
+
const bio = contributor.firstChild;
|
|
69
|
+
expect(bio.type).toBe(schema.nodes.bio);
|
|
70
|
+
expect(bio.childCount).toBe(2);
|
|
71
|
+
const image = findNodeByType(bio, schema.nodes.image_element);
|
|
72
|
+
expect(findNodeByType(image, schema.nodes.figure).attrs.src).toBe('agnete-hornnes.png');
|
|
73
|
+
expect(findNodeByType(image, schema.nodes.alt_text).textContent).toBe('Headshot of Agnete Hviid Hornnes');
|
|
74
|
+
const paragraph = bio.lastChild;
|
|
75
|
+
expect(paragraph.type).toBe(schema.nodes.paragraph);
|
|
76
|
+
expect(paragraph.textContent).toBe('Agnete is a Professor of Neurology at Herlev og Gentofte Hospital, specializing in stroke research.');
|
|
77
|
+
expect(bio).toMatchSnapshot();
|
|
78
|
+
});
|
|
79
|
+
it('should not add bio content to contributors without a bio element', async () => {
|
|
80
|
+
const jats = await readAndParseFixture('jats-import.xml');
|
|
81
|
+
const node = parseJATSArticle(jats, sectionCategories);
|
|
82
|
+
const [, contributor] = findNodesByType(node, schema.nodes.contributor);
|
|
83
|
+
expect(contributor.childCount).toBe(0);
|
|
84
|
+
expect(findNodesByType(node, schema.nodes.bio)).toHaveLength(1);
|
|
85
|
+
});
|
|
86
|
+
});
|
|
61
87
|
describe('affiliations', () => {
|
|
62
88
|
it('should correctly parse affiliation nodes', async () => {
|
|
63
89
|
const jats = await readAndParseFixture('jats-import.xml');
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2026 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 { findChildrenByAttr, findChildrenByType } from 'prosemirror-utils';
|
|
17
|
+
import { isNodeOfType } from '../../schema';
|
|
18
|
+
import { normalizeID } from './lib';
|
|
19
|
+
export class JATSExporterBase {
|
|
20
|
+
constructor() {
|
|
21
|
+
this.nodesMap = new Map();
|
|
22
|
+
this.populateNodesMap = () => {
|
|
23
|
+
this.manuscriptNode.descendants((node) => {
|
|
24
|
+
const type = node.type;
|
|
25
|
+
const nodes = this.nodesMap.get(type) ?? [];
|
|
26
|
+
nodes.push(node);
|
|
27
|
+
this.nodesMap.set(type, nodes);
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
this.createElement = (tag, content, attrs) => {
|
|
31
|
+
const $element = this.document.createElement(tag);
|
|
32
|
+
if (content) {
|
|
33
|
+
$element.textContent = content;
|
|
34
|
+
}
|
|
35
|
+
if (attrs) {
|
|
36
|
+
Object.entries(attrs).forEach(([k, v]) => {
|
|
37
|
+
if (v) {
|
|
38
|
+
$element.setAttribute(k, v);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
return $element;
|
|
43
|
+
};
|
|
44
|
+
this.appendElement = ($parent, tag, content, attrs) => {
|
|
45
|
+
const $element = this.createElement(tag, content, attrs);
|
|
46
|
+
$parent.appendChild($element);
|
|
47
|
+
return $element;
|
|
48
|
+
};
|
|
49
|
+
this.changeTag = ($node, tag) => {
|
|
50
|
+
const $clone = this.createElement(tag);
|
|
51
|
+
for (const attr of $node.attributes) {
|
|
52
|
+
$clone.setAttributeNS(null, attr.name, attr.value);
|
|
53
|
+
}
|
|
54
|
+
while ($node.firstChild) {
|
|
55
|
+
$clone.appendChild($node.firstChild);
|
|
56
|
+
}
|
|
57
|
+
$node.replaceWith($clone);
|
|
58
|
+
return $clone;
|
|
59
|
+
};
|
|
60
|
+
this.processChildNodes = ($element, node, contentNodeType) => {
|
|
61
|
+
node.forEach((childNode) => {
|
|
62
|
+
if (childNode.type === contentNodeType) {
|
|
63
|
+
if (childNode.attrs.id) {
|
|
64
|
+
$element.appendChild(this.serializeNode(childNode));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else if (childNode.type === node.type.schema.nodes.paragraph) {
|
|
68
|
+
$element.appendChild(this.serializeNode(childNode));
|
|
69
|
+
}
|
|
70
|
+
else if (childNode.type === node.type.schema.nodes.missing_figure) {
|
|
71
|
+
$element.appendChild(this.serializeNode(childNode));
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
isChildOfNodeType(targetID, type, descend = false) {
|
|
77
|
+
const nodes = this.getChildrenOfType(type);
|
|
78
|
+
return nodes.some((node) => {
|
|
79
|
+
const result = findChildrenByAttr(node, (attrs) => attrs.id === targetID, descend)[0];
|
|
80
|
+
return !!result;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
getChildrenOfType(type, node) {
|
|
84
|
+
const nodes = node
|
|
85
|
+
? findChildrenByType(node, type).map(({ node }) => node)
|
|
86
|
+
: this.nodesMap.get(type);
|
|
87
|
+
return (nodes ?? []).filter((n) => isNodeOfType(n, type));
|
|
88
|
+
}
|
|
89
|
+
getFirstChildOfType(type, node) {
|
|
90
|
+
return this.getChildrenOfType(type, node)[0];
|
|
91
|
+
}
|
|
92
|
+
fillEmptyElements($article, selector, tagName = 'p') {
|
|
93
|
+
const $empty = Array.from($article.querySelectorAll(selector)).filter(($el) => !$el.innerHTML);
|
|
94
|
+
$empty.forEach(($element) => $element.appendChild(this.createElement(tagName)));
|
|
95
|
+
}
|
|
96
|
+
createElementWithID(node, nodeName) {
|
|
97
|
+
const $element = this.createElement(nodeName);
|
|
98
|
+
$element.setAttribute('id', normalizeID(node.attrs.id));
|
|
99
|
+
return $element;
|
|
100
|
+
}
|
|
101
|
+
serializeNode(node) {
|
|
102
|
+
return this.serializer.serializeNode(node, {
|
|
103
|
+
document: this.document,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
appendChildIfPresent($parent, tagName, textContent) {
|
|
107
|
+
if (!textContent) {
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const $element = this.createElement(tagName);
|
|
111
|
+
$element.textContent = textContent;
|
|
112
|
+
$parent.appendChild($element);
|
|
113
|
+
}
|
|
114
|
+
}
|