@iebh/polyglot 4.5.0 → 4.5.1

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.
@@ -4,13 +4,9 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports["default"] = void 0;
7
-
8
7
  var _global = _interopRequireDefault(require("./global.js"));
9
-
10
8
  var _lodash = _interopRequireDefault(require("lodash"));
11
-
12
9
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
13
-
14
10
  /**
15
11
  * Collection of utility functions to apply common behaviour to a compiled tree
16
12
  * @var {Object}
@@ -30,20 +26,21 @@ var tools = {
30
26
 
31
27
  var treeWalker = function treeWalker(tree, path) {
32
28
  tree.forEach(function (branch, branchKey) {
33
- var nodePath = path.concat(branchKey); // Fire callback if it matches
29
+ var nodePath = path.concat(branchKey);
34
30
 
31
+ // Fire callback if it matches
35
32
  if (!types || _lodash["default"].includes(types, branch.type)) {
36
33
  var result = callback(branch, nodePath);
37
34
  if (result === 'DEL') removals.push(nodePath);
38
- } // Walk down nodes if its a group
39
-
35
+ }
40
36
 
37
+ // Walk down nodes if its a group
41
38
  if (branch.type == 'group' || branch.type == 'line') treeWalker(branch.nodes, nodePath.concat(['nodes']));
42
39
  });
43
40
  };
41
+ treeWalker(tree, []);
44
42
 
45
- treeWalker(tree, []); // Crop all items marked as removals
46
-
43
+ // Crop all items marked as removals
47
44
  removals.reverse() // Walk in reverse order so we don't screw up arrays
48
45
  .forEach(function (path) {
49
46
  var nodeName = path.pop();
@@ -52,7 +49,6 @@ var tools = {
52
49
  });
53
50
  return tree;
54
51
  },
55
-
56
52
  /**
57
53
  * Apply a series of text replacements to every matching node object within a tree
58
54
  * This function mutates tree
@@ -74,10 +70,10 @@ var tools = {
74
70
  escapeRegExp: function escapeRegExp(string) {
75
71
  return string.replace(/[.*+?^${}()[\]\\]/g, '\\$&'); // $& means the whole matched string
76
72
  },
73
+
77
74
  // Replace multiple terms at once
78
75
  multiReplace: function multiReplace(text, replaceObj) {
79
76
  var template = tools.escapeRegExp(Object.keys(replaceObj).join("|"));
80
-
81
77
  if (template.length > 0) {
82
78
  var regex = new RegExp(template, "g");
83
79
  return text.replace(regex, function (match) {
@@ -87,7 +83,6 @@ var tools = {
87
83
  return text;
88
84
  }
89
85
  },
90
-
91
86
  /**
92
87
  * Retrieve the contents of a template by its ID
93
88
  * NOTE: If the specific engine definition is not found 'default' is used (and it will be pre-parsed via .translate())
@@ -102,7 +97,6 @@ var tools = {
102
97
  if (!_global["default"].templates[template].engines[engine]) return "Template: \"".concat(template, "\" not found for engine: \"").concat(engine, "\"");
103
98
  return '';
104
99
  },
105
-
106
100
  /**
107
101
  * Structure the wild cards correctly for cochrane to ensure no wildcards appear inside quotation marks
108
102
  * @param {string} text The text to parse
@@ -114,56 +108,47 @@ var tools = {
114
108
  var words = text.split(" ");
115
109
  var lastMatch = -1;
116
110
  var foundMatch = false;
117
-
118
111
  var _loop = function _loop(i) {
119
112
  if (wildcards.some(function (wildcard) {
120
113
  return words[i].includes(wildcard);
121
114
  })) {
122
- foundMatch = true; // Add quotation marks to previous word/s if the previous word was not a match
123
-
115
+ foundMatch = true;
116
+ // Add quotation marks to previous word/s if the previous word was not a match
124
117
  if (i - 1 > lastMatch) {
125
118
  words[lastMatch + 1] = highlighting ? '<font color="DarkBlue">"' + words[lastMatch + 1] : '"' + words[lastMatch + 1];
126
119
  words[i - 1] = highlighting ? words[i - 1] + '"</font>' : words[i - 1] + '"';
127
120
  }
128
-
129
- lastMatch = i; // Check that there is a word before and it is not a wildcard word
130
-
121
+ lastMatch = i;
122
+ // Check that there is a word before and it is not a wildcard word
131
123
  if (i > 0 && !wildcards.some(function (wildcard) {
132
124
  return words[i - 1].includes(wildcard);
133
125
  })) {
134
126
  words[i] = highlighting ? '<font color="purple">NEXT</font> ' + words[i] : 'NEXT ' + words[i];
135
- } // Check that there is a word after
136
-
137
-
127
+ }
128
+ // Check that there is a word after
138
129
  if (i < words.length - 1) {
139
130
  words[i] = highlighting ? words[i] + ' <font color="purple">NEXT</font>' : words[i] + " NEXT";
140
131
  }
141
132
  }
142
133
  };
143
-
144
134
  for (var i = 0; i < words.length; i++) {
145
135
  _loop(i);
146
- } // Add quotation marks to word/s after the final match
147
-
148
-
136
+ }
137
+ // Add quotation marks to word/s after the final match
149
138
  if (lastMatch + 1 < words.length) {
150
139
  words[lastMatch + 1] = highlighting ? '<font color="DarkBlue">"' + words[lastMatch + 1] : '"' + words[lastMatch + 1];
151
140
  words[words.length - 1] = highlighting ? words[words.length - 1] + '"</font>' : words[words.length - 1] + '"';
152
141
  }
153
-
154
142
  return foundMatch ? "(".concat(words.join(" "), ")") : words.join(" ");
155
143
  },
156
-
157
144
  /**
158
145
  * Print number in format defined by engine
159
146
  * @param {string} engine Engine to use
160
147
  * @param {string} ref Branch ref (e.g. 1)
161
148
  * @return {string} Formatted number
162
- */
163
- printNumber: function printNumber(engine, ref) {
149
+ */printNumber: function printNumber(engine, ref) {
164
150
  // Get line number format for engine
165
151
  var number = ref;
166
-
167
152
  switch (engine) {
168
153
  case 'PubMed full':
169
154
  case 'PubMed abbreviation':
@@ -175,24 +160,19 @@ var tools = {
175
160
  case 'Scopus (advanced search)':
176
161
  number = "#" + ref;
177
162
  break;
178
-
179
163
  case 'Ovid MEDLINE':
180
164
  case 'PsycInfo (Ovid)':
181
165
  case 'ProQuest Health and Medical':
182
166
  number = ref;
183
167
  break;
184
-
185
168
  case 'CINAHL (Ebsco)':
186
169
  case 'SPORTDiscus':
187
170
  number = "S" + ref;
188
171
  break;
189
-
190
172
  default:
191
173
  }
192
-
193
174
  return number;
194
175
  },
195
-
196
176
  /**
197
177
  * Determine if a phrase needs to be enclosed within speachmarks and return the result
198
178
  * @param {Object} branch Phrase branch to examine
@@ -202,12 +182,11 @@ var tools = {
202
182
  */
203
183
  quotePhrase: function quotePhrase(branch, engine, settings) {
204
184
  var text = _lodash["default"].trimEnd(branch.content);
185
+ var space = /\s/.test(text);
205
186
 
206
- var space = /\s/.test(text); // Apply wildcard replacements
207
-
187
+ // Apply wildcard replacements
208
188
  if (settings.replaceWildcards) {
209
189
  var replaceObj = {};
210
-
211
190
  switch (engine) {
212
191
  case 'PubMed full':
213
192
  case 'PubMed abbreviation':
@@ -217,23 +196,19 @@ var tools = {
217
196
  '#': settings.highlighting ? tools.createTooltip("*", "As PubMed does not single character wildcards a wildcard is used here", "highlight") : '*'
218
197
  };
219
198
  break;
220
-
221
199
  case 'Ovid MEDLINE':
222
200
  break;
223
201
  // Nothing needed
224
-
225
202
  case 'Cochrane Library':
226
203
  if (space) {
227
204
  text = tools.wildCardCochrane(text, settings.highlighting);
228
205
  }
229
-
230
206
  replaceObj = {
231
207
  '$': settings.highlighting ? tools.createTooltip("?", "As Cochrane does not support single character truncation, the 0 or 1 character truncation is used here.", "highlight") : '?',
232
208
  '#': '?'
233
209
  };
234
210
  return tools.multiReplace(text, replaceObj);
235
211
  // Return here to prevent duplicate quotes
236
-
237
212
  case 'Embase (Elsevier)':
238
213
  case 'Web of Science':
239
214
  case 'WoS Advanced':
@@ -243,7 +218,6 @@ var tools = {
243
218
  '#': '?'
244
219
  };
245
220
  break;
246
-
247
221
  case 'CINAHL (Ebsco)':
248
222
  replaceObj = {
249
223
  '$': '?',
@@ -251,7 +225,6 @@ var tools = {
251
225
  '#': '?'
252
226
  };
253
227
  break;
254
-
255
228
  case 'Scopus (basic search)':
256
229
  case 'Scopus (advanced search)':
257
230
  // space = true; //Always include quotes with scopus to make phrase a "loose phrase"
@@ -261,20 +234,17 @@ var tools = {
261
234
  '#': '?'
262
235
  };
263
236
  break;
264
-
265
237
  case 'PsycInfo (Ovid)':
266
238
  replaceObj = {
267
239
  '$': '#'
268
240
  };
269
241
  break;
270
-
271
242
  case 'ProQuest Health and Medical':
272
243
  replaceObj = {
273
244
  '$': '?',
274
245
  '#': '?'
275
246
  };
276
247
  break;
277
-
278
248
  case 'SPORTDiscus':
279
249
  if (!settings.testing) {
280
250
  space = true; //Always include quotes with SPORTDiscus
@@ -285,7 +255,6 @@ var tools = {
285
255
  '?': '#'
286
256
  };
287
257
  break;
288
-
289
258
  case 'Informit Health Collection':
290
259
  replaceObj = {
291
260
  '$': '?',
@@ -293,13 +262,10 @@ var tools = {
293
262
  };
294
263
  break;
295
264
  }
296
-
297
265
  text = tools.multiReplace(text, replaceObj);
298
266
  }
299
-
300
267
  return engine == 'Embase (Elsevier)' ? space ? settings.highlighting ? "<font color='DarkBlue'>'" + text + "'</font>" : "'" + text + "'" : text : space ? settings.highlighting ? '<font color="DarkBlue">"' + text + '"</font>' : '"' + text + '"' : text;
301
268
  },
302
-
303
269
  /**
304
270
  * Convert the '$or' / '$and' nodes within a tree into a nested structure
305
271
  * This function will also flatten identical branches (i.e. run-on multiple $and / $or into one array)
@@ -308,27 +274,26 @@ var tools = {
308
274
  */
309
275
  renestConditions: function renestConditions(tree) {
310
276
  if (!_lodash["default"].isArray(tree)) return tree; // Not an array - skip
311
- // Transform arrays of the form: [X1, $or/$and, X2] => {$or/$and: [X1, X2]}
312
277
 
278
+ // Transform arrays of the form: [X1, $or/$and, X2] => {$or/$and: [X1, X2]}
313
279
  return tree.reduce(function (res, branch, index, arr) {
314
280
  var firstKey = (0, _lodash["default"])(branch).keys().first();
315
-
316
281
  if (firstKey == '$or' || firstKey == '$and') {
317
282
  // Is a combinator
318
283
  var expression = {};
319
- expression[firstKey] = [res.pop(), // Right side is the last thing we added to the buffer
284
+ expression[firstKey] = [res.pop(),
285
+ // Right side is the last thing we added to the buffer
320
286
  arr.splice(index + 1, 1)[0] // Left side is the next thing we're going to look at in the array
321
287
  ];
288
+
322
289
  res.push(expression);
323
290
  } else {
324
291
  // Unknown - just push to array and carry on processing
325
292
  res.push(branch);
326
293
  }
327
-
328
294
  return res;
329
295
  }, []);
330
296
  },
331
-
332
297
  /**
333
298
  * Combine multiple run-on $and / $or conditional branches into one branch
334
299
  * This function is a companion function to renestConditions and should be called directly afterwards if needed
@@ -345,25 +310,19 @@ var tools = {
345
310
  var settings = _lodash["default"].defaults(options, {
346
311
  depth: 10
347
312
  });
348
-
349
313
  var collapses = [];
350
-
351
314
  var traverseTree = function traverseTree(branch) {
352
315
  var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
353
-
354
316
  // Recurse into each tree node and make a bottom-up list of nodes we need to collapse
355
317
  _lodash["default"].forEach(branch, function (v, k) {
356
318
  // Use _.map if its an array and _.mapValues if we're examining an object
357
319
  if (_lodash["default"].isObject(v)) {
358
320
  var firstKey = (0, _lodash["default"])(branch).keys().first();
359
-
360
321
  if (path.length > 1 && (firstKey == '$or' || firstKey == '$and')) {
361
322
  // Mark for cleanup later (when we can do a bottom-up traversal)
362
323
  var lastKey = _lodash["default"].findLast(collapses, function (i) {
363
324
  return i.key == '$and' || i.key == '$or';
364
325
  }); // Collapse only identical keys
365
-
366
-
367
326
  if (!lastKey || lastKey.key == firstKey) {
368
327
  collapses.push({
369
328
  key: firstKey,
@@ -371,50 +330,43 @@ var tools = {
371
330
  });
372
331
  }
373
332
  }
374
-
375
333
  if (settings.depth && path.length > settings.depth) return; // Stop recursing after depth has been reached
376
-
377
334
  traverseTree(v, path.concat([k]));
378
335
  }
379
336
  });
380
337
  };
381
-
382
338
  traverseTree(tree);
383
339
  collapses.forEach(function (collapse) {
384
340
  var parent = _lodash["default"].get(tree, collapse.path.slice(0, -1));
385
-
386
341
  var child = _lodash["default"].get(tree, collapse.path.concat([collapse.key]));
387
-
388
342
  if (!child || !parent || !parent.length) return;
389
343
  var child2 = parent[1];
390
- if (child2) child.push(child2); // Wrap $or conditions (that have an '$and' parent) in an object {{{
344
+ if (child2) child.push(child2);
391
345
 
346
+ // Wrap $or conditions (that have an '$and' parent) in an object {{{
392
347
  var lastParent = (0, _lodash["default"])(collapse.path).slice(0, -1).findLast(_lodash["default"].isString);
393
348
  if (lastParent && lastParent == '$and' && collapse.key == '$or') child = {
394
349
  $or: child
395
- }; // }}}
350
+ };
351
+ // }}}
396
352
 
397
353
  _lodash["default"].set(tree, collapse.path.slice(0, -1), child);
398
354
  });
399
355
  return tree;
400
356
  },
401
-
402
357
  /**
403
358
  * Create a tooltip with a specified message
404
359
  * @param {string} content Content to append tooltip to
405
360
  * @param {string} message Message to contain inside tooltip
406
361
  * @param {string} css CSS class to use
407
- */
408
- createTooltip: function createTooltip(content, message, css) {
362
+ */createTooltip: function createTooltip(content, message, css) {
409
363
  css = typeof css !== 'undefined' ? css : "black-underline";
410
364
  return "<span class=\"" + css + '" v-tooltip="`' + message + '`">' + content + '</span>';
411
365
  },
412
-
413
366
  /**
414
367
  * Create a popover with options to replace empty field tags with specified field tag
415
368
  * @param {string} content Content to append popover to
416
- */
417
- createPopover: function createPopover(content, offset) {
369
+ */createPopover: function createPopover(content, offset) {
418
370
  return '<v-popover offset="8" placement="right">' + '<span class="blue-underline">' + content + '</span>' + '<template slot="popover">' + '<h3 class="popover-header">Add Field Tag</h3>' + '<input class="tooltip-content" v-model="customField" placeholder="Field tag" />' + '<div class="replace-all">' + '<input type="checkbox" id="checkbox" v-model="replaceAll">' + '<label for="checkbox">Replace All</label>' + '</div>' + '<div class="replace-buttons">' + '<button v-on:click="replaceFields(customField, replaceAll, ' + offset + ')" type="button" class="btn btn-primary">Replace</button>' + '<button v-close-popover type="button" class="btn btn-dark">Close</button>' + '</div>' + '</template>' + '</v-popover>';
419
371
  }
420
372
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iebh/polyglot",
3
- "version": "4.5.0",
3
+ "version": "4.5.1",
4
4
  "description": "IEBH-SRA tool to convert between different medical database search formats",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -30,7 +30,11 @@
30
30
  "medical",
31
31
  "research"
32
32
  ],
33
- "author": "Matt Carter <m@ttcarter.com> (https://github.com/hash-bang), Connor Forbes <cforbes.software@gmail.com> (https://github.com/connorf25)",
33
+ "author": [
34
+ "Matt Carter <m@ttcarter.com> (https://github.com/hash-bang)",
35
+ "Connor Forbes <cforbes.software@gmail.com> (https://github.com/connorf25)",
36
+ "Justin Cark <jclark@bond.edu.au> (https://github.com/Justin-Clarc)"
37
+ ],
34
38
  "license": "MIT",
35
39
  "bugs": {
36
40
  "url": "https://github.com/IEBH/sra-polyglot/issues"