@manuscripts/body-editor 2.8.21 → 2.8.23
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 +4 -0
- package/dist/cjs/components/references/CitationEditor.js +19 -2
- package/dist/cjs/components/references/ImportBibliographyForm.js +194 -0
- package/dist/cjs/components/references/ImportBibliographyModal.js +147 -0
- package/dist/cjs/components/references/ReferenceSearch.js +5 -2
- package/dist/cjs/lib/files.js +2 -2
- package/dist/cjs/versions.js +1 -1
- package/dist/es/commands.js +5 -1
- package/dist/es/components/references/CitationEditor.js +19 -2
- package/dist/es/components/references/ImportBibliographyForm.js +167 -0
- package/dist/es/components/references/ImportBibliographyModal.js +117 -0
- package/dist/es/components/references/ReferenceSearch.js +6 -3
- package/dist/es/lib/files.js +2 -2
- package/dist/es/versions.js +1 -1
- package/dist/types/components/references/ImportBibliographyForm.d.ts +22 -0
- package/dist/types/components/references/ImportBibliographyModal.d.ts +7 -0
- package/dist/types/components/references/ReferenceSearch.d.ts +1 -0
- package/dist/types/lib/doc.d.ts +36 -9
- package/dist/types/lib/footnotes.d.ts +1 -1
- package/dist/types/lib/utils.d.ts +4 -4
- package/dist/types/versions.d.ts +1 -1
- package/package.json +4 -4
package/dist/cjs/commands.js
CHANGED
|
@@ -38,6 +38,10 @@ const search_replace_1 = require("./plugins/search-replace");
|
|
|
38
38
|
const autocompletion_1 = require("./plugins/section_title/autocompletion");
|
|
39
39
|
const addToStart = (state, dispatch) => {
|
|
40
40
|
const { selection } = state;
|
|
41
|
+
const props = (0, editor_props_1.getEditorProps)(state);
|
|
42
|
+
if (props.getCapabilities().editWithoutTracking) {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
41
45
|
if (!dispatch ||
|
|
42
46
|
!(selection instanceof prosemirror_state_1.TextSelection) ||
|
|
43
47
|
(selection.$from.node().type !== transform_1.schema.nodes.paragraph &&
|
|
@@ -33,6 +33,7 @@ const react_1 = __importStar(require("react"));
|
|
|
33
33
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
34
34
|
const array_reducer_1 = require("../../lib/array-reducer");
|
|
35
35
|
const CitationViewer_1 = require("./CitationViewer");
|
|
36
|
+
const ImportBibliographyModal_1 = require("./ImportBibliographyModal");
|
|
36
37
|
const ReferenceLine_1 = require("./ReferenceLine");
|
|
37
38
|
const ReferenceSearch_1 = require("./ReferenceSearch");
|
|
38
39
|
const ReferencesModal_1 = require("./ReferencesModal");
|
|
@@ -112,6 +113,7 @@ const CitationEditor = ({ query, rids: $rids, items: $items, citationCounts, sou
|
|
|
112
113
|
show: false,
|
|
113
114
|
});
|
|
114
115
|
const [searching, setSearching] = (0, react_1.useState)(false);
|
|
116
|
+
const [importing, setImporting] = (0, react_1.useState)(false);
|
|
115
117
|
const handleAdd = () => {
|
|
116
118
|
setSearching(false);
|
|
117
119
|
const item = {
|
|
@@ -122,17 +124,32 @@ const CitationEditor = ({ query, rids: $rids, items: $items, citationCounts, sou
|
|
|
122
124
|
handleCite([item]);
|
|
123
125
|
setEditingForm({ show: true, item: item });
|
|
124
126
|
};
|
|
127
|
+
const handleImport = () => {
|
|
128
|
+
setSearching(false);
|
|
129
|
+
setImporting(true);
|
|
130
|
+
};
|
|
131
|
+
const handleSaveImport = (data) => {
|
|
132
|
+
data.forEach((item) => {
|
|
133
|
+
const newItem = Object.assign({}, item);
|
|
134
|
+
newItem.id = (0, json_schema_1.generateID)(json_schema_1.ObjectTypes.BibliographyItem);
|
|
135
|
+
handleSave(newItem);
|
|
136
|
+
handleCite([newItem]);
|
|
137
|
+
});
|
|
138
|
+
};
|
|
125
139
|
const cited = (0, react_1.useMemo)(() => {
|
|
126
140
|
return rids.flatMap((rid) => items.filter((i) => i.id === rid));
|
|
127
141
|
}, [rids, items]);
|
|
142
|
+
if (importing) {
|
|
143
|
+
return (react_1.default.createElement(ImportBibliographyModal_1.ImportBibliographyModal, { onCancel: () => setImporting(false), onSave: handleSaveImport }));
|
|
144
|
+
}
|
|
128
145
|
if (searching) {
|
|
129
|
-
return (react_1.default.createElement(ReferenceSearch_1.ReferenceSearch, { sources: sources, items: items, onAdd: handleAdd, onCite: (items) => {
|
|
146
|
+
return (react_1.default.createElement(ReferenceSearch_1.ReferenceSearch, { sources: sources, items: items, onAdd: handleAdd, onImport: handleImport, onCite: (items) => {
|
|
130
147
|
setSearching(false);
|
|
131
148
|
handleCite(items);
|
|
132
149
|
}, onCancel: () => setSearching(false) }));
|
|
133
150
|
}
|
|
134
151
|
if (!rids.length) {
|
|
135
|
-
return (react_1.default.createElement(ReferenceSearch_1.ReferenceSearch, { query: query, sources: sources, items: items, onAdd: handleAdd, onCite: handleCite, onCancel: onCancel }));
|
|
152
|
+
return (react_1.default.createElement(ReferenceSearch_1.ReferenceSearch, { query: query, sources: sources, items: items, onAdd: handleAdd, onImport: handleImport, onCite: handleCite, onCancel: onCancel }));
|
|
136
153
|
}
|
|
137
154
|
return (react_1.default.createElement(react_1.default.Fragment, null,
|
|
138
155
|
react_1.default.createElement(style_guide_1.Dialog, { isOpen: deleteDialog.show, category: style_guide_1.Category.confirmation, header: "Remove cited item", message: "Are you sure you want to remove this cited item? It will still exist in the reference list.", actions: {
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*!
|
|
3
|
+
* © 2025 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
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
41
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
42
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
43
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
44
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
45
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
46
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
47
|
+
});
|
|
48
|
+
};
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.ImportBibliographyForm = void 0;
|
|
51
|
+
const library_1 = require("@manuscripts/library");
|
|
52
|
+
const style_guide_1 = require("@manuscripts/style-guide");
|
|
53
|
+
const formik_1 = require("formik");
|
|
54
|
+
const lodash_1 = require("lodash");
|
|
55
|
+
const react_1 = __importStar(require("react"));
|
|
56
|
+
const styled_components_1 = __importStar(require("styled-components"));
|
|
57
|
+
const ReferenceLine_1 = require("./ReferenceLine");
|
|
58
|
+
const ImportBibliographyForm = ({ onCancel, onSave, }) => {
|
|
59
|
+
const [dragging, setDragging] = (0, react_1.useState)(false);
|
|
60
|
+
const formik = (0, formik_1.useFormik)({
|
|
61
|
+
initialValues: {
|
|
62
|
+
content: '',
|
|
63
|
+
err: '',
|
|
64
|
+
data: [],
|
|
65
|
+
},
|
|
66
|
+
onSubmit: (values, { setSubmitting }) => {
|
|
67
|
+
onSave(values.data);
|
|
68
|
+
setSubmitting(false);
|
|
69
|
+
},
|
|
70
|
+
onReset: onCancel,
|
|
71
|
+
});
|
|
72
|
+
const setDataField = (0, react_1.useCallback)((fileContent) => __awaiter(void 0, void 0, void 0, function* () {
|
|
73
|
+
const NO_CITATION = 'No citation available';
|
|
74
|
+
const ERROR_CITATION = 'Error generating citation';
|
|
75
|
+
try {
|
|
76
|
+
if (!fileContent.trim()) {
|
|
77
|
+
formik.setFieldValue('err', NO_CITATION);
|
|
78
|
+
formik.setFieldValue('data', []);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const data = yield (0, library_1.transformBibliography)(fileContent.trim());
|
|
82
|
+
formik.setFieldValue('data', data ? data : []);
|
|
83
|
+
formik.setFieldValue('err', '');
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error('Citation generation error:', error);
|
|
87
|
+
formik.setFieldValue('err', ERROR_CITATION);
|
|
88
|
+
formik.setFieldValue('data', []);
|
|
89
|
+
}
|
|
90
|
+
}), []);
|
|
91
|
+
const debouncedGenerateData = (0, react_1.useMemo)(() => (0, lodash_1.debounce)(setDataField, 300), [setDataField]);
|
|
92
|
+
(0, react_1.useEffect)(() => {
|
|
93
|
+
debouncedGenerateData(formik.values.content);
|
|
94
|
+
}, [debouncedGenerateData, formik.values.content]);
|
|
95
|
+
const handleDrop = (event) => {
|
|
96
|
+
event.preventDefault();
|
|
97
|
+
setDragging(false);
|
|
98
|
+
const file = event.dataTransfer.files[0];
|
|
99
|
+
if (file) {
|
|
100
|
+
readFileContent(file);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const handleFileChange = (event) => {
|
|
104
|
+
var _a;
|
|
105
|
+
const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
106
|
+
if (file) {
|
|
107
|
+
readFileContent(file);
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
const readFileContent = (file) => {
|
|
111
|
+
const reader = new FileReader();
|
|
112
|
+
reader.onload = (e) => {
|
|
113
|
+
var _a;
|
|
114
|
+
if ((_a = e.target) === null || _a === void 0 ? void 0 : _a.result) {
|
|
115
|
+
formik.setFieldValue('content', e.target.result);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
reader.readAsText(file);
|
|
119
|
+
};
|
|
120
|
+
return (react_1.default.createElement("form", { onSubmit: formik.handleSubmit, onReset: formik.handleReset },
|
|
121
|
+
react_1.default.createElement(DropContainer, { onDrop: handleDrop, onDragOver: (e) => {
|
|
122
|
+
e.preventDefault();
|
|
123
|
+
setDragging(true);
|
|
124
|
+
}, onDragLeave: () => setDragging(false), active: dragging },
|
|
125
|
+
react_1.default.createElement("input", { id: "file", name: "file", type: "file", onChange: handleFileChange, style: { display: 'none' } }),
|
|
126
|
+
react_1.default.createElement(Label, { htmlFor: "file" }, "Drag & Drop or Click here to upload a file.")),
|
|
127
|
+
react_1.default.createElement(LabelContainer, null,
|
|
128
|
+
react_1.default.createElement(Label, null, "Alternatively, you can directly Copy&Paste below, the text of the bibliography items.")),
|
|
129
|
+
react_1.default.createElement(style_guide_1.TextArea, { name: "content", rows: 6, value: formik.values.content, onChange: formik.handleChange }),
|
|
130
|
+
react_1.default.createElement(Preview, null,
|
|
131
|
+
formik.values.err,
|
|
132
|
+
formik.values.data.map((item) => (react_1.default.createElement(ReferenceLine_1.ReferenceLine, { item: item, key: item.id })))),
|
|
133
|
+
react_1.default.createElement(ButtonContainer, null,
|
|
134
|
+
react_1.default.createElement(style_guide_1.SecondaryButton, { type: "reset" }, "Cancel"),
|
|
135
|
+
react_1.default.createElement(style_guide_1.PrimaryButton, { type: "submit", disabled: !formik.dirty || formik.isSubmitting || !formik.values.data.length }, "Save"))));
|
|
136
|
+
};
|
|
137
|
+
exports.ImportBibliographyForm = ImportBibliographyForm;
|
|
138
|
+
const Preview = styled_components_1.default.div `
|
|
139
|
+
display: flex;
|
|
140
|
+
flex-direction: column;
|
|
141
|
+
gap: ${(props) => 4 * props.theme.grid.unit}px;
|
|
142
|
+
min-height: 50px;
|
|
143
|
+
margin-top: ${(props) => 4 * props.theme.grid.unit}px;
|
|
144
|
+
margin-bottom: ${(props) => props.theme.grid.unit}px;
|
|
145
|
+
`;
|
|
146
|
+
const LabelContainer = styled_components_1.default.div `
|
|
147
|
+
display: flex;
|
|
148
|
+
justify-content: space-between;
|
|
149
|
+
align-items: center;
|
|
150
|
+
margin-top: ${(props) => 4 * props.theme.grid.unit}px;
|
|
151
|
+
margin-bottom: ${(props) => props.theme.grid.unit}px;
|
|
152
|
+
`;
|
|
153
|
+
const Label = styled_components_1.default.label `
|
|
154
|
+
font-size: ${(props) => props.theme.font.size.normal};
|
|
155
|
+
line-height: ${(props) => props.theme.font.lineHeight.large};
|
|
156
|
+
font-family: ${(props) => props.theme.font.family.Lato};
|
|
157
|
+
display: block;
|
|
158
|
+
color: ${(props) => props.theme.colors.text.secondary};
|
|
159
|
+
`;
|
|
160
|
+
const ButtonContainer = styled_components_1.default.div `
|
|
161
|
+
display: flex;
|
|
162
|
+
justify-content: flex-end;
|
|
163
|
+
margin-top: ${(props) => 4 * props.theme.grid.unit}px;
|
|
164
|
+
gap: ${(props) => 2 * props.theme.grid.unit}px;
|
|
165
|
+
`;
|
|
166
|
+
const activeBoxStyle = (0, styled_components_1.css) `
|
|
167
|
+
background: #f2fbfc;
|
|
168
|
+
border: 1px dashed #bce7f6;
|
|
169
|
+
`;
|
|
170
|
+
const DropContainer = styled_components_1.default.div `
|
|
171
|
+
background: ${(props) => props.theme.colors.background.secondary};
|
|
172
|
+
border: 1px dashed ${(props) => props.theme.colors.border.secondary};
|
|
173
|
+
box-sizing: border-box;
|
|
174
|
+
border-radius: ${(props) => props.theme.grid.radius.default};
|
|
175
|
+
cursor: pointer;
|
|
176
|
+
${({ active }) => active && activeBoxStyle};
|
|
177
|
+
|
|
178
|
+
&:hover {
|
|
179
|
+
${activeBoxStyle}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
& label {
|
|
183
|
+
width: 100%;
|
|
184
|
+
height: 80px;
|
|
185
|
+
display: flex;
|
|
186
|
+
align-items: center;
|
|
187
|
+
justify-content: center;
|
|
188
|
+
text-align: center;
|
|
189
|
+
font-size: ${(props) => props.theme.font.size.normal};
|
|
190
|
+
line-height: ${(props) => props.theme.font.lineHeight.large};
|
|
191
|
+
font-family: ${(props) => props.theme.font.family.Lato};
|
|
192
|
+
color: ${(props) => props.theme.colors.text.onLight};
|
|
193
|
+
}
|
|
194
|
+
`;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.ImportBibliographyModal = void 0;
|
|
30
|
+
const style_guide_1 = require("@manuscripts/style-guide");
|
|
31
|
+
const react_1 = __importStar(require("react"));
|
|
32
|
+
const styled_components_1 = __importDefault(require("styled-components"));
|
|
33
|
+
const ImportBibliographyForm_1 = require("./ImportBibliographyForm");
|
|
34
|
+
const exampleBibtex = `@book{abramowitz+stegun,
|
|
35
|
+
author = "Milton {Abramowitz} and Irene A. {Stegun}",
|
|
36
|
+
title = "Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables",
|
|
37
|
+
publisher = "Dover",
|
|
38
|
+
year = 1964,
|
|
39
|
+
address = "New York City",
|
|
40
|
+
edition = "ninth Dover printing, tenth GPO printing"
|
|
41
|
+
}`;
|
|
42
|
+
const examplePubmed = `Example Identifiers:
|
|
43
|
+
pmid:17170128
|
|
44
|
+
PMC1852221`;
|
|
45
|
+
const exampleRis = `TY - JOUR
|
|
46
|
+
AU - Shannon, Claude E.
|
|
47
|
+
PY - 1948
|
|
48
|
+
DA - July
|
|
49
|
+
TI - A Mathematical Theory of Communication
|
|
50
|
+
T2 - Bell System Technical Journal
|
|
51
|
+
SP - 379
|
|
52
|
+
EP - 423
|
|
53
|
+
VL - 27
|
|
54
|
+
ER - `;
|
|
55
|
+
const exampleEnw = `%0 Journal Article
|
|
56
|
+
%D 2018
|
|
57
|
+
%@ 0903-4641
|
|
58
|
+
%A Abbassi-Daloii, Tooba
|
|
59
|
+
%A Yousefi, Soheil
|
|
60
|
+
%A Sekhavati, Mohammad Hadi
|
|
61
|
+
%A Tahmoorespur, Mojtaba
|
|
62
|
+
%J APMIS
|
|
63
|
+
%N 1
|
|
64
|
+
%P 65-75
|
|
65
|
+
%T Impact of heat shock protein 60KD in combination with outer membrane proteins on immune response against Brucella melitensis
|
|
66
|
+
%R https://doi.org/10.1111/apm.12778
|
|
67
|
+
%U https://onlinelibrary.wiley.com/doi/abs/10.1111/apm.12778
|
|
68
|
+
%V 126
|
|
69
|
+
%X Lorem ipsum dolor sit amet`;
|
|
70
|
+
const exampleDoi = `Example DOI Identifiers:
|
|
71
|
+
10.1080/15588742.2015.1017684
|
|
72
|
+
http://dx.doi.org/10.1080/15588742.2015.1017684`;
|
|
73
|
+
const ImportBibliographyModal = ({ onCancel, onSave }) => {
|
|
74
|
+
const [isOpen, setOpen] = (0, react_1.useState)(true);
|
|
75
|
+
const handleCancel = () => {
|
|
76
|
+
handleClose();
|
|
77
|
+
};
|
|
78
|
+
const handleClose = () => setOpen(false);
|
|
79
|
+
const handleSave = (data) => {
|
|
80
|
+
onSave(data);
|
|
81
|
+
handleClose();
|
|
82
|
+
};
|
|
83
|
+
return (react_1.default.createElement(style_guide_1.StyledModal, { isOpen: isOpen, onRequestClose: onCancel },
|
|
84
|
+
react_1.default.createElement(style_guide_1.ModalContainer, { "data-cy": "import-bibliography-modal" },
|
|
85
|
+
react_1.default.createElement(style_guide_1.ModalHeader, null,
|
|
86
|
+
react_1.default.createElement(style_guide_1.CloseButton, { onClick: onCancel, "data-cy": "modal-close-button" })),
|
|
87
|
+
react_1.default.createElement(ModalBody, null,
|
|
88
|
+
react_1.default.createElement(ModalTitle, null, "Import Bibliography"),
|
|
89
|
+
react_1.default.createElement("p", null,
|
|
90
|
+
react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "example_bibtex" }, "BibTex"),
|
|
91
|
+
",",
|
|
92
|
+
' ',
|
|
93
|
+
react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "example_pubmed" }, "PubMed"),
|
|
94
|
+
",",
|
|
95
|
+
' ',
|
|
96
|
+
react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "example_ris" }, "RIS"),
|
|
97
|
+
",",
|
|
98
|
+
' ',
|
|
99
|
+
react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "example_enw" }, "ENW"),
|
|
100
|
+
' ',
|
|
101
|
+
"and",
|
|
102
|
+
' ',
|
|
103
|
+
react_1.default.createElement(SpanWithExample, { "data-tooltip-id": "example_doi" }, "DOI"),
|
|
104
|
+
' ',
|
|
105
|
+
"formats are supported"),
|
|
106
|
+
react_1.default.createElement(ImportBibliographyForm_1.ImportBibliographyForm, { onCancel: handleCancel, onSave: handleSave }),
|
|
107
|
+
react_1.default.createElement(Example, { id: "example_bibtex", place: "bottom" },
|
|
108
|
+
react_1.default.createElement("div", null,
|
|
109
|
+
react_1.default.createElement("pre", null, exampleBibtex))),
|
|
110
|
+
react_1.default.createElement(Example, { id: "example_pubmed", place: "bottom" },
|
|
111
|
+
react_1.default.createElement("div", null,
|
|
112
|
+
react_1.default.createElement("pre", null, examplePubmed))),
|
|
113
|
+
react_1.default.createElement(Example, { id: "example_ris", place: "bottom" },
|
|
114
|
+
react_1.default.createElement("div", null,
|
|
115
|
+
react_1.default.createElement("pre", null, exampleRis))),
|
|
116
|
+
react_1.default.createElement(Example, { id: "example_enw", place: "bottom" },
|
|
117
|
+
react_1.default.createElement("div", null,
|
|
118
|
+
react_1.default.createElement("pre", null, exampleEnw))),
|
|
119
|
+
react_1.default.createElement(Example, { id: "example_doi", place: "bottom" },
|
|
120
|
+
react_1.default.createElement("div", null,
|
|
121
|
+
react_1.default.createElement("pre", null, exampleDoi)))))));
|
|
122
|
+
};
|
|
123
|
+
exports.ImportBibliographyModal = ImportBibliographyModal;
|
|
124
|
+
const ModalBody = styled_components_1.default.div `
|
|
125
|
+
box-sizing: border-box;
|
|
126
|
+
padding: ${(props) => 6 * props.theme.grid.unit}px;
|
|
127
|
+
background-color: ${(props) => props.theme.colors.background.primary};
|
|
128
|
+
width: 640px;
|
|
129
|
+
max-width: 60vw;
|
|
130
|
+
max-height: 80vh;
|
|
131
|
+
`;
|
|
132
|
+
const ModalTitle = styled_components_1.default.h2 `
|
|
133
|
+
font-family: ${(props) => props.theme.font.family.sans};
|
|
134
|
+
font-size: ${(props) => props.theme.font.size.medium};
|
|
135
|
+
font-weight: ${(props) => props.theme.font.weight.bold};
|
|
136
|
+
color: ${(props) => props.theme.colors.text.primary};
|
|
137
|
+
margin: 0;
|
|
138
|
+
`;
|
|
139
|
+
const SpanWithExample = styled_components_1.default.span `
|
|
140
|
+
text-decoration: underline dotted;
|
|
141
|
+
text-underline-offset: 4px;
|
|
142
|
+
`;
|
|
143
|
+
const Example = (0, styled_components_1.default)(style_guide_1.Tooltip) `
|
|
144
|
+
text-align: left !important;
|
|
145
|
+
max-width: 480px !important;
|
|
146
|
+
overflow: hidden !important;
|
|
147
|
+
`;
|
|
@@ -79,7 +79,7 @@ const AddReferenceActions = (0, styled_components_1.default)(style_guide_1.Butto
|
|
|
79
79
|
}
|
|
80
80
|
}
|
|
81
81
|
`;
|
|
82
|
-
const ReferenceSearch = ({ query: initialQuery, sources, items, onAdd, onCite, onCancel }) => {
|
|
82
|
+
const ReferenceSearch = ({ query: initialQuery, sources, items, onAdd, onImport, onCite, onCancel, }) => {
|
|
83
83
|
const [query, setQuery] = (0, react_1.useState)(initialQuery || '');
|
|
84
84
|
const [selections, setSelections] = (0, react_1.useState)(new Map());
|
|
85
85
|
const toggleSelection = (item) => {
|
|
@@ -115,7 +115,10 @@ const ReferenceSearch = ({ query: initialQuery, sources, items, onAdd, onCite, o
|
|
|
115
115
|
react_1.default.createElement(AddReferenceActions, null,
|
|
116
116
|
react_1.default.createElement(style_guide_1.IconTextButton, { onClick: onAdd },
|
|
117
117
|
react_1.default.createElement(style_guide_1.AddNewIcon, null),
|
|
118
|
-
"Add new")
|
|
118
|
+
"Add new"),
|
|
119
|
+
react_1.default.createElement(style_guide_1.IconTextButton, { onClick: onImport },
|
|
120
|
+
react_1.default.createElement(style_guide_1.UploadIcon, null),
|
|
121
|
+
"Import new")),
|
|
119
122
|
react_1.default.createElement(style_guide_1.ButtonGroup, null,
|
|
120
123
|
react_1.default.createElement(style_guide_1.SecondaryButton, { onClick: onCancel }, "Close"),
|
|
121
124
|
react_1.default.createElement(style_guide_1.PrimaryButton, { onClick: handleClick, disabled: selections.size === 0 }, "Cite")))));
|
package/dist/cjs/lib/files.js
CHANGED
|
@@ -53,14 +53,14 @@ const groupFiles = (doc, files) => {
|
|
|
53
53
|
supplements.push({
|
|
54
54
|
node,
|
|
55
55
|
pos,
|
|
56
|
-
file: getFile(node.attrs.href)
|
|
56
|
+
file: getFile(node.attrs.href),
|
|
57
57
|
});
|
|
58
58
|
}
|
|
59
59
|
if (node.type === transform_1.schema.nodes.attachment) {
|
|
60
60
|
attachments.push({
|
|
61
61
|
node,
|
|
62
62
|
pos,
|
|
63
|
-
file: getFile(node.attrs.href)
|
|
63
|
+
file: getFile(node.attrs.href),
|
|
64
64
|
});
|
|
65
65
|
}
|
|
66
66
|
});
|
package/dist/cjs/versions.js
CHANGED
package/dist/es/commands.js
CHANGED
|
@@ -23,7 +23,7 @@ import { addColumnAfter, addColumnBefore, addRow, selectedRect, } from 'prosemir
|
|
|
23
23
|
import { findWrapping, liftTarget, ReplaceAroundStep, ReplaceStep, } from 'prosemirror-transform';
|
|
24
24
|
import { findChildrenByType, findParentNodeOfType, findParentNodeOfTypeClosestToPos, flatten, hasParentNodeOfType, } from 'prosemirror-utils';
|
|
25
25
|
import { getCommentKey, getCommentRange } from './lib/comments';
|
|
26
|
-
import { findAbstractsNode, findBackmatter, findBibliographySection, findBody,
|
|
26
|
+
import { findAbstractsNode, findBackmatter, findBibliographySection, findBody, findFootnotesSection, insertAttachmentsNode, insertAwardsNode, insertFootnotesSection, insertSupplementsNode, } from './lib/doc';
|
|
27
27
|
import { createFootnote, findFootnotesContainerNode, getFootnotesElementState, } from './lib/footnotes';
|
|
28
28
|
import { findWordBoundaries, isNodeOfType, nearestAncestor, } from './lib/helpers';
|
|
29
29
|
import { isDeleted } from './lib/track-changes-utils';
|
|
@@ -34,6 +34,10 @@ import { searchReplaceKey } from './plugins/search-replace';
|
|
|
34
34
|
import { checkForCompletion } from './plugins/section_title/autocompletion';
|
|
35
35
|
export const addToStart = (state, dispatch) => {
|
|
36
36
|
const { selection } = state;
|
|
37
|
+
const props = getEditorProps(state);
|
|
38
|
+
if (props.getCapabilities().editWithoutTracking) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
37
41
|
if (!dispatch ||
|
|
38
42
|
!(selection instanceof TextSelection) ||
|
|
39
43
|
(selection.$from.node().type !== schema.nodes.paragraph &&
|
|
@@ -4,6 +4,7 @@ import React, { useMemo, useReducer, useState } from 'react';
|
|
|
4
4
|
import styled from 'styled-components';
|
|
5
5
|
import { arrayReducer, attrsReducer } from '../../lib/array-reducer';
|
|
6
6
|
import { CitedItem, CitedItems } from './CitationViewer';
|
|
7
|
+
import { ImportBibliographyModal } from './ImportBibliographyModal';
|
|
7
8
|
import { ReferenceLine } from './ReferenceLine';
|
|
8
9
|
import { ReferenceSearch } from './ReferenceSearch';
|
|
9
10
|
import { ReferencesModal } from './ReferencesModal';
|
|
@@ -83,6 +84,7 @@ export const CitationEditor = ({ query, rids: $rids, items: $items, citationCoun
|
|
|
83
84
|
show: false,
|
|
84
85
|
});
|
|
85
86
|
const [searching, setSearching] = useState(false);
|
|
87
|
+
const [importing, setImporting] = useState(false);
|
|
86
88
|
const handleAdd = () => {
|
|
87
89
|
setSearching(false);
|
|
88
90
|
const item = {
|
|
@@ -93,17 +95,32 @@ export const CitationEditor = ({ query, rids: $rids, items: $items, citationCoun
|
|
|
93
95
|
handleCite([item]);
|
|
94
96
|
setEditingForm({ show: true, item: item });
|
|
95
97
|
};
|
|
98
|
+
const handleImport = () => {
|
|
99
|
+
setSearching(false);
|
|
100
|
+
setImporting(true);
|
|
101
|
+
};
|
|
102
|
+
const handleSaveImport = (data) => {
|
|
103
|
+
data.forEach((item) => {
|
|
104
|
+
const newItem = Object.assign({}, item);
|
|
105
|
+
newItem.id = generateID(ObjectTypes.BibliographyItem);
|
|
106
|
+
handleSave(newItem);
|
|
107
|
+
handleCite([newItem]);
|
|
108
|
+
});
|
|
109
|
+
};
|
|
96
110
|
const cited = useMemo(() => {
|
|
97
111
|
return rids.flatMap((rid) => items.filter((i) => i.id === rid));
|
|
98
112
|
}, [rids, items]);
|
|
113
|
+
if (importing) {
|
|
114
|
+
return (React.createElement(ImportBibliographyModal, { onCancel: () => setImporting(false), onSave: handleSaveImport }));
|
|
115
|
+
}
|
|
99
116
|
if (searching) {
|
|
100
|
-
return (React.createElement(ReferenceSearch, { sources: sources, items: items, onAdd: handleAdd, onCite: (items) => {
|
|
117
|
+
return (React.createElement(ReferenceSearch, { sources: sources, items: items, onAdd: handleAdd, onImport: handleImport, onCite: (items) => {
|
|
101
118
|
setSearching(false);
|
|
102
119
|
handleCite(items);
|
|
103
120
|
}, onCancel: () => setSearching(false) }));
|
|
104
121
|
}
|
|
105
122
|
if (!rids.length) {
|
|
106
|
-
return (React.createElement(ReferenceSearch, { query: query, sources: sources, items: items, onAdd: handleAdd, onCite: handleCite, onCancel: onCancel }));
|
|
123
|
+
return (React.createElement(ReferenceSearch, { query: query, sources: sources, items: items, onAdd: handleAdd, onImport: handleImport, onCite: handleCite, onCancel: onCancel }));
|
|
107
124
|
}
|
|
108
125
|
return (React.createElement(React.Fragment, null,
|
|
109
126
|
React.createElement(Dialog, { isOpen: deleteDialog.show, category: Category.confirmation, header: "Remove cited item", message: "Are you sure you want to remove this cited item? It will still exist in the reference list.", actions: {
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2025 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
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
17
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
18
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
19
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
20
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
21
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
22
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
import { transformBibliography } from '@manuscripts/library';
|
|
26
|
+
import { PrimaryButton, SecondaryButton, TextArea, } from '@manuscripts/style-guide';
|
|
27
|
+
import { useFormik } from 'formik';
|
|
28
|
+
import { debounce } from 'lodash';
|
|
29
|
+
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
|
30
|
+
import styled, { css } from 'styled-components';
|
|
31
|
+
import { ReferenceLine } from './ReferenceLine';
|
|
32
|
+
export const ImportBibliographyForm = ({ onCancel, onSave, }) => {
|
|
33
|
+
const [dragging, setDragging] = useState(false);
|
|
34
|
+
const formik = useFormik({
|
|
35
|
+
initialValues: {
|
|
36
|
+
content: '',
|
|
37
|
+
err: '',
|
|
38
|
+
data: [],
|
|
39
|
+
},
|
|
40
|
+
onSubmit: (values, { setSubmitting }) => {
|
|
41
|
+
onSave(values.data);
|
|
42
|
+
setSubmitting(false);
|
|
43
|
+
},
|
|
44
|
+
onReset: onCancel,
|
|
45
|
+
});
|
|
46
|
+
const setDataField = useCallback((fileContent) => __awaiter(void 0, void 0, void 0, function* () {
|
|
47
|
+
const NO_CITATION = 'No citation available';
|
|
48
|
+
const ERROR_CITATION = 'Error generating citation';
|
|
49
|
+
try {
|
|
50
|
+
if (!fileContent.trim()) {
|
|
51
|
+
formik.setFieldValue('err', NO_CITATION);
|
|
52
|
+
formik.setFieldValue('data', []);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const data = yield transformBibliography(fileContent.trim());
|
|
56
|
+
formik.setFieldValue('data', data ? data : []);
|
|
57
|
+
formik.setFieldValue('err', '');
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error('Citation generation error:', error);
|
|
61
|
+
formik.setFieldValue('err', ERROR_CITATION);
|
|
62
|
+
formik.setFieldValue('data', []);
|
|
63
|
+
}
|
|
64
|
+
}), []);
|
|
65
|
+
const debouncedGenerateData = useMemo(() => debounce(setDataField, 300), [setDataField]);
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
debouncedGenerateData(formik.values.content);
|
|
68
|
+
}, [debouncedGenerateData, formik.values.content]);
|
|
69
|
+
const handleDrop = (event) => {
|
|
70
|
+
event.preventDefault();
|
|
71
|
+
setDragging(false);
|
|
72
|
+
const file = event.dataTransfer.files[0];
|
|
73
|
+
if (file) {
|
|
74
|
+
readFileContent(file);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const handleFileChange = (event) => {
|
|
78
|
+
var _a;
|
|
79
|
+
const file = (_a = event.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
80
|
+
if (file) {
|
|
81
|
+
readFileContent(file);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
const readFileContent = (file) => {
|
|
85
|
+
const reader = new FileReader();
|
|
86
|
+
reader.onload = (e) => {
|
|
87
|
+
var _a;
|
|
88
|
+
if ((_a = e.target) === null || _a === void 0 ? void 0 : _a.result) {
|
|
89
|
+
formik.setFieldValue('content', e.target.result);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
reader.readAsText(file);
|
|
93
|
+
};
|
|
94
|
+
return (React.createElement("form", { onSubmit: formik.handleSubmit, onReset: formik.handleReset },
|
|
95
|
+
React.createElement(DropContainer, { onDrop: handleDrop, onDragOver: (e) => {
|
|
96
|
+
e.preventDefault();
|
|
97
|
+
setDragging(true);
|
|
98
|
+
}, onDragLeave: () => setDragging(false), active: dragging },
|
|
99
|
+
React.createElement("input", { id: "file", name: "file", type: "file", onChange: handleFileChange, style: { display: 'none' } }),
|
|
100
|
+
React.createElement(Label, { htmlFor: "file" }, "Drag & Drop or Click here to upload a file.")),
|
|
101
|
+
React.createElement(LabelContainer, null,
|
|
102
|
+
React.createElement(Label, null, "Alternatively, you can directly Copy&Paste below, the text of the bibliography items.")),
|
|
103
|
+
React.createElement(TextArea, { name: "content", rows: 6, value: formik.values.content, onChange: formik.handleChange }),
|
|
104
|
+
React.createElement(Preview, null,
|
|
105
|
+
formik.values.err,
|
|
106
|
+
formik.values.data.map((item) => (React.createElement(ReferenceLine, { item: item, key: item.id })))),
|
|
107
|
+
React.createElement(ButtonContainer, null,
|
|
108
|
+
React.createElement(SecondaryButton, { type: "reset" }, "Cancel"),
|
|
109
|
+
React.createElement(PrimaryButton, { type: "submit", disabled: !formik.dirty || formik.isSubmitting || !formik.values.data.length }, "Save"))));
|
|
110
|
+
};
|
|
111
|
+
const Preview = styled.div `
|
|
112
|
+
display: flex;
|
|
113
|
+
flex-direction: column;
|
|
114
|
+
gap: ${(props) => 4 * props.theme.grid.unit}px;
|
|
115
|
+
min-height: 50px;
|
|
116
|
+
margin-top: ${(props) => 4 * props.theme.grid.unit}px;
|
|
117
|
+
margin-bottom: ${(props) => props.theme.grid.unit}px;
|
|
118
|
+
`;
|
|
119
|
+
const LabelContainer = styled.div `
|
|
120
|
+
display: flex;
|
|
121
|
+
justify-content: space-between;
|
|
122
|
+
align-items: center;
|
|
123
|
+
margin-top: ${(props) => 4 * props.theme.grid.unit}px;
|
|
124
|
+
margin-bottom: ${(props) => props.theme.grid.unit}px;
|
|
125
|
+
`;
|
|
126
|
+
const Label = styled.label `
|
|
127
|
+
font-size: ${(props) => props.theme.font.size.normal};
|
|
128
|
+
line-height: ${(props) => props.theme.font.lineHeight.large};
|
|
129
|
+
font-family: ${(props) => props.theme.font.family.Lato};
|
|
130
|
+
display: block;
|
|
131
|
+
color: ${(props) => props.theme.colors.text.secondary};
|
|
132
|
+
`;
|
|
133
|
+
const ButtonContainer = styled.div `
|
|
134
|
+
display: flex;
|
|
135
|
+
justify-content: flex-end;
|
|
136
|
+
margin-top: ${(props) => 4 * props.theme.grid.unit}px;
|
|
137
|
+
gap: ${(props) => 2 * props.theme.grid.unit}px;
|
|
138
|
+
`;
|
|
139
|
+
const activeBoxStyle = css `
|
|
140
|
+
background: #f2fbfc;
|
|
141
|
+
border: 1px dashed #bce7f6;
|
|
142
|
+
`;
|
|
143
|
+
const DropContainer = styled.div `
|
|
144
|
+
background: ${(props) => props.theme.colors.background.secondary};
|
|
145
|
+
border: 1px dashed ${(props) => props.theme.colors.border.secondary};
|
|
146
|
+
box-sizing: border-box;
|
|
147
|
+
border-radius: ${(props) => props.theme.grid.radius.default};
|
|
148
|
+
cursor: pointer;
|
|
149
|
+
${({ active }) => active && activeBoxStyle};
|
|
150
|
+
|
|
151
|
+
&:hover {
|
|
152
|
+
${activeBoxStyle}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
& label {
|
|
156
|
+
width: 100%;
|
|
157
|
+
height: 80px;
|
|
158
|
+
display: flex;
|
|
159
|
+
align-items: center;
|
|
160
|
+
justify-content: center;
|
|
161
|
+
text-align: center;
|
|
162
|
+
font-size: ${(props) => props.theme.font.size.normal};
|
|
163
|
+
line-height: ${(props) => props.theme.font.lineHeight.large};
|
|
164
|
+
font-family: ${(props) => props.theme.font.family.Lato};
|
|
165
|
+
color: ${(props) => props.theme.colors.text.onLight};
|
|
166
|
+
}
|
|
167
|
+
`;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { CloseButton, ModalContainer, ModalHeader, StyledModal, Tooltip, } from '@manuscripts/style-guide';
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
import { ImportBibliographyForm } from './ImportBibliographyForm';
|
|
5
|
+
const exampleBibtex = `@book{abramowitz+stegun,
|
|
6
|
+
author = "Milton {Abramowitz} and Irene A. {Stegun}",
|
|
7
|
+
title = "Handbook of Mathematical Functions with Formulas, Graphs, and Mathematical Tables",
|
|
8
|
+
publisher = "Dover",
|
|
9
|
+
year = 1964,
|
|
10
|
+
address = "New York City",
|
|
11
|
+
edition = "ninth Dover printing, tenth GPO printing"
|
|
12
|
+
}`;
|
|
13
|
+
const examplePubmed = `Example Identifiers:
|
|
14
|
+
pmid:17170128
|
|
15
|
+
PMC1852221`;
|
|
16
|
+
const exampleRis = `TY - JOUR
|
|
17
|
+
AU - Shannon, Claude E.
|
|
18
|
+
PY - 1948
|
|
19
|
+
DA - July
|
|
20
|
+
TI - A Mathematical Theory of Communication
|
|
21
|
+
T2 - Bell System Technical Journal
|
|
22
|
+
SP - 379
|
|
23
|
+
EP - 423
|
|
24
|
+
VL - 27
|
|
25
|
+
ER - `;
|
|
26
|
+
const exampleEnw = `%0 Journal Article
|
|
27
|
+
%D 2018
|
|
28
|
+
%@ 0903-4641
|
|
29
|
+
%A Abbassi-Daloii, Tooba
|
|
30
|
+
%A Yousefi, Soheil
|
|
31
|
+
%A Sekhavati, Mohammad Hadi
|
|
32
|
+
%A Tahmoorespur, Mojtaba
|
|
33
|
+
%J APMIS
|
|
34
|
+
%N 1
|
|
35
|
+
%P 65-75
|
|
36
|
+
%T Impact of heat shock protein 60KD in combination with outer membrane proteins on immune response against Brucella melitensis
|
|
37
|
+
%R https://doi.org/10.1111/apm.12778
|
|
38
|
+
%U https://onlinelibrary.wiley.com/doi/abs/10.1111/apm.12778
|
|
39
|
+
%V 126
|
|
40
|
+
%X Lorem ipsum dolor sit amet`;
|
|
41
|
+
const exampleDoi = `Example DOI Identifiers:
|
|
42
|
+
10.1080/15588742.2015.1017684
|
|
43
|
+
http://dx.doi.org/10.1080/15588742.2015.1017684`;
|
|
44
|
+
export const ImportBibliographyModal = ({ onCancel, onSave }) => {
|
|
45
|
+
const [isOpen, setOpen] = useState(true);
|
|
46
|
+
const handleCancel = () => {
|
|
47
|
+
handleClose();
|
|
48
|
+
};
|
|
49
|
+
const handleClose = () => setOpen(false);
|
|
50
|
+
const handleSave = (data) => {
|
|
51
|
+
onSave(data);
|
|
52
|
+
handleClose();
|
|
53
|
+
};
|
|
54
|
+
return (React.createElement(StyledModal, { isOpen: isOpen, onRequestClose: onCancel },
|
|
55
|
+
React.createElement(ModalContainer, { "data-cy": "import-bibliography-modal" },
|
|
56
|
+
React.createElement(ModalHeader, null,
|
|
57
|
+
React.createElement(CloseButton, { onClick: onCancel, "data-cy": "modal-close-button" })),
|
|
58
|
+
React.createElement(ModalBody, null,
|
|
59
|
+
React.createElement(ModalTitle, null, "Import Bibliography"),
|
|
60
|
+
React.createElement("p", null,
|
|
61
|
+
React.createElement(SpanWithExample, { "data-tooltip-id": "example_bibtex" }, "BibTex"),
|
|
62
|
+
",",
|
|
63
|
+
' ',
|
|
64
|
+
React.createElement(SpanWithExample, { "data-tooltip-id": "example_pubmed" }, "PubMed"),
|
|
65
|
+
",",
|
|
66
|
+
' ',
|
|
67
|
+
React.createElement(SpanWithExample, { "data-tooltip-id": "example_ris" }, "RIS"),
|
|
68
|
+
",",
|
|
69
|
+
' ',
|
|
70
|
+
React.createElement(SpanWithExample, { "data-tooltip-id": "example_enw" }, "ENW"),
|
|
71
|
+
' ',
|
|
72
|
+
"and",
|
|
73
|
+
' ',
|
|
74
|
+
React.createElement(SpanWithExample, { "data-tooltip-id": "example_doi" }, "DOI"),
|
|
75
|
+
' ',
|
|
76
|
+
"formats are supported"),
|
|
77
|
+
React.createElement(ImportBibliographyForm, { onCancel: handleCancel, onSave: handleSave }),
|
|
78
|
+
React.createElement(Example, { id: "example_bibtex", place: "bottom" },
|
|
79
|
+
React.createElement("div", null,
|
|
80
|
+
React.createElement("pre", null, exampleBibtex))),
|
|
81
|
+
React.createElement(Example, { id: "example_pubmed", place: "bottom" },
|
|
82
|
+
React.createElement("div", null,
|
|
83
|
+
React.createElement("pre", null, examplePubmed))),
|
|
84
|
+
React.createElement(Example, { id: "example_ris", place: "bottom" },
|
|
85
|
+
React.createElement("div", null,
|
|
86
|
+
React.createElement("pre", null, exampleRis))),
|
|
87
|
+
React.createElement(Example, { id: "example_enw", place: "bottom" },
|
|
88
|
+
React.createElement("div", null,
|
|
89
|
+
React.createElement("pre", null, exampleEnw))),
|
|
90
|
+
React.createElement(Example, { id: "example_doi", place: "bottom" },
|
|
91
|
+
React.createElement("div", null,
|
|
92
|
+
React.createElement("pre", null, exampleDoi)))))));
|
|
93
|
+
};
|
|
94
|
+
const ModalBody = styled.div `
|
|
95
|
+
box-sizing: border-box;
|
|
96
|
+
padding: ${(props) => 6 * props.theme.grid.unit}px;
|
|
97
|
+
background-color: ${(props) => props.theme.colors.background.primary};
|
|
98
|
+
width: 640px;
|
|
99
|
+
max-width: 60vw;
|
|
100
|
+
max-height: 80vh;
|
|
101
|
+
`;
|
|
102
|
+
const ModalTitle = styled.h2 `
|
|
103
|
+
font-family: ${(props) => props.theme.font.family.sans};
|
|
104
|
+
font-size: ${(props) => props.theme.font.size.medium};
|
|
105
|
+
font-weight: ${(props) => props.theme.font.weight.bold};
|
|
106
|
+
color: ${(props) => props.theme.colors.text.primary};
|
|
107
|
+
margin: 0;
|
|
108
|
+
`;
|
|
109
|
+
const SpanWithExample = styled.span `
|
|
110
|
+
text-decoration: underline dotted;
|
|
111
|
+
text-underline-offset: 4px;
|
|
112
|
+
`;
|
|
113
|
+
const Example = styled(Tooltip) `
|
|
114
|
+
text-align: left !important;
|
|
115
|
+
max-width: 480px !important;
|
|
116
|
+
overflow: hidden !important;
|
|
117
|
+
`;
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* See the License for the specific language governing permissions and
|
|
14
14
|
* limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
import { AddNewIcon, ButtonGroup, IconTextButton, PrimaryButton, SecondaryButton, } from '@manuscripts/style-guide';
|
|
16
|
+
import { AddNewIcon, ButtonGroup, IconTextButton, PrimaryButton, SecondaryButton, UploadIcon, } from '@manuscripts/style-guide';
|
|
17
17
|
import { debounce } from 'lodash';
|
|
18
18
|
import React, { useState } from 'react';
|
|
19
19
|
import styled from 'styled-components';
|
|
@@ -50,7 +50,7 @@ const AddReferenceActions = styled(ButtonGroup) `
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
`;
|
|
53
|
-
export const ReferenceSearch = ({ query: initialQuery, sources, items, onAdd, onCite, onCancel }) => {
|
|
53
|
+
export const ReferenceSearch = ({ query: initialQuery, sources, items, onAdd, onImport, onCite, onCancel, }) => {
|
|
54
54
|
const [query, setQuery] = useState(initialQuery || '');
|
|
55
55
|
const [selections, setSelections] = useState(new Map());
|
|
56
56
|
const toggleSelection = (item) => {
|
|
@@ -86,7 +86,10 @@ export const ReferenceSearch = ({ query: initialQuery, sources, items, onAdd, on
|
|
|
86
86
|
React.createElement(AddReferenceActions, null,
|
|
87
87
|
React.createElement(IconTextButton, { onClick: onAdd },
|
|
88
88
|
React.createElement(AddNewIcon, null),
|
|
89
|
-
"Add new")
|
|
89
|
+
"Add new"),
|
|
90
|
+
React.createElement(IconTextButton, { onClick: onImport },
|
|
91
|
+
React.createElement(UploadIcon, null),
|
|
92
|
+
"Import new")),
|
|
90
93
|
React.createElement(ButtonGroup, null,
|
|
91
94
|
React.createElement(SecondaryButton, { onClick: onCancel }, "Close"),
|
|
92
95
|
React.createElement(PrimaryButton, { onClick: handleClick, disabled: selections.size === 0 }, "Cite")))));
|
package/dist/es/lib/files.js
CHANGED
|
@@ -50,14 +50,14 @@ export const groupFiles = (doc, files) => {
|
|
|
50
50
|
supplements.push({
|
|
51
51
|
node,
|
|
52
52
|
pos,
|
|
53
|
-
file: getFile(node.attrs.href)
|
|
53
|
+
file: getFile(node.attrs.href),
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
56
|
if (node.type === schema.nodes.attachment) {
|
|
57
57
|
attachments.push({
|
|
58
58
|
node,
|
|
59
59
|
pos,
|
|
60
|
-
file: getFile(node.attrs.href)
|
|
60
|
+
file: getFile(node.attrs.href),
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
63
|
});
|
package/dist/es/versions.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const VERSION = '2.8.
|
|
1
|
+
export const VERSION = '2.8.23';
|
|
2
2
|
export const MATHJAX_VERSION = '3.2.2';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* © 2025 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 { BibliographyItemAttrs } from '@manuscripts/transform';
|
|
17
|
+
import React from 'react';
|
|
18
|
+
export interface ImportBibFormProps {
|
|
19
|
+
onCancel: () => void;
|
|
20
|
+
onSave: (data: BibliographyItemAttrs[]) => void;
|
|
21
|
+
}
|
|
22
|
+
export declare const ImportBibliographyForm: ({ onCancel, onSave, }: ImportBibFormProps) => React.JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { BibliographyItemAttrs } from '@manuscripts/transform';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export interface ImportBibliographyModalProps {
|
|
4
|
+
onCancel: () => void;
|
|
5
|
+
onSave: (data: BibliographyItemAttrs[]) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare const ImportBibliographyModal: React.FC<ImportBibliographyModalProps>;
|
package/dist/types/lib/doc.d.ts
CHANGED
|
@@ -1,18 +1,45 @@
|
|
|
1
1
|
import { ManuscriptNode, ManuscriptTransaction } from '@manuscripts/transform';
|
|
2
|
-
export declare const insertAwardsNode: (tr: ManuscriptTransaction) =>
|
|
3
|
-
|
|
2
|
+
export declare const insertAwardsNode: (tr: ManuscriptTransaction) => {
|
|
3
|
+
node: import("prosemirror-model").Node;
|
|
4
|
+
pos: number;
|
|
5
|
+
};
|
|
6
|
+
export declare const insertSupplementsNode: (tr: ManuscriptTransaction) => {
|
|
7
|
+
node: import("prosemirror-model").Node;
|
|
8
|
+
pos: number;
|
|
9
|
+
};
|
|
4
10
|
export declare const insertAttachmentsNode: (tr: ManuscriptTransaction) => {
|
|
5
11
|
node: import("prosemirror-model").Node;
|
|
6
12
|
pos: number;
|
|
7
13
|
};
|
|
8
|
-
export declare const insertFootnotesSection: (tr: ManuscriptTransaction) =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
export declare const
|
|
13
|
-
|
|
14
|
+
export declare const insertFootnotesSection: (tr: ManuscriptTransaction) => {
|
|
15
|
+
node: import("prosemirror-model").Node;
|
|
16
|
+
pos: number;
|
|
17
|
+
};
|
|
18
|
+
export declare const findAbstractsNode: (doc: ManuscriptNode) => {
|
|
19
|
+
node: import("prosemirror-model").Node;
|
|
20
|
+
pos: number;
|
|
21
|
+
};
|
|
22
|
+
export declare const findBody: (doc: ManuscriptNode) => {
|
|
23
|
+
node: import("prosemirror-model").Node;
|
|
24
|
+
pos: number;
|
|
25
|
+
};
|
|
26
|
+
export declare const findBackmatter: (doc: ManuscriptNode) => {
|
|
27
|
+
node: import("prosemirror-model").Node;
|
|
28
|
+
pos: number;
|
|
29
|
+
};
|
|
30
|
+
export declare const findBibliographySection: (doc: ManuscriptNode) => {
|
|
31
|
+
node: import("prosemirror-model").Node;
|
|
32
|
+
pos: number;
|
|
33
|
+
};
|
|
34
|
+
export declare const findFootnotesSection: (doc: ManuscriptNode) => {
|
|
35
|
+
node: import("prosemirror-model").Node;
|
|
36
|
+
pos: number;
|
|
37
|
+
};
|
|
14
38
|
export declare const findGraphicalAbstractFigureElement: (doc: ManuscriptNode) => {
|
|
15
39
|
node: import("prosemirror-model").Node;
|
|
16
40
|
pos: number;
|
|
17
41
|
} | undefined;
|
|
18
|
-
export declare const findNodeByID: (doc: ManuscriptNode, id: string) =>
|
|
42
|
+
export declare const findNodeByID: (doc: ManuscriptNode, id: string) => {
|
|
43
|
+
node: import("prosemirror-model").Node;
|
|
44
|
+
pos: number;
|
|
45
|
+
};
|
|
@@ -18,7 +18,7 @@ export declare const findFootnotesContainerNode: (doc: ManuscriptNode, pos: numb
|
|
|
18
18
|
node: import("prosemirror-model").Node;
|
|
19
19
|
pos: number;
|
|
20
20
|
};
|
|
21
|
-
export declare const findParentFootnote: (selection: import("prosemirror-state").Selection) => import("prosemirror-utils").
|
|
21
|
+
export declare const findParentFootnote: (selection: import("prosemirror-state").Selection) => import("prosemirror-utils/dist/types").FindResult;
|
|
22
22
|
export declare const getFootnotesElementState: (state: ManuscriptEditorState, id: string) => import("../plugins/footnotes").FootnotesElementState | undefined;
|
|
23
23
|
export declare const getFootnoteLabel: (state: ManuscriptEditorState, footnote: FootnoteNode) => string;
|
|
24
24
|
export declare const createFootnote: () => FootnoteNode;
|
|
@@ -20,10 +20,10 @@ export declare function iterateChildren(node: ManuscriptNode, recurse?: boolean)
|
|
|
20
20
|
export declare const getMatchingChild: (parent: ManuscriptNode, matcher: (node: ManuscriptNode) => boolean, deep?: boolean) => ManuscriptNode | undefined;
|
|
21
21
|
export declare const getMatchingDescendant: (parent: ManuscriptNode, matcher: (node: ManuscriptNode) => boolean) => ManuscriptNode | undefined;
|
|
22
22
|
export declare const getChildOfType: (parent: ManuscriptNode, nodeType: ManuscriptNodeType, deep?: boolean) => boolean;
|
|
23
|
-
export declare const findParentNodeWithId: (
|
|
24
|
-
export declare const findParentNodeWithIdValue: (
|
|
25
|
-
export declare const findParentSection: (
|
|
26
|
-
export declare const findParentElement: (selection: Selection, validIds?: string[]) => import("prosemirror-utils").
|
|
23
|
+
export declare const findParentNodeWithId: ({ $from, $to }: Selection, validateSameParent?: boolean | undefined) => import("prosemirror-utils/dist/types").FindResult;
|
|
24
|
+
export declare const findParentNodeWithIdValue: ({ $from, $to }: Selection, validateSameParent?: boolean | undefined) => import("prosemirror-utils/dist/types").FindResult;
|
|
25
|
+
export declare const findParentSection: ({ $from, $to }: Selection, validateSameParent?: boolean | undefined) => import("prosemirror-utils/dist/types").FindResult;
|
|
26
|
+
export declare const findParentElement: (selection: Selection, validIds?: string[]) => import("prosemirror-utils/dist/types").FindResult;
|
|
27
27
|
export declare const isChildOfNodeTypes: (doc: ManuscriptNode, pos: number, parentNodeTypes: NodeType[]) => boolean;
|
|
28
28
|
export declare const isSelectionInNode: (state: EditorState, targetNode: ProseMirrorNode) => boolean;
|
|
29
29
|
export declare const createHeader: (typeName: string, text: string) => HTMLHeadingElement;
|
package/dist/types/versions.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const VERSION = "2.8.
|
|
1
|
+
export declare const VERSION = "2.8.23";
|
|
2
2
|
export declare const MATHJAX_VERSION = "3.2.2";
|
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": "2.8.
|
|
4
|
+
"version": "2.8.23",
|
|
5
5
|
"repository": "github:Atypon-OpenSource/manuscripts-body-editor",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"main": "dist/cjs",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@iarna/word-count": "^1.1.2",
|
|
33
33
|
"@manuscripts/json-schema": "2.2.11",
|
|
34
|
-
"@manuscripts/library": "1.3.
|
|
34
|
+
"@manuscripts/library": "1.3.13",
|
|
35
35
|
"@manuscripts/style-guide": "2.1.6",
|
|
36
36
|
"@manuscripts/track-changes-plugin": "1.10.1",
|
|
37
|
-
"@manuscripts/transform": "3.0.
|
|
37
|
+
"@manuscripts/transform": "3.0.50",
|
|
38
38
|
"@popperjs/core": "^2.11.8",
|
|
39
39
|
"astrocite-eutils": "^0.16.4",
|
|
40
40
|
"codemirror": "^5.58.1",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"prosemirror-state": "^1.4.2",
|
|
57
57
|
"prosemirror-tables": "^1.5.0",
|
|
58
58
|
"prosemirror-transform": "^1.7.0",
|
|
59
|
-
"prosemirror-utils": "^
|
|
59
|
+
"prosemirror-utils": "^1.2.2",
|
|
60
60
|
"prosemirror-view": "^1.29.1",
|
|
61
61
|
"react": "^18.3.1",
|
|
62
62
|
"react-dnd": "^16.0.1",
|