henkan 2.4.10 → 2.4.12

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/dist/index.mjs CHANGED
@@ -2449,17 +2449,34 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2449
2449
  ...dictReading.commonness !== void 0 && dictReading.commonness.length > 0 ? { common: true } : {}
2450
2450
  }));
2451
2451
  word.translations = [];
2452
+ const meanings = dictWord.hasPhrases === true && examples !== void 0 ? [] : void 0;
2453
+ const seenPhrases = /* @__PURE__ */ new Set();
2452
2454
  for (const dictMeaning of dictWord.meanings) {
2453
2455
  const translationTypes = [];
2454
2456
  const translations = dictMeaning.translations.map(
2455
2457
  (translation) => {
2456
- if (typeof translation === "string") return translation;
2457
- else {
2458
+ if (typeof translation === "string") {
2459
+ if (meanings !== void 0) {
2460
+ const cleanTranslation = translation.replaceAll(/\([^)]*\)|\[[^\]]*\]|\{[^}]*\}/g, "").trim();
2461
+ if (!seenPhrases.has(cleanTranslation)) {
2462
+ seenPhrases.add(cleanTranslation);
2463
+ meanings.push(cleanTranslation);
2464
+ }
2465
+ }
2466
+ return translation;
2467
+ } else {
2458
2468
  const translationNoteAndTag = noteMap.get(
2459
2469
  translation.type
2460
2470
  );
2461
2471
  translationTypes.push(translationNoteAndTag[1]);
2462
2472
  word.tags.push(`word::${translationNoteAndTag[0]}`);
2473
+ if (meanings !== void 0) {
2474
+ const cleanTranslation = translation.translation.replaceAll(/\([^)]*\)|\[[^\]]*\]|\{[^}]*\}/g, "").trim();
2475
+ if (!seenPhrases.has(cleanTranslation)) {
2476
+ seenPhrases.add(cleanTranslation);
2477
+ meanings.push(cleanTranslation);
2478
+ }
2479
+ }
2463
2480
  return translation.translation;
2464
2481
  }
2465
2482
  }
@@ -2513,6 +2530,7 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2513
2530
  word.usuallyInKana = true;
2514
2531
  word.tags.push("word::usually_in_kana_for_all_senses");
2515
2532
  }
2533
+ seenPhrases.clear();
2516
2534
  if (kanjiDic !== void 0 && word.kanjiForms !== void 0) {
2517
2535
  const kanji = [];
2518
2536
  const seenChars = /* @__PURE__ */ new Set();
@@ -2533,7 +2551,7 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2533
2551
  }
2534
2552
  if (kanji.length > 0) word.kanji = kanji;
2535
2553
  }
2536
- if (dictWord.hasPhrases === true && examples !== void 0) {
2554
+ if (meanings !== void 0) {
2537
2555
  const exampleList = examples instanceof Map ? examples.get(dictWord.id) ?? [] : examples;
2538
2556
  const rkf = getValidForms(
2539
2557
  dictWord.readings,
@@ -2544,24 +2562,16 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2544
2562
  rkf.readings.map((r) => r.reading)
2545
2563
  );
2546
2564
  const kanjiForms = rkf.kanjiForms !== void 0 ? new Set(rkf.kanjiForms.map((kf) => kf.form)) : void 0;
2547
- const meanings = new Set(
2548
- dictWord.meanings.flatMap(
2549
- (m) => m.translations.map((t) => {
2550
- if (typeof t === "string")
2551
- return t.replaceAll(/\([^)]*\)|\[[^\]]*\]|\{[^}]*\}/g, "").trim();
2552
- else
2553
- return t.translation.replaceAll(/\([^)]*\)|\[[^\]]*\]|\{[^}]*\}/g, "").trim();
2554
- })
2555
- )
2556
- ).values().toArray();
2565
+ let readingMatchingKanjiFormExamples = [];
2557
2566
  let kanjiFormExamples = [];
2558
- const readingMatchingKanjiFormExamples = [];
2559
2567
  let readingExamples = [];
2560
- const readingMatchingKanjiForms = /* @__PURE__ */ new Set();
2561
- const seenPhrases = /* @__PURE__ */ new Set();
2568
+ let hasReadingMatchingKanjiFormWithTranslation = false;
2562
2569
  for (const example of exampleList)
2563
2570
  for (let i = 0; i < example.parts.length; i++) {
2564
2571
  if (seenPhrases.has(example.phrase)) break;
2572
+ const includesTranslation = meanings.some(
2573
+ (m) => example.translation.includes(m)
2574
+ );
2565
2575
  const part = example.parts[i];
2566
2576
  const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading);
2567
2577
  const readingAsInflectedFormMatch = part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
@@ -2570,17 +2580,19 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2570
2580
  if (readingAsReadingMatch || readingAsInflectedFormMatch || referenceIDMatch) {
2571
2581
  readingMatchingKanjiFormExamples.push({
2572
2582
  ex: example,
2573
- partIndex: i
2583
+ partIndex: i,
2584
+ form: part.baseForm,
2585
+ ...referenceIDMatch ? { referenceIDMatch: true } : {},
2586
+ ...includesTranslation ? { includesTranslation: true } : {}
2574
2587
  });
2575
- readingMatchingKanjiForms.add(part.baseForm);
2588
+ if (!hasReadingMatchingKanjiFormWithTranslation && includesTranslation)
2589
+ hasReadingMatchingKanjiFormWithTranslation = true;
2576
2590
  } else
2577
2591
  kanjiFormExamples.push({
2578
2592
  ex: example,
2579
2593
  partIndex: i,
2580
2594
  form: part.baseForm,
2581
- ...meanings.some(
2582
- (m) => example.translation.includes(m)
2583
- ) ? { includesTranslation: true } : {}
2595
+ ...includesTranslation ? { includesTranslation: true } : {}
2584
2596
  });
2585
2597
  seenPhrases.add(example.phrase);
2586
2598
  break;
@@ -2591,20 +2603,28 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2591
2603
  ex: example,
2592
2604
  partIndex: i,
2593
2605
  ...referenceIDMatch ? { referenceIDMatch: true } : {},
2594
- ...!referenceIDMatch && meanings.some((m) => example.translation.includes(m)) ? { includesTranslation: true } : {}
2606
+ ...includesTranslation ? { includesTranslation: true } : {}
2595
2607
  });
2596
2608
  seenPhrases.add(example.phrase);
2597
2609
  break;
2598
2610
  }
2599
2611
  }
2600
- const hasKfExamplesWithTranslation = kanjiFormExamples.some(
2612
+ if (readingMatchingKanjiFormExamples.length > 0) {
2613
+ if (hasReadingMatchingKanjiFormWithTranslation)
2614
+ readingMatchingKanjiFormExamples = readingMatchingKanjiFormExamples.filter(
2615
+ (ex) => ex.includesTranslation === true || ex.referenceIDMatch === true || ex.ex.parts.some(
2616
+ (part) => ex.form === part.baseForm && part.glossNumber !== void 0
2617
+ )
2618
+ );
2619
+ kanjiFormExamples.length = 0;
2620
+ }
2621
+ if (kanjiFormExamples.length > 0 && kanjiFormExamples.some(
2601
2622
  (ex) => ex.includesTranslation === true
2602
- );
2603
- if (kanjiFormExamples.length > 0 && readingMatchingKanjiForms.size > 0)
2623
+ ))
2604
2624
  kanjiFormExamples = kanjiFormExamples.filter(
2605
- (ex) => ex.form !== void 0 && readingMatchingKanjiForms.has(ex.form) && (!hasKfExamplesWithTranslation || ex.includesTranslation === true || ex.ex.parts.some(
2606
- (part) => readingMatchingKanjiForms.has(part.baseForm) && part.glossNumber !== void 0
2607
- ))
2625
+ (ex) => ex.includesTranslation === true || ex.ex.parts.some(
2626
+ (part) => ex.form === part.baseForm && part.glossNumber !== void 0
2627
+ )
2608
2628
  );
2609
2629
  if (readingExamples.length > 0 && readingExamples.some(
2610
2630
  (ex) => ex.includesTranslation === true || ex.referenceIDMatch === true
@@ -2614,9 +2634,7 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2614
2634
  );
2615
2635
  let wordExamples = [
2616
2636
  ...word.kanjiForms !== void 0 ? [...readingMatchingKanjiFormExamples, ...kanjiFormExamples] : readingExamples
2617
- ].toSorted(
2618
- (a, b) => a.ex.phrase.length - b.ex.phrase.length
2619
- );
2637
+ ];
2620
2638
  seenPhrases.clear();
2621
2639
  const glossSpecificExamples = [];
2622
2640
  for (let i = 0; i < word.translations.length; i++)
@@ -2649,12 +2667,14 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2649
2667
  wordExamples = glossSpecificExamples;
2650
2668
  }
2651
2669
  if (wordExamples.length > 0) {
2652
- word.phrases = (glossSpecificExamples.length === 0 ? wordExamples.slice(0, 5) : wordExamples).map((ex) => ({
2653
- phrase: ex.ex.furigana ?? ex.ex.phrase,
2654
- translation: ex.ex.translation,
2655
- originalPhrase: ex.ex.phrase,
2656
- ...ex.ex.glossNumber !== void 0 ? { glossNumber: ex.ex.glossNumber } : {}
2657
- }));
2670
+ word.phrases = (glossSpecificExamples.length === 0 ? wordExamples.slice(0, 5) : wordExamples).map(
2671
+ (ex) => ({
2672
+ phrase: ex.ex.furigana ?? ex.ex.phrase,
2673
+ translation: ex.ex.translation,
2674
+ originalPhrase: ex.ex.phrase,
2675
+ ...ex.ex.glossNumber !== void 0 ? { glossNumber: ex.ex.glossNumber } : {}
2676
+ })
2677
+ );
2658
2678
  word.tags.push("word::has_phrases");
2659
2679
  if (glossSpecificExamples.length > 0)
2660
2680
  word.tags.push("word::has_meaning-specific_phrases");
@@ -2691,7 +2711,7 @@ function isGrammar(entry) {
2691
2711
  }
2692
2712
  var createNotes = (notes, phrase) => `${phrase === true ? "<details><summary>Show translation</summary>" : ""}<ul class="note-list">${notes.map((note) => `<li class="note">${note}</li>`).join("")}</ul>${phrase === true ? "</details>" : ""}`;
2693
2713
  var createEntry = (entry, notes, phrase, glossSpecific) => `<div class="entry${glossSpecific === true ? " gloss-specific" : ""}">${entry}${notes !== void 0 && notes.length > 0 ? createNotes(notes, phrase) : ""}</div>`;
2694
- function generateAnkiNote(entry, customData) {
2714
+ function generateAnkiNote(entry, customData, additionalTags) {
2695
2715
  const fields = [];
2696
2716
  if (isWord(entry)) {
2697
2717
  const firstReading = createEntry(
@@ -2811,12 +2831,7 @@ function generateAnkiNote(entry, customData) {
2811
2831
  kanjiEntry.meanings
2812
2832
  )
2813
2833
  ).join("") : '<span class="word word-kanji" id="no-kanji">(no kanji)</span>',
2814
- searchField,
2815
- ...entry.tags !== void 0 && entry.tags.length > 0 ? [
2816
- entry.tags.map(
2817
- (tag) => tag.trim().toLowerCase().replaceAll(" ", "::")
2818
- ).join(" ")
2819
- ] : []
2834
+ searchField
2820
2835
  );
2821
2836
  }
2822
2837
  if (isRadical(entry))
@@ -2843,12 +2858,7 @@ function generateAnkiNote(entry, customData) {
2843
2858
  entry.strokes !== void 0 ? createEntry(
2844
2859
  `<span class="radical radical-strokes">${entry.strokes}<br>${entry.svg !== void 0 ? `<img class="radical radical-stroke-order" src="${entry.svg}" alt="${entry.radical} stroke order SVG">` : "(no stroke order SVG available)"}</span>`
2845
2860
  ) : '<span class="radical radical-strokes" id="no-strokes">(no stroke number)</span>',
2846
- entry.sources !== void 0 ? `<span class="radical radical-source">${entry.sources.map((source, index) => `<a href="${source}" target="_blank">Source ${index + 1}</a>`).join("<br>")}</span>` : '<span class="radical radical-source" id="no-sources">(no sources)</span>',
2847
- ...entry.tags !== void 0 && entry.tags.length > 0 ? [
2848
- entry.tags.map(
2849
- (tag) => tag.trim().toLowerCase().replaceAll(" ", "::")
2850
- ).join(" ")
2851
- ] : []
2861
+ entry.sources !== void 0 ? `<span class="radical radical-source">${entry.sources.map((source, index) => `<a href="${source}" target="_blank">Source ${index + 1}</a>`).join("<br>")}</span>` : '<span class="radical radical-source" id="no-sources">(no sources)</span>'
2852
2862
  );
2853
2863
  if (isKanji(entry))
2854
2864
  fields.push(
@@ -2889,12 +2899,7 @@ function generateAnkiNote(entry, customData) {
2889
2899
  entry.strokes !== void 0 ? createEntry(
2890
2900
  `<span class="kanji kanji-strokes">${entry.strokes}<br>${entry.svg !== void 0 ? `<img class="kanji kanji-stroke-order" src="${entry.svg}" alt="${entry.kanji} stroke order SVG">` : "(no stroke order SVG available)"}</span>`
2891
2901
  ) : '<span class="kanji kanji-strokes" id="no-strokes">(no stroke number)</span>',
2892
- entry.source !== void 0 ? `<span class="kanji kanji-source"><a href="${entry.source}" target="_blank">Source</a></span>` : '<span class="kanji kanji-source" id="no-source">(no components/mnemonic source)</span>',
2893
- ...entry.tags !== void 0 && entry.tags.length > 0 ? [
2894
- entry.tags.map(
2895
- (tag) => tag.trim().toLowerCase().replaceAll(" ", "::")
2896
- ).join(" ")
2897
- ] : []
2902
+ entry.source !== void 0 ? `<span class="kanji kanji-source"><a href="${entry.source}" target="_blank">Source</a></span>` : '<span class="kanji kanji-source" id="no-source">(no components/mnemonic source)</span>'
2898
2903
  );
2899
2904
  if (isKana(entry))
2900
2905
  fields.push(
@@ -2904,12 +2909,7 @@ function generateAnkiNote(entry, customData) {
2904
2909
  ),
2905
2910
  entry.svg !== void 0 ? createEntry(
2906
2911
  `<img class="kana kana-stroke-order" src="${entry.svg}" alt="${entry.kana} stroke order SVG">`
2907
- ) : "(no stroke order SVG available)",
2908
- ...entry.tags !== void 0 && entry.tags.length > 0 ? [
2909
- entry.tags.map(
2910
- (tag) => tag.trim().toLowerCase().replaceAll(" ", "::")
2911
- ).join(" ")
2912
- ] : []
2912
+ ) : "(no stroke order SVG available)"
2913
2913
  );
2914
2914
  if (isGrammar(entry))
2915
2915
  fields.push(
@@ -2934,16 +2934,15 @@ function generateAnkiNote(entry, customData) {
2934
2934
  true
2935
2935
  )
2936
2936
  ).join("") : '<span class="grammar grammar-phrase" id="no-phrases">(no phrases)</span>',
2937
- entry.source !== void 0 ? `<span class="grammar grammar-source"><a href="${entry.source}" target="_blank">Source</a></span>` : '<span class="grammar grammar-source" id="no-source">(no source)</span>',
2938
- ...entry.tags !== void 0 && entry.tags.length > 0 ? [
2939
- entry.tags.map(
2940
- (tag) => tag.trim().toLowerCase().replaceAll(" ", "::")
2941
- ).join(" ")
2942
- ] : []
2937
+ entry.source !== void 0 ? `<span class="grammar grammar-source"><a href="${entry.source}" target="_blank">Source</a></span>` : '<span class="grammar grammar-source" id="no-source">(no source)</span>'
2938
+ );
2939
+ if (entry.tags !== void 0 && entry.tags.length > 0 || additionalTags !== void 0 && additionalTags.length > 0)
2940
+ fields.push(
2941
+ [...entry.tags ?? [], ...additionalTags ?? []].map((tag) => tag.trim().toLowerCase().replaceAll(" ", "::")).join(" ")
2943
2942
  );
2944
2943
  return fields.map((field) => field.replaceAll("\n", "<br>"));
2945
2944
  }
2946
- function generateAnkiNotesFile(list, defaultNoteInfo, customData) {
2945
+ function generateAnkiNotesFile(list, defaultNoteInfo, customData, additionalTags) {
2947
2946
  const headers = [noteHeaderKeys.separator, noteHeaderKeys.html];
2948
2947
  let ankiNotes = "";
2949
2948
  if (list.length > 0) {
@@ -2993,7 +2992,11 @@ function generateAnkiNotesFile(list, defaultNoteInfo, customData) {
2993
2992
  headers.push(`${noteHeaderKeys.deck}${++headerCount}`);
2994
2993
  hasHeader.deckPath = true;
2995
2994
  }
2996
- const note = generateAnkiNote(result, customData);
2995
+ const note = generateAnkiNote(
2996
+ result,
2997
+ customData,
2998
+ additionalTags
2999
+ );
2997
3000
  if (!hasHeader.tags) {
2998
3001
  headers.push(`${noteHeaderKeys.tags}${note.length + headerCount}`);
2999
3002
  hasHeader.tags = true;