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.cjs.js CHANGED
@@ -2512,17 +2512,34 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2512
2512
  ...dictReading.commonness !== void 0 && dictReading.commonness.length > 0 ? { common: true } : {}
2513
2513
  }));
2514
2514
  word.translations = [];
2515
+ const meanings = dictWord.hasPhrases === true && examples !== void 0 ? [] : void 0;
2516
+ const seenPhrases = /* @__PURE__ */ new Set();
2515
2517
  for (const dictMeaning of dictWord.meanings) {
2516
2518
  const translationTypes = [];
2517
2519
  const translations = dictMeaning.translations.map(
2518
2520
  (translation) => {
2519
- if (typeof translation === "string") return translation;
2520
- else {
2521
+ if (typeof translation === "string") {
2522
+ if (meanings !== void 0) {
2523
+ const cleanTranslation = translation.replaceAll(/\([^)]*\)|\[[^\]]*\]|\{[^}]*\}/g, "").trim();
2524
+ if (!seenPhrases.has(cleanTranslation)) {
2525
+ seenPhrases.add(cleanTranslation);
2526
+ meanings.push(cleanTranslation);
2527
+ }
2528
+ }
2529
+ return translation;
2530
+ } else {
2521
2531
  const translationNoteAndTag = noteMap.get(
2522
2532
  translation.type
2523
2533
  );
2524
2534
  translationTypes.push(translationNoteAndTag[1]);
2525
2535
  word.tags.push(`word::${translationNoteAndTag[0]}`);
2536
+ if (meanings !== void 0) {
2537
+ const cleanTranslation = translation.translation.replaceAll(/\([^)]*\)|\[[^\]]*\]|\{[^}]*\}/g, "").trim();
2538
+ if (!seenPhrases.has(cleanTranslation)) {
2539
+ seenPhrases.add(cleanTranslation);
2540
+ meanings.push(cleanTranslation);
2541
+ }
2542
+ }
2526
2543
  return translation.translation;
2527
2544
  }
2528
2545
  }
@@ -2576,6 +2593,7 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2576
2593
  word.usuallyInKana = true;
2577
2594
  word.tags.push("word::usually_in_kana_for_all_senses");
2578
2595
  }
2596
+ seenPhrases.clear();
2579
2597
  if (kanjiDic !== void 0 && word.kanjiForms !== void 0) {
2580
2598
  const kanji = [];
2581
2599
  const seenChars = /* @__PURE__ */ new Set();
@@ -2596,7 +2614,7 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2596
2614
  }
2597
2615
  if (kanji.length > 0) word.kanji = kanji;
2598
2616
  }
2599
- if (dictWord.hasPhrases === true && examples !== void 0) {
2617
+ if (meanings !== void 0) {
2600
2618
  const exampleList = examples instanceof Map ? examples.get(dictWord.id) ?? [] : examples;
2601
2619
  const rkf = getValidForms(
2602
2620
  dictWord.readings,
@@ -2607,24 +2625,16 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2607
2625
  rkf.readings.map((r) => r.reading)
2608
2626
  );
2609
2627
  const kanjiForms = rkf.kanjiForms !== void 0 ? new Set(rkf.kanjiForms.map((kf) => kf.form)) : void 0;
2610
- const meanings = new Set(
2611
- dictWord.meanings.flatMap(
2612
- (m) => m.translations.map((t) => {
2613
- if (typeof t === "string")
2614
- return t.replaceAll(/\([^)]*\)|\[[^\]]*\]|\{[^}]*\}/g, "").trim();
2615
- else
2616
- return t.translation.replaceAll(/\([^)]*\)|\[[^\]]*\]|\{[^}]*\}/g, "").trim();
2617
- })
2618
- )
2619
- ).values().toArray();
2628
+ let readingMatchingKanjiFormExamples = [];
2620
2629
  let kanjiFormExamples = [];
2621
- const readingMatchingKanjiFormExamples = [];
2622
2630
  let readingExamples = [];
2623
- const readingMatchingKanjiForms = /* @__PURE__ */ new Set();
2624
- const seenPhrases = /* @__PURE__ */ new Set();
2631
+ let hasReadingMatchingKanjiFormWithTranslation = false;
2625
2632
  for (const example of exampleList)
2626
2633
  for (let i = 0; i < example.parts.length; i++) {
2627
2634
  if (seenPhrases.has(example.phrase)) break;
2635
+ const includesTranslation = meanings.some(
2636
+ (m) => example.translation.includes(m)
2637
+ );
2628
2638
  const part = example.parts[i];
2629
2639
  const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading);
2630
2640
  const readingAsInflectedFormMatch = part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
@@ -2633,17 +2643,19 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2633
2643
  if (readingAsReadingMatch || readingAsInflectedFormMatch || referenceIDMatch) {
2634
2644
  readingMatchingKanjiFormExamples.push({
2635
2645
  ex: example,
2636
- partIndex: i
2646
+ partIndex: i,
2647
+ form: part.baseForm,
2648
+ ...referenceIDMatch ? { referenceIDMatch: true } : {},
2649
+ ...includesTranslation ? { includesTranslation: true } : {}
2637
2650
  });
2638
- readingMatchingKanjiForms.add(part.baseForm);
2651
+ if (!hasReadingMatchingKanjiFormWithTranslation && includesTranslation)
2652
+ hasReadingMatchingKanjiFormWithTranslation = true;
2639
2653
  } else
2640
2654
  kanjiFormExamples.push({
2641
2655
  ex: example,
2642
2656
  partIndex: i,
2643
2657
  form: part.baseForm,
2644
- ...meanings.some(
2645
- (m) => example.translation.includes(m)
2646
- ) ? { includesTranslation: true } : {}
2658
+ ...includesTranslation ? { includesTranslation: true } : {}
2647
2659
  });
2648
2660
  seenPhrases.add(example.phrase);
2649
2661
  break;
@@ -2654,20 +2666,28 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2654
2666
  ex: example,
2655
2667
  partIndex: i,
2656
2668
  ...referenceIDMatch ? { referenceIDMatch: true } : {},
2657
- ...!referenceIDMatch && meanings.some((m) => example.translation.includes(m)) ? { includesTranslation: true } : {}
2669
+ ...includesTranslation ? { includesTranslation: true } : {}
2658
2670
  });
2659
2671
  seenPhrases.add(example.phrase);
2660
2672
  break;
2661
2673
  }
2662
2674
  }
2663
- const hasKfExamplesWithTranslation = kanjiFormExamples.some(
2675
+ if (readingMatchingKanjiFormExamples.length > 0) {
2676
+ if (hasReadingMatchingKanjiFormWithTranslation)
2677
+ readingMatchingKanjiFormExamples = readingMatchingKanjiFormExamples.filter(
2678
+ (ex) => ex.includesTranslation === true || ex.referenceIDMatch === true || ex.ex.parts.some(
2679
+ (part) => ex.form === part.baseForm && part.glossNumber !== void 0
2680
+ )
2681
+ );
2682
+ kanjiFormExamples.length = 0;
2683
+ }
2684
+ if (kanjiFormExamples.length > 0 && kanjiFormExamples.some(
2664
2685
  (ex) => ex.includesTranslation === true
2665
- );
2666
- if (kanjiFormExamples.length > 0 && readingMatchingKanjiForms.size > 0)
2686
+ ))
2667
2687
  kanjiFormExamples = kanjiFormExamples.filter(
2668
- (ex) => ex.form !== void 0 && readingMatchingKanjiForms.has(ex.form) && (!hasKfExamplesWithTranslation || ex.includesTranslation === true || ex.ex.parts.some(
2669
- (part) => readingMatchingKanjiForms.has(part.baseForm) && part.glossNumber !== void 0
2670
- ))
2688
+ (ex) => ex.includesTranslation === true || ex.ex.parts.some(
2689
+ (part) => ex.form === part.baseForm && part.glossNumber !== void 0
2690
+ )
2671
2691
  );
2672
2692
  if (readingExamples.length > 0 && readingExamples.some(
2673
2693
  (ex) => ex.includesTranslation === true || ex.referenceIDMatch === true
@@ -2677,9 +2697,7 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2677
2697
  );
2678
2698
  let wordExamples = [
2679
2699
  ...word.kanjiForms !== void 0 ? [...readingMatchingKanjiFormExamples, ...kanjiFormExamples] : readingExamples
2680
- ].toSorted(
2681
- (a, b) => a.ex.phrase.length - b.ex.phrase.length
2682
- );
2700
+ ];
2683
2701
  seenPhrases.clear();
2684
2702
  const glossSpecificExamples = [];
2685
2703
  for (let i = 0; i < word.translations.length; i++)
@@ -2712,12 +2730,14 @@ function getWord(searchedWord, dict, kanjiDic, examples, definitions, noteTypeNa
2712
2730
  wordExamples = glossSpecificExamples;
2713
2731
  }
2714
2732
  if (wordExamples.length > 0) {
2715
- word.phrases = (glossSpecificExamples.length === 0 ? wordExamples.slice(0, 5) : wordExamples).map((ex) => ({
2716
- phrase: ex.ex.furigana ?? ex.ex.phrase,
2717
- translation: ex.ex.translation,
2718
- originalPhrase: ex.ex.phrase,
2719
- ...ex.ex.glossNumber !== void 0 ? { glossNumber: ex.ex.glossNumber } : {}
2720
- }));
2733
+ word.phrases = (glossSpecificExamples.length === 0 ? wordExamples.slice(0, 5) : wordExamples).map(
2734
+ (ex) => ({
2735
+ phrase: ex.ex.furigana ?? ex.ex.phrase,
2736
+ translation: ex.ex.translation,
2737
+ originalPhrase: ex.ex.phrase,
2738
+ ...ex.ex.glossNumber !== void 0 ? { glossNumber: ex.ex.glossNumber } : {}
2739
+ })
2740
+ );
2721
2741
  word.tags.push("word::has_phrases");
2722
2742
  if (glossSpecificExamples.length > 0)
2723
2743
  word.tags.push("word::has_meaning-specific_phrases");
@@ -2754,7 +2774,7 @@ function isGrammar(entry) {
2754
2774
  }
2755
2775
  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>" : ""}`;
2756
2776
  var createEntry = (entry, notes, phrase, glossSpecific) => `<div class="entry${glossSpecific === true ? " gloss-specific" : ""}">${entry}${notes !== void 0 && notes.length > 0 ? createNotes(notes, phrase) : ""}</div>`;
2757
- function generateAnkiNote(entry, customData) {
2777
+ function generateAnkiNote(entry, customData, additionalTags) {
2758
2778
  const fields = [];
2759
2779
  if (isWord(entry)) {
2760
2780
  const firstReading = createEntry(
@@ -2874,12 +2894,7 @@ function generateAnkiNote(entry, customData) {
2874
2894
  kanjiEntry.meanings
2875
2895
  )
2876
2896
  ).join("") : '<span class="word word-kanji" id="no-kanji">(no kanji)</span>',
2877
- searchField,
2878
- ...entry.tags !== void 0 && entry.tags.length > 0 ? [
2879
- entry.tags.map(
2880
- (tag) => tag.trim().toLowerCase().replaceAll(" ", "::")
2881
- ).join(" ")
2882
- ] : []
2897
+ searchField
2883
2898
  );
2884
2899
  }
2885
2900
  if (isRadical(entry))
@@ -2906,12 +2921,7 @@ function generateAnkiNote(entry, customData) {
2906
2921
  entry.strokes !== void 0 ? createEntry(
2907
2922
  `<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>`
2908
2923
  ) : '<span class="radical radical-strokes" id="no-strokes">(no stroke number)</span>',
2909
- 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>',
2910
- ...entry.tags !== void 0 && entry.tags.length > 0 ? [
2911
- entry.tags.map(
2912
- (tag) => tag.trim().toLowerCase().replaceAll(" ", "::")
2913
- ).join(" ")
2914
- ] : []
2924
+ 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>'
2915
2925
  );
2916
2926
  if (isKanji(entry))
2917
2927
  fields.push(
@@ -2952,12 +2962,7 @@ function generateAnkiNote(entry, customData) {
2952
2962
  entry.strokes !== void 0 ? createEntry(
2953
2963
  `<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>`
2954
2964
  ) : '<span class="kanji kanji-strokes" id="no-strokes">(no stroke number)</span>',
2955
- 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>',
2956
- ...entry.tags !== void 0 && entry.tags.length > 0 ? [
2957
- entry.tags.map(
2958
- (tag) => tag.trim().toLowerCase().replaceAll(" ", "::")
2959
- ).join(" ")
2960
- ] : []
2965
+ 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>'
2961
2966
  );
2962
2967
  if (isKana(entry))
2963
2968
  fields.push(
@@ -2967,12 +2972,7 @@ function generateAnkiNote(entry, customData) {
2967
2972
  ),
2968
2973
  entry.svg !== void 0 ? createEntry(
2969
2974
  `<img class="kana kana-stroke-order" src="${entry.svg}" alt="${entry.kana} stroke order SVG">`
2970
- ) : "(no stroke order SVG available)",
2971
- ...entry.tags !== void 0 && entry.tags.length > 0 ? [
2972
- entry.tags.map(
2973
- (tag) => tag.trim().toLowerCase().replaceAll(" ", "::")
2974
- ).join(" ")
2975
- ] : []
2975
+ ) : "(no stroke order SVG available)"
2976
2976
  );
2977
2977
  if (isGrammar(entry))
2978
2978
  fields.push(
@@ -2997,16 +2997,15 @@ function generateAnkiNote(entry, customData) {
2997
2997
  true
2998
2998
  )
2999
2999
  ).join("") : '<span class="grammar grammar-phrase" id="no-phrases">(no phrases)</span>',
3000
- 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>',
3001
- ...entry.tags !== void 0 && entry.tags.length > 0 ? [
3002
- entry.tags.map(
3003
- (tag) => tag.trim().toLowerCase().replaceAll(" ", "::")
3004
- ).join(" ")
3005
- ] : []
3000
+ 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>'
3001
+ );
3002
+ if (entry.tags !== void 0 && entry.tags.length > 0 || additionalTags !== void 0 && additionalTags.length > 0)
3003
+ fields.push(
3004
+ [...entry.tags ?? [], ...additionalTags ?? []].map((tag) => tag.trim().toLowerCase().replaceAll(" ", "::")).join(" ")
3006
3005
  );
3007
3006
  return fields.map((field) => field.replaceAll("\n", "<br>"));
3008
3007
  }
3009
- function generateAnkiNotesFile(list, defaultNoteInfo, customData) {
3008
+ function generateAnkiNotesFile(list, defaultNoteInfo, customData, additionalTags) {
3010
3009
  const headers = [noteHeaderKeys.separator, noteHeaderKeys.html];
3011
3010
  let ankiNotes = "";
3012
3011
  if (list.length > 0) {
@@ -3056,7 +3055,11 @@ function generateAnkiNotesFile(list, defaultNoteInfo, customData) {
3056
3055
  headers.push(`${noteHeaderKeys.deck}${++headerCount}`);
3057
3056
  hasHeader.deckPath = true;
3058
3057
  }
3059
- const note = generateAnkiNote(result, customData);
3058
+ const note = generateAnkiNote(
3059
+ result,
3060
+ customData,
3061
+ additionalTags
3062
+ );
3060
3063
  if (!hasHeader.tags) {
3061
3064
  headers.push(`${noteHeaderKeys.tags}${note.length + headerCount}`);
3062
3065
  hasHeader.tags = true;