scv-bilara 3.165.2 → 3.166.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scv-bilara",
3
- "version": "3.165.2",
3
+ "version": "3.166.2",
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.78",
18
+ "scv-esm": "^1.111.80",
19
19
  "suttacentral-api": "^2.16.11",
20
20
  "tmp": "^0.2.3"
21
21
  },
@@ -430,14 +430,18 @@ found : segs:${segsMatched} by:${method} mlDocs:${nDocs} docs:${nRefs} ${ref
430
430
  );
431
431
  }
432
432
  mlDocs.forEach((mld,im) => {
433
- let {suid, author_uid, lang} = mld;
433
+ let {suid, author, author_uid, lang} = mld;
434
434
  mld.segments().forEach((seg,i) => {
435
435
  var scid = seg.scid;
436
- var sep = '-----------------------';
436
+ var sep = '---';
437
437
  if (i === 0) {
438
438
  let sm = mld.hasOwnProperty('segsMatched') ? mld.segsMatched : '';
439
439
  let score = mld.score.toFixed(3);
440
- let title = `doc:${im+1}/${nDocs} ${suid}/${lang}/${author_uid} score:${score}`;
440
+ let title = [
441
+ `doc:${im+1}/${nDocs}`,
442
+ `${author} ${suid}/${lang}/${author_uid}`,
443
+ `score:${score}`
444
+ ].join(' ');
441
445
  console.log(`${sep} ${title} ${sep}`);
442
446
  }
443
447
  let scidText = [
@@ -550,13 +554,18 @@ function outLines(res, pattern, n=0) {
550
554
  var {
551
555
  lang,
552
556
  searchLang,
557
+ author,
553
558
  docLang,
554
559
  docAuthor,
560
+ docAuthorName,
555
561
  refLang,
556
562
  refAuthor,
557
563
  } = res;
558
564
  console.log(
559
- `---:pli/ms doc:${docLang}/${docAuthor} ref:${refLang}/${refAuthor}`);
565
+ `---:pli/ms`,
566
+ `doc:${docLang}/${docAuthor} ${docAuthorName}`,
567
+ `ref:${refLang}/${refAuthor}`
568
+ );
560
569
  n = Number(n);
561
570
  res.mlDocs.forEach(mld => {
562
571
  var suid = mld.suid;
@@ -29,7 +29,7 @@
29
29
 
30
30
  class BilaraData {
31
31
  constructor(opts = {}) {
32
- const msg = "BilaraData.ctor()";
32
+ const msg = "B8a.ctor()";
33
33
  const dbg = DBG_BD_INIT;
34
34
  (opts.logger || logger).logInstance(this, opts);
35
35
  this.name = opts.name || "bilara-data";
@@ -49,6 +49,7 @@
49
49
  opts.publication ||
50
50
  new Publication({
51
51
  includeUnpublished,
52
+ name: this.name,
52
53
  root: this.root,
53
54
  });
54
55
  this.bilaraPathMap = this.publication.bilaraPathMap;
@@ -101,7 +102,7 @@
101
102
  author,
102
103
  includeUnpublished = this.includeUnpublished,
103
104
  }) {
104
- const msg = "BilaraData.isBilaraDoc() ";
105
+ const msg = "B8a.isBilaraDoc() ";
105
106
  let { bilaraPathMap: bpm, publication } = this;
106
107
  let sp = bpm.suidPaths(suid);
107
108
 
@@ -456,7 +457,7 @@
456
457
  }
457
458
 
458
459
  loadMLDoc(...args) {
459
- const msg = "BilaraData.loadMLDoc() ";
460
+ const msg = "B8a.loadMLDoc() ";
460
461
  var loadArgs = this.loadArgs(args);
461
462
  var {
462
463
  suid: suidRef,
@@ -529,10 +530,9 @@
529
530
  }
530
531
 
531
532
  async trilingualDoc(suttaRef, opts={}) {
532
- const msg = "BilaraData.trilingualDoc() ";
533
+ const msg = "B8a.trilingualDoc() ";
533
534
  const dbg = DBG.TRILINGUALDOC;
534
- let { bilaraPathMap: bpm, root } = this;
535
- suttaRef = SuttaRef.create(suttaRef);
535
+ let { bilaraPathMap: bpm, root } = this; suttaRef = SuttaRef.create(suttaRef);
536
536
  let {
537
537
  rootLang = 'pli',
538
538
  rootAuthor = 'ms',
@@ -574,61 +574,24 @@
574
574
  logLevel && (mldOpts.logLevel = logLevel);
575
575
  dbg && console.log(msg, '[1]mldOpts', mldOpts);
576
576
  let mld = await new MLDoc(mldOpts).load(root);
577
- dbg && console.log(msg, 'mld=>', {
578
- docLang: mld?.docLang,
579
- docAuthor: mld?.docAuthor,
580
- bilaraPaths: mld?.bilaraPaths,
581
- langSegs: mld?.langSegs,
582
- '...': '...',
583
- });
577
+ if (dbg) {
578
+ let dbgOut = mld && {
579
+ author: mld.author,
580
+ docLang: mld.docLang,
581
+ docAuthor: mld.docAuthor,
582
+ docAuthorName: mld.docAuthorName,
583
+ trilingual: mld.trilingual,
584
+ bilaraPaths: mld.bilaraPaths,
585
+ langSegs: mld.langSegs,
586
+ '...': '...',
587
+ };
588
+ console.log(msg, '[2]mld', dbgOut);
589
+ }
584
590
  return mld;
585
591
  }
586
592
 
587
- async loadMLDocLegacy(suidRef) {
588
- try {
589
- let suidParts = suidRef.split("/");
590
- let sutta = await this.scApi.loadLegacySutta.apply(
591
- this.scApi,
592
- suidParts
593
- );
594
- if (!sutta) {
595
- let e = new Error(`loadMLDocLegacy() not found:${suidRef}`);
596
- e.suidRef = suidRef;
597
- throw e;
598
- }
599
- let {
600
- lang,
601
- author_uid,
602
- sutta_uid,
603
- segmented,
604
- segments = [],
605
- suttaplex,
606
- } = sutta;
607
- let segMap = {};
608
- segments.forEach((seg) => {
609
- segMap[seg.scid] = seg;
610
- });
611
- this.info(`loadMLDocLegacy(${suidRef})`);
612
- return new MLDoc({
613
- bilaraPaths: [], // legacy have no paths
614
- lang,
615
- author_uid,
616
- segMap,
617
- suttaplex,
618
- segmented,
619
- sutta_uid,
620
- langSegs: {
621
- [lang]: segments.length,
622
- },
623
- });
624
- } catch (e) {
625
- this.warn(`loadMLDocLegacy(${suidRef})`, e.message);
626
- throw e;
627
- }
628
- }
629
-
630
593
  canonicalSuttaId(id, type="acro") {
631
- const msg = 'BilaraData.canonicalSuttaId()';
594
+ const msg = 'B8a.canonicalSuttaId()';
632
595
  if (!this.initialized) {
633
596
  let emsg = `${msg}, initialize() required`;
634
597
  throw new Error(emsg);
@@ -851,7 +814,7 @@
851
814
  }
852
815
 
853
816
  expandRange(suttaRef) {
854
- const msg = "BilaraData.expandRange";
817
+ const msg = "B8a.expandRange";
855
818
  const dbg = DBG.SUTTA_UIDSEARCH;
856
819
  suttaRef = suttaRef.split(":")[0];
857
820
  var reCollection = new RegExp("[0-9].*", "u");
@@ -950,7 +913,7 @@
950
913
  }
951
914
 
952
915
  sutta_uidSearch(pattern, maxResults = 5) {
953
- const msg = 'BilaraData.sutta_uidSearch() ';
916
+ const msg = 'B8a.sutta_uidSearch() ';
954
917
  const dbg = DBG.SUTTA_UIDSEARCH;
955
918
  var method = "sutta_uid";
956
919
  var uids = this.suttaList(pattern).slice(0, maxResults);
@@ -1,396 +1,396 @@
1
1
  (function(exports) {
2
- const fs = require('fs');
3
- const path = require('path');
4
- const { logger } = require('log-instance');
5
- const { Files } = require('memo-again');
6
- const { AuthorsV2, BilaraPath, SuttaCentralId } = require("scv-esm");
7
- const STUBFILESIZE = 5;
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const { logger } = require('log-instance');
5
+ const { Files } = require('memo-again');
6
+ const { AuthorsV2, BilaraPath, SuttaCentralId } = require("scv-esm");
7
+ const STUBFILESIZE = 5;
8
8
 
9
- class BilaraPathMap {
10
- constructor(opts = {}) {
11
- (opts.logger || logger).logInstance(this);
12
- this.root = opts.root ||
13
- path.join(Files.LOCAL_DIR, "bilara-data");
14
- let rootDir = path.dirname(this.root);
15
- let rootName = this.root.replace(rootDir,'').substring(1);
16
- this.rootLang = opts.rootLang || 'pli';
17
- this.rootAuthor = opts.rootAuthor || 'ms';
18
- if (opts.suidMapFile) {
19
- this.suidMapFile = opts.suidMapFile;
20
- } else if ( rootName === 'ebt-data') {
21
- this.suidMapFile = path.join(__dirname, "auto", "suidmap.json");
22
- } else {
23
- this.suidMapFile = path.join(rootDir, `suidmap-${rootName}.json`);
24
- }
25
- this.validatePath = opts.validatePath || ((key,value,suid)=>true);
26
- this.publication = opts.publication;
27
- this.initialized = false;
28
- }
9
+ class BilaraPathMap {
10
+ constructor(opts = {}) {
11
+ (opts.logger || logger).logInstance(this);
12
+ this.root = opts.root ||
13
+ path.join(Files.LOCAL_DIR, "ebt-data");
14
+ let rootDir = path.dirname(this.root);
15
+ let rootName = this.root.replace(rootDir,'').substring(1);
16
+ this.rootLang = opts.rootLang || 'pli';
17
+ this.rootAuthor = opts.rootAuthor || 'ms';
18
+ if (opts.suidMapFile) {
19
+ this.suidMapFile = opts.suidMapFile;
20
+ } else if ( rootName === 'ebt-data') {
21
+ this.suidMapFile = path.join(__dirname, "auto", "suidmap.json");
22
+ } else {
23
+ this.suidMapFile = path.join(rootDir, `suidmap-${rootName}.json`);
24
+ }
25
+ this.validatePath = opts.validatePath || ((key,value,suid)=>true);
26
+ this.publication = opts.publication;
27
+ this.initialized = false;
28
+ }
29
29
 
30
- static get ALL_TYPES() { return [
31
- 'root',
32
- 'translation',
33
- 'html',
34
- 'variant',
35
- 'reference',
36
- 'comment',
37
- ]};
30
+ static get ALL_TYPES() { return [
31
+ 'root',
32
+ 'translation',
33
+ 'html',
34
+ 'variant',
35
+ 'reference',
36
+ 'comment',
37
+ ]};
38
38
 
39
- static langAuthorRegExp(lang, author) {
40
- return lang && author
41
- ? new RegExp(`-${lang}-${author}.json`, "i")
42
- : undefined;
43
- }
39
+ static langAuthorRegExp(lang, author) {
40
+ return lang && author
41
+ ? new RegExp(`-${lang}-${author}.json`, "i")
42
+ : undefined;
43
+ }
44
44
 
45
- async initialize() { try {
46
- var { suidMapFile } = this;
47
- let suidMap;
45
+ async initialize() { try {
46
+ var { suidMapFile } = this;
47
+ let suidMap;
48
48
 
49
- if (fs.existsSync(suidMapFile)) {
50
- try {
51
- suidMap = JSON.parse(
52
- await fs.promises.readFile(suidMapFile))
53
- } catch (e) {
54
- this.warn(`initialize() ${e.message} => rebuilding ${suidMapFile}`);
55
- }
56
- }
57
- if (!suidMap) {
58
- this.info(`initialize() building ${suidMapFile}`);
59
- suidMap = this.buildSuidMap();
49
+ if (fs.existsSync(suidMapFile)) {
50
+ try {
51
+ suidMap = JSON.parse(
52
+ await fs.promises.readFile(suidMapFile))
53
+ } catch (e) {
54
+ this.warn(`initialize() ${e.message} => rebuilding ${suidMapFile}`);
60
55
  }
61
- this.suidMap = await suidMap;
62
- this.initialized = true;
63
- return this;
64
- } catch(e) {
65
- this.warn(`initialize()`, suidMapFile, e.message);
66
- throw e;
67
- }}
56
+ }
57
+ if (!suidMap) {
58
+ this.info(`initialize() building ${suidMapFile}`);
59
+ suidMap = this.buildSuidMap();
60
+ }
61
+ this.suidMap = await suidMap;
62
+ this.initialized = true;
63
+ return this;
64
+ } catch(e) {
65
+ this.warn(`initialize()`, suidMapFile, e.message);
66
+ throw e;
67
+ }}
68
68
 
69
- async tipitakaPaths(opts={}) { try {
70
- var {
71
- root,
72
- rootLang,
73
- rootAuthor,
74
- } = this;
75
- let {
76
- lang=rootLang,
77
- author=rootAuthor,
78
- } = opts;
79
- var takaPath = path.join(root,
80
- lang===rootLang ? 'root' : 'translation',
81
- lang,
82
- author,
83
- '/',
84
- );
85
- var readOpts = {withFileTypes:true};
86
- var exclude = [
87
- '[0-9]',
88
- 'playground', // Blake
89
- ].join('|');
90
- var reExclude = new RegExp(`(${exclude})`,"ui");
91
- let pathStack = [];
92
- let pathList = [];
93
- if (fs.existsSync(takaPath)) {
94
- pathStack.push(takaPath);
69
+ async tipitakaPaths(opts={}) { try {
70
+ var {
71
+ root,
72
+ rootLang,
73
+ rootAuthor,
74
+ } = this;
75
+ let {
76
+ lang=rootLang,
77
+ author=rootAuthor,
78
+ } = opts;
79
+ var takaPath = path.join(root,
80
+ lang===rootLang ? 'root' : 'translation',
81
+ lang,
82
+ author,
83
+ '/',
84
+ );
85
+ var readOpts = {withFileTypes:true};
86
+ var exclude = [
87
+ '[0-9]',
88
+ 'playground', // Blake
89
+ ].join('|');
90
+ var reExclude = new RegExp(`(${exclude})`,"ui");
91
+ let pathStack = [];
92
+ let pathList = [];
93
+ if (fs.existsSync(takaPath)) {
94
+ pathStack.push(takaPath);
95
+ }
96
+ while (pathStack.length) {
97
+ let dirPath = pathStack.pop();
98
+ if (reExclude.test(dirPath)) {
99
+ this.info(`tipitakaPaths() exclude:`, dirPath);
100
+ continue;
95
101
  }
96
- while (pathStack.length) {
97
- let dirPath = pathStack.pop();
98
- if (reExclude.test(dirPath)) {
99
- this.info(`tipitakaPaths() exclude:`, dirPath);
100
- continue;
102
+ var dirKids = fs.readdirSync(dirPath, readOpts);
103
+ let relativePath = dirPath.replace(takaPath, '');
104
+ relativePath && pathList.push(relativePath);
105
+ for (var i = 0; i < dirKids.length; i++) {
106
+ var e = dirKids[i];
107
+ if (e.isDirectory()) {
108
+ let kidPath = path.join(dirPath, e.name);
109
+ pathStack.push(kidPath);
101
110
  }
102
- var dirKids = fs.readdirSync(dirPath, readOpts);
103
- let relativePath = dirPath.replace(takaPath, '');
104
- relativePath && pathList.push(relativePath);
105
- for (var i = 0; i < dirKids.length; i++) {
106
- var e = dirKids[i];
107
- if (e.isDirectory()) {
108
- let kidPath = path.join(dirPath, e.name);
109
- pathStack.push(kidPath);
110
- }
111
- }
112
- }
113
- return pathList.sort();
114
- } catch(e) {
115
- this.warn(`tipitakaPaths()`, e.message);
116
- throw e;
117
- }}
118
-
119
- bilaraPaths(opts={}) {
120
- const msg = 'BilaraPathMap.bilaraPaths()';
121
- const dbg = 0;
122
- if (typeof opts === 'string') {
123
- opts = { suid: opts };
124
111
  }
125
- var {
126
- suid,
127
- lang,
128
- author,
129
- types,
130
- refAuthor,
131
- } = opts;
132
- types = types || ['root','translation'];
133
- var reTypes = new RegExp(`^(${types.join('|')})`, 'u');
134
- var paths = this.suidPaths(suid) || [];
135
- dbg && console.log(msg, {paths});
136
- var bps = Object.keys(paths).reduce((a,k) => {
137
- var bp = paths[k];
138
- reTypes.test(bp) && a.push(bp);
139
- return a;
140
- },[]);
141
- if (typeof lang === 'string') {
142
- let re = new RegExp(`/${lang}/`,'u');
143
- bps = bps.filter(bp => re.test(bp));
144
- } else if (lang instanceof Array) {
145
- let re = new RegExp(`/(${lang.join('|')})/`,'u');
146
- bps = bps.filter(bp => re.test(bp));
147
- }
148
- if (author) {
149
- let re = new RegExp(`.*-${author}.json`,'u');
150
- bps = bps.filter(bp => re.test(bp));
151
- }
152
-
153
- return bps.map(bp => new BilaraPath(bp));;
154
112
  }
113
+ return pathList.sort();
114
+ } catch(e) {
115
+ this.warn(`tipitakaPaths()`, e.message);
116
+ throw e;
117
+ }}
155
118
 
156
-
157
- transPath(rootPath, lang, author) {
158
- const msg = "BilaraPathMap.transPat()";
159
- const dbg = 0;
160
- let { root } = this;
161
- let bilaraPath = rootPath
162
- .replace(/root/g, 'translation')
163
- .replace(/pli/g, lang)
164
- .replace(/ms/g, author);
165
- let fullPath = path.join(root, bilaraPath);
166
- if (!fs.existsSync(fullPath)) {
167
- dbg && console.log(msg, '[1]!existsSync', {fullPath});
168
- return null;
169
- }
170
- let stats = fs.statSync(fullPath);
171
- if (stats.size < 5) {
172
- dbg && console.log(msg, '[2]!size', {fullPath});
173
- return null;
174
- }
175
-
176
- dbg && console.log(msg, '[3]ok', bilaraPath);
177
- return bilaraPath;
119
+ bilaraPaths(opts={}) {
120
+ const msg = 'BilaraPathMap.bilaraPaths()';
121
+ const dbg = 0;
122
+ if (typeof opts === 'string') {
123
+ opts = { suid: opts };
178
124
  }
179
-
180
- trilingualPaths(opts={}) {
181
- const msg = "BilaraPathMap.trilingualPaths() ";
182
- const dbg = 0;
183
- let {
125
+ var {
184
126
  suid,
185
- rootLang = 'pli',
186
- rootAuthor = 'ms',
187
- refLang,
127
+ lang,
128
+ author,
129
+ types,
188
130
  refAuthor,
189
- docLang,
190
- docAuthor,
191
- } = opts;
192
- let { root } = this;
193
- if (!refAuthor && !refLang) {
194
- refLang = 'en';
195
- refAuthor = 'sujato';
196
- }
197
-
198
- let pathMap = this.suidPaths(suid);
199
- let paths = Object.keys(pathMap).reduce((a,k)=>{
200
- a.push(pathMap[k]);
131
+ } = opts;
132
+ types = types || ['root','translation'];
133
+ var reTypes = new RegExp(`^(${types.join('|')})`, 'u');
134
+ var paths = this.suidPaths(suid) || [];
135
+ dbg && console.log(msg, {paths});
136
+ var bps = Object.keys(paths).reduce((a,k) => {
137
+ var bp = paths[k];
138
+ reTypes.test(bp) && a.push(bp);
201
139
  return a;
202
- }, []);
203
-
204
- let { langAuthorRegExp } = BilaraPathMap;
205
- let reRoot = langAuthorRegExp(rootLang, rootAuthor);
206
- let mldPaths = paths.filter(p=>reRoot && reRoot.test(p));
207
- let rootPath = mldPaths[0];
208
- if (rootPath) {
209
- let docPath = this.transPath(rootPath, docLang, docAuthor);
210
- let refPath = this.transPath(rootPath, refLang, refAuthor);
211
- if (docPath) {
212
- mldPaths.push(docPath);
213
- }
214
- if (refPath && refPath !== docPath) {
215
- mldPaths.push(refPath);
216
- }
217
- dbg && console.log(msg, mldPaths);
218
- }
219
- dbg && console.log(msg, {mldPaths});
220
- return mldPaths;
140
+ },[]);
141
+ if (typeof lang === 'string') {
142
+ let re = new RegExp(`/${lang}/`,'u');
143
+ bps = bps.filter(bp => re.test(bp));
144
+ } else if (lang instanceof Array) {
145
+ let re = new RegExp(`/(${lang.join('|')})/`,'u');
146
+ bps = bps.filter(bp => re.test(bp));
221
147
  }
222
-
223
- suidPaths(suid) {
224
- if (!this.initialized) {
225
- throw new Error(`initialize() has not been called`);
226
- }
227
- if (!suid) {
228
- throw new Error('BilaraPathMap.suidPaths() suid is required');
229
- }
230
- var suidParts = suid.split('/');
231
- var key = suidParts[0];
232
- let map = this.suidMap[key];
233
- return map && Object.keys(map).reduce((a,k) => {
234
- let v = map[k];
235
- let kParts = k.split('/');
236
- let vParts = v.split('/');
237
- let suidParts = suid.split('/');
238
- a[k] = `${k}/${v}/${suidParts[0]}_${kParts.join('-')}.json`;
239
- return a;
240
- }, {});
148
+ if (author) {
149
+ let re = new RegExp(`.*-${author}.json`,'u');
150
+ bps = bps.filter(bp => re.test(bp));
241
151
  }
242
152
 
243
- suidLanguages(suid) {
244
- let suidPaths = this.suidPaths(suid);
245
- return !suidPaths
246
- ? undefined
247
- : Object.keys(suidPaths)
248
- .sort()
249
- .reduce((a,k)=>{
250
- let bilaraPath = suidPaths[k];
251
- if (/^(translation|root)/.test(bilaraPath)) {
252
- let [type,lang,author,category,nikaya] =
253
- bilaraPath.split('/');
254
- a.push({
255
- suid: suid.split('/')[0],
256
- lang,
257
- author,
258
- category,
259
- nikaya,
260
- bilaraPath,
261
- });
262
- }
263
- return a;
264
- },[]);
153
+ return bps.map(bp => new BilaraPath(bp));;
154
+ }
155
+
156
+
157
+ transPath(rootPath, lang, author) {
158
+ const msg = "BilaraPathMap.transPat()";
159
+ const dbg = 0;
160
+ let { root } = this;
161
+ let bilaraPath = rootPath
162
+ .replace(/root/g, 'translation')
163
+ .replace(/pli/g, lang)
164
+ .replace(/ms/g, author);
165
+ let fullPath = path.join(root, bilaraPath);
166
+ if (!fs.existsSync(fullPath)) {
167
+ dbg && console.log(msg, '[1]!existsSync', {fullPath});
168
+ return null;
169
+ }
170
+ let stats = fs.statSync(fullPath);
171
+ if (stats.size < 5) {
172
+ dbg && console.log(msg, '[2]!size', {fullPath});
173
+ return null;
174
+ }
175
+
176
+ dbg && console.log(msg, '[3]ok', bilaraPath);
177
+ return bilaraPath;
178
+ }
179
+
180
+ trilingualPaths(opts={}) {
181
+ const msg = "BilaraPathMap.trilingualPaths() ";
182
+ const dbg = 0;
183
+ let {
184
+ suid,
185
+ rootLang = 'pli',
186
+ rootAuthor = 'ms',
187
+ refLang,
188
+ refAuthor,
189
+ docLang,
190
+ docAuthor,
191
+ } = opts;
192
+ let { root } = this;
193
+ if (!refAuthor && !refLang) {
194
+ refLang = 'en';
195
+ refAuthor = 'sujato';
196
+ }
197
+
198
+ let pathMap = this.suidPaths(suid);
199
+ let paths = Object.keys(pathMap).reduce((a,k)=>{
200
+ a.push(pathMap[k]);
201
+ return a;
202
+ }, []);
203
+
204
+ let { langAuthorRegExp } = BilaraPathMap;
205
+ let reRoot = langAuthorRegExp(rootLang, rootAuthor);
206
+ let mldPaths = paths.filter(p=>reRoot && reRoot.test(p));
207
+ let rootPath = mldPaths[0];
208
+ if (rootPath) {
209
+ let docPath = this.transPath(rootPath, docLang, docAuthor);
210
+ let refPath = this.transPath(rootPath, refLang, refAuthor);
211
+ if (docPath) {
212
+ mldPaths.push(docPath);
265
213
  }
214
+ if (refPath && refPath !== docPath) {
215
+ mldPaths.push(refPath);
216
+ }
217
+ dbg && console.log(msg, mldPaths);
218
+ }
219
+ dbg && console.log(msg, {mldPaths});
220
+ return mldPaths;
221
+ }
266
222
 
267
- suidPath(suid) {
268
- if (!suid) {
269
- throw new Error('BilaraPathMap.suidPath() suid is required');
270
- }
271
- var pathInfo = this.suidPaths(suid);
272
- var suidParts = suid.split('/');
273
- var key = suidParts.length === 1
274
- ? `root/pli/ms`
275
- : `translation/${suidParts[1]}/${suidParts[2]}`;
276
- return pathInfo && pathInfo[key];
223
+ suidPaths(suid) {
224
+ if (!this.initialized) {
225
+ throw new Error(`initialize() has not been called`);
226
+ }
227
+ if (!suid) {
228
+ throw new Error('BilaraPathMap.suidPaths() suid is required');
277
229
  }
230
+ var suidParts = suid.split('/');
231
+ var key = suidParts[0];
232
+ let map = this.suidMap[key];
233
+ return map && Object.keys(map).reduce((a,k) => {
234
+ let v = map[k];
235
+ let kParts = k.split('/');
236
+ let vParts = v.split('/');
237
+ let suidParts = suid.split('/');
238
+ a[k] = `${k}/${v}/${suidParts[0]}_${kParts.join('-')}.json`;
239
+ return a;
240
+ }, {});
241
+ }
278
242
 
279
- async _loadPaths(key) { try {
280
- var {
281
- root,
282
- suidMap,
283
- validatePath,
284
- publication,
285
- } = this;
286
- var keyRoot = path.join(root, key);
287
- var rootPrefix = `${root}/`;
288
- var readOpts = {withFileTypes:true};
289
- var exclude = [
290
- 'abhidhamma', // (later)
291
- '\bma\b', // Chinese
292
- '\bsa\b', // Chinese
293
- 'site',
294
- 'sc-page',
295
- 'blurb',
296
- 'name', // metadata
297
- 'playground', // Blake
298
- ].join('|');
299
- var reExclude = new RegExp(`(${exclude})`,"ui");
300
- var traverse = (dirPath)=>{
301
- if (reExclude.test(dirPath)) {
302
- this.debug(`_loadPaths(${key}) exclude:`, dirPath);
303
- return;
304
- }
305
- var dirKids = fs.readdirSync(dirPath, readOpts);
306
- for (var i = 0; i < dirKids.length; i++) {
307
- var e = dirKids[i];
308
- if (e.isDirectory()) {
309
- let kidPath = path.join(dirPath, e.name);
310
- traverse(kidPath);
311
- } else if (/.*json$/u.test(e.name)) {
312
- var ePath = path.join(dirPath, e.name);
313
- var stat = fs.statSync(ePath);
314
- if (stat.size <= STUBFILESIZE) {
315
- // ignore stub file
316
- } else if (publication && !publication.isPublishedPath(ePath)) {
317
- this.debug(`skipping ${ePath}`);
318
- } else {
319
- let suid = e.name.replace(/_.*/,'');
320
- let suidPath = dirPath.replace(rootPrefix, '')
321
- + `/${e.name}`;
322
- let valueParts = suidPath
323
- .replace(new RegExp(`${key}/`),'')
324
- .split('/');
325
- valueParts.pop();
326
- let value = valueParts.join('/');
327
- if (validatePath(key,value,suid)) {
328
- (suidMap[suid] = suidMap[suid] || {})[key] = value;
329
- }
330
- }
243
+ suidLanguages(suid) {
244
+ let suidPaths = this.suidPaths(suid);
245
+ return !suidPaths
246
+ ? undefined
247
+ : Object.keys(suidPaths)
248
+ .sort()
249
+ .reduce((a,k)=>{
250
+ let bilaraPath = suidPaths[k];
251
+ if (/^(translation|root)/.test(bilaraPath)) {
252
+ let [type,lang,author,category,nikaya] =
253
+ bilaraPath.split('/');
254
+ a.push({
255
+ suid: suid.split('/')[0],
256
+ lang,
257
+ author,
258
+ category,
259
+ nikaya,
260
+ bilaraPath,
261
+ });
331
262
  }
332
- }
333
- };
334
- let msStart = Date.now();
335
- fs.existsSync(keyRoot) && traverse(keyRoot);
336
- return suidMap;
337
- } catch(e) {
338
- this.warn(`_loadPaths(${key})`, e.message);
339
- throw e;
340
- }}
263
+ return a;
264
+ },[]);
265
+ }
341
266
 
342
- async buildSuidMap(opts={}) {
343
- let msStart = Date.now();
344
- let {
345
- loadHtml = false,
346
- loadVariant = false,
347
- loadReference = false,
348
- loadComment = false,
349
- } = opts;
350
- var readdir = fs.promises.readdir;
351
- let suidMap = this.suidMap = {};
352
- var transPath = path.join(this.root, "translation");
353
- var rdOpts = {withFileTypes:true};
354
- var langs = (await readdir(transPath, rdOpts))
355
- .reduce((a,e)=> (e.isDirectory()
356
- ? [...a,e.name] : a),[]);
357
- for (var il=0; il < langs.length; il++) {
358
- var l = langs[il];
359
- var authPath = path.join(transPath,l);
360
- var auths = (await readdir(authPath, rdOpts))
361
- .reduce((a,e)=>(e.isDirectory()
362
- ? [...a,e.name] : a), []);
363
- for (var ia=0; ia < auths.length; ia++) {
364
- var key = `translation/${l}/${auths[ia]}`;
365
- if (/en\/(patton|comm-team)/.test(key)) {
366
- continue; // ignore lzh->en translations
367
- }
368
- await this._loadPaths(key);
369
- if (loadComment) {
370
- let key = `comment/${l}/${auths[ia]}`;
371
- await this._loadPaths(key);
267
+ suidPath(suid) {
268
+ if (!suid) {
269
+ throw new Error('BilaraPathMap.suidPath() suid is required');
270
+ }
271
+ var pathInfo = this.suidPaths(suid);
272
+ var suidParts = suid.split('/');
273
+ var key = suidParts.length === 1
274
+ ? `root/pli/ms`
275
+ : `translation/${suidParts[1]}/${suidParts[2]}`;
276
+ return pathInfo && pathInfo[key];
277
+ }
278
+
279
+ async _loadPaths(key) { try {
280
+ var {
281
+ root,
282
+ suidMap,
283
+ validatePath,
284
+ publication,
285
+ } = this;
286
+ var keyRoot = path.join(root, key);
287
+ var rootPrefix = `${root}/`;
288
+ var readOpts = {withFileTypes:true};
289
+ var exclude = [
290
+ 'abhidhamma', // (later)
291
+ '\bma\b', // Chinese
292
+ '\bsa\b', // Chinese
293
+ 'site',
294
+ 'sc-page',
295
+ 'blurb',
296
+ 'name', // metadata
297
+ 'playground', // Blake
298
+ ].join('|');
299
+ var reExclude = new RegExp(`(${exclude})`,"ui");
300
+ var traverse = (dirPath)=>{
301
+ if (reExclude.test(dirPath)) {
302
+ this.debug(`_loadPaths(${key}) exclude:`, dirPath);
303
+ return;
304
+ }
305
+ var dirKids = fs.readdirSync(dirPath, readOpts);
306
+ for (var i = 0; i < dirKids.length; i++) {
307
+ var e = dirKids[i];
308
+ if (e.isDirectory()) {
309
+ let kidPath = path.join(dirPath, e.name);
310
+ traverse(kidPath);
311
+ } else if (/.*json$/u.test(e.name)) {
312
+ var ePath = path.join(dirPath, e.name);
313
+ var stat = fs.statSync(ePath);
314
+ if (stat.size <= STUBFILESIZE) {
315
+ // ignore stub file
316
+ } else if (publication && !publication.isPublishedPath(ePath)) {
317
+ this.debug(`skipping ${ePath}`);
318
+ } else {
319
+ let suid = e.name.replace(/_.*/,'');
320
+ let suidPath = dirPath.replace(rootPrefix, '')
321
+ + `/${e.name}`;
322
+ let valueParts = suidPath
323
+ .replace(new RegExp(`${key}/`),'')
324
+ .split('/');
325
+ valueParts.pop();
326
+ let value = valueParts.join('/');
327
+ if (validatePath(key,value,suid)) {
328
+ (suidMap[suid] = suidMap[suid] || {})[key] = value;
329
+ }
372
330
  }
373
331
  }
374
332
  }
375
- suidMap = Object.keys(suidMap)
376
- .sort(SuttaCentralId.compareLow)
377
- .reduce((a,k) =>{
378
- a[k] = suidMap[k];
379
- return a;
380
- }, {});
381
- this.suidMap = suidMap;
333
+ };
334
+ let msStart = Date.now();
335
+ fs.existsSync(keyRoot) && traverse(keyRoot);
336
+ return suidMap;
337
+ } catch(e) {
338
+ this.warn(`_loadPaths(${key})`, e.message);
339
+ throw e;
340
+ }}
382
341
 
383
- await this._loadPaths("root/pli/ms");
384
- loadHtml && await this._loadPaths("html/pli/ms");
385
- loadReference &&await this._loadPaths("reference/pli/ms");
386
- loadVariant && await this._loadPaths("variant/pli/ms");
387
- let { suidMapFile } = this;
388
- await fs.promises.writeFile(suidMapFile, JSON.stringify(suidMap, null, '\t'));
389
- this.info(`buildSuidMap() ${suidMapFile} ${Date.now()-msStart}ms`);
390
- return suidMap;
391
- }
342
+ async buildSuidMap(opts={}) {
343
+ let msStart = Date.now();
344
+ let {
345
+ loadHtml = false,
346
+ loadVariant = false,
347
+ loadReference = false,
348
+ loadComment = false,
349
+ } = opts;
350
+ var readdir = fs.promises.readdir;
351
+ let suidMap = this.suidMap = {};
352
+ var transPath = path.join(this.root, "translation");
353
+ var rdOpts = {withFileTypes:true};
354
+ var langs = (await readdir(transPath, rdOpts))
355
+ .reduce((a,e)=> (e.isDirectory()
356
+ ? [...a,e.name] : a),[]);
357
+ for (var il=0; il < langs.length; il++) {
358
+ var l = langs[il];
359
+ var authPath = path.join(transPath,l);
360
+ var auths = (await readdir(authPath, rdOpts))
361
+ .reduce((a,e)=>(e.isDirectory()
362
+ ? [...a,e.name] : a), []);
363
+ for (var ia=0; ia < auths.length; ia++) {
364
+ var key = `translation/${l}/${auths[ia]}`;
365
+ if (/en\/(patton|comm-team)/.test(key)) {
366
+ continue; // ignore lzh->en translations
367
+ }
368
+ await this._loadPaths(key);
369
+ if (loadComment) {
370
+ let key = `comment/${l}/${auths[ia]}`;
371
+ await this._loadPaths(key);
372
+ }
373
+ }
374
+ }
375
+ suidMap = Object.keys(suidMap)
376
+ .sort(SuttaCentralId.compareLow)
377
+ .reduce((a,k) =>{
378
+ a[k] = suidMap[k];
379
+ return a;
380
+ }, {});
381
+ this.suidMap = suidMap;
382
+
383
+ await this._loadPaths("root/pli/ms");
384
+ loadHtml && await this._loadPaths("html/pli/ms");
385
+ loadReference &&await this._loadPaths("reference/pli/ms");
386
+ loadVariant && await this._loadPaths("variant/pli/ms");
387
+ let { suidMapFile } = this;
388
+ await fs.promises.writeFile(suidMapFile, JSON.stringify(suidMap, null, '\t'));
389
+ this.info(`buildSuidMap() ${suidMapFile} ${Date.now()-msStart}ms`);
390
+ return suidMap;
392
391
  }
392
+ }
393
393
 
394
- module.exports = exports.BilaraPathMap = BilaraPathMap;
394
+ module.exports = exports.BilaraPathMap = BilaraPathMap;
395
395
  })(typeof exports === "object" ? exports : (exports = {}));
396
396
 
package/src/defines.cjs CHANGED
@@ -6,7 +6,9 @@ module.exports.DBG_MLD = 0;
6
6
  module.exports.DBG = {
7
7
  FIND: 0,
8
8
  FINDARGS: 0,
9
+ MLD_CTOR: 0,
9
10
  MLD_LOAD: 0,
11
+ MLD_TITLES: 0,
10
12
  SEEKER: 0,
11
13
  SEARCH_SCRIPT: 0,
12
14
  SLOWFIND: 0,
package/src/ml-doc.js CHANGED
@@ -3,7 +3,7 @@ const fs = require("fs");
3
3
  const path = require("path");
4
4
  const { logger } = require('log-instance');
5
5
  const { Files } = require('memo-again');
6
- const { BilaraPath } = require("scv-esm");
6
+ const { AuthorsV2, BilaraPath } = require("scv-esm");
7
7
  const Unicode = require('./unicode');
8
8
  const Pali = require('./pali');
9
9
  const { SuttaCentralId } = require('scv-esm');
@@ -12,31 +12,68 @@ const { DBG, DBG_MLD, } = require("./defines.cjs");
12
12
 
13
13
  class MLDoc {
14
14
  constructor(opts = {}) {
15
+ const msg = 'M3c.ctor:';
16
+ const dbg = DBG.MLD_CTOR;
17
+ dbg>1 && console.log(msg, '[1]opts', opts);
15
18
  (opts.logger || logger).logInstance(this, opts);
16
19
  var {
20
+ author,
21
+ author_uid,
17
22
  bilaraPaths,
23
+ category = 'sutta',
24
+ docAuthorName,
25
+ footer = MLDoc.SC_FOOTER,
26
+ hyphen = "\u00ad",
27
+ lang,
28
+ langSegs,
29
+ maxWord = 30,
30
+ minWord = 5,
31
+ score = 0, // search relevance
32
+ segMap = {},
33
+ segsMatched,
34
+ sutta_uid,
35
+ title,
36
+ trilingual,
37
+ type = 'translation',
18
38
  } = opts;
19
39
  if (bilaraPaths == null) {
20
40
  throw new Error(`bilaraPaths is required`);
21
41
  }
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;
42
+ lang = lang || MLDoc.bilaraPathLanguages(bilaraPaths, lang).pop();
43
+ if (author == null) {
44
+ let aInfo = AuthorsV2.authorInfo(author_uid);
45
+ author = aInfo?.name?.join(', ');
46
+ }
47
+ if (author) {
48
+ this.author = author;
49
+ }
50
+
51
+ Object.assign(this, {
52
+ segMap, // For console debugging, this is first
53
+
54
+ author,
55
+ author_uid,
56
+ bilaraPaths,
57
+ category,
58
+ footer,
59
+ hyphen,
60
+ lang,
61
+ langSegs,
62
+ maxWord,
63
+ minWord,
64
+ score,
65
+ segsMatched,
66
+ sutta_uid,
67
+ title,
68
+ type,
69
+ });
70
+ if (trilingual) {
71
+ this.trilingual = trilingual;
38
72
  this.docLang = opts.docLang;
39
73
  this.docAuthor = opts.docAuthor;
74
+ if (author) {
75
+ this.docAuthorName = docAuthorName || author;
76
+ }
40
77
  this.refLang = opts.refLang || 'en';
41
78
  this.refAuthor = opts.refAuthor || 'sujato';
42
79
  }
@@ -45,6 +82,14 @@ class MLDoc {
45
82
  });
46
83
  }
47
84
 
85
+ static get SC_FOOTER() {
86
+ return [
87
+ '<a href="https://suttacentral.net/licensing">',
88
+ 'Creative Commons Zero (CC0 1.0 Universal)',
89
+ '</a>',
90
+ ].join('');
91
+ }
92
+
48
93
  static compare(m1, m2) {
49
94
  var cmp = m2.score - m1.score;
50
95
  return cmp ? cmp : SuttaCentralId.compareLow(m1.suid, m2.suid);
@@ -122,7 +167,7 @@ class MLDoc {
122
167
 
123
168
  titles(lang = this.lang) {
124
169
  const msg = 'M3c.titles:';
125
- const dbg = DBG.MLD_LOAD;
170
+ const dbg = DBG.MLD_TITLES;
126
171
  let headSegs = this.segments().slice(0,4);
127
172
  dbg && console.log(msg, {lang, headSegs});
128
173
  var titles = headSegs.slice(0, 4).reduce((a, s, i) => {
@@ -149,11 +194,7 @@ class MLDoc {
149
194
  return result;
150
195
  }
151
196
 
152
- languages() {
153
- let {
154
- bilaraPaths,
155
- lang,
156
- } = this;
197
+ static bilaraPathLanguages(bilaraPaths, lang='en') {
157
198
  return bilaraPaths.length
158
199
  ? Object.keys(bilaraPaths.reduce((a, bp) => {
159
200
  a[bp.split('/')[1]] = true;
@@ -235,6 +276,9 @@ class MLDoc {
235
276
  this.author = header.author;
236
277
  this.author_uid = header.author_uid;
237
278
  this.footer = header.footer;
279
+ if (trilingual) {
280
+ this.docAuthorName = this.author;
281
+ }
238
282
 
239
283
  dbg && console.log(msg, '[3]header', header);
240
284
  }
package/src/seeker.cjs CHANGED
@@ -1038,25 +1038,7 @@
1038
1038
  `${suid}/${refLang || lang}/${author}`
1039
1039
  );
1040
1040
  } else {
1041
- this.debug(`slowFind() -> loadMLDocLegacy(${suid}/${lang})`);
1042
- try {
1043
- mld = await bd.loadMLDocLegacy(suttaRef);
1044
- mlDocs.push(mld);
1045
- matchingRefs.push(suttaRef);
1046
- var resFilter = mld.filterSegments({
1047
- pattern,
1048
- resultPattern,
1049
- languages: [searchLang],
1050
- showMatchesOnly,
1051
- });
1052
- segsMatched += resFilter.matched;
1053
- mld.segsMatched = resFilter.matched;
1054
- if (matchHighlight) {
1055
- mld.highlightMatch(resultPattern, matchHighlight);
1056
- }
1057
- } catch (e) {
1058
- this.warn(`suid:${suid} =>`, e.message);
1059
- }
1041
+ this.warn(`NOT SUPPORTED: legacy ${suid}`);
1060
1042
  }
1061
1043
  }
1062
1044
  }