@@ -54,22 +54,24 @@ function isInflectionGloss(glosses, formOf) {
54
54
}
55
55
56
56
/**
57
- * @param {GlossTree } glossTree
57
+ * @param {GlossTwig } glossTwig
58
58
* @param {number } level
59
- * @returns {* }
59
+ * @returns {import('types').TermBank.StructuredContent[] }
60
60
*/
61
- function handleLevel ( glossTree , level ) {
61
+ function handleLevel ( glossTwig , level ) {
62
+ /** @type {import('types').TermBank.StructuredContent[] } */
62
63
const nestDefs = [ ] ;
63
64
let defIndex = 0 ;
64
65
65
- for ( const [ def , children ] of glossTree ) {
66
+ for ( const [ def , children ] of glossTwig ) {
66
67
defIndex += 1 ;
67
68
68
69
if ( children . size > 0 ) {
69
70
const nextLevel = level + 1 ;
70
71
const childDefs = handleLevel ( children , nextLevel ) ;
71
72
72
73
const listType = level === 1 ? "li" : "number" ;
74
+ /** @type {import('types').TermBank.StructuredContent } */
73
75
const content = level === 1 ? def : [ { "tag" : "span" , "data" : { "listType" : "number" } , "content" : `${ defIndex } . ` } , def ] ;
74
76
75
77
nestDefs . push ( [
@@ -85,11 +87,11 @@ function handleLevel(glossTree, level) {
85
87
}
86
88
87
89
/**
88
- * @param {GlossTree } glossTree
90
+ * @param {GlossTwig } glossTwig
89
91
* @param {SenseInfo } sense
90
92
*/
91
- function handleNest ( glossTree , sense ) {
92
- const nestedGloss = handleLevel ( glossTree , 1 ) ;
93
+ function handleNest ( glossTwig , sense ) {
94
+ const nestedGloss = handleLevel ( glossTwig , 1 ) ;
93
95
94
96
if ( nestedGloss . length > 0 ) {
95
97
for ( const entry of nestedGloss ) {
@@ -227,45 +229,116 @@ function handleLine(parsedLine) {
227
229
saveIpaResult ( word , readings , pos , ipaObj ) ;
228
230
}
229
231
230
- /** @type {GlossTree } */
232
+ const glossTree = getGlossTree ( sensesWithoutInflectionGlosses ) ;
233
+
234
+ for ( const [ gloss , branches ] of glossTree ) {
235
+ const tags = branches . get ( '_tags' ) || [ ] ;
236
+ const examples = branches . get ( '_examples' ) || [ ] ;
237
+ branches . delete ( '_tags' ) ;
238
+ branches . delete ( '_examples' ) ;
239
+
240
+ /** @type {SenseInfo } */
241
+ const currSense = { glosses : [ ] , tags, examples } ;
242
+ if ( branches . size === 0 ) {
243
+ if ( examples . length > 0 ) {
244
+ currSense . glosses . push ( {
245
+ "type" : "structured-content" ,
246
+ "content" : [
247
+ gloss ,
248
+ getStructuredExamples ( examples )
249
+ ]
250
+ } ) ;
251
+ } else {
252
+ currSense . glosses . push ( gloss ) ;
253
+ }
254
+
255
+ } else {
256
+ /** @type {GlossBranch } */
257
+ const syntheticBranch = new Map ( ) ;
258
+ syntheticBranch . set ( gloss , branches ) ;
259
+ handleNest ( syntheticBranch , currSense ) ;
260
+ }
261
+
262
+ if ( currSense . glosses . length > 0 ) {
263
+ saveSenseResult ( word , readings , pos , currSense ) ;
264
+ }
265
+ }
266
+ }
267
+
268
+ /**
269
+ * @param {Example[] } examples
270
+ * @returns {import('types').TermBank.StructuredContent[] }
271
+ */
272
+ function getStructuredExamples ( examples ) {
273
+ return examples . map ( ( { text, english} ) => {
274
+ return {
275
+ "tag" : "div" ,
276
+ "data" : {
277
+ "content" : "extra-info"
278
+ } ,
279
+ "content" : {
280
+ "tag" :"div" ,
281
+ "data" : {
282
+ "content" : "example-sentence"
283
+ } ,
284
+ "content" :[ {
285
+ "tag" : "div" ,
286
+ "data" : {
287
+ "content" : "example-sentence-a" ,
288
+ } ,
289
+ "content" : text
290
+ } ,
291
+ {
292
+ "tag" : "div" ,
293
+ "data" : {
294
+ "content" : "example-sentence-b"
295
+ } ,
296
+ "content" : english
297
+ }
298
+ ] }
299
+ }
300
+ } ) ;
301
+ }
302
+
303
+ /**
304
+ * @param {TidySense[] } sensesWithoutInflectionGlosses
305
+ * @returns {GlossTree }
306
+ */
307
+ function getGlossTree ( sensesWithoutInflectionGlosses ) {
231
308
const glossTree = new Map ( ) ;
232
309
for ( const sense of sensesWithoutInflectionGlosses ) {
233
310
const { glossesArray, tags } = sense ;
311
+ let { examples = [ ] } = sense ;
312
+
313
+ examples = examples
314
+ . filter ( ( { text, english} ) => text && ( text . length <= 70 || text . length <= 90 && ! english ) ) // Filter out verbose examples
315
+ . map ( ( example , index ) => ( { ...example , originalIndex : index } ) ) // Step 1: Decorate with original index
316
+ . sort ( ( { english : englishA , originalIndex : indexA } , { english : englishB , originalIndex : indexB } ) => {
317
+ if ( englishA && ! englishB ) return - 1 ; // English items first
318
+ if ( ! englishA && englishB ) return 1 ; // Non-English items last
319
+ return indexA - indexB ; // Step 2: Stable sort by original index if equal
320
+ } )
321
+ . map ( ( { text, english} ) => ( { text, english} ) ) // Step 3: Pick only properties that will be used
322
+ . slice ( 0 , 2 ) ;
323
+
324
+
234
325
let temp = glossTree ;
235
326
for ( const [ levelIndex , levelGloss ] of glossesArray . entries ( ) ) {
236
327
let curr = temp . get ( levelGloss ) ;
237
- if ( ! curr ) {
328
+ if ( ! curr ) {
238
329
curr = new Map ( ) ;
239
330
temp . set ( levelGloss , curr ) ;
240
- if ( levelIndex === 0 ) {
331
+ if ( levelIndex === 0 ) {
241
332
curr . set ( '_tags' , tags ) ;
333
+ curr . set ( '_examples' , examples ) ;
242
334
}
243
335
} else if ( levelIndex === 0 ) {
244
336
curr . set ( '_tags' , tags . filter ( value => curr ?. get ( '_tags' ) ?. includes ( value ) ) ) ;
245
337
}
246
338
temp = curr ;
247
339
}
248
340
}
249
-
250
- for ( const [ gloss , children ] of glossTree ) {
251
- const tags = children . get ( '_tags' ) || [ ] ;
252
- children . delete ( '_tags' ) ;
253
-
254
- /** @type {SenseInfo } */
255
- const currSense = { glosses : [ ] , tags } ;
256
- if ( children . size === 0 ) {
257
- currSense . glosses . push ( gloss ) ;
258
- } else {
259
- /** @type {GlossTree } */
260
- const branch = new Map ( ) ;
261
- branch . set ( gloss , children ) ;
262
- handleNest ( branch , currSense ) ;
263
- }
264
-
265
- if ( currSense . glosses . length > 0 ) {
266
- saveSenseResult ( word , readings , pos , currSense ) ;
267
- }
268
- }
341
+ return glossTree ;
269
342
}
270
343
271
344
/**
0 commit comments