@iebh/polyglot 4.5.1 → 4.6.2
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/.ignore +1 -1
- package/.vscode/launch.json +36 -0
- package/LICENSE +20 -20
- package/README.md +283 -262
- package/lib/data/fieldCodesObject.js +1 -1
- package/lib/data/meshObject.js +1 -1
- package/lib/data/meshTranslationsObject.js +1 -1
- package/lib/index.js +33 -33
- package/lib/modules/engines/generic.js +24 -11
- package/lib/modules/engines.js +17 -16
- package/lib/modules/global.js +13 -11
- package/lib/modules/parse.js +17 -17
- package/lib/modules/tools.js +88 -67
- package/package.json +60 -58
package/lib/index.js
CHANGED
|
@@ -31,26 +31,26 @@ var _global = _interopRequireDefault(require("./modules/global.js"));
|
|
|
31
31
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
32
32
|
var polyglot;
|
|
33
33
|
var _default = polyglot = {
|
|
34
|
-
/**
|
|
35
|
-
* Translate the given query using the given engine ID
|
|
36
|
-
* This is really just a wrapper for the parse() + engine[ENGINE].compile() pipeline
|
|
37
|
-
* Output will be run via preProcess() + postProcess()
|
|
38
|
-
* @param {string} query The query to translate
|
|
39
|
-
* @param {string} engine The ID of the engine to use
|
|
40
|
-
* @param {Object} options Optional options structure to pass to the engine
|
|
41
|
-
* @return {string} The translated search query
|
|
34
|
+
/**
|
|
35
|
+
* Translate the given query using the given engine ID
|
|
36
|
+
* This is really just a wrapper for the parse() + engine[ENGINE].compile() pipeline
|
|
37
|
+
* Output will be run via preProcess() + postProcess()
|
|
38
|
+
* @param {string} query The query to translate
|
|
39
|
+
* @param {string} engine The ID of the engine to use
|
|
40
|
+
* @param {Object} options Optional options structure to pass to the engine
|
|
41
|
+
* @return {string} The translated search query
|
|
42
42
|
*/
|
|
43
43
|
translate: function translate(query, engine, options) {
|
|
44
44
|
var tree = (0, _parse.parse)(query, options);
|
|
45
45
|
return polyglot.postProcess(_generic["default"].compile(_lodash["default"].cloneDeep(tree), options, engine), options);
|
|
46
46
|
},
|
|
47
|
-
/**
|
|
48
|
-
* Translate the given query using all the supported engines
|
|
49
|
-
* Calling this function instead of individual 'translate()' calls is much more efficient as the tree needs to be compiled only once
|
|
50
|
-
* Output will be run via preProcess() + postProcess()
|
|
51
|
-
* @param {string} query The query to translate
|
|
52
|
-
* @param {Object} options Optional options structure to pass to each engine
|
|
53
|
-
* @return {Object} The translated search query in each case where the engine ID is the key of the object and the value is the translated string
|
|
47
|
+
/**
|
|
48
|
+
* Translate the given query using all the supported engines
|
|
49
|
+
* Calling this function instead of individual 'translate()' calls is much more efficient as the tree needs to be compiled only once
|
|
50
|
+
* Output will be run via preProcess() + postProcess()
|
|
51
|
+
* @param {string} query The query to translate
|
|
52
|
+
* @param {Object} options Optional options structure to pass to each engine
|
|
53
|
+
* @return {Object} The translated search query in each case where the engine ID is the key of the object and the value is the translated string
|
|
54
54
|
*/
|
|
55
55
|
translateAll: function translateAll(query, options) {
|
|
56
56
|
var output = {};
|
|
@@ -62,12 +62,12 @@ var _default = polyglot = {
|
|
|
62
62
|
output['lexicalTreeJSON'] = _engines["default"].lexicalTreeJSON.compile(tree, options), options;
|
|
63
63
|
return output;
|
|
64
64
|
},
|
|
65
|
-
/**
|
|
66
|
-
* Pre-proess the compile tree before it gets handed to each engines compile function
|
|
67
|
-
* @param {Object} tree The tree to compile
|
|
68
|
-
* @param {Object} [options] Additional options - these are provided downstream from the parent 'parse()' function
|
|
69
|
-
* @return {Object} The mutated tree
|
|
70
|
-
* @see parse()
|
|
65
|
+
/**
|
|
66
|
+
* Pre-proess the compile tree before it gets handed to each engines compile function
|
|
67
|
+
* @param {Object} tree The tree to compile
|
|
68
|
+
* @param {Object} [options] Additional options - these are provided downstream from the parent 'parse()' function
|
|
69
|
+
* @return {Object} The mutated tree
|
|
70
|
+
* @see parse()
|
|
71
71
|
*/
|
|
72
72
|
preProcess: function preProcess(tree, options) {
|
|
73
73
|
var settings = _lodash["default"].defaults(options, {});
|
|
@@ -76,18 +76,18 @@ var _default = polyglot = {
|
|
|
76
76
|
|
|
77
77
|
return tree;
|
|
78
78
|
},
|
|
79
|
-
/**
|
|
80
|
-
* Post process the data from an engine
|
|
81
|
-
* This function applies the following behaviours:
|
|
82
|
-
* - If HTML is true all `\n` characters are replaced with `<br/>`
|
|
83
|
-
* - If HTML is false all <span> item wrappers are removed
|
|
84
|
-
* @param {string} text The output from the engine - called from translate() / translateAll()
|
|
85
|
-
* @param {Object} options Options provided during post-processing - these are provided downstream from the parent 'parse()' function
|
|
86
|
-
* @param {boolean} [options.forceString] Force the output to be a string even if the module returns something unusual (e.g. mongodb driver returns an object)
|
|
87
|
-
* @param {boolean} [options.html=true] Provide HTML output
|
|
88
|
-
* @param {boolean} [options.trim=true] Trim all output lines
|
|
89
|
-
* @returns {string} The post processed text
|
|
90
|
-
* @see parse()
|
|
79
|
+
/**
|
|
80
|
+
* Post process the data from an engine
|
|
81
|
+
* This function applies the following behaviours:
|
|
82
|
+
* - If HTML is true all `\n` characters are replaced with `<br/>`
|
|
83
|
+
* - If HTML is false all <span> item wrappers are removed
|
|
84
|
+
* @param {string} text The output from the engine - called from translate() / translateAll()
|
|
85
|
+
* @param {Object} options Options provided during post-processing - these are provided downstream from the parent 'parse()' function
|
|
86
|
+
* @param {boolean} [options.forceString] Force the output to be a string even if the module returns something unusual (e.g. mongodb driver returns an object)
|
|
87
|
+
* @param {boolean} [options.html=true] Provide HTML output
|
|
88
|
+
* @param {boolean} [options.trim=true] Trim all output lines
|
|
89
|
+
* @returns {string} The post processed text
|
|
90
|
+
* @see parse()
|
|
91
91
|
*/
|
|
92
92
|
postProcess: function postProcess(text, options) {
|
|
93
93
|
var settings = _lodash["default"].defaults(options, {
|
|
@@ -11,9 +11,12 @@ var _fieldCodesObject = _interopRequireDefault(require("../../data/fieldCodesObj
|
|
|
11
11
|
var _meshObject = _interopRequireDefault(require("../../data/meshObject.js"));
|
|
12
12
|
var _meshTranslationsObject = _interopRequireDefault(require("../../data/meshTranslationsObject.js"));
|
|
13
13
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
14
|
-
function
|
|
15
|
-
function
|
|
16
|
-
function
|
|
14
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
15
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
16
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
18
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
|
|
19
|
+
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } // Translation Objects
|
|
17
20
|
// Function to fix cinahl exploded mesh (move + sign back before ")
|
|
18
21
|
function fixCinahl(content) {
|
|
19
22
|
content = content.replace(/"\+/, '+"');
|
|
@@ -24,12 +27,12 @@ var _default = {
|
|
|
24
27
|
id: 'generic',
|
|
25
28
|
title: 'generic',
|
|
26
29
|
aliases: ['generic', 'g'],
|
|
27
|
-
/**
|
|
28
|
-
* Compile a tree structure to PubMed output
|
|
29
|
-
* @param {array} tree The parsed tree to process
|
|
30
|
-
* @param {Object} [options] Optional options to use when compiling
|
|
31
|
-
* @param {boolean} [options.replaceWildcards=true] Whether to replace wildcard characters (usually '?' or '$') within phrase nodes with this engines equivelent
|
|
32
|
-
* @return {string} The compiled output
|
|
30
|
+
/**
|
|
31
|
+
* Compile a tree structure to PubMed output
|
|
32
|
+
* @param {array} tree The parsed tree to process
|
|
33
|
+
* @param {Object} [options] Optional options to use when compiling
|
|
34
|
+
* @param {boolean} [options.replaceWildcards=true] Whether to replace wildcard characters (usually '?' or '$') within phrase nodes with this engines equivelent
|
|
35
|
+
* @return {string} The compiled output
|
|
33
36
|
*/
|
|
34
37
|
compile: function compile(tree, options, engine) {
|
|
35
38
|
var settings = _lodash["default"].defaults(options, {
|
|
@@ -62,7 +65,7 @@ var _default = {
|
|
|
62
65
|
}
|
|
63
66
|
}).join("");
|
|
64
67
|
// Fix to move '+' back one space when quoting
|
|
65
|
-
if (engine
|
|
68
|
+
if (engine == "CINAHL (Ebsco)" || engine == "PsycInfo (Ebsco)") {
|
|
66
69
|
content = fixCinahl(content);
|
|
67
70
|
}
|
|
68
71
|
buffer += comment && settings.highlighting ? _tools["default"].createTooltip(content, comment) : content;
|
|
@@ -195,7 +198,7 @@ var _default = {
|
|
|
195
198
|
}
|
|
196
199
|
}).join("");
|
|
197
200
|
// Fix to move '+' back one space when quoting
|
|
198
|
-
if (engine == "CINAHL (Ebsco)") {
|
|
201
|
+
if (engine == "CINAHL (Ebsco)" || engine == "PsycInfo (Ebsco)") {
|
|
199
202
|
content = fixCinahl(content);
|
|
200
203
|
}
|
|
201
204
|
buffer += _comment3 && settings.highlighting ? _tools["default"].createTooltip(content, _comment3) : content;
|
|
@@ -229,6 +232,8 @@ var _default = {
|
|
|
229
232
|
switch (engine) {
|
|
230
233
|
case 'PubMed full':
|
|
231
234
|
case 'PubMed abbreviation':
|
|
235
|
+
//HTA
|
|
236
|
+
case 'International HTA Database':
|
|
232
237
|
buffer += 'AND';
|
|
233
238
|
break;
|
|
234
239
|
case 'Ovid MEDLINE':
|
|
@@ -245,6 +250,9 @@ var _default = {
|
|
|
245
250
|
case 'CINAHL (Ebsco)':
|
|
246
251
|
buffer += "N".concat(branch.proximity);
|
|
247
252
|
break;
|
|
253
|
+
case 'PsycInfo (Ebsco)':
|
|
254
|
+
buffer += "N".concat(branch.proximity);
|
|
255
|
+
break;
|
|
248
256
|
case 'Scopus (basic search)':
|
|
249
257
|
case 'Scopus (advanced search)':
|
|
250
258
|
buffer += "W/".concat(branch.proximity);
|
|
@@ -258,6 +266,8 @@ var _default = {
|
|
|
258
266
|
switch (engine) {
|
|
259
267
|
case 'PubMed full':
|
|
260
268
|
case 'PubMed abbreviation':
|
|
269
|
+
//HTA
|
|
270
|
+
case 'International HTA Database':
|
|
261
271
|
buffer += 'AND';
|
|
262
272
|
break;
|
|
263
273
|
case 'Ovid MEDLINE':
|
|
@@ -277,6 +287,9 @@ var _default = {
|
|
|
277
287
|
case 'CINAHL (Ebsco)':
|
|
278
288
|
buffer += 'W1';
|
|
279
289
|
break;
|
|
290
|
+
case 'PsycInfo (Ebsco)':
|
|
291
|
+
buffer += 'W1';
|
|
292
|
+
break;
|
|
280
293
|
case 'Scopus (basic search)':
|
|
281
294
|
case 'Scopus (advanced search)':
|
|
282
295
|
buffer += 'W/1';
|
package/lib/modules/engines.js
CHANGED
|
@@ -4,17 +4,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports["default"] = void 0;
|
|
7
|
-
/**
|
|
8
|
-
* Collection of supported engines
|
|
9
|
-
* Each engine should specify:
|
|
10
|
-
* title - Human readable name of the engine
|
|
11
|
-
* aliases - Alternative names for each engine
|
|
12
|
-
* compile() - function that takes a parsed tree array and returns a string (string can contain HTML markup of the form <span class="black-underline" v-tooltip="message"> content </span>)
|
|
13
|
-
* open() - optional function that takes a query and provides the direct searching method
|
|
14
|
-
* debugging - optional boolean specifying that the engine is for debugging purposes only
|
|
15
|
-
*
|
|
16
|
-
* @var {array}
|
|
17
|
-
*/
|
|
7
|
+
/**
|
|
8
|
+
* Collection of supported engines
|
|
9
|
+
* Each engine should specify:
|
|
10
|
+
* title - Human readable name of the engine
|
|
11
|
+
* aliases - Alternative names for each engine
|
|
12
|
+
* compile() - function that takes a parsed tree array and returns a string (string can contain HTML markup of the form <span class="black-underline" v-tooltip="message"> content </span>)
|
|
13
|
+
* open() - optional function that takes a query and provides the direct searching method
|
|
14
|
+
* debugging - optional boolean specifying that the engine is for debugging purposes only
|
|
15
|
+
*
|
|
16
|
+
* @var {array}
|
|
17
|
+
*/
|
|
18
|
+
var _default = {
|
|
18
19
|
// Lexical tree (JSON) {{{
|
|
19
20
|
lexicalTreeJSON: {
|
|
20
21
|
id: 'lexicalTreeJSON',
|
|
@@ -23,11 +24,11 @@ exports["default"] = void 0;
|
|
|
23
24
|
debugging: true,
|
|
24
25
|
// Mark this module for debugging only
|
|
25
26
|
|
|
26
|
-
/**
|
|
27
|
-
* Compile a tree structure to JSON output
|
|
28
|
-
* @param {array} tree The parsed tree to process
|
|
29
|
-
* @param {Object} [options] Optional options to use when compiling
|
|
30
|
-
* @return {string} The compiled output
|
|
27
|
+
/**
|
|
28
|
+
* Compile a tree structure to JSON output
|
|
29
|
+
* @param {array} tree The parsed tree to process
|
|
30
|
+
* @param {Object} [options] Optional options to use when compiling
|
|
31
|
+
* @return {string} The compiled output
|
|
31
32
|
*/
|
|
32
33
|
compile: function compile(tree, options) {
|
|
33
34
|
return tree;
|
package/lib/modules/global.js
CHANGED
|
@@ -6,10 +6,10 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports["default"] = void 0;
|
|
7
7
|
// File contains global variables
|
|
8
8
|
var _default = {
|
|
9
|
-
/**
|
|
10
|
-
* List of example search queries
|
|
11
|
-
* See tests/examples.js for the outputs in each case
|
|
12
|
-
* @var {array}
|
|
9
|
+
/**
|
|
10
|
+
* List of example search queries
|
|
11
|
+
* See tests/examples.js for the outputs in each case
|
|
12
|
+
* @var {array}
|
|
13
13
|
*/
|
|
14
14
|
examples: [{
|
|
15
15
|
title: 'Failure of antibiotic prescribing for bacterial infections',
|
|
@@ -35,13 +35,13 @@ var _default = {
|
|
|
35
35
|
no_field_tag: [] // Stores offsets for phrases with no field tags (for replacement)
|
|
36
36
|
},
|
|
37
37
|
|
|
38
|
-
/**
|
|
39
|
-
* List of templates
|
|
40
|
-
* Each key is the (case insensitive; specify in lowercase) keyword used in angular brackets
|
|
41
|
-
* Each value is an object containing 'name', 'description', 'debugging' and an engines object with an additional 'default' key
|
|
42
|
-
* @var {Object}
|
|
43
|
-
* @example
|
|
44
|
-
* {rct: {engines: {default: 'foo', ovid: 'bar'}}} // `<rct>` => 'foo' in most databases and 'bar' in Ovid MEDLINE
|
|
38
|
+
/**
|
|
39
|
+
* List of templates
|
|
40
|
+
* Each key is the (case insensitive; specify in lowercase) keyword used in angular brackets
|
|
41
|
+
* Each value is an object containing 'name', 'description', 'debugging' and an engines object with an additional 'default' key
|
|
42
|
+
* @var {Object}
|
|
43
|
+
* @example
|
|
44
|
+
* {rct: {engines: {default: 'foo', ovid: 'bar'}}} // `<rct>` => 'foo' in most databases and 'bar' in Ovid MEDLINE
|
|
45
45
|
*/
|
|
46
46
|
// TODO: Update templates to match new engines
|
|
47
47
|
templates: {
|
|
@@ -50,6 +50,7 @@ var _default = {
|
|
|
50
50
|
description: 'Standard Cochrane RCT Filter',
|
|
51
51
|
engines: {
|
|
52
52
|
"CINAHL (Ebsco)": '(MH "Clinical Trials+") OR (MH "Quantitative Studies") OR TI placebo* OR AB placebo* OR (MH "Placebos") OR (MH "Random Assignment") OR TI random* OR AB random* OR TI ((singl* or doubl* or tripl* or trebl*) W1 (blind* or mask*)) OR AB ((singl* or doubl* or tripl* or trebl*) W1 (blind* or mask*)) OR TI clinic* trial* OR AB clinic* trial* OR PT clinical trial',
|
|
53
|
+
"PsycInfo (Ebsco)": '(MH "Clinical Trials+") OR (MH "Quantitative Studies") OR TI placebo* OR AB placebo* OR (MH "Placebos") OR (MH "Random Assignment") OR TI random* OR AB random* OR TI ((singl* or doubl* or tripl* or trebl*) W1 (blind* or mask*)) OR AB ((singl* or doubl* or tripl* or trebl*) W1 (blind* or mask*)) OR TI clinic* trial* OR AB clinic* trial* OR PT clinical trial',
|
|
53
54
|
"Embase (Elsevier)": "random* OR factorial OR crossover OR placebo OR blind OR blinded OR assign OR assigned OR allocate OR allocated OR 'crossover procedure'/exp OR 'double-blind procedure'/exp OR 'randomized controlled trial'/exp OR 'single-blind procedure'/exp NOT ('animal'/exp NOT ('animal'/exp AND 'human'/exp))",
|
|
54
55
|
"Ovid MEDLINE": '((randomized controlled trial or controlled clinical trial).pt. or randomized.ab. or randomised.ab. or placebo.ab. or drug therapy.fs. or randomly.ab. or trial.ab. or groups.ab.) not (exp animals/ not humans.sh.)',
|
|
55
56
|
"PsycInfo (Ovid)": 'SU.EXACT("Treatment Effectiveness Evaluation") OR SU.EXACT.EXPLODE("Treatment Outcomes") OR SU.EXACT("Placebo") OR SU.EXACT("Followup Studies") OR placebo* OR random* OR "comparative stud*" OR clinical NEAR/3 trial* OR research NEAR/3 design OR evaluat* NEAR/3 stud* OR prospectiv* NEAR/3 stud* OR (singl* OR doubl* OR trebl* OR tripl*) NEAR/3 (blind* OR mask*)',
|
|
@@ -64,6 +65,7 @@ var _default = {
|
|
|
64
65
|
description: 'Standard Cochrane SR Filter',
|
|
65
66
|
engines: {
|
|
66
67
|
"CINAHL (Ebsco)": 'TI Medline AB Medline OR TI Pubmed AB Pubmed OR (TI systematic AB systematic AND TI review AB review) OR TI meta-analysis OR AB meta-analysis',
|
|
68
|
+
"PsycInfo (Ebsco)": 'TI Medline AB Medline OR TI Pubmed AB Pubmed OR (TI systematic AB systematic AND TI review AB review) OR TI meta-analysis OR AB meta-analysis',
|
|
67
69
|
"Embase (Elsevier)": 'Medline:ti,ab OR Pubmed:ti,ab OR (systematic:ti,ab AND review:ti,ab) OR meta-analysis:pt OR CDSR:jt',
|
|
68
70
|
"Ovid MEDLINE": 'search:.tw.OR meta analysis.mp,pt.OR review.pt.OR di.xs. OR associated.tw.',
|
|
69
71
|
"PubMed full": 'search*[Title/Abstract] OR meta analysis[Publication Type] OR meta analysis[Title/Abstract] OR meta analysis[MeSH] OR review[Publication Type] OR diagnosis[MeSH Subheading] OR associated[Title/Abstract]',
|
package/lib/modules/parse.js
CHANGED
|
@@ -17,17 +17,17 @@ function escapeRegExp(string) {
|
|
|
17
17
|
return string.replace(/[.*+?^${}()[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
/**
|
|
21
|
-
* Parse a given string into a lexical object tree
|
|
22
|
-
* This tree can then be recompiled via each engines compile()
|
|
23
|
-
* @param {string} query The query string to compile. This can be multiline
|
|
24
|
-
* @param {Object} [options] Optional options to use when parsing
|
|
25
|
-
* @param {boolean} [options.groupLines=false] Wrap lines inside their own groups (only applies if multiple lines are present)
|
|
26
|
-
* @param {boolean} [options.groupLinesAlways=true] Group lines even if there is only one apparent line (i.e. enclose single line queries within brackets)
|
|
27
|
-
* @param {boolean} [options.transposeLines=true] Insert all line references where needed (e.g. `1 - 3/OR`)
|
|
28
|
-
* @param {boolean} [options.removeNumbering=true] Remove any number prefixes from lines - this is a classic copy/paste error from certain online search engines (e.g. `1. Term` -> `term`)
|
|
29
|
-
* @param {boolean} [options.preserveNewlines=true] Preserve newlines in the output as 'raw' tree nodes
|
|
30
|
-
* @return {array} Array representing the parsed tree nodes
|
|
20
|
+
/**
|
|
21
|
+
* Parse a given string into a lexical object tree
|
|
22
|
+
* This tree can then be recompiled via each engines compile()
|
|
23
|
+
* @param {string} query The query string to compile. This can be multiline
|
|
24
|
+
* @param {Object} [options] Optional options to use when parsing
|
|
25
|
+
* @param {boolean} [options.groupLines=false] Wrap lines inside their own groups (only applies if multiple lines are present)
|
|
26
|
+
* @param {boolean} [options.groupLinesAlways=true] Group lines even if there is only one apparent line (i.e. enclose single line queries within brackets)
|
|
27
|
+
* @param {boolean} [options.transposeLines=true] Insert all line references where needed (e.g. `1 - 3/OR`)
|
|
28
|
+
* @param {boolean} [options.removeNumbering=true] Remove any number prefixes from lines - this is a classic copy/paste error from certain online search engines (e.g. `1. Term` -> `term`)
|
|
29
|
+
* @param {boolean} [options.preserveNewlines=true] Preserve newlines in the output as 'raw' tree nodes
|
|
30
|
+
* @return {array} Array representing the parsed tree nodes
|
|
31
31
|
*/
|
|
32
32
|
var parse = function parse(query, options) {
|
|
33
33
|
var settings = _lodash["default"].defaults(options, {
|
|
@@ -81,9 +81,9 @@ var parse = function parse(query, options) {
|
|
|
81
81
|
// }}}
|
|
82
82
|
|
|
83
83
|
// Utility functions {{{
|
|
84
|
-
/**
|
|
85
|
-
* Trim previous leaf content if it has any text
|
|
86
|
-
* The leaf will be removed completely if it is now blank
|
|
84
|
+
/**
|
|
85
|
+
* Trim previous leaf content if it has any text
|
|
86
|
+
* The leaf will be removed completely if it is now blank
|
|
87
87
|
*/
|
|
88
88
|
function trimLastLeaf() {
|
|
89
89
|
if (leaf && _lodash["default"].includes(['phrase', 'raw'], leaf.type) && / $/.test(leaf.content)) {
|
|
@@ -92,9 +92,9 @@ var parse = function parse(query, options) {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
;
|
|
95
|
-
/**
|
|
96
|
-
* End the previous line branch and create a new one
|
|
97
|
-
* this function is run every time a new raw node is inserted
|
|
95
|
+
/**
|
|
96
|
+
* End the previous line branch and create a new one
|
|
97
|
+
* this function is run every time a new raw node is inserted
|
|
98
98
|
*/
|
|
99
99
|
function newLine(currentNumber) {
|
|
100
100
|
lastGroup = branch;
|
package/lib/modules/tools.js
CHANGED
|
@@ -7,19 +7,19 @@ exports["default"] = void 0;
|
|
|
7
7
|
var _global = _interopRequireDefault(require("./global.js"));
|
|
8
8
|
var _lodash = _interopRequireDefault(require("lodash"));
|
|
9
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
|
|
10
|
-
/**
|
|
11
|
-
* Collection of utility functions to apply common behaviour to a compiled tree
|
|
12
|
-
* @var {Object}
|
|
10
|
+
/**
|
|
11
|
+
* Collection of utility functions to apply common behaviour to a compiled tree
|
|
12
|
+
* @var {Object}
|
|
13
13
|
*/
|
|
14
14
|
var tools = {
|
|
15
|
-
/**
|
|
16
|
-
* Visit the given node types within a deeply nested tree and run a function
|
|
17
|
-
* This function may mutate the input tree depending on the actions of the callbacks
|
|
18
|
-
* NOTE: If the return value of the callback is `"DEL"` the node is deleted
|
|
19
|
-
* @param {array} tree The tree sturcture to operate on
|
|
20
|
-
* @param {null|array} types Node filter to apply to (if falsy all are used)
|
|
21
|
-
* @param {function} callback The callback to call with each node. Called as (node, path)
|
|
22
|
-
* @return {array} The input tree
|
|
15
|
+
/**
|
|
16
|
+
* Visit the given node types within a deeply nested tree and run a function
|
|
17
|
+
* This function may mutate the input tree depending on the actions of the callbacks
|
|
18
|
+
* NOTE: If the return value of the callback is `"DEL"` the node is deleted
|
|
19
|
+
* @param {array} tree The tree sturcture to operate on
|
|
20
|
+
* @param {null|array} types Node filter to apply to (if falsy all are used)
|
|
21
|
+
* @param {function} callback The callback to call with each node. Called as (node, path)
|
|
22
|
+
* @return {array} The input tree
|
|
23
23
|
*/
|
|
24
24
|
visit: function visit(tree, types, callback) {
|
|
25
25
|
var removals = []; // Stack of removal paths we are performing when done
|
|
@@ -49,13 +49,13 @@ var tools = {
|
|
|
49
49
|
});
|
|
50
50
|
return tree;
|
|
51
51
|
},
|
|
52
|
-
/**
|
|
53
|
-
* Apply a series of text replacements to every matching node object within a tree
|
|
54
|
-
* This function mutates tree
|
|
55
|
-
* @param {array} tree The tree sturcture to operate on
|
|
56
|
-
* @param {null|array} types Type filter to apply. If falsy all are used
|
|
57
|
-
* @param {array} replacements Array of replacements to apply. Each must be of the form `{subject: STRING|REGEXP, value: STRING|FUNCTION}`
|
|
58
|
-
* @return {array} The input tree element with the replacements applied
|
|
52
|
+
/**
|
|
53
|
+
* Apply a series of text replacements to every matching node object within a tree
|
|
54
|
+
* This function mutates tree
|
|
55
|
+
* @param {array} tree The tree sturcture to operate on
|
|
56
|
+
* @param {null|array} types Type filter to apply. If falsy all are used
|
|
57
|
+
* @param {array} replacements Array of replacements to apply. Each must be of the form `{subject: STRING|REGEXP, value: STRING|FUNCTION}`
|
|
58
|
+
* @return {array} The input tree element with the replacements applied
|
|
59
59
|
*/
|
|
60
60
|
replaceContent: function replaceContent(tree, types, replacements) {
|
|
61
61
|
this.visit(tree, types, function (branch) {
|
|
@@ -83,12 +83,12 @@ var tools = {
|
|
|
83
83
|
return text;
|
|
84
84
|
}
|
|
85
85
|
},
|
|
86
|
-
/**
|
|
87
|
-
* Retrieve the contents of a template by its ID
|
|
88
|
-
* NOTE: If the specific engine definition is not found 'default' is used (and it will be pre-parsed via .translate())
|
|
89
|
-
* @param {string} template The template to resolve
|
|
90
|
-
* @param {string} engine The current engine (used to get the correct sub-templating string)
|
|
91
|
-
* @return {string} The resolved template
|
|
86
|
+
/**
|
|
87
|
+
* Retrieve the contents of a template by its ID
|
|
88
|
+
* NOTE: If the specific engine definition is not found 'default' is used (and it will be pre-parsed via .translate())
|
|
89
|
+
* @param {string} template The template to resolve
|
|
90
|
+
* @param {string} engine The current engine (used to get the correct sub-templating string)
|
|
91
|
+
* @return {string} The resolved template
|
|
92
92
|
*/
|
|
93
93
|
resolveTemplate: function resolveTemplate(template, engine) {
|
|
94
94
|
if (!_global["default"].templates[template]) return 'UNKNOWN-TEMPLATE:' + template;
|
|
@@ -97,11 +97,11 @@ var tools = {
|
|
|
97
97
|
if (!_global["default"].templates[template].engines[engine]) return "Template: \"".concat(template, "\" not found for engine: \"").concat(engine, "\"");
|
|
98
98
|
return '';
|
|
99
99
|
},
|
|
100
|
-
/**
|
|
101
|
-
* Structure the wild cards correctly for cochrane to ensure no wildcards appear inside quotation marks
|
|
102
|
-
* @param {string} text The text to parse
|
|
103
|
-
* @param {Boolean} highlighting Whether to assign custom fonts
|
|
104
|
-
* @return {string} The parsed string seperated by NEXT
|
|
100
|
+
/**
|
|
101
|
+
* Structure the wild cards correctly for cochrane to ensure no wildcards appear inside quotation marks
|
|
102
|
+
* @param {string} text The text to parse
|
|
103
|
+
* @param {Boolean} highlighting Whether to assign custom fonts
|
|
104
|
+
* @return {string} The parsed string seperated by NEXT
|
|
105
105
|
*/
|
|
106
106
|
wildCardCochrane: function wildCardCochrane(text, highlighting) {
|
|
107
107
|
var wildcards = ["?", "$", "*"];
|
|
@@ -141,12 +141,13 @@ var tools = {
|
|
|
141
141
|
}
|
|
142
142
|
return foundMatch ? "(".concat(words.join(" "), ")") : words.join(" ");
|
|
143
143
|
},
|
|
144
|
-
/**
|
|
145
|
-
* Print number in format defined by engine
|
|
146
|
-
* @param {string} engine Engine to use
|
|
147
|
-
* @param {string} ref Branch ref (e.g. 1)
|
|
148
|
-
* @return {string} Formatted number
|
|
149
|
-
*/
|
|
144
|
+
/**
|
|
145
|
+
* Print number in format defined by engine
|
|
146
|
+
* @param {string} engine Engine to use
|
|
147
|
+
* @param {string} ref Branch ref (e.g. 1)
|
|
148
|
+
* @return {string} Formatted number
|
|
149
|
+
*/
|
|
150
|
+
printNumber: function printNumber(engine, ref) {
|
|
150
151
|
// Get line number format for engine
|
|
151
152
|
var number = ref;
|
|
152
153
|
switch (engine) {
|
|
@@ -158,6 +159,8 @@ var tools = {
|
|
|
158
159
|
case 'WoS Advanced':
|
|
159
160
|
case 'Scopus (basic search)':
|
|
160
161
|
case 'Scopus (advanced search)':
|
|
162
|
+
//HTA
|
|
163
|
+
case 'International HTA Database':
|
|
161
164
|
number = "#" + ref;
|
|
162
165
|
break;
|
|
163
166
|
case 'Ovid MEDLINE':
|
|
@@ -166,6 +169,7 @@ var tools = {
|
|
|
166
169
|
number = ref;
|
|
167
170
|
break;
|
|
168
171
|
case 'CINAHL (Ebsco)':
|
|
172
|
+
case 'PsycInfo (Ebsco)':
|
|
169
173
|
case 'SPORTDiscus':
|
|
170
174
|
number = "S" + ref;
|
|
171
175
|
break;
|
|
@@ -173,12 +177,12 @@ var tools = {
|
|
|
173
177
|
}
|
|
174
178
|
return number;
|
|
175
179
|
},
|
|
176
|
-
/**
|
|
177
|
-
* Determine if a phrase needs to be enclosed within speachmarks and return the result
|
|
178
|
-
* @param {Object} branch Phrase branch to examine
|
|
179
|
-
* @param {string} engine Optional engine ID to examine for other enclose methods
|
|
180
|
-
* @param {boolean} highlighting Optional bool to determine if html color styling is added
|
|
181
|
-
* @return {string} The phrase enclosed as needed
|
|
180
|
+
/**
|
|
181
|
+
* Determine if a phrase needs to be enclosed within speachmarks and return the result
|
|
182
|
+
* @param {Object} branch Phrase branch to examine
|
|
183
|
+
* @param {string} engine Optional engine ID to examine for other enclose methods
|
|
184
|
+
* @param {boolean} highlighting Optional bool to determine if html color styling is added
|
|
185
|
+
* @return {string} The phrase enclosed as needed
|
|
182
186
|
*/
|
|
183
187
|
quotePhrase: function quotePhrase(branch, engine, settings) {
|
|
184
188
|
var text = _lodash["default"].trimEnd(branch.content);
|
|
@@ -225,6 +229,13 @@ var tools = {
|
|
|
225
229
|
'#': '?'
|
|
226
230
|
};
|
|
227
231
|
break;
|
|
232
|
+
case 'PsycInfo (Ebsco)':
|
|
233
|
+
replaceObj = {
|
|
234
|
+
'$': '?',
|
|
235
|
+
'?': '#',
|
|
236
|
+
'#': '?'
|
|
237
|
+
};
|
|
238
|
+
break;
|
|
228
239
|
case 'Scopus (basic search)':
|
|
229
240
|
case 'Scopus (advanced search)':
|
|
230
241
|
// space = true; //Always include quotes with scopus to make phrase a "loose phrase"
|
|
@@ -261,16 +272,24 @@ var tools = {
|
|
|
261
272
|
'?': '*1'
|
|
262
273
|
};
|
|
263
274
|
break;
|
|
275
|
+
//HTA
|
|
276
|
+
case 'International HTA Database':
|
|
277
|
+
replaceObj = {
|
|
278
|
+
'$': settings.highlighting ? tools.createTooltip("*", "As INAHTA does not support single character truncation a wildcard is used here", "highlight") : '*',
|
|
279
|
+
'?': settings.highlighting ? tools.createTooltip("*", "As INAHTA does not support single character truncation a wildcard is used here", "highlight") : '*',
|
|
280
|
+
'#': settings.highlighting ? tools.createTooltip("*", "As INAHTA does not support single character truncation a wildcard is used here", "highlight") : '*'
|
|
281
|
+
};
|
|
282
|
+
break;
|
|
264
283
|
}
|
|
265
284
|
text = tools.multiReplace(text, replaceObj);
|
|
266
285
|
}
|
|
267
286
|
return engine == 'Embase (Elsevier)' ? space ? settings.highlighting ? "<font color='DarkBlue'>'" + text + "'</font>" : "'" + text + "'" : text : space ? settings.highlighting ? '<font color="DarkBlue">"' + text + '"</font>' : '"' + text + '"' : text;
|
|
268
287
|
},
|
|
269
|
-
/**
|
|
270
|
-
* Convert the '$or' / '$and' nodes within a tree into a nested structure
|
|
271
|
-
* This function will also flatten identical branches (i.e. run-on multiple $and / $or into one array)
|
|
272
|
-
* @param {Object} tree The object tree to recombine
|
|
273
|
-
* @returns {Object} The recombined tree
|
|
288
|
+
/**
|
|
289
|
+
* Convert the '$or' / '$and' nodes within a tree into a nested structure
|
|
290
|
+
* This function will also flatten identical branches (i.e. run-on multiple $and / $or into one array)
|
|
291
|
+
* @param {Object} tree The object tree to recombine
|
|
292
|
+
* @returns {Object} The recombined tree
|
|
274
293
|
*/
|
|
275
294
|
renestConditions: function renestConditions(tree) {
|
|
276
295
|
if (!_lodash["default"].isArray(tree)) return tree; // Not an array - skip
|
|
@@ -294,17 +313,17 @@ var tools = {
|
|
|
294
313
|
return res;
|
|
295
314
|
}, []);
|
|
296
315
|
},
|
|
297
|
-
/**
|
|
298
|
-
* Combine multiple run-on $and / $or conditional branches into one branch
|
|
299
|
-
* This function is a companion function to renestConditions and should be called directly afterwards if needed
|
|
300
|
-
* @param {Object} tree The tree to traverse
|
|
301
|
-
* @param {Object} [options] Additional options to accept
|
|
302
|
-
* @param {number} [options.depth=10] The maximum depth to traverse before giving up, set to 0 to infinitely recurse
|
|
303
|
-
* @return {Object} The collapsed tree
|
|
304
|
-
* @example
|
|
305
|
-
* {left, joinAnd, right} => {joinAnd: [left, right]}
|
|
306
|
-
* @example
|
|
307
|
-
* {foo, joinOr, bar, joinOr, baz} => {joinOr: [foo, bar, baz]}
|
|
316
|
+
/**
|
|
317
|
+
* Combine multiple run-on $and / $or conditional branches into one branch
|
|
318
|
+
* This function is a companion function to renestConditions and should be called directly afterwards if needed
|
|
319
|
+
* @param {Object} tree The tree to traverse
|
|
320
|
+
* @param {Object} [options] Additional options to accept
|
|
321
|
+
* @param {number} [options.depth=10] The maximum depth to traverse before giving up, set to 0 to infinitely recurse
|
|
322
|
+
* @return {Object} The collapsed tree
|
|
323
|
+
* @example
|
|
324
|
+
* {left, joinAnd, right} => {joinAnd: [left, right]}
|
|
325
|
+
* @example
|
|
326
|
+
* {foo, joinOr, bar, joinOr, baz} => {joinOr: [foo, bar, baz]}
|
|
308
327
|
*/
|
|
309
328
|
combineConditions: function combineConditions(tree, options) {
|
|
310
329
|
var settings = _lodash["default"].defaults(options, {
|
|
@@ -354,19 +373,21 @@ var tools = {
|
|
|
354
373
|
});
|
|
355
374
|
return tree;
|
|
356
375
|
},
|
|
357
|
-
/**
|
|
358
|
-
* Create a tooltip with a specified message
|
|
359
|
-
* @param {string} content Content to append tooltip to
|
|
360
|
-
* @param {string} message Message to contain inside tooltip
|
|
361
|
-
* @param {string} css CSS class to use
|
|
362
|
-
*/
|
|
376
|
+
/**
|
|
377
|
+
* Create a tooltip with a specified message
|
|
378
|
+
* @param {string} content Content to append tooltip to
|
|
379
|
+
* @param {string} message Message to contain inside tooltip
|
|
380
|
+
* @param {string} css CSS class to use
|
|
381
|
+
*/
|
|
382
|
+
createTooltip: function createTooltip(content, message, css) {
|
|
363
383
|
css = typeof css !== 'undefined' ? css : "black-underline";
|
|
364
384
|
return "<span class=\"" + css + '" v-tooltip="`' + message + '`">' + content + '</span>';
|
|
365
385
|
},
|
|
366
|
-
/**
|
|
367
|
-
* Create a popover with options to replace empty field tags with specified field tag
|
|
368
|
-
* @param {string} content Content to append popover to
|
|
369
|
-
*/
|
|
386
|
+
/**
|
|
387
|
+
* Create a popover with options to replace empty field tags with specified field tag
|
|
388
|
+
* @param {string} content Content to append popover to
|
|
389
|
+
*/
|
|
390
|
+
createPopover: function createPopover(content, offset) {
|
|
370
391
|
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>';
|
|
371
392
|
}
|
|
372
393
|
};
|