@iebh/polyglot
Version:
IEBH-SRA tool to convert between different medical database search formats
355 lines (354 loc) • 17.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _tools = _interopRequireDefault(require("../tools.js"));
var _global = _interopRequireDefault(require("../global.js"));
var _lodash = _interopRequireDefault(require("lodash"));
var _fieldCodesObject = _interopRequireDefault(require("../../data/fieldCodesObject.js"));
var _meshObject = _interopRequireDefault(require("../../data/meshObject.js"));
var _meshTranslationsObject = _interopRequireDefault(require("../../data/meshTranslationsObject.js"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
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); }
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; }
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; }
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; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
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
// Function to fix cinahl exploded mesh (move + sign back before ")
function fixCinahl(content) {
content = content.replace(/"\+/, '+"');
content = content.replace(/"<\/font><font color="blue">\+/, '+"</font><font color="blue">');
return content;
}
var _default = {
id: 'generic',
title: 'generic',
aliases: ['generic', 'g'],
/**
* Compile a tree structure to PubMed output
* @param {array} tree The parsed tree to process
* @param {Object} [options] Optional options to use when compiling
* @param {boolean} [options.replaceWildcards=true] Whether to replace wildcard characters (usually '?' or '$') within phrase nodes with this engines equivelent
* @return {string} The compiled output
*/
compile: function compile(tree, options, engine) {
var settings = _lodash["default"].defaults(options, {
replaceWildcards: true,
testing: false
});
var compileWalker = function compileWalker(tree) {
return tree.map(function (branch, branchIndex) {
var buffer = '';
switch (branch.type) {
case 'line':
buffer += compileWalker(branch.nodes);
break;
case 'group':
if (branch.field) {
if (engine === "Ovid MEDLINE" || engine === "Scopus (advanced search)" || engine === "Embase (Elsevier)" || engine === "WoS Advanced") {
// Put field code outside brackets
if (branch.field.match(/mesh/i)) {
var translateObject = _meshObject["default"][engine] ? _meshObject["default"][engine][branch.field] : null;
var termArray = translateObject.terms;
var comment = translateObject.comment;
var content = termArray.map(function (el) {
if (el && el.toLowerCase() !== "test") {
return settings.highlighting ? "<font color=\"blue\">".concat(el, "</font>") : el;
} else if (el && el.toLowerCase() === "test") {
return _tools["default"].quotePhrase(branch, engine, settings);
} else {
// Empty string
return el;
}
}).join("");
// Fix to move '+' back one space when quoting
if (engine == "CINAHL (Ebsco)" || engine == "PsycInfo (Ebsco)" || engine == "Business Source Ultimate") {
content = fixCinahl(content);
}
buffer += comment && settings.highlighting ? _tools["default"].createTooltip(content, comment) : content;
} else {
var translateObject = _fieldCodesObject["default"][engine] ? _fieldCodesObject["default"][engine][branch.field] : null;
if (translateObject) {
var _termArray = translateObject.terms;
var _comment = translateObject.comment;
var _content = _termArray.map(function (el) {
if (el && el.toLowerCase() !== "test") {
return settings.highlighting ? "<font color=\"LightSeaGreen\">".concat(el, "</font>") : el;
} else if (el && el.toLowerCase() === "test") {
return engine === "Scopus (advanced search)" ? compileWalker(branch.nodes) : '(' + compileWalker(branch.nodes) + ')';
} else {
// Empty string
return el;
}
}).join("");
buffer += _comment && settings.highlighting ? _tools["default"].createTooltip(_content, _comment) : _content;
}
}
} else {
// Expand field code inside brackets for other engines
// If the group has a filter decorate all its children with that field
// This mutates the tree for the other engine compile functions
var isMesh = branch.field.match(/mesh/i);
branch.nodes = _tools["default"].visit(branch.nodes, ['phrase'], function (b) {
if (isMesh) {
b.type = 'mesh';
}
b.field = branch.field;
});
branch.nodes = _tools["default"].visit(branch.nodes, ['group'], function (b) {
return b.field = branch.field;
});
buffer += '(' + compileWalker(branch.nodes) + ')';
}
} else {
buffer += '(' + compileWalker(branch.nodes) + ')';
}
break;
case 'ref':
if (settings.transposeLines) {
// Expand each line to show full query
var node;
for (node in branch.nodes) {
if (node == 0) {
// First line is printed as is wrapped in brackets
buffer += '(' + compileWalker(branch.nodes[node]) + ')';
} else {
// Remaining lines are appended with the condition
buffer += ' ' + branch.cond + ' (' + compileWalker(branch.nodes[node]) + ')';
}
}
} else {
// Only print each line number in format defined by engine
// If branch.ref is array then user specified OR/1-4
if (Array.isArray(branch.ref)) {
for (node in branch.ref) {
if (node == 0) {
buffer += _tools["default"].printNumber(engine, branch.ref[node]);
} else {
buffer += ' ' + branch.cond + ' ' + _tools["default"].printNumber(engine, branch.ref[node]);
}
}
} else {
buffer += _tools["default"].printNumber(engine, branch.ref);
}
}
break;
case 'phrase':
if (branch.field) {
var translateObject = _fieldCodesObject["default"][engine] ? _fieldCodesObject["default"][engine][branch.field] : null;
if (translateObject) {
var _termArray2 = translateObject.terms;
var _comment2 = translateObject.comment;
var _content2 = _termArray2.map(function (el) {
if (el && el.toLowerCase() !== "test") {
return settings.highlighting ? "<font color=\"LightSeaGreen\">".concat(el, "</font>") : el;
} else if (el && el.toLowerCase() === "test") {
return _tools["default"].quotePhrase(branch, engine, settings);
} else {
// Empty string
return el;
}
}).join("");
buffer += _comment2 && settings.highlighting ? _tools["default"].createTooltip(_content2, _comment2) : _content2;
} else {
buffer += _tools["default"].createTooltip('<font color="#ff6161">' + _tools["default"].quotePhrase(branch, engine, _objectSpread(_objectSpread({}, settings), {}, {
highlighting: false
})) + '</font>', "No field tag found for engine");
}
} else {
// If no field tag exists create popover with ability to replace field tag
if (_global["default"].variables.no_field_tag.indexOf(branch.offset + branch.content.length) === -1) {
_global["default"].variables.no_field_tag.push(branch.offset + branch.content.length);
}
if (settings.highlighting) {
buffer += _tools["default"].createPopover(_tools["default"].quotePhrase(branch, engine, settings), branch.offset + branch.content.length);
} else {
buffer += _tools["default"].quotePhrase(branch, engine, settings);
}
}
break;
case 'mesh':
var translateObject = _meshObject["default"][engine] ? _meshObject["default"][engine][branch.field] : null;
if (translateObject) {
var _termArray3 = translateObject.terms;
var _comment3 = translateObject.comment;
var containsHeading = false;
var content = _termArray3.map(function (el) {
if (el && el.toLowerCase() !== "test") {
// If heading already exists dont add second / at end (for ovid)
if (containsHeading && el == "/") {
return "";
}
return settings.highlighting ? "<font color=\"blue\">".concat(el, "</font>") : el;
} else if (el && el.toLowerCase() === "test") {
// Perform logic for the phrase in the mesh
var phrase = _tools["default"].quotePhrase(branch, engine, settings);
// If a subheading exists (e.g. psoriasis/dt)
if (branch.heading) {
containsHeading = true;
phrase += settings.highlighting ? _tools["default"].createTooltip("/" + branch.heading, "Subheading may need to be manually translated", "red-underline") : "/" + branch.heading;
}
return phrase;
} else {
// Empty string
return el;
}
}).join("");
// Fix to move '+' back one space when quoting
if (engine == "CINAHL (Ebsco)" || engine == "PsycInfo (Ebsco)" || engine == "Business Source Ultimate") {
content = fixCinahl(content);
}
buffer += _comment3 && settings.highlighting ? _tools["default"].createTooltip(content, _comment3) : content;
} else {
buffer += _tools["default"].createTooltip('<font color="#ff6161">' + _tools["default"].quotePhrase(branch, engine, _objectSpread(_objectSpread({}, settings), {}, {
highlighting: false
})) + '</font>', "No mesh tag found for engine");
}
break;
case 'meshTranslation':
var translateObject = _meshTranslationsObject["default"][engine] ? _meshTranslationsObject["default"][engine][branch.field] : null;
if (translateObject) {
var _termArray4 = translateObject.terms;
var _comment4 = translateObject.comment;
var _content3 = _termArray4.map(function (el) {
if (el && el.toLowerCase() !== "test") {
return settings.highlighting ? "<font color=\"purple\">".concat(el, "</font>") : el;
} else {
// Empty string
return el;
}
}).join("");
buffer += _comment4 && settings.highlighting ? _tools["default"].createTooltip(_content3, _comment4) : _content3;
} else {
buffer += _tools["default"].createTooltip('<font color="#ff6161">' + _tools["default"].quotePhrase(branch, engine, _objectSpread(_objectSpread({}, settings), {}, {
highlighting: false
})) + '</font>', "No mesh tag found for engine");
}
break;
case 'joinNear':
switch (engine) {
case 'PubMed full':
case 'PubMed abbreviation':
//HTA
case 'International HTA Database':
buffer += 'AND';
break;
case 'Ovid MEDLINE':
case 'PsycInfo (Ovid)':
buffer += "ADJ".concat(branch.proximity);
break;
case 'Cochrane Library':
case 'Embase (Elsevier)':
case 'Web of Science':
case 'WoS Advanced':
case 'ProQuest Health and Medical':
buffer += "NEAR/".concat(branch.proximity);
break;
case 'CINAHL (Ebsco)':
buffer += "N".concat(branch.proximity);
break;
case 'Business Source Ultimate':
buffer += "N".concat(branch.proximity);
break;
case 'PsycInfo (Ebsco)':
buffer += "N".concat(branch.proximity);
break;
case 'Scopus (basic search)':
case 'Scopus (advanced search)':
buffer += "W/".concat(branch.proximity);
break;
case 'SPORTDiscus':
buffer += "N".concat(branch.proximity);
break;
}
break;
case 'joinNext':
switch (engine) {
case 'PubMed full':
case 'PubMed abbreviation':
//HTA
case 'International HTA Database':
buffer += 'AND';
break;
case 'Ovid MEDLINE':
case 'PsycInfo (Ovid)':
buffer += 'ADJ';
break;
case 'Cochrane Library':
buffer += 'NEXT';
break;
case 'Embase (Elsevier)':
buffer += 'NEXT/1';
break;
case 'Web of Science':
case 'WoS Advanced':
buffer += 'NEAR/0';
break;
case 'CINAHL (Ebsco)':
buffer += 'W1';
break;
case 'Business Source Ultimate':
buffer += 'W1';
break;
case 'PsycInfo (Ebsco)':
buffer += 'W1';
break;
case 'Scopus (basic search)':
case 'Scopus (advanced search)':
buffer += 'W/1';
break;
case 'SPORTDiscus':
buffer += 'W1';
break;
case 'ProQuest Health and Medical':
buffer += 'PRE/0';
}
break;
case 'joinAnd':
buffer += 'AND';
break;
case 'joinOr':
buffer += 'OR';
break;
case 'joinNot':
buffer += 'NOT';
break;
case 'raw':
buffer += branch.content;
break;
case 'template':
buffer += _tools["default"].resolveTemplate(branch.content, engine);
break;
case 'comment':
// Do nothing
break;
default:
throw new Error('Unsupported object tree type: ' + branch.type);
}
return buffer
// Add spacing provided... its not a raw buffer or the last entity within the structure
+ (branch.type == 'raw' ||
// Its not a raw node
branch.type == 'line' ||
// Its not a line node
branchIndex == tree.length - 1 ||
// Its not the last item in the sequence
branchIndex < tree.length - 1 && tree[branchIndex + 1] && tree[branchIndex + 1].type && tree[branchIndex + 1].type == 'raw' ? '' : ' ');
}).join('');
};
return compileWalker(tree);
},
open: function open(query) {
return {
method: 'GET',
action: 'https://www.ncbi.nlm.nih.gov/pubmed',
fields: {
term: query
}
};
},
openTerms: 'any search box'
};
exports["default"] = _default;