scv-bilara 3.164.76 → 3.165.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.
- package/package.json +2 -2
- package/src/auto/suidmap.json +1 -0
- package/src/defines.cjs +1 -0
- package/src/ml-doc.js +384 -371
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scv-bilara",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.165.1",
|
|
4
4
|
"description": "SuttaCentral bilara-data library",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"directories": {
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"log-instance": "^1.6.0",
|
|
16
16
|
"memo-again": "^0.10.0",
|
|
17
17
|
"merkle-json": "^2.2.0",
|
|
18
|
-
"scv-esm": "^1.111.
|
|
18
|
+
"scv-esm": "^1.111.77",
|
|
19
19
|
"suttacentral-api": "^2.16.11",
|
|
20
20
|
"tmp": "^0.2.3"
|
|
21
21
|
},
|
package/src/auto/suidmap.json
CHANGED
|
@@ -9609,6 +9609,7 @@
|
|
|
9609
9609
|
"translation/de/sabbamitta": "sutta/mn",
|
|
9610
9610
|
"translation/en/sujato": "sutta/mn",
|
|
9611
9611
|
"translation/fr/noeismet": "sutta/mn",
|
|
9612
|
+
"translation/fr/wijayaratna": "sutta/mn",
|
|
9612
9613
|
"translation/gu/trush": "sutta/mn",
|
|
9613
9614
|
"translation/pl/hardao": "sutta/mn",
|
|
9614
9615
|
"translation/ru/sv": "sutta/mn",
|
package/src/defines.cjs
CHANGED
package/src/ml-doc.js
CHANGED
|
@@ -1,426 +1,439 @@
|
|
|
1
1
|
(function (exports) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
DBG,
|
|
13
|
-
DBG_MLD,
|
|
14
|
-
} = require("./defines.cjs");
|
|
2
|
+
const fs = require("fs");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
const { logger } = require('log-instance');
|
|
5
|
+
const { Files } = require('memo-again');
|
|
6
|
+
const { BilaraPath } = require("scv-esm");
|
|
7
|
+
const Unicode = require('./unicode');
|
|
8
|
+
const Pali = require('./pali');
|
|
9
|
+
const { SuttaCentralId } = require('scv-esm');
|
|
10
|
+
const BILARA_PATH = path.join(Files.LOCAL_DIR, 'bilara-data');
|
|
11
|
+
const { DBG, DBG_MLD, } = require("./defines.cjs");
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
this.bilaraPaths = bilaraPaths;
|
|
26
|
-
this.author_uid = opts.author_uid;
|
|
27
|
-
this.type = opts.type || 'translation';
|
|
28
|
-
this.category = opts.category || 'sutta';
|
|
29
|
-
this.sutta_uid = opts.sutta_uid;
|
|
30
|
-
this.lang = opts.lang || this.languages().pop();
|
|
31
|
-
this.segMap = opts.segMap || {};
|
|
32
|
-
this.score = opts.score || 0; // search relevance
|
|
33
|
-
this.hyphen = opts.hyphen || "\u00ad";
|
|
34
|
-
this.maxWord = opts.maxWord || 30;
|
|
35
|
-
this.minWord = opts.minWord || 5;
|
|
36
|
-
this.title = opts.title;
|
|
37
|
-
this.segsMatched = opts.segsMatched;
|
|
38
|
-
this.langSegs = opts.langSegs;
|
|
39
|
-
if (opts.trilingual) {
|
|
40
|
-
this.trilingual = true;
|
|
41
|
-
this.docLang = opts.docLang;
|
|
42
|
-
this.docAuthor = opts.docAuthor;
|
|
43
|
-
this.refLang = opts.refLang || 'en';
|
|
44
|
-
this.refAuthor = opts.refAuthor || 'sujato';
|
|
45
|
-
}
|
|
46
|
-
Object.defineProperty(this, "unicode", {
|
|
47
|
-
value: opts.unicode || new Unicode(),
|
|
48
|
-
});
|
|
13
|
+
class MLDoc {
|
|
14
|
+
constructor(opts = {}) {
|
|
15
|
+
(opts.logger || logger).logInstance(this, opts);
|
|
16
|
+
var {
|
|
17
|
+
bilaraPaths,
|
|
18
|
+
} = opts;
|
|
19
|
+
if (bilaraPaths == null) {
|
|
20
|
+
throw new Error(`bilaraPaths is required`);
|
|
49
21
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
22
|
+
this.bilaraPaths = bilaraPaths;
|
|
23
|
+
this.author_uid = opts.author_uid;
|
|
24
|
+
this.type = opts.type || 'translation';
|
|
25
|
+
this.category = opts.category || 'sutta';
|
|
26
|
+
this.sutta_uid = opts.sutta_uid;
|
|
27
|
+
this.lang = opts.lang || this.languages().pop();
|
|
28
|
+
this.segMap = opts.segMap || {};
|
|
29
|
+
this.score = opts.score || 0; // search relevance
|
|
30
|
+
this.hyphen = opts.hyphen || "\u00ad";
|
|
31
|
+
this.maxWord = opts.maxWord || 30;
|
|
32
|
+
this.minWord = opts.minWord || 5;
|
|
33
|
+
this.title = opts.title;
|
|
34
|
+
this.segsMatched = opts.segsMatched;
|
|
35
|
+
this.langSegs = opts.langSegs;
|
|
36
|
+
if (opts.trilingual) {
|
|
37
|
+
this.trilingual = true;
|
|
38
|
+
this.docLang = opts.docLang;
|
|
39
|
+
this.docAuthor = opts.docAuthor;
|
|
40
|
+
this.refLang = opts.refLang || 'en';
|
|
41
|
+
this.refAuthor = opts.refAuthor || 'sujato';
|
|
54
42
|
}
|
|
43
|
+
Object.defineProperty(this, "unicode", {
|
|
44
|
+
value: opts.unicode || new Unicode(),
|
|
45
|
+
});
|
|
46
|
+
}
|
|
55
47
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (a === 'pli') { // Pali is primary source
|
|
62
|
-
return -1;
|
|
63
|
-
} else if (b === 'pli') {
|
|
64
|
-
return 1;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (a === 'en') { // English is secondary source
|
|
68
|
-
return -1;
|
|
69
|
-
} else if (b === 'en') {
|
|
70
|
-
return 1;
|
|
71
|
-
}
|
|
48
|
+
static compare(m1, m2) {
|
|
49
|
+
var cmp = m2.score - m1.score;
|
|
50
|
+
return cmp ? cmp : SuttaCentralId.compareLow(m1.suid, m2.suid);
|
|
51
|
+
}
|
|
72
52
|
|
|
73
|
-
|
|
53
|
+
static langCompare_pli_en(a, b) {
|
|
54
|
+
if (a === b) {
|
|
55
|
+
return 0;
|
|
74
56
|
}
|
|
75
57
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
} = this;
|
|
81
|
-
return sutta_uid || bilaraPaths.reduce((a, bp) => {
|
|
82
|
-
var suid = BilaraPath.pathParts(bp).suid;
|
|
83
|
-
if (a && suid !== a) {
|
|
84
|
-
throw new Error(`uid mismatch ` +
|
|
85
|
-
`expected:${a} ` +
|
|
86
|
-
`actual:${suid} `);
|
|
87
|
-
}
|
|
88
|
-
return a || suid;
|
|
89
|
-
}, null);
|
|
58
|
+
if (a === 'pli') { // Pali is primary source
|
|
59
|
+
return -1;
|
|
60
|
+
} else if (b === 'pli') {
|
|
61
|
+
return 1;
|
|
90
62
|
}
|
|
91
63
|
|
|
92
|
-
|
|
93
|
-
return
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
}, undefined);
|
|
64
|
+
if (a === 'en') { // English is secondary source
|
|
65
|
+
return -1;
|
|
66
|
+
} else if (b === 'en') {
|
|
67
|
+
return 1;
|
|
97
68
|
}
|
|
98
69
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
70
|
+
return a.localeCompare(b); // arbitrary but consistent
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
get suid() {
|
|
74
|
+
var {
|
|
75
|
+
bilaraPaths,
|
|
76
|
+
sutta_uid,
|
|
77
|
+
} = this;
|
|
78
|
+
return sutta_uid || bilaraPaths.reduce((a, bp) => {
|
|
79
|
+
var suid = BilaraPath.pathParts(bp).suid;
|
|
80
|
+
if (a && suid !== a) {
|
|
81
|
+
throw new Error(`uid mismatch ` +
|
|
82
|
+
`expected:${a} ` +
|
|
83
|
+
`actual:${suid} `);
|
|
84
|
+
}
|
|
85
|
+
return a || suid;
|
|
86
|
+
}, null);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
get root_text() {
|
|
90
|
+
return this.bilaraPaths.reduce((a, bp) => {
|
|
91
|
+
var parts = BilaraPath.pathParts(bp);
|
|
92
|
+
return parts.type === 'root' ? parts : a;
|
|
93
|
+
}, undefined);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
get translations() {
|
|
97
|
+
let {
|
|
98
|
+
bilaraPaths,
|
|
99
|
+
author_uid,
|
|
100
|
+
lang,
|
|
101
|
+
type,
|
|
102
|
+
sutta_uid,
|
|
103
|
+
category,
|
|
104
|
+
} = this;
|
|
105
|
+
if (bilaraPaths.length) {
|
|
106
|
+
return bilaraPaths
|
|
107
|
+
.map(bp => BilaraPath.pathParts(bp))
|
|
108
|
+
.filter(t => t.type === 'translation');
|
|
109
|
+
} else {
|
|
110
|
+
return [{ // legacy translation
|
|
104
111
|
type,
|
|
105
|
-
|
|
112
|
+
lang,
|
|
113
|
+
author_uid,
|
|
106
114
|
category,
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
} else {
|
|
113
|
-
return [{ // legacy translation
|
|
114
|
-
type,
|
|
115
|
-
lang,
|
|
116
|
-
author_uid,
|
|
117
|
-
category,
|
|
118
|
-
collection: sutta_uid.replace(/[-0-9.]+/, ''),
|
|
119
|
-
suttaRef: `${sutta_uid}/${lang}/${author_uid}`,
|
|
120
|
-
//bilaraPath: translationPath('an/an1/an1.1-10','en','sujato'),
|
|
121
|
-
sutta_uid,
|
|
122
|
-
}];
|
|
123
|
-
}
|
|
115
|
+
collection: sutta_uid.replace(/[-0-9.]+/, ''),
|
|
116
|
+
suttaRef: `${sutta_uid}/${lang}/${author_uid}`,
|
|
117
|
+
//bilaraPath: translationPath('an/an1/an1.1-10','en','sujato'),
|
|
118
|
+
sutta_uid,
|
|
119
|
+
}];
|
|
124
120
|
}
|
|
121
|
+
}
|
|
125
122
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
123
|
+
titles(lang = this.lang) {
|
|
124
|
+
const msg = 'M3c.titles:';
|
|
125
|
+
const dbg = DBG.MLD_LOAD;
|
|
126
|
+
let headSegs = this.segments().slice(0,4);
|
|
127
|
+
dbg && console.log(msg, {lang, headSegs});
|
|
128
|
+
var titles = headSegs.slice(0, 4).reduce((a, s, i) => {
|
|
129
|
+
if (s) {
|
|
130
|
+
let text = (s[lang] || s.en || s.pli || '');
|
|
131
|
+
let segNum = s.scid.split(':')[1];
|
|
132
|
+
if (segNum.match(/^0/)) {
|
|
133
|
+
text.length && a.push(text.trim());
|
|
134
|
+
} else {
|
|
135
|
+
this.debug(`titles() ignoring segments[${i}] with segNum:${segNum}`, s);
|
|
136
136
|
}
|
|
137
|
-
return a;
|
|
138
|
-
}, []);
|
|
139
|
-
if (titles.length === 0) {
|
|
140
|
-
titles = [`(no-title-${this.suid})`];
|
|
141
137
|
}
|
|
142
|
-
return
|
|
138
|
+
return a;
|
|
139
|
+
}, []);
|
|
140
|
+
if (titles.length === 0) {
|
|
141
|
+
titles = [`(no-title-${this.suid})`];
|
|
143
142
|
}
|
|
143
|
+
return titles;
|
|
144
|
+
}
|
|
144
145
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
146
|
+
scids() {
|
|
147
|
+
var result = Object.keys(this.segMap);
|
|
148
|
+
result.sort(SuttaCentralId.compareLow);
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
150
151
|
|
|
151
|
-
|
|
152
|
-
|
|
152
|
+
languages() {
|
|
153
|
+
let {
|
|
154
|
+
bilaraPaths,
|
|
155
|
+
lang,
|
|
156
|
+
} = this;
|
|
157
|
+
return bilaraPaths.length
|
|
158
|
+
? Object.keys(bilaraPaths.reduce((a, bp) => {
|
|
159
|
+
a[bp.split('/')[1]] = true;
|
|
160
|
+
return a;
|
|
161
|
+
}, {})).sort(MLDoc.langCompare_pli_en)
|
|
162
|
+
: [lang];
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
async load(root = BILARA_PATH) {
|
|
166
|
+
const msg = "M3c.load() ";
|
|
167
|
+
const dbg = DBG.MLD_LOAD;
|
|
168
|
+
try {
|
|
169
|
+
var {
|
|
170
|
+
segMap,
|
|
153
171
|
bilaraPaths,
|
|
154
|
-
|
|
172
|
+
docLang,
|
|
173
|
+
docAuthor,
|
|
174
|
+
refLang,
|
|
175
|
+
refAuthor,
|
|
176
|
+
trilingual,
|
|
155
177
|
} = this;
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
: [lang];
|
|
162
|
-
}
|
|
178
|
+
this.langSegs = {};
|
|
179
|
+
let langMap = {};
|
|
180
|
+
var p_bp = [];
|
|
181
|
+
dbg && console.log(msg, '[1]',
|
|
182
|
+
{bilaraPaths, lang, docAuthor, refAuthor});
|
|
163
183
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
var
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
trilingual,
|
|
176
|
-
} = this;
|
|
177
|
-
this.langSegs = {};
|
|
178
|
-
let langMap = {};
|
|
179
|
-
var p_bp = [];
|
|
180
|
-
dbg && console.log(msg, {bilaraPaths, docAuthor, refAuthor});
|
|
181
|
-
for (var ip = 0; ip < bilaraPaths.length; ip++) {
|
|
182
|
-
var parts = BilaraPath.pathParts(bilaraPaths[ip]);
|
|
183
|
-
var bp = path.join(root, parts.bilaraPath);
|
|
184
|
-
var fh = fs.existsSync(bp) && await fs.promises.open(bp);
|
|
185
|
-
var isTrans = parts.type === 'translation';
|
|
186
|
-
var isRoot = parts.type === 'root';
|
|
187
|
-
var lang = isTrans || isRoot
|
|
188
|
-
? parts.lang
|
|
189
|
-
: parts.type;
|
|
190
|
-
if (trilingual && parts.author_uid === refAuthor) {
|
|
191
|
-
lang = 'ref';
|
|
192
|
-
}
|
|
193
|
-
if (langMap[lang]) {
|
|
194
|
-
//console.log(msg, `skipping: ${bilaraPaths[ip]}`, {lang});
|
|
195
|
-
fh && fh.close();
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
langMap[lang] = true;
|
|
199
|
-
if (fh) {
|
|
200
|
-
try {
|
|
201
|
-
var bpe = {
|
|
202
|
-
fh,
|
|
203
|
-
bp,
|
|
204
|
-
p_read: fh.readFile(),
|
|
205
|
-
lang,
|
|
206
|
-
};
|
|
207
|
-
p_bp.push(bpe);
|
|
208
|
-
} catch(e) {
|
|
209
|
-
this.warn(`${msg} Could not read Bilara file:`, bp);
|
|
210
|
-
throw e;
|
|
211
|
-
}
|
|
212
|
-
} else {
|
|
213
|
-
this.log(`${msg} path not found:${bp}`);
|
|
214
|
-
}
|
|
184
|
+
for (var ip = 0; ip < bilaraPaths.length; ip++) {
|
|
185
|
+
var parts = BilaraPath.pathParts(bilaraPaths[ip]);
|
|
186
|
+
var bp = path.join(root, parts.bilaraPath);
|
|
187
|
+
var fh = fs.existsSync(bp) && await fs.promises.open(bp);
|
|
188
|
+
var isTrans = parts.type === 'translation';
|
|
189
|
+
var isRoot = parts.type === 'root';
|
|
190
|
+
var lang = isTrans || isRoot
|
|
191
|
+
? parts.lang
|
|
192
|
+
: parts.type;
|
|
193
|
+
if (trilingual && parts.author_uid === refAuthor) {
|
|
194
|
+
lang = 'ref';
|
|
215
195
|
}
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
let copyRefDoc = lang === 'ref' && sameAuthor;
|
|
224
|
-
var json = await p_read;
|
|
196
|
+
if (langMap[lang]) {
|
|
197
|
+
dbg && console.log(msg, `[2]skipping: ${bilaraPaths[ip]}`);
|
|
198
|
+
fh && fh.close();
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
langMap[lang] = true;
|
|
202
|
+
if (fh) {
|
|
225
203
|
try {
|
|
226
|
-
var
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
});
|
|
234
|
-
m[lang] = strings[k];
|
|
235
|
-
if (copyRefDoc) {
|
|
236
|
-
m[docLang] = strings[k];
|
|
237
|
-
}
|
|
238
|
-
});
|
|
204
|
+
var bpe = {
|
|
205
|
+
fh,
|
|
206
|
+
bp,
|
|
207
|
+
p_read: fh.readFile(),
|
|
208
|
+
lang,
|
|
209
|
+
};
|
|
210
|
+
p_bp.push(bpe);
|
|
239
211
|
} catch(e) {
|
|
240
212
|
this.warn(`${msg} Could not read Bilara file:`, bp);
|
|
241
213
|
throw e;
|
|
242
214
|
}
|
|
215
|
+
} else {
|
|
216
|
+
this.log(`${msg} path not found:${bp}`);
|
|
243
217
|
}
|
|
244
|
-
|
|
218
|
+
}
|
|
245
219
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
220
|
+
// assemble content
|
|
221
|
+
let sameAuthor = trilingual &&
|
|
222
|
+
refLang === docLang &&
|
|
223
|
+
refAuthor === docAuthor;
|
|
224
|
+
for (var ip = 0; ip < p_bp.length; ip++) {
|
|
225
|
+
var { fh, bp, p_read, lang, } = p_bp[ip];
|
|
226
|
+
let copyRefDoc = lang === 'ref' && sameAuthor;
|
|
227
|
+
var json = await p_read;
|
|
228
|
+
let header;
|
|
229
|
+
try {
|
|
230
|
+
let strings = JSON.parse(json);
|
|
231
|
+
header = strings.__header__;
|
|
232
|
+
if (header) {
|
|
233
|
+
delete strings.__header__;
|
|
234
|
+
this.sutta_uid = header.suid;
|
|
235
|
+
this.author = header.author;
|
|
236
|
+
this.author_uid = header.author_uid;
|
|
237
|
+
this.footer = header.footer;
|
|
238
|
+
|
|
239
|
+
dbg && console.log(msg, '[3]header', header);
|
|
240
|
+
}
|
|
241
|
+
fh.close();
|
|
242
|
+
let keys = Object.keys(strings);
|
|
243
|
+
this.langSegs[lang] = keys.length;
|
|
244
|
+
keys.forEach(k => {
|
|
245
|
+
var m = (segMap[k] = segMap[k] || {
|
|
246
|
+
scid: k,
|
|
247
|
+
});
|
|
248
|
+
m[lang] = strings[k];
|
|
249
|
+
if (copyRefDoc) {
|
|
250
|
+
m[docLang] = strings[k];
|
|
251
|
+
}
|
|
252
|
+
});
|
|
253
|
+
} catch(e) {
|
|
254
|
+
this.warn(`${msg} Could not read Bilara file:`, bp);
|
|
255
|
+
throw e;
|
|
256
|
+
}
|
|
250
257
|
}
|
|
251
|
-
|
|
258
|
+
this.title = this.titles().join('\n');
|
|
252
259
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
260
|
+
return this;
|
|
261
|
+
} catch (e) {
|
|
262
|
+
this.warn(msg, e.message);
|
|
263
|
+
throw e;
|
|
257
264
|
}
|
|
265
|
+
}
|
|
258
266
|
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
}
|
|
267
|
+
segments() {
|
|
268
|
+
return this.scids().map(scid => Object.assign({
|
|
269
|
+
scid,
|
|
270
|
+
}, this.segMap[scid]));
|
|
271
|
+
}
|
|
263
272
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if (!a && text) {
|
|
269
|
-
if (rexList.reduce((a, re) => a && re.test(text), true)) {
|
|
270
|
-
return true;
|
|
271
|
-
} else if (l === 'pli') {
|
|
272
|
-
var romText = unicode.romanize(text);
|
|
273
|
-
return rexList.reduce(
|
|
274
|
-
(a, re) => a && re.test(romText), true);
|
|
275
|
-
}
|
|
273
|
+
matchScid({ seg, scidPat }) {
|
|
274
|
+
var match = SuttaCentralId.match(seg.scid, scidPat);
|
|
275
|
+
return match;
|
|
276
|
+
}
|
|
276
277
|
|
|
278
|
+
matchText({ seg, languages, rexList }) {
|
|
279
|
+
var unicode = this.unicode;
|
|
280
|
+
return languages.reduce((a, l) => {
|
|
281
|
+
var text = seg[l];
|
|
282
|
+
if (!a && text) {
|
|
283
|
+
if (rexList.reduce((a, re) => a && re.test(text), true)) {
|
|
284
|
+
return true;
|
|
285
|
+
} else if (l === 'pli') {
|
|
286
|
+
var romText = unicode.romanize(text);
|
|
287
|
+
return rexList.reduce(
|
|
288
|
+
(a, re) => a && re.test(romText), true);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
}
|
|
292
|
+
return a;
|
|
293
|
+
}, false);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
jsPattern(pat, opts = 'ui') {
|
|
297
|
+
var p = pat.toString();
|
|
298
|
+
const quotes = `"'\u0060\u2018\u201e\u201c\u201a`;
|
|
299
|
+
var result = p.startsWith('\\b')
|
|
300
|
+
? new RegExp(`(?<=[\\s,.:;${quotes}]|^)${p.substring(2)}`, opts)
|
|
301
|
+
: new RegExp(p, opts);
|
|
302
|
+
return result;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
hyphenate(hyphenator = new Pali()) {
|
|
306
|
+
var { maxWord, } = hyphenator;
|
|
307
|
+
var lang = "pli";
|
|
308
|
+
var scids = this.scids();
|
|
309
|
+
scids.forEach((scid, i) => {
|
|
310
|
+
var seg = this.segMap[scid];
|
|
311
|
+
var text = seg[lang];
|
|
312
|
+
var words = text.split(" ");
|
|
313
|
+
var changed = false;
|
|
314
|
+
var hyphenated = words.reduce((a, w) => {
|
|
315
|
+
if (w.length > maxWord) {
|
|
316
|
+
changed = true;
|
|
317
|
+
a.push(hyphenator.hyphenate(w));
|
|
318
|
+
} else {
|
|
319
|
+
a.push(w);
|
|
277
320
|
}
|
|
278
321
|
return a;
|
|
279
|
-
},
|
|
280
|
-
|
|
322
|
+
}, []);
|
|
323
|
+
changed && (seg[lang] = hyphenated.join(" "));
|
|
324
|
+
});
|
|
325
|
+
}
|
|
281
326
|
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
:
|
|
288
|
-
|
|
327
|
+
filterSegments(...args) {
|
|
328
|
+
const msg = "M3c.filterSegments()";
|
|
329
|
+
const dbg = DBG_MLD;
|
|
330
|
+
if (typeof args[0] === 'string') {
|
|
331
|
+
var opts = {
|
|
332
|
+
resultPattern: args[0],
|
|
333
|
+
languages: args[1],
|
|
334
|
+
showMatchesOnly: args[2],
|
|
335
|
+
}
|
|
336
|
+
} else {
|
|
337
|
+
opts = args[0];
|
|
289
338
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
339
|
+
var {
|
|
340
|
+
pattern,
|
|
341
|
+
resultPattern,
|
|
342
|
+
languages,
|
|
343
|
+
showMatchesOnly,
|
|
344
|
+
method,
|
|
345
|
+
} = opts;
|
|
346
|
+
var matchScid = SuttaCentralId.test(resultPattern);
|
|
347
|
+
showMatchesOnly = showMatchesOnly === undefined
|
|
348
|
+
? true : showMatchesOnly;
|
|
349
|
+
languages = languages === undefined
|
|
350
|
+
? this.languages() : languages;
|
|
351
|
+
pattern = pattern || resultPattern;
|
|
352
|
+
var scids = this.scids();
|
|
353
|
+
var suid = this.suid;
|
|
354
|
+
if (resultPattern instanceof RegExp) {
|
|
355
|
+
var rexList = [this.jsPattern(resultPattern)];
|
|
356
|
+
} else if (1 && method === 'phrase') {
|
|
357
|
+
var rexList = [this.jsPattern(resultPattern, 'imu')];
|
|
358
|
+
} else if (matchScid) {
|
|
359
|
+
// SuttaCentral.match
|
|
360
|
+
} else {
|
|
361
|
+
let resultPatterns = resultPattern.split('|');
|
|
362
|
+
let patterns = pattern.split(' ').map(p => {
|
|
363
|
+
return p.charAt(0) === '_'
|
|
364
|
+
? p.substring(1) // unconstrained match
|
|
365
|
+
: `\\b${p}`; // word start match
|
|
310
366
|
});
|
|
367
|
+
let srcPats = resultPatterns.length === patterns.length
|
|
368
|
+
? resultPatterns
|
|
369
|
+
: patterns;
|
|
370
|
+
var rexList = srcPats.map(p => this.jsPattern(p));
|
|
311
371
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
372
|
+
var unicode = this.unicode;
|
|
373
|
+
var matchLow = SuttaCentralId.rangeLow(resultPattern);
|
|
374
|
+
var matchHigh = SuttaCentralId.rangeHigh(resultPattern);
|
|
375
|
+
var matched = 0;
|
|
376
|
+
scids.forEach((scid, i) => {
|
|
377
|
+
var seg = this.segMap[scid];
|
|
378
|
+
var match;
|
|
379
|
+
if (matchScid) {
|
|
380
|
+
match = SuttaCentralId.match(seg.scid, pattern);
|
|
381
|
+
dbg>1 && console.log(msg, '[1]matchScid', {
|
|
382
|
+
pattern, seg, match});
|
|
323
383
|
} else {
|
|
324
|
-
|
|
384
|
+
match = this.matchText({ seg, languages, rexList });
|
|
385
|
+
dbg>1 && console.log(msg, '[2]matchScid', {
|
|
386
|
+
pattern, seg, match, languages});
|
|
325
387
|
}
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
languages,
|
|
330
|
-
showMatchesOnly,
|
|
331
|
-
method,
|
|
332
|
-
} = opts;
|
|
333
|
-
var matchScid = SuttaCentralId.test(resultPattern);
|
|
334
|
-
showMatchesOnly = showMatchesOnly === undefined
|
|
335
|
-
? true : showMatchesOnly;
|
|
336
|
-
languages = languages === undefined
|
|
337
|
-
? this.languages() : languages;
|
|
338
|
-
pattern = pattern || resultPattern;
|
|
339
|
-
var scids = this.scids();
|
|
340
|
-
var suid = this.suid;
|
|
341
|
-
if (resultPattern instanceof RegExp) {
|
|
342
|
-
var rexList = [this.jsPattern(resultPattern)];
|
|
343
|
-
} else if (1 && method === 'phrase') {
|
|
344
|
-
var rexList = [this.jsPattern(resultPattern, 'imu')];
|
|
345
|
-
} else if (matchScid) {
|
|
346
|
-
// SuttaCentral.match
|
|
388
|
+
if (match) {
|
|
389
|
+
matched++;
|
|
390
|
+
seg.matched = true;
|
|
347
391
|
} else {
|
|
348
|
-
|
|
349
|
-
let patterns = pattern.split(' ').map(p => {
|
|
350
|
-
return p.charAt(0) === '_'
|
|
351
|
-
? p.substring(1) // unconstrained match
|
|
352
|
-
: `\\b${p}`; // word start match
|
|
353
|
-
});
|
|
354
|
-
let srcPats = resultPatterns.length === patterns.length
|
|
355
|
-
? resultPatterns
|
|
356
|
-
: patterns;
|
|
357
|
-
var rexList = srcPats.map(p => this.jsPattern(p));
|
|
358
|
-
}
|
|
359
|
-
var unicode = this.unicode;
|
|
360
|
-
var matchLow = SuttaCentralId.rangeLow(resultPattern);
|
|
361
|
-
var matchHigh = SuttaCentralId.rangeHigh(resultPattern);
|
|
362
|
-
var matched = 0;
|
|
363
|
-
scids.forEach((scid, i) => {
|
|
364
|
-
var seg = this.segMap[scid];
|
|
365
|
-
var match;
|
|
366
|
-
if (matchScid) {
|
|
367
|
-
match = SuttaCentralId.match(seg.scid, pattern);
|
|
368
|
-
dbgv && console.log(msg, '[1]matchScid', {
|
|
369
|
-
pattern, seg, match});
|
|
370
|
-
} else {
|
|
371
|
-
match = this.matchText({ seg, languages, rexList });
|
|
372
|
-
dbgv && console.log(msg, '[2]matchScid', {
|
|
373
|
-
pattern, seg, match, languages});
|
|
374
|
-
}
|
|
375
|
-
if (match) {
|
|
376
|
-
matched++;
|
|
377
|
-
seg.matched = true;
|
|
378
|
-
} else {
|
|
379
|
-
showMatchesOnly && delete this.segMap[scid];
|
|
380
|
-
}
|
|
381
|
-
});
|
|
382
|
-
dbg && console.log(msg, '[3]', {
|
|
383
|
-
matched, pattern, suid, languages,});
|
|
384
|
-
var score = matchScid
|
|
385
|
-
? 0
|
|
386
|
-
: Number((matched + matched / scids.length).toFixed(3));
|
|
387
|
-
this.score = score;
|
|
388
|
-
return {
|
|
389
|
-
matched,
|
|
390
|
-
matchLow,
|
|
391
|
-
matchHigh,
|
|
392
|
-
matchScid,
|
|
393
|
-
rexList,
|
|
394
|
-
suid,
|
|
395
|
-
score,
|
|
392
|
+
showMatchesOnly && delete this.segMap[scid];
|
|
396
393
|
}
|
|
394
|
+
});
|
|
395
|
+
dbg && console.log(msg, '[3]', {
|
|
396
|
+
matched, pattern, suid, languages,});
|
|
397
|
+
var score = matchScid
|
|
398
|
+
? 0
|
|
399
|
+
: Number((matched + matched / scids.length).toFixed(3));
|
|
400
|
+
this.score = score;
|
|
401
|
+
return {
|
|
402
|
+
matched,
|
|
403
|
+
matchLow,
|
|
404
|
+
matchHigh,
|
|
405
|
+
matchScid,
|
|
406
|
+
rexList,
|
|
407
|
+
suid,
|
|
408
|
+
score,
|
|
397
409
|
}
|
|
410
|
+
}
|
|
398
411
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
});
|
|
412
|
+
highlightMatch(pattern, matchHighlight) {
|
|
413
|
+
var scids = this.scids();
|
|
414
|
+
if (SuttaCentralId.test(pattern)) {
|
|
415
|
+
// scids are semantic and should never be highlighted
|
|
416
|
+
//scids.forEach(scid => {
|
|
417
|
+
//var seg = this.segMap[scid];
|
|
418
|
+
//seg.scid = seg.scid.replace(/^.*$/, matchHighlight);
|
|
419
|
+
//});
|
|
420
|
+
} else {
|
|
421
|
+
var rex = pattern instanceof RegExp
|
|
422
|
+
? rex : new RegExp(pattern, "gui");
|
|
423
|
+
var rex = this.jsPattern(pattern, "gui");
|
|
424
|
+
scids.forEach(scid => {
|
|
425
|
+
var seg = this.segMap[scid];
|
|
426
|
+
Object.keys(seg).forEach(k => {
|
|
427
|
+
if (k !== 'scid' && k !== 'matched') {
|
|
428
|
+
seg[k] = seg[k].replace(rex, matchHighlight);
|
|
429
|
+
}
|
|
418
430
|
});
|
|
419
|
-
}
|
|
420
|
-
return this;
|
|
431
|
+
});
|
|
421
432
|
}
|
|
422
|
-
|
|
433
|
+
return this;
|
|
423
434
|
}
|
|
424
435
|
|
|
425
|
-
|
|
436
|
+
} // class MLDoc
|
|
437
|
+
|
|
438
|
+
module.exports = exports.MLDoc = MLDoc;
|
|
426
439
|
})(typeof exports === "object" ? exports : (exports = {}));
|