@manuscripts/body-editor 1.6.17 → 1.6.18-LEAN-3092
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/commands.js +9 -7
- package/dist/cjs/lib/mathml-to-svg.js +70 -0
- package/dist/cjs/lib/tex-to-svg.js +60 -0
- package/dist/cjs/views/equation.js +8 -3
- package/dist/cjs/views/equation_editable.js +3 -9
- package/dist/cjs/views/equation_element.js +6 -3
- package/dist/cjs/views/inline_equation.js +8 -3
- package/dist/cjs/views/inline_equation_editable.js +3 -9
- package/dist/es/commands.js +10 -8
- package/dist/es/lib/mathml-to-svg.js +66 -0
- package/dist/es/lib/tex-to-svg.js +56 -0
- package/dist/es/views/equation.js +8 -3
- package/dist/es/views/equation_editable.js +3 -9
- package/dist/es/views/equation_element.js +6 -3
- package/dist/es/views/inline_equation.js +8 -3
- package/dist/es/views/inline_equation_editable.js +3 -9
- package/dist/types/lib/mathml-to-svg.d.ts +17 -0
- package/dist/types/lib/tex-to-svg.d.ts +18 -0
- package/package.json +7 -6
package/dist/cjs/commands.js
CHANGED
|
@@ -109,7 +109,6 @@ const createBlock = (nodeType, position, state, dispatch) => {
|
|
|
109
109
|
case state.schema.nodes.equation_element:
|
|
110
110
|
node = state.schema.nodes.equation_element.create({}, [
|
|
111
111
|
state.schema.nodes.equation.create(),
|
|
112
|
-
createAndFillFigcaptionElement(state),
|
|
113
112
|
]);
|
|
114
113
|
break;
|
|
115
114
|
default:
|
|
@@ -264,10 +263,10 @@ const insertCrossReference = (state, dispatch) => {
|
|
|
264
263
|
};
|
|
265
264
|
exports.insertCrossReference = insertCrossReference;
|
|
266
265
|
const insertInlineEquation = (state, dispatch) => {
|
|
267
|
-
const inlineMathFragment = (0, transform_1.buildInlineMathFragment)(state.selection.$anchor.parent.attrs.id, selectedText().replace(/^\$/, '').replace(/\$$/, ''));
|
|
268
266
|
const sourcePos = state.selection.from - 1;
|
|
269
267
|
const tr = state.tr.replaceSelectionWith(state.schema.nodes.inline_equation.create({
|
|
270
|
-
|
|
268
|
+
format: 'tex',
|
|
269
|
+
contents: selectedText().replace(/^\$/, '').replace(/\$$/, ''),
|
|
271
270
|
}));
|
|
272
271
|
if (dispatch) {
|
|
273
272
|
const selection = prosemirror_state_1.NodeSelection.create(tr.doc, tr.mapping.map(sourcePos) + 1);
|
|
@@ -287,9 +286,9 @@ const insertInlineFootnote = (kind) => (state, dispatch) => {
|
|
|
287
286
|
});
|
|
288
287
|
const tr = state.tr;
|
|
289
288
|
tr.insert(insertedAt, node);
|
|
290
|
-
const
|
|
289
|
+
const footnotesSection = (0, prosemirror_utils_1.findChildrenByType)(tr.doc, transform_1.schema.nodes.footnotes_section)[0];
|
|
291
290
|
let selectionPos;
|
|
292
|
-
if (!
|
|
291
|
+
if (!footnotesSection) {
|
|
293
292
|
const section = state.schema.nodes.footnotes_section.create({}, [
|
|
294
293
|
state.schema.nodes.section_title.create({}, state.schema.text('Notes')),
|
|
295
294
|
state.schema.nodes.footnotes_element.create({}, footnote),
|
|
@@ -299,8 +298,11 @@ const insertInlineFootnote = (kind) => (state, dispatch) => {
|
|
|
299
298
|
selectionPos = backmatter.pos + section.nodeSize - 3;
|
|
300
299
|
}
|
|
301
300
|
else {
|
|
302
|
-
const
|
|
303
|
-
const pos =
|
|
301
|
+
const footnoteElement = (0, prosemirror_utils_1.findChildrenByType)(footnotesSection.node, transform_1.schema.nodes.footnotes_element);
|
|
302
|
+
const pos = footnotesSection.pos +
|
|
303
|
+
footnoteElement[0].pos +
|
|
304
|
+
footnoteElement[0].node.nodeSize -
|
|
305
|
+
1;
|
|
304
306
|
tr.insert(pos, footnote);
|
|
305
307
|
selectionPos = pos + 2;
|
|
306
308
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
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.convertMathMLToSVG = void 0;
|
|
19
|
+
require("mathjax-full/js/util/entities/all");
|
|
20
|
+
const transform_1 = require("@manuscripts/transform");
|
|
21
|
+
const HTMLAdaptor_1 = require("mathjax-full/js/adaptors/HTMLAdaptor");
|
|
22
|
+
const MmlFactory_1 = require("mathjax-full/js/core/MmlTree/MmlFactory");
|
|
23
|
+
const HTMLDocument_1 = require("mathjax-full/js/handlers/html/HTMLDocument");
|
|
24
|
+
const mathml_1 = require("mathjax-full/js/input/mathml");
|
|
25
|
+
const svg_1 = require("mathjax-full/js/output/svg");
|
|
26
|
+
class ManuscriptsMmlFactory extends MmlFactory_1.MmlFactory {
|
|
27
|
+
constructor() {
|
|
28
|
+
super();
|
|
29
|
+
this.nodeMap.set('image', this.nodeMap.get('none'));
|
|
30
|
+
}
|
|
31
|
+
create(kind, properties = {}, children = []) {
|
|
32
|
+
if (kind === 'image') {
|
|
33
|
+
return this.node['none'](properties, children);
|
|
34
|
+
}
|
|
35
|
+
return this.node[kind](properties, children);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
class ManuscriptsHTMLAdaptor extends HTMLAdaptor_1.HTMLAdaptor {
|
|
39
|
+
setAttribute(node, name, value, ns) {
|
|
40
|
+
if (name !== 'xmlns') {
|
|
41
|
+
ns ? node.setAttributeNS(ns, name, value) : node.setAttribute(name, value);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const InputJax = new mathml_1.MathML();
|
|
46
|
+
const OutputJax = new svg_1.SVG({
|
|
47
|
+
fontCache: 'none',
|
|
48
|
+
});
|
|
49
|
+
const adaptor = new ManuscriptsHTMLAdaptor(window);
|
|
50
|
+
const doc = new HTMLDocument_1.HTMLDocument(document, adaptor, {
|
|
51
|
+
InputJax,
|
|
52
|
+
OutputJax,
|
|
53
|
+
MmlFactory: new ManuscriptsMmlFactory(),
|
|
54
|
+
});
|
|
55
|
+
doc.addStyleSheet();
|
|
56
|
+
const convertMathMLToSVG = (mathml, display) => {
|
|
57
|
+
const item = doc.convert(mathml, {
|
|
58
|
+
display,
|
|
59
|
+
em: 16,
|
|
60
|
+
ex: 8,
|
|
61
|
+
containerWidth: 1000000,
|
|
62
|
+
lineWidth: 1000000,
|
|
63
|
+
scale: 1,
|
|
64
|
+
});
|
|
65
|
+
if (!item || !item.firstChild) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
return transform_1.xmlSerializer.serializeToString(item.firstChild);
|
|
69
|
+
};
|
|
70
|
+
exports.convertMathMLToSVG = convertMathMLToSVG;
|
|
@@ -0,0 +1,60 @@
|
|
|
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.convertTeXToSVG = exports.packages = void 0;
|
|
19
|
+
require("mathjax-full/js/util/entities/all");
|
|
20
|
+
const transform_1 = require("@manuscripts/transform");
|
|
21
|
+
const HTMLAdaptor_1 = require("mathjax-full/js/adaptors/HTMLAdaptor");
|
|
22
|
+
const HTMLDocument_1 = require("mathjax-full/js/handlers/html/HTMLDocument");
|
|
23
|
+
const tex_1 = require("mathjax-full/js/input/tex");
|
|
24
|
+
const AllPackages_1 = require("mathjax-full/js/input/tex/AllPackages");
|
|
25
|
+
const svg_1 = require("mathjax-full/js/output/svg");
|
|
26
|
+
exports.packages = AllPackages_1.AllPackages.filter((name) => name !== 'html' && name !== 'bussproofs');
|
|
27
|
+
class ManuscriptsHTMLAdaptor extends HTMLAdaptor_1.HTMLAdaptor {
|
|
28
|
+
setAttribute(node, name, value, ns) {
|
|
29
|
+
if (name !== 'xmlns') {
|
|
30
|
+
ns ? node.setAttributeNS(ns, name, value) : node.setAttribute(name, value);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const InputJax = new tex_1.TeX({
|
|
35
|
+
packages: exports.packages,
|
|
36
|
+
});
|
|
37
|
+
const OutputJax = new svg_1.SVG({
|
|
38
|
+
fontCache: 'none',
|
|
39
|
+
});
|
|
40
|
+
const adaptor = new ManuscriptsHTMLAdaptor(window);
|
|
41
|
+
const doc = new HTMLDocument_1.HTMLDocument(document, adaptor, {
|
|
42
|
+
InputJax,
|
|
43
|
+
OutputJax,
|
|
44
|
+
});
|
|
45
|
+
doc.addStyleSheet();
|
|
46
|
+
const convertTeXToSVG = (tex, display) => {
|
|
47
|
+
const item = doc.convert(tex, {
|
|
48
|
+
display,
|
|
49
|
+
em: 16,
|
|
50
|
+
ex: 8,
|
|
51
|
+
containerWidth: 1000000,
|
|
52
|
+
lineWidth: 1000000,
|
|
53
|
+
scale: 1,
|
|
54
|
+
});
|
|
55
|
+
if (!item || !item.firstChild) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
return transform_1.xmlSerializer.serializeToString(item.firstChild);
|
|
59
|
+
};
|
|
60
|
+
exports.convertTeXToSVG = convertTeXToSVG;
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.EquationView = void 0;
|
|
19
19
|
const dompurify_1 = require("../lib/dompurify");
|
|
20
|
+
const mathml_to_svg_1 = require("../lib/mathml-to-svg");
|
|
21
|
+
const tex_to_svg_1 = require("../lib/tex-to-svg");
|
|
20
22
|
const base_node_view_1 = require("./base_node_view");
|
|
21
23
|
const creators_1 = require("./creators");
|
|
22
24
|
class EquationView extends base_node_view_1.BaseNodeView {
|
|
@@ -32,12 +34,15 @@ class EquationView extends base_node_view_1.BaseNodeView {
|
|
|
32
34
|
this.dom.setAttribute('id', this.node.attrs.id);
|
|
33
35
|
};
|
|
34
36
|
this.updateContents = () => {
|
|
35
|
-
const {
|
|
37
|
+
const { contents, format } = this.node.attrs;
|
|
38
|
+
const svgContent = format === 'tex'
|
|
39
|
+
? (0, tex_to_svg_1.convertTeXToSVG)(contents, true)
|
|
40
|
+
: (0, mathml_to_svg_1.convertMathMLToSVG)(contents, true);
|
|
36
41
|
while (this.dom.hasChildNodes()) {
|
|
37
42
|
this.dom.removeChild(this.dom.firstChild);
|
|
38
43
|
}
|
|
39
|
-
if (
|
|
40
|
-
const fragment = (0, dompurify_1.sanitize)(
|
|
44
|
+
if (svgContent) {
|
|
45
|
+
const fragment = (0, dompurify_1.sanitize)(svgContent, {
|
|
41
46
|
USE_PROFILES: { svg: true },
|
|
42
47
|
});
|
|
43
48
|
this.dom.appendChild(fragment);
|
|
@@ -48,7 +48,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
48
48
|
};
|
|
49
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
50
|
exports.EquationEditableView = void 0;
|
|
51
|
-
const transform_1 = require("@manuscripts/transform");
|
|
52
51
|
const prosemirror_state_1 = require("prosemirror-state");
|
|
53
52
|
const creators_1 = require("./creators");
|
|
54
53
|
const equation_1 = require("./equation");
|
|
@@ -62,21 +61,16 @@ class EquationEditableView extends equation_1.EquationView {
|
|
|
62
61
|
const { createEditor } = yield Promise.resolve().then(() => __importStar(require('../lib/codemirror')));
|
|
63
62
|
const placeholder = 'Enter LaTeX equation, e.g. "a^2 = \\sqrt{b^2 + c^2}"';
|
|
64
63
|
const input = yield createEditor({
|
|
65
|
-
value: this.node.attrs.
|
|
64
|
+
value: this.node.attrs.contents || '',
|
|
66
65
|
mode: 'stex',
|
|
67
66
|
placeholder,
|
|
68
67
|
autofocus: true,
|
|
69
68
|
});
|
|
70
69
|
input.on('changes', () => __awaiter(this, void 0, void 0, function* () {
|
|
71
|
-
const
|
|
72
|
-
const SVGStringRepresentation = yield (0, transform_1.convertTeXToSVG)(TeXRepresentation, true);
|
|
73
|
-
if (!SVGStringRepresentation) {
|
|
74
|
-
throw new Error('No SVG output from MathJax');
|
|
75
|
-
}
|
|
70
|
+
const contents = input.getValue();
|
|
76
71
|
const pos = this.getPos();
|
|
77
72
|
const { tr } = this.view.state;
|
|
78
|
-
tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), {
|
|
79
|
-
SVGStringRepresentation })).setSelection(prosemirror_state_1.NodeSelection.create(tr.doc, pos));
|
|
73
|
+
tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { contents, format: 'tex' })).setSelection(prosemirror_state_1.NodeSelection.create(tr.doc, pos));
|
|
80
74
|
this.view.dispatch(tr);
|
|
81
75
|
}));
|
|
82
76
|
const wrapper = document.createElement('div');
|
|
@@ -27,9 +27,12 @@ class EquationElementView extends block_view_1.default {
|
|
|
27
27
|
this.elementType = 'figure';
|
|
28
28
|
this.updateContents = () => {
|
|
29
29
|
var _a;
|
|
30
|
-
const {
|
|
31
|
-
|
|
32
|
-
|
|
30
|
+
const { label } = this.node.attrs;
|
|
31
|
+
if (label) {
|
|
32
|
+
const labelEl = document.createElement('label');
|
|
33
|
+
labelEl.textContent = label;
|
|
34
|
+
this.dom.appendChild(labelEl);
|
|
35
|
+
}
|
|
33
36
|
if ((_a = this.node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
|
|
34
37
|
const lastChange = this.node.attrs.dataTracked[this.node.attrs.dataTracked.length - 1];
|
|
35
38
|
this.dom.setAttribute('data-track-status', lastChange.status);
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.InlineEquationView = void 0;
|
|
19
19
|
const dompurify_1 = require("../lib/dompurify");
|
|
20
|
+
const mathml_to_svg_1 = require("../lib/mathml-to-svg");
|
|
21
|
+
const tex_to_svg_1 = require("../lib/tex-to-svg");
|
|
20
22
|
const track_changes_utils_1 = require("../lib/track-changes-utils");
|
|
21
23
|
const base_node_view_1 = require("./base_node_view");
|
|
22
24
|
const creators_1 = require("./creators");
|
|
@@ -29,12 +31,15 @@ class InlineEquationView extends base_node_view_1.BaseNodeView {
|
|
|
29
31
|
};
|
|
30
32
|
this.updateContents = () => {
|
|
31
33
|
if (!(0, track_changes_utils_1.isRejectedInsert)(this.node)) {
|
|
32
|
-
const {
|
|
34
|
+
const { contents, format } = this.node.attrs;
|
|
33
35
|
while (this.dom.hasChildNodes()) {
|
|
34
36
|
this.dom.removeChild(this.dom.firstChild);
|
|
35
37
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
const svgContent = format === 'tex'
|
|
39
|
+
? (0, tex_to_svg_1.convertTeXToSVG)(contents, true)
|
|
40
|
+
: (0, mathml_to_svg_1.convertMathMLToSVG)(contents, true);
|
|
41
|
+
if (svgContent) {
|
|
42
|
+
const fragment = (0, dompurify_1.sanitize)(svgContent, {
|
|
38
43
|
USE_PROFILES: { svg: true },
|
|
39
44
|
});
|
|
40
45
|
this.dom.appendChild(fragment);
|
|
@@ -48,7 +48,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
48
48
|
};
|
|
49
49
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
50
|
exports.InlineEquationEditableView = void 0;
|
|
51
|
-
const transform_1 = require("@manuscripts/transform");
|
|
52
51
|
const prosemirror_state_1 = require("prosemirror-state");
|
|
53
52
|
const creators_1 = require("./creators");
|
|
54
53
|
const inline_equation_1 = require("./inline_equation");
|
|
@@ -62,21 +61,16 @@ class InlineEquationEditableView extends inline_equation_1.InlineEquationView {
|
|
|
62
61
|
const { createEditor } = yield Promise.resolve().then(() => __importStar(require('../lib/codemirror')));
|
|
63
62
|
const placeholder = 'Enter LaTeX equation, e.g. "E=mc^2"';
|
|
64
63
|
const input = yield createEditor({
|
|
65
|
-
value: this.node.attrs.
|
|
64
|
+
value: this.node.attrs.contents || '',
|
|
66
65
|
mode: 'stex',
|
|
67
66
|
placeholder,
|
|
68
67
|
autofocus: true,
|
|
69
68
|
});
|
|
70
69
|
input.on('changes', () => __awaiter(this, void 0, void 0, function* () {
|
|
71
|
-
const
|
|
72
|
-
const SVGRepresentation = yield (0, transform_1.convertTeXToSVG)(TeXRepresentation, true);
|
|
73
|
-
if (!SVGRepresentation) {
|
|
74
|
-
throw new Error('No SVG output from MathJax');
|
|
75
|
-
}
|
|
70
|
+
const contents = input.getValue();
|
|
76
71
|
const pos = this.getPos();
|
|
77
72
|
const { tr } = this.view.state;
|
|
78
|
-
tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), {
|
|
79
|
-
SVGRepresentation })).setSelection(prosemirror_state_1.NodeSelection.create(tr.doc, pos));
|
|
73
|
+
tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { format: 'tex', contents })).setSelection(prosemirror_state_1.NodeSelection.create(tr.doc, pos));
|
|
80
74
|
this.view.dispatch(tr);
|
|
81
75
|
}));
|
|
82
76
|
this.props.popper.show(this.dom, input.getWrapperElement(), 'bottom');
|
package/dist/es/commands.js
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import { ObjectTypes } from '@manuscripts/json-schema';
|
|
17
17
|
import { skipTracking } from '@manuscripts/track-changes-plugin';
|
|
18
|
-
import { buildComment,
|
|
18
|
+
import { buildComment, generateID, isElementNodeType, isInBibliographySection, isListNode, isSectionNodeType, schema, } from '@manuscripts/transform';
|
|
19
19
|
import { NodeRange } from 'prosemirror-model';
|
|
20
20
|
import { wrapInList } from 'prosemirror-schema-list';
|
|
21
21
|
import { NodeSelection, TextSelection, } from 'prosemirror-state';
|
|
@@ -101,7 +101,6 @@ export const createBlock = (nodeType, position, state, dispatch) => {
|
|
|
101
101
|
case state.schema.nodes.equation_element:
|
|
102
102
|
node = state.schema.nodes.equation_element.create({}, [
|
|
103
103
|
state.schema.nodes.equation.create(),
|
|
104
|
-
createAndFillFigcaptionElement(state),
|
|
105
104
|
]);
|
|
106
105
|
break;
|
|
107
106
|
default:
|
|
@@ -247,10 +246,10 @@ export const insertCrossReference = (state, dispatch) => {
|
|
|
247
246
|
return true;
|
|
248
247
|
};
|
|
249
248
|
export const insertInlineEquation = (state, dispatch) => {
|
|
250
|
-
const inlineMathFragment = buildInlineMathFragment(state.selection.$anchor.parent.attrs.id, selectedText().replace(/^\$/, '').replace(/\$$/, ''));
|
|
251
249
|
const sourcePos = state.selection.from - 1;
|
|
252
250
|
const tr = state.tr.replaceSelectionWith(state.schema.nodes.inline_equation.create({
|
|
253
|
-
|
|
251
|
+
format: 'tex',
|
|
252
|
+
contents: selectedText().replace(/^\$/, '').replace(/\$$/, ''),
|
|
254
253
|
}));
|
|
255
254
|
if (dispatch) {
|
|
256
255
|
const selection = NodeSelection.create(tr.doc, tr.mapping.map(sourcePos) + 1);
|
|
@@ -269,9 +268,9 @@ export const insertInlineFootnote = (kind) => (state, dispatch) => {
|
|
|
269
268
|
});
|
|
270
269
|
const tr = state.tr;
|
|
271
270
|
tr.insert(insertedAt, node);
|
|
272
|
-
const
|
|
271
|
+
const footnotesSection = findChildrenByType(tr.doc, schema.nodes.footnotes_section)[0];
|
|
273
272
|
let selectionPos;
|
|
274
|
-
if (!
|
|
273
|
+
if (!footnotesSection) {
|
|
275
274
|
const section = state.schema.nodes.footnotes_section.create({}, [
|
|
276
275
|
state.schema.nodes.section_title.create({}, state.schema.text('Notes')),
|
|
277
276
|
state.schema.nodes.footnotes_element.create({}, footnote),
|
|
@@ -281,8 +280,11 @@ export const insertInlineFootnote = (kind) => (state, dispatch) => {
|
|
|
281
280
|
selectionPos = backmatter.pos + section.nodeSize - 3;
|
|
282
281
|
}
|
|
283
282
|
else {
|
|
284
|
-
const
|
|
285
|
-
const pos =
|
|
283
|
+
const footnoteElement = findChildrenByType(footnotesSection.node, schema.nodes.footnotes_element);
|
|
284
|
+
const pos = footnotesSection.pos +
|
|
285
|
+
footnoteElement[0].pos +
|
|
286
|
+
footnoteElement[0].node.nodeSize -
|
|
287
|
+
1;
|
|
286
288
|
tr.insert(pos, footnote);
|
|
287
289
|
selectionPos = pos + 2;
|
|
288
290
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
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 'mathjax-full/js/util/entities/all';
|
|
17
|
+
import { xmlSerializer } from '@manuscripts/transform';
|
|
18
|
+
import { HTMLAdaptor } from 'mathjax-full/js/adaptors/HTMLAdaptor';
|
|
19
|
+
import { MmlFactory } from 'mathjax-full/js/core/MmlTree/MmlFactory';
|
|
20
|
+
import { HTMLDocument } from 'mathjax-full/js/handlers/html/HTMLDocument';
|
|
21
|
+
import { MathML } from 'mathjax-full/js/input/mathml';
|
|
22
|
+
import { SVG } from 'mathjax-full/js/output/svg';
|
|
23
|
+
class ManuscriptsMmlFactory extends MmlFactory {
|
|
24
|
+
constructor() {
|
|
25
|
+
super();
|
|
26
|
+
this.nodeMap.set('image', this.nodeMap.get('none'));
|
|
27
|
+
}
|
|
28
|
+
create(kind, properties = {}, children = []) {
|
|
29
|
+
if (kind === 'image') {
|
|
30
|
+
return this.node['none'](properties, children);
|
|
31
|
+
}
|
|
32
|
+
return this.node[kind](properties, children);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
class ManuscriptsHTMLAdaptor extends HTMLAdaptor {
|
|
36
|
+
setAttribute(node, name, value, ns) {
|
|
37
|
+
if (name !== 'xmlns') {
|
|
38
|
+
ns ? node.setAttributeNS(ns, name, value) : node.setAttribute(name, value);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
const InputJax = new MathML();
|
|
43
|
+
const OutputJax = new SVG({
|
|
44
|
+
fontCache: 'none',
|
|
45
|
+
});
|
|
46
|
+
const adaptor = new ManuscriptsHTMLAdaptor(window);
|
|
47
|
+
const doc = new HTMLDocument(document, adaptor, {
|
|
48
|
+
InputJax,
|
|
49
|
+
OutputJax,
|
|
50
|
+
MmlFactory: new ManuscriptsMmlFactory(),
|
|
51
|
+
});
|
|
52
|
+
doc.addStyleSheet();
|
|
53
|
+
export const convertMathMLToSVG = (mathml, display) => {
|
|
54
|
+
const item = doc.convert(mathml, {
|
|
55
|
+
display,
|
|
56
|
+
em: 16,
|
|
57
|
+
ex: 8,
|
|
58
|
+
containerWidth: 1000000,
|
|
59
|
+
lineWidth: 1000000,
|
|
60
|
+
scale: 1,
|
|
61
|
+
});
|
|
62
|
+
if (!item || !item.firstChild) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return xmlSerializer.serializeToString(item.firstChild);
|
|
66
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
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 'mathjax-full/js/util/entities/all';
|
|
17
|
+
import { xmlSerializer } from '@manuscripts/transform';
|
|
18
|
+
import { HTMLAdaptor } from 'mathjax-full/js/adaptors/HTMLAdaptor';
|
|
19
|
+
import { HTMLDocument } from 'mathjax-full/js/handlers/html/HTMLDocument';
|
|
20
|
+
import { TeX } from 'mathjax-full/js/input/tex';
|
|
21
|
+
import { AllPackages } from 'mathjax-full/js/input/tex/AllPackages';
|
|
22
|
+
import { SVG } from 'mathjax-full/js/output/svg';
|
|
23
|
+
export const packages = AllPackages.filter((name) => name !== 'html' && name !== 'bussproofs');
|
|
24
|
+
class ManuscriptsHTMLAdaptor extends HTMLAdaptor {
|
|
25
|
+
setAttribute(node, name, value, ns) {
|
|
26
|
+
if (name !== 'xmlns') {
|
|
27
|
+
ns ? node.setAttributeNS(ns, name, value) : node.setAttribute(name, value);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const InputJax = new TeX({
|
|
32
|
+
packages,
|
|
33
|
+
});
|
|
34
|
+
const OutputJax = new SVG({
|
|
35
|
+
fontCache: 'none',
|
|
36
|
+
});
|
|
37
|
+
const adaptor = new ManuscriptsHTMLAdaptor(window);
|
|
38
|
+
const doc = new HTMLDocument(document, adaptor, {
|
|
39
|
+
InputJax,
|
|
40
|
+
OutputJax,
|
|
41
|
+
});
|
|
42
|
+
doc.addStyleSheet();
|
|
43
|
+
export const convertTeXToSVG = (tex, display) => {
|
|
44
|
+
const item = doc.convert(tex, {
|
|
45
|
+
display,
|
|
46
|
+
em: 16,
|
|
47
|
+
ex: 8,
|
|
48
|
+
containerWidth: 1000000,
|
|
49
|
+
lineWidth: 1000000,
|
|
50
|
+
scale: 1,
|
|
51
|
+
});
|
|
52
|
+
if (!item || !item.firstChild) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
return xmlSerializer.serializeToString(item.firstChild);
|
|
56
|
+
};
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import { sanitize } from '../lib/dompurify';
|
|
17
|
+
import { convertMathMLToSVG } from '../lib/mathml-to-svg';
|
|
18
|
+
import { convertTeXToSVG } from '../lib/tex-to-svg';
|
|
17
19
|
import { BaseNodeView } from './base_node_view';
|
|
18
20
|
import { createNodeView } from './creators';
|
|
19
21
|
export class EquationView extends BaseNodeView {
|
|
@@ -29,12 +31,15 @@ export class EquationView extends BaseNodeView {
|
|
|
29
31
|
this.dom.setAttribute('id', this.node.attrs.id);
|
|
30
32
|
};
|
|
31
33
|
this.updateContents = () => {
|
|
32
|
-
const {
|
|
34
|
+
const { contents, format } = this.node.attrs;
|
|
35
|
+
const svgContent = format === 'tex'
|
|
36
|
+
? convertTeXToSVG(contents, true)
|
|
37
|
+
: convertMathMLToSVG(contents, true);
|
|
33
38
|
while (this.dom.hasChildNodes()) {
|
|
34
39
|
this.dom.removeChild(this.dom.firstChild);
|
|
35
40
|
}
|
|
36
|
-
if (
|
|
37
|
-
const fragment = sanitize(
|
|
41
|
+
if (svgContent) {
|
|
42
|
+
const fragment = sanitize(svgContent, {
|
|
38
43
|
USE_PROFILES: { svg: true },
|
|
39
44
|
});
|
|
40
45
|
this.dom.appendChild(fragment);
|
|
@@ -22,7 +22,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
22
22
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
|
-
import { convertTeXToSVG } from '@manuscripts/transform';
|
|
26
25
|
import { NodeSelection } from 'prosemirror-state';
|
|
27
26
|
import { createEditableNodeView } from './creators';
|
|
28
27
|
import { EquationView } from './equation';
|
|
@@ -36,21 +35,16 @@ export class EquationEditableView extends EquationView {
|
|
|
36
35
|
const { createEditor } = yield import('../lib/codemirror');
|
|
37
36
|
const placeholder = 'Enter LaTeX equation, e.g. "a^2 = \\sqrt{b^2 + c^2}"';
|
|
38
37
|
const input = yield createEditor({
|
|
39
|
-
value: this.node.attrs.
|
|
38
|
+
value: this.node.attrs.contents || '',
|
|
40
39
|
mode: 'stex',
|
|
41
40
|
placeholder,
|
|
42
41
|
autofocus: true,
|
|
43
42
|
});
|
|
44
43
|
input.on('changes', () => __awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
const
|
|
46
|
-
const SVGStringRepresentation = yield convertTeXToSVG(TeXRepresentation, true);
|
|
47
|
-
if (!SVGStringRepresentation) {
|
|
48
|
-
throw new Error('No SVG output from MathJax');
|
|
49
|
-
}
|
|
44
|
+
const contents = input.getValue();
|
|
50
45
|
const pos = this.getPos();
|
|
51
46
|
const { tr } = this.view.state;
|
|
52
|
-
tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), {
|
|
53
|
-
SVGStringRepresentation })).setSelection(NodeSelection.create(tr.doc, pos));
|
|
47
|
+
tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { contents, format: 'tex' })).setSelection(NodeSelection.create(tr.doc, pos));
|
|
54
48
|
this.view.dispatch(tr);
|
|
55
49
|
}));
|
|
56
50
|
const wrapper = document.createElement('div');
|
|
@@ -21,9 +21,12 @@ export class EquationElementView extends BlockView {
|
|
|
21
21
|
this.elementType = 'figure';
|
|
22
22
|
this.updateContents = () => {
|
|
23
23
|
var _a;
|
|
24
|
-
const {
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
const { label } = this.node.attrs;
|
|
25
|
+
if (label) {
|
|
26
|
+
const labelEl = document.createElement('label');
|
|
27
|
+
labelEl.textContent = label;
|
|
28
|
+
this.dom.appendChild(labelEl);
|
|
29
|
+
}
|
|
27
30
|
if ((_a = this.node.attrs.dataTracked) === null || _a === void 0 ? void 0 : _a.length) {
|
|
28
31
|
const lastChange = this.node.attrs.dataTracked[this.node.attrs.dataTracked.length - 1];
|
|
29
32
|
this.dom.setAttribute('data-track-status', lastChange.status);
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
import { sanitize } from '../lib/dompurify';
|
|
17
|
+
import { convertMathMLToSVG } from '../lib/mathml-to-svg';
|
|
18
|
+
import { convertTeXToSVG } from '../lib/tex-to-svg';
|
|
17
19
|
import { isRejectedInsert } from '../lib/track-changes-utils';
|
|
18
20
|
import { BaseNodeView } from './base_node_view';
|
|
19
21
|
import { createNodeView } from './creators';
|
|
@@ -26,12 +28,15 @@ export class InlineEquationView extends BaseNodeView {
|
|
|
26
28
|
};
|
|
27
29
|
this.updateContents = () => {
|
|
28
30
|
if (!isRejectedInsert(this.node)) {
|
|
29
|
-
const {
|
|
31
|
+
const { contents, format } = this.node.attrs;
|
|
30
32
|
while (this.dom.hasChildNodes()) {
|
|
31
33
|
this.dom.removeChild(this.dom.firstChild);
|
|
32
34
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
const svgContent = format === 'tex'
|
|
36
|
+
? convertTeXToSVG(contents, true)
|
|
37
|
+
: convertMathMLToSVG(contents, true);
|
|
38
|
+
if (svgContent) {
|
|
39
|
+
const fragment = sanitize(svgContent, {
|
|
35
40
|
USE_PROFILES: { svg: true },
|
|
36
41
|
});
|
|
37
42
|
this.dom.appendChild(fragment);
|
|
@@ -22,7 +22,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
22
22
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
23
23
|
});
|
|
24
24
|
};
|
|
25
|
-
import { convertTeXToSVG } from '@manuscripts/transform';
|
|
26
25
|
import { NodeSelection } from 'prosemirror-state';
|
|
27
26
|
import { createEditableNodeView } from './creators';
|
|
28
27
|
import { InlineEquationView } from './inline_equation';
|
|
@@ -36,21 +35,16 @@ export class InlineEquationEditableView extends InlineEquationView {
|
|
|
36
35
|
const { createEditor } = yield import('../lib/codemirror');
|
|
37
36
|
const placeholder = 'Enter LaTeX equation, e.g. "E=mc^2"';
|
|
38
37
|
const input = yield createEditor({
|
|
39
|
-
value: this.node.attrs.
|
|
38
|
+
value: this.node.attrs.contents || '',
|
|
40
39
|
mode: 'stex',
|
|
41
40
|
placeholder,
|
|
42
41
|
autofocus: true,
|
|
43
42
|
});
|
|
44
43
|
input.on('changes', () => __awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
const
|
|
46
|
-
const SVGRepresentation = yield convertTeXToSVG(TeXRepresentation, true);
|
|
47
|
-
if (!SVGRepresentation) {
|
|
48
|
-
throw new Error('No SVG output from MathJax');
|
|
49
|
-
}
|
|
44
|
+
const contents = input.getValue();
|
|
50
45
|
const pos = this.getPos();
|
|
51
46
|
const { tr } = this.view.state;
|
|
52
|
-
tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), {
|
|
53
|
-
SVGRepresentation })).setSelection(NodeSelection.create(tr.doc, pos));
|
|
47
|
+
tr.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, this.node.attrs), { format: 'tex', contents })).setSelection(NodeSelection.create(tr.doc, pos));
|
|
54
48
|
this.view.dispatch(tr);
|
|
55
49
|
}));
|
|
56
50
|
this.props.popper.show(this.dom, input.getWrapperElement(), 'bottom');
|
|
@@ -0,0 +1,17 @@
|
|
|
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 'mathjax-full/js/util/entities/all';
|
|
17
|
+
export declare const convertMathMLToSVG: (mathml: string, display: boolean) => string | null;
|
|
@@ -0,0 +1,18 @@
|
|
|
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 'mathjax-full/js/util/entities/all';
|
|
17
|
+
export declare const packages: string[];
|
|
18
|
+
export declare const convertTeXToSVG: (tex: string, display: boolean) => string | null;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@manuscripts/body-editor",
|
|
3
3
|
"description": "Prosemirror components for editing and viewing manuscripts",
|
|
4
|
-
"version": "1.6.
|
|
4
|
+
"version": "1.6.18-LEAN-3092",
|
|
5
5
|
"repository": "github:Atypon-OpenSource/manuscripts-body-editor",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "dist/cjs",
|
|
@@ -29,13 +29,14 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@iarna/word-count": "^1.1.2",
|
|
31
31
|
"@manuscripts/assets": "^0.6.4",
|
|
32
|
-
"@manuscripts/json-schema": "
|
|
33
|
-
"@manuscripts/library": "1.3.2",
|
|
34
|
-
"@manuscripts/style-guide": "1.7.0",
|
|
32
|
+
"@manuscripts/json-schema": "2.2.2-LEAN-3094",
|
|
33
|
+
"@manuscripts/library": "1.3.2-LEAN-3092-1",
|
|
34
|
+
"@manuscripts/style-guide": "1.7.0-LEAN-3092-0",
|
|
35
35
|
"@manuscripts/track-changes-plugin": "^1.7.5",
|
|
36
|
-
"@manuscripts/transform": "2.0.4",
|
|
36
|
+
"@manuscripts/transform": "2.0.4-LEAN-3094",
|
|
37
37
|
"astrocite-eutils": "^0.16.4",
|
|
38
38
|
"axios": "^1.2.2",
|
|
39
|
+
"mathjax-full": "^3.2.2",
|
|
39
40
|
"codemirror": "^5.58.1",
|
|
40
41
|
"dompurify": "^2.4.1",
|
|
41
42
|
"grapheme-splitter": "^1.0.4",
|
|
@@ -126,4 +127,4 @@
|
|
|
126
127
|
"resolutions": {
|
|
127
128
|
"@types/react": "^17.0.2"
|
|
128
129
|
}
|
|
129
|
-
}
|
|
130
|
+
}
|