@iebh/polyglot 5.2.0 → 5.3.0

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.
@@ -1,78 +1,78 @@
1
- import xlsx from 'xlsx';
2
-
3
- var sheetToArr = function(sheet){
4
- var result = [];
5
- var row;
6
- var rowNum;
7
- var colNum;
8
- var range = xlsx.utils.decode_range(sheet['!ref']);
9
- for(rowNum = range.s.r + 1; rowNum <= range.e.r; rowNum++) {
10
- row = {};
11
- for(colNum = range.s.c; colNum <= range.e.c; colNum++) {
12
- var nextCell = sheet[
13
- xlsx.utils.encode_cell({r: rowNum, c: colNum})
14
- ];
15
- var key = sheet[
16
- xlsx.utils.encode_cell({r: range.s.r, c: colNum})
17
- ].w;
18
- if(key && nextCell) {
19
- row[key] = nextCell
20
- }
21
- }
22
- if(Object.keys(row).length > 0) {
23
- result.push(row);
24
- }
25
- }
26
- return result;
27
- };
28
-
29
- export default settings => {
30
- /**
31
- * Collection of row sources to use when running a test
32
- * This is calculated from the input data
33
- * @type {array<Object>} Collection of sources extracted from the input data
34
- * @property {string} id The row ID to use to extract data per line
35
- */
36
- var sources;
37
- return Promise.resolve()
38
- .then(()=> xlsx.readFile(`./v4.xlsx`))
39
- .then(workbook => {
40
- return sheetToArr(workbook.Sheets[settings.sheet]);
41
- })
42
- // Extract source rows to aim for from the data set
43
- .then(sheet => {
44
- // Calculate sources
45
- sources = Object.keys(sheet[0])
46
- .filter(header =>
47
- ![...settings.omitCols, settings.rowHeader].includes(header) // Skip omitted columns
48
- )
49
- .map(header => ({
50
- id: header
51
- }));
52
- // Return sliced data - removing all header areas
53
- return sheet.slice(settings.dataRowStart); // Remove first row
54
- })
55
- // Create lookup map
56
- .then(sheet => {
57
- let engineObject = {};
58
- sources.forEach(source => {
59
- engineObject[source.id] = {};
60
- sheet.forEach((row, rowIndex) => {
61
- if(row[source.id]) {
62
- if (!engineObject[source.id][row[settings.rowHeader]]?.w) {
63
- let termArray = row[source.id].w.split(/(Test)/g)
64
- engineObject[source.id][row[settings.rowHeader].w] = {
65
- terms: termArray,
66
- comment: row[source.id].c ? row[source.id].c[0]?.t : undefined
67
- };
68
- } else {
69
- console.log("Duplicate key:", row[settings.rowHeader].w);
70
- }
71
- } else {
72
- console.error(`\n${source.id}'s "${row[settings.rowHeader].w}" is undefined\n`)
73
- }
74
- })
75
- })
76
- return engineObject;
77
- })
1
+ import xlsx from 'xlsx';
2
+
3
+ var sheetToArr = function(sheet){
4
+ var result = [];
5
+ var row;
6
+ var rowNum;
7
+ var colNum;
8
+ var range = xlsx.utils.decode_range(sheet['!ref']);
9
+ for(rowNum = range.s.r + 1; rowNum <= range.e.r; rowNum++) {
10
+ row = {};
11
+ for(colNum = range.s.c; colNum <= range.e.c; colNum++) {
12
+ var nextCell = sheet[
13
+ xlsx.utils.encode_cell({r: rowNum, c: colNum})
14
+ ];
15
+ var key = sheet[
16
+ xlsx.utils.encode_cell({r: range.s.r, c: colNum})
17
+ ].w;
18
+ if(key && nextCell) {
19
+ row[key] = nextCell
20
+ }
21
+ }
22
+ if(Object.keys(row).length > 0) {
23
+ result.push(row);
24
+ }
25
+ }
26
+ return result;
27
+ };
28
+
29
+ export default settings => {
30
+ /**
31
+ * Collection of row sources to use when running a test
32
+ * This is calculated from the input data
33
+ * @type {array<Object>} Collection of sources extracted from the input data
34
+ * @property {string} id The row ID to use to extract data per line
35
+ */
36
+ var sources;
37
+ return Promise.resolve()
38
+ .then(()=> xlsx.readFile(`./v4.xlsx`))
39
+ .then(workbook => {
40
+ return sheetToArr(workbook.Sheets[settings.sheet]);
41
+ })
42
+ // Extract source rows to aim for from the data set
43
+ .then(sheet => {
44
+ // Calculate sources
45
+ sources = Object.keys(sheet[0])
46
+ .filter(header =>
47
+ ![...settings.omitCols, settings.rowHeader].includes(header) // Skip omitted columns
48
+ )
49
+ .map(header => ({
50
+ id: header
51
+ }));
52
+ // Return sliced data - removing all header areas
53
+ return sheet.slice(settings.dataRowStart); // Remove first row
54
+ })
55
+ // Create lookup map
56
+ .then(sheet => {
57
+ let engineObject = {};
58
+ sources.forEach(source => {
59
+ engineObject[source.id] = {};
60
+ sheet.forEach((row, rowIndex) => {
61
+ if(row[source.id]) {
62
+ if (!engineObject[source.id][row[settings.rowHeader]]?.w) {
63
+ let termArray = row[source.id].w.split(/(Test)/g)
64
+ engineObject[source.id][row[settings.rowHeader].w] = {
65
+ terms: termArray,
66
+ comment: row[source.id].c ? row[source.id].c[0]?.t : undefined
67
+ };
68
+ } else {
69
+ console.log("Duplicate key:", row[settings.rowHeader].w);
70
+ }
71
+ } else {
72
+ console.error(`\n${source.id}'s "${row[settings.rowHeader].w}" is undefined\n`)
73
+ }
74
+ })
75
+ })
76
+ return engineObject;
77
+ })
78
78
  }
@@ -1,141 +1,141 @@
1
- import xlsx from 'xlsx';
2
-
3
- /**
4
- * Collection of row sources to use when running a test
5
- * This is calculated from the input data
6
- * @type {array<Object>} Collection of sources extracted from the input data
7
- * @property {string} id The row ID to use to extract data per line
8
- */
9
- var sources;
10
-
11
- function permute(input, permArr = [], usedChars = []) {
12
- var i, ch;
13
- for (i = 0; i < input.length; i++) {
14
- ch = input.splice(i, 1)[0];
15
- usedChars.push(ch);
16
- if (input.length == 0) {
17
- permArr.push(usedChars.slice());
18
- }
19
- permute(input, permArr, usedChars);
20
- input.splice(i, 0, ch);
21
- usedChars.pop();
22
- }
23
- return permArr
24
- };
25
-
26
-
27
- export default settings => {
28
- return Promise.resolve()
29
- .then(()=> xlsx.readFile(`./v4.xlsx`))
30
- .then(workbook => {
31
- return xlsx.utils.sheet_to_json(workbook.Sheets[settings.sheet]);
32
- })
33
- // Extract source rows to aim for from the data set
34
- .then(sheet => {
35
- // Calculate sources
36
- sources = Object.keys(sheet[0])
37
- .filter(header =>
38
- [...settings.includeCols].includes(header) // Filter include cols
39
- )
40
- .filter(header =>
41
- ![...settings.omitCols, settings.rowHeader].includes(header) // Skip omitted columns
42
- )
43
- .map(header => ({
44
- id: header
45
- }));
46
- // Return sliced data - removing all header areas
47
- return sheet.slice(settings.dataRowStart); // Remove first row
48
- })
49
- // Create lookup map
50
- .then(sheet => {
51
- let parseObject = {};
52
- sheet.forEach((row, rowIndex) => {
53
- sources.forEach(source => {
54
- // Match based on field code
55
- if(row[source.id] && settings.matchFieldCode) {
56
- var match = row[source.id].match(/Test(?<fieldCode>[^\n]*)/); // Only does basic match
57
- if (match && match.groups.fieldCode) {
58
- var fieldCode = match.groups.fieldCode;
59
- // Permute field code if it could have different variations (e.g. .ti,ab. or .ab,ti.)
60
- var variations = [ fieldCode ];
61
- if (fieldCode.includes(",")) {
62
- variations = []; // Clear variations array to prevent duplicate field code
63
- var periodSplit;
64
- var permutations;
65
- periodSplit = (fieldCode.split(/(\.)/g)); // Split by period
66
- periodSplit = periodSplit.filter(el => el.length > 0); // Filter out empty strings
67
- const index = periodSplit.findIndex(el => el.includes(",")) // Find index that has comma
68
- permutations = permute(periodSplit[index].split(",")); // Calculate permutations for index
69
- permutations = permutations.map(el => el.join(",")); // Join permuatations by comma
70
- permutations.forEach(el => { // For each permutation reconstruct string and push to array
71
- var fieldCodePermutation = [
72
- ...periodSplit.slice(0, index),
73
- el,
74
- ...periodSplit.slice(index + 1)
75
- ].join("");
76
- variations.push(fieldCodePermutation);
77
- })
78
- }
79
- // Push fieldCode and explanation to Map
80
- variations.forEach(fieldCodeVariation => {
81
- if (!parseObject[fieldCodeVariation.toLowerCase()]) {
82
- parseObject[fieldCodeVariation.toLowerCase()] = row[settings.rowHeader];
83
- } else {
84
- console.log(
85
- `Duplicate key (${source.id})`,
86
- `'${fieldCodeVariation.toLowerCase()}'`,
87
- "for",
88
- `'${row[settings.rowHeader]}'`,
89
- "already exists for",
90
- `'${parseObject[fieldCodeVariation.toLowerCase()]}'`
91
- );
92
- }
93
- })
94
- } else {
95
- console.error(`\n${row[source.id]} failed to match field code\n`)
96
- }
97
- }
98
- // Match based on entire string (for mesh translations)
99
- else if (row[source.id]) {
100
- const key = row[source.id].toLowerCase().replace(/"/g, '')
101
- if (!parseObject[key]) {
102
- parseObject[key] = row[settings.rowHeader];
103
- } else {
104
- console.log(
105
- `Duplicate key (${source.id})`,
106
- `'${key}'`,
107
- "for",
108
- `'${row[settings.rowHeader]}'`,
109
- "already exists for",
110
- `'${parseObject[key]}'`
111
- );
112
- }
113
- } else {
114
- console.error(`\n${source.id}'s "${row[settings.rowHeader]}" is undefined\n`)
115
- }
116
- })
117
- })
118
- // For any key that ends in '.', remove it (for optional end period on ovid tranlsations)
119
- // e.g. .ti. === .ti
120
- Object.keys(parseObject).forEach(key => {
121
- if (key.slice(-1) === ".") {
122
- const newKey = key.slice(0, -1);
123
- parseObject[newKey] = parseObject[key];
124
- }
125
- })
126
- // Create alternative keys with & or and
127
- Object.keys(parseObject).forEach(key => {
128
- const newKey = key.replace(/&/g, "and");
129
- parseObject[newKey] = parseObject[key];
130
- })
131
- // Sort keys descending to ensure longest is matched first
132
- const ordered = Object.keys(parseObject).sort().reverse().reduce(
133
- (obj, key) => {
134
- obj[key] = parseObject[key];
135
- return obj;
136
- },
137
- {}
138
- );
139
- return ordered;
140
- })
1
+ import xlsx from 'xlsx';
2
+
3
+ /**
4
+ * Collection of row sources to use when running a test
5
+ * This is calculated from the input data
6
+ * @type {array<Object>} Collection of sources extracted from the input data
7
+ * @property {string} id The row ID to use to extract data per line
8
+ */
9
+ var sources;
10
+
11
+ function permute(input, permArr = [], usedChars = []) {
12
+ var i, ch;
13
+ for (i = 0; i < input.length; i++) {
14
+ ch = input.splice(i, 1)[0];
15
+ usedChars.push(ch);
16
+ if (input.length == 0) {
17
+ permArr.push(usedChars.slice());
18
+ }
19
+ permute(input, permArr, usedChars);
20
+ input.splice(i, 0, ch);
21
+ usedChars.pop();
22
+ }
23
+ return permArr
24
+ };
25
+
26
+
27
+ export default settings => {
28
+ return Promise.resolve()
29
+ .then(()=> xlsx.readFile(`./v4.xlsx`))
30
+ .then(workbook => {
31
+ return xlsx.utils.sheet_to_json(workbook.Sheets[settings.sheet]);
32
+ })
33
+ // Extract source rows to aim for from the data set
34
+ .then(sheet => {
35
+ // Calculate sources
36
+ sources = Object.keys(sheet[0])
37
+ .filter(header =>
38
+ [...settings.includeCols].includes(header) // Filter include cols
39
+ )
40
+ .filter(header =>
41
+ ![...settings.omitCols, settings.rowHeader].includes(header) // Skip omitted columns
42
+ )
43
+ .map(header => ({
44
+ id: header
45
+ }));
46
+ // Return sliced data - removing all header areas
47
+ return sheet.slice(settings.dataRowStart); // Remove first row
48
+ })
49
+ // Create lookup map
50
+ .then(sheet => {
51
+ let parseObject = {};
52
+ sheet.forEach((row, rowIndex) => {
53
+ sources.forEach(source => {
54
+ // Match based on field code
55
+ if(row[source.id] && settings.matchFieldCode) {
56
+ var match = row[source.id].match(/Test(?<fieldCode>[^\n]*)/); // Only does basic match
57
+ if (match && match.groups.fieldCode) {
58
+ var fieldCode = match.groups.fieldCode;
59
+ // Permute field code if it could have different variations (e.g. .ti,ab. or .ab,ti.)
60
+ var variations = [ fieldCode ];
61
+ if (fieldCode.includes(",")) {
62
+ variations = []; // Clear variations array to prevent duplicate field code
63
+ var periodSplit;
64
+ var permutations;
65
+ periodSplit = (fieldCode.split(/(\.)/g)); // Split by period
66
+ periodSplit = periodSplit.filter(el => el.length > 0); // Filter out empty strings
67
+ const index = periodSplit.findIndex(el => el.includes(",")) // Find index that has comma
68
+ permutations = permute(periodSplit[index].split(",")); // Calculate permutations for index
69
+ permutations = permutations.map(el => el.join(",")); // Join permuatations by comma
70
+ permutations.forEach(el => { // For each permutation reconstruct string and push to array
71
+ var fieldCodePermutation = [
72
+ ...periodSplit.slice(0, index),
73
+ el,
74
+ ...periodSplit.slice(index + 1)
75
+ ].join("");
76
+ variations.push(fieldCodePermutation);
77
+ })
78
+ }
79
+ // Push fieldCode and explanation to Map
80
+ variations.forEach(fieldCodeVariation => {
81
+ if (!parseObject[fieldCodeVariation.toLowerCase()]) {
82
+ parseObject[fieldCodeVariation.toLowerCase()] = row[settings.rowHeader];
83
+ } else {
84
+ console.log(
85
+ `Duplicate key (${source.id})`,
86
+ `'${fieldCodeVariation.toLowerCase()}'`,
87
+ "for",
88
+ `'${row[settings.rowHeader]}'`,
89
+ "already exists for",
90
+ `'${parseObject[fieldCodeVariation.toLowerCase()]}'`
91
+ );
92
+ }
93
+ })
94
+ } else {
95
+ console.error(`\n${row[source.id]} failed to match field code\n`)
96
+ }
97
+ }
98
+ // Match based on entire string (for mesh translations)
99
+ else if (row[source.id]) {
100
+ const key = row[source.id].toLowerCase().replace(/"/g, '')
101
+ if (!parseObject[key]) {
102
+ parseObject[key] = row[settings.rowHeader];
103
+ } else {
104
+ console.log(
105
+ `Duplicate key (${source.id})`,
106
+ `'${key}'`,
107
+ "for",
108
+ `'${row[settings.rowHeader]}'`,
109
+ "already exists for",
110
+ `'${parseObject[key]}'`
111
+ );
112
+ }
113
+ } else {
114
+ console.error(`\n${source.id}'s "${row[settings.rowHeader]}" is undefined\n`)
115
+ }
116
+ })
117
+ })
118
+ // For any key that ends in '.', remove it (for optional end period on ovid tranlsations)
119
+ // e.g. .ti. === .ti
120
+ Object.keys(parseObject).forEach(key => {
121
+ if (key.slice(-1) === ".") {
122
+ const newKey = key.slice(0, -1);
123
+ parseObject[newKey] = parseObject[key];
124
+ }
125
+ })
126
+ // Create alternative keys with & or and
127
+ Object.keys(parseObject).forEach(key => {
128
+ const newKey = key.replace(/&/g, "and");
129
+ parseObject[newKey] = parseObject[key];
130
+ })
131
+ // Sort keys descending to ensure longest is matched first
132
+ const ordered = Object.keys(parseObject).sort().reverse().reduce(
133
+ (obj, key) => {
134
+ obj[key] = parseObject[key];
135
+ return obj;
136
+ },
137
+ {}
138
+ );
139
+ return ordered;
140
+ })
141
141
  }
package/data/package.json CHANGED
@@ -1,3 +1,3 @@
1
- {
2
- "type": "module"
1
+ {
2
+ "type": "module"
3
3
  }
@@ -1,62 +1,62 @@
1
- import * as fs from 'fs';
2
- import xlsxToParseMap from "./modules/xlsxToParseMap.js"
3
- import xlsxToEngineObject from "./modules/xlsxToEngineObject.js"
4
-
5
- /**
6
- * Testkit settings
7
- * @property {string} sheet ID of the sheet to extract the syntax tests from
8
- * @property {boolean} matchFieldCode Whether to try and regex match the field code
9
- * @property {array<string>} omitCols Column headings to ignore when processing the sheet (implies also `rowHeader` as an item)
10
- * @property {string} includeCols Columns to include when parsing
11
- * @property {string} rowHeader Which column header should be used as the row description / header
12
- * @property {number} [dataRowStart] Row offset to start reading data from, if falsy is calculated as driverRow+1
13
- */
14
- var settings = {
15
- sheet: 'fieldCodes',
16
- matchFieldCode: true,
17
- omitCols: ['Searching type'],
18
- includeCols: ['PubMed full', 'PubMed abbreviation', 'PubMed abbreviation 2', 'Ovid MEDLINE', 'Ovid MEDLINE 2', 'Ovid MEDLINE 3'],
19
- rowHeader: 'Explanation',
20
- dataRowStart: 0,
21
- };
22
-
23
- // Field Codes {{{
24
- xlsxToParseMap(settings).then(parseMap => {
25
- fs.writeFileSync(
26
- '../src/data/fieldCodesParse.js',
27
- `export default JSON.parse(\`${JSON.stringify(parseMap).replace(/\\/g, "\\\\")}\`)` // Replace \ with \\ to escape \}\`)`
28
- );
29
- });
30
-
31
- xlsxToEngineObject(settings).then(engineObject => {
32
- fs.writeFileSync(
33
- '../src/data/fieldCodesObject.js',
34
- `export default JSON.parse(\`${JSON.stringify(engineObject).replace(/\\/g, "\\\\")}\`)` // Replace \ with \\ to escape \
35
- )
36
- });
37
- // }}}
38
-
39
- // Mesh {{{
40
- xlsxToEngineObject({ ...settings, sheet: 'mesh' }).then(engineObject => {
41
- fs.writeFileSync(
42
- '../src/data/meshObject.js',
43
- `export default JSON.parse(\`${JSON.stringify(engineObject).replace(/\\/g, "\\\\")}\`)` // Replace \ with \\ to escape \
44
- )
45
- });
46
- // }}}
47
-
48
- // Mesh Translations {{{
49
- xlsxToParseMap({ ...settings, sheet: 'meshTranslations', matchFieldCode: false }).then(parseMap => {
50
- fs.writeFileSync(
51
- '../src/data/meshTranslationsParse.js',
52
- `export default JSON.parse(\`${JSON.stringify(parseMap).replace(/\\/g, "\\\\")}\`)` // Replace \ with \\ to escape \}\`)`
53
- );
54
- });
55
-
56
- xlsxToEngineObject({ ...settings, sheet: 'meshTranslations' }).then(engineObject => {
57
- fs.writeFileSync(
58
- '../src/data/meshTranslationsObject.js',
59
- `export default JSON.parse(\`${JSON.stringify(engineObject).replace(/\\/g, "\\\\")}\`)` // Replace \ with \\ to escape \
60
- )
61
- });
1
+ import * as fs from 'fs';
2
+ import xlsxToParseMap from "./modules/xlsxToParseMap.js"
3
+ import xlsxToEngineObject from "./modules/xlsxToEngineObject.js"
4
+
5
+ /**
6
+ * Testkit settings
7
+ * @property {string} sheet ID of the sheet to extract the syntax tests from
8
+ * @property {boolean} matchFieldCode Whether to try and regex match the field code
9
+ * @property {array<string>} omitCols Column headings to ignore when processing the sheet (implies also `rowHeader` as an item)
10
+ * @property {string} includeCols Columns to include when parsing
11
+ * @property {string} rowHeader Which column header should be used as the row description / header
12
+ * @property {number} [dataRowStart] Row offset to start reading data from, if falsy is calculated as driverRow+1
13
+ */
14
+ var settings = {
15
+ sheet: 'fieldCodes',
16
+ matchFieldCode: true,
17
+ omitCols: ['Searching type'],
18
+ includeCols: ['PubMed full', 'PubMed abbreviation', 'PubMed abbreviation 2', 'Ovid MEDLINE', 'Ovid MEDLINE 2', 'Ovid MEDLINE 3'],
19
+ rowHeader: 'Explanation',
20
+ dataRowStart: 0,
21
+ };
22
+
23
+ // Field Codes {{{
24
+ xlsxToParseMap(settings).then(parseMap => {
25
+ fs.writeFileSync(
26
+ '../src/data/fieldCodesParse.js',
27
+ `export default JSON.parse(\`${JSON.stringify(parseMap).replace(/\\/g, "\\\\")}\`)` // Replace \ with \\ to escape \}\`)`
28
+ );
29
+ });
30
+
31
+ xlsxToEngineObject(settings).then(engineObject => {
32
+ fs.writeFileSync(
33
+ '../src/data/fieldCodesObject.js',
34
+ `export default JSON.parse(\`${JSON.stringify(engineObject).replace(/\\/g, "\\\\")}\`)` // Replace \ with \\ to escape \
35
+ )
36
+ });
37
+ // }}}
38
+
39
+ // Mesh {{{
40
+ xlsxToEngineObject({ ...settings, sheet: 'mesh' }).then(engineObject => {
41
+ fs.writeFileSync(
42
+ '../src/data/meshObject.js',
43
+ `export default JSON.parse(\`${JSON.stringify(engineObject).replace(/\\/g, "\\\\")}\`)` // Replace \ with \\ to escape \
44
+ )
45
+ });
46
+ // }}}
47
+
48
+ // Mesh Translations {{{
49
+ xlsxToParseMap({ ...settings, sheet: 'meshTranslations', matchFieldCode: false }).then(parseMap => {
50
+ fs.writeFileSync(
51
+ '../src/data/meshTranslationsParse.js',
52
+ `export default JSON.parse(\`${JSON.stringify(parseMap).replace(/\\/g, "\\\\")}\`)` // Replace \ with \\ to escape \}\`)`
53
+ );
54
+ });
55
+
56
+ xlsxToEngineObject({ ...settings, sheet: 'meshTranslations' }).then(engineObject => {
57
+ fs.writeFileSync(
58
+ '../src/data/meshTranslationsObject.js',
59
+ `export default JSON.parse(\`${JSON.stringify(engineObject).replace(/\\/g, "\\\\")}\`)` // Replace \ with \\ to escape \
60
+ )
61
+ });
62
62
  // }}}
package/data/v4.xlsx CHANGED
Binary file