henkan 0.8.0 → 0.9.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.
Files changed (57) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs.js +47 -66
  3. package/dist/index.cjs.js.map +3 -3
  4. package/dist/index.mjs +49 -66
  5. package/dist/index.mjs.map +2 -2
  6. package/dist/types/utils.d.ts +8 -11
  7. package/dist/types/utils.d.ts.map +1 -1
  8. package/docs/api/functions/capitalizeString.md +1 -1
  9. package/docs/api/functions/convertJMdict.md +1 -1
  10. package/docs/api/functions/convertKanjiDic.md +1 -1
  11. package/docs/api/functions/convertKradFile.md +1 -1
  12. package/docs/api/functions/convertRadkFile.md +1 -1
  13. package/docs/api/functions/convertTanakaCorpus.md +1 -1
  14. package/docs/api/functions/generateAnkiNote.md +1 -1
  15. package/docs/api/functions/generateAnkiNotesFile.md +1 -1
  16. package/docs/api/functions/getKanji.md +1 -1
  17. package/docs/api/functions/getKanjiExtended.md +1 -1
  18. package/docs/api/functions/getWord.md +1 -1
  19. package/docs/api/functions/isStringArray.md +1 -1
  20. package/docs/api/functions/isValidArray.md +1 -1
  21. package/docs/api/functions/isValidArrayWithFirstElement.md +1 -1
  22. package/docs/api/functions/shuffleArray.md +1 -1
  23. package/docs/api/functions/synthesizeSpeech.md +13 -25
  24. package/docs/api/interfaces/DictKanji.md +5 -5
  25. package/docs/api/interfaces/DictKanjiForm.md +4 -4
  26. package/docs/api/interfaces/DictKanjiMisc.md +5 -5
  27. package/docs/api/interfaces/DictKanjiReading.md +3 -3
  28. package/docs/api/interfaces/DictKanjiReadingMeaning.md +3 -3
  29. package/docs/api/interfaces/DictKanjiReadingMeaningGroup.md +3 -3
  30. package/docs/api/interfaces/DictKanjiWithRadicals.md +3 -3
  31. package/docs/api/interfaces/DictMeaning.md +11 -11
  32. package/docs/api/interfaces/DictRadical.md +4 -4
  33. package/docs/api/interfaces/DictReading.md +5 -5
  34. package/docs/api/interfaces/DictWord.md +8 -8
  35. package/docs/api/interfaces/ExamplePart.md +7 -7
  36. package/docs/api/interfaces/GlossSpecificNumber.md +3 -3
  37. package/docs/api/interfaces/Grammar.md +15 -15
  38. package/docs/api/interfaces/GrammarMeaning.md +3 -3
  39. package/docs/api/interfaces/Kana.md +11 -11
  40. package/docs/api/interfaces/Kanji.md +22 -22
  41. package/docs/api/interfaces/KanjiComponent.md +3 -3
  42. package/docs/api/interfaces/KanjiForm.md +4 -4
  43. package/docs/api/interfaces/NoteAndTag.md +3 -3
  44. package/docs/api/interfaces/Phrase.md +5 -5
  45. package/docs/api/interfaces/Radical.md +16 -16
  46. package/docs/api/interfaces/Reading.md +5 -5
  47. package/docs/api/interfaces/ResultEntry.md +7 -7
  48. package/docs/api/interfaces/TanakaExample.md +7 -7
  49. package/docs/api/interfaces/Translation.md +3 -3
  50. package/docs/api/interfaces/UsefulRegExps.md +8 -8
  51. package/docs/api/interfaces/Word.md +14 -14
  52. package/docs/api/type-aliases/Dict.md +1 -1
  53. package/docs/api/type-aliases/DictName.md +1 -1
  54. package/docs/api/type-aliases/EntryType.md +1 -1
  55. package/docs/api/type-aliases/JLPT.md +1 -1
  56. package/docs/api/type-aliases/Result.md +1 -1
  57. package/package.json +4 -4
package/dist/index.mjs CHANGED
@@ -1082,7 +1082,9 @@ var noteMap = /* @__PURE__ */ new Map([
1082
1082
  import libxml from "libxmljs2";
1083
1083
  import xml from "xml2js";
1084
1084
  import iconv from "iconv-lite";
1085
- import fetch from "node-fetch";
1085
+ import {
1086
+ SynthesizeSpeechCommand
1087
+ } from "@aws-sdk/client-polly";
1086
1088
  var Kuroshiro = __require("kuroshiro");
1087
1089
  var KuromojiAnalyzer = __require("kuroshiro-analyzer-kuromoji");
1088
1090
  function capitalizeString(value) {
@@ -1668,7 +1670,7 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1668
1670
  )) && (word.common === void 0 || reading.common === true)
1669
1671
  ).map((reading) => reading.reading)
1670
1672
  );
1671
- const kanjiForms = word.kanjiForms ? new Set(
1673
+ const kanjiForms = word.kanjiForms && word.kanjiForms.length > 0 ? new Set(
1672
1674
  word.kanjiForms.map(
1673
1675
  (kanjiForm) => kanjiForm.kanjiForm
1674
1676
  )
@@ -1676,56 +1678,49 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1676
1678
  const kanjiFormExamples = [];
1677
1679
  const readingMatchingKanjiFormExamples = [];
1678
1680
  const readingExamples = [];
1679
- const partParts = /* @__PURE__ */ new Set();
1680
1681
  for (const example of examples)
1681
- for (const part of example.parts) {
1682
- const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading) || part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
1683
- if (kanjiForms && kanjiForms.size > 0 && kanjiForms.has(part.baseForm)) {
1684
- if (readingAsReadingMatch) {
1685
- readingMatchingKanjiFormExamples.push(example);
1686
- partParts.add(part.baseForm).add(part.reading);
1687
- } else {
1688
- kanjiFormExamples.push(example);
1689
- partParts.add(part.baseForm);
1690
- }
1682
+ for (let i = 0; i < example.parts.length; i++) {
1683
+ const part = example.parts[i];
1684
+ const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading);
1685
+ const readingAsInflectedFormMatch = part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
1686
+ const referenceIDMatch = part.referenceID !== void 0 && word.id !== void 0 && part.referenceID === word.id;
1687
+ if (kanjiForms && kanjiForms.has(part.baseForm) || referenceIDMatch) {
1688
+ if (readingAsReadingMatch || readingAsInflectedFormMatch)
1689
+ readingMatchingKanjiFormExamples.push({
1690
+ ex: example,
1691
+ partIndex: i
1692
+ });
1693
+ else kanjiFormExamples.push({ ex: example, partIndex: i });
1691
1694
  break;
1692
1695
  }
1693
1696
  const readingAsBaseFormMatch = readings.has(part.baseForm);
1694
- const referenceIDMatch = part.referenceID !== void 0 && word.id !== void 0 && part.referenceID === word.id;
1695
- if (readingAsBaseFormMatch || referenceIDMatch) {
1696
- readingExamples.push(example);
1697
- if (readingAsBaseFormMatch) partParts.add(part.baseForm);
1698
- if (referenceIDMatch) partParts.add(part.referenceID);
1697
+ if ((readingAsBaseFormMatch || referenceIDMatch) && kanjiForms === void 0) {
1698
+ readingExamples.push({ ex: example, partIndex: i });
1699
1699
  break;
1700
1700
  }
1701
1701
  }
1702
- const exampleSize = readingMatchingKanjiFormExamples.length + kanjiFormExamples.length + readingExamples.length;
1703
- const includeReadingThreshold = Math.max(
1704
- 10,
1705
- Math.round(exampleSize * 0.5)
1706
- );
1707
1702
  const includeKanjiFormExamples = word.kanjiForms !== void 0;
1708
- const includeReadingExamples = readingExamples.length >= includeReadingThreshold && readingExamples.length >= readingMatchingKanjiFormExamples.length && readingExamples.length >= kanjiFormExamples.length || readingExamples.length >= includeReadingThreshold && word.usuallyInKana === true || word.kanjiForms === void 0;
1709
1703
  let wordExamples = [
1710
- ...readingMatchingKanjiFormExamples,
1711
- ...includeKanjiFormExamples ? kanjiFormExamples : [],
1712
- ...includeReadingExamples ? readingExamples : []
1704
+ ...includeKanjiFormExamples ? [...readingMatchingKanjiFormExamples, ...kanjiFormExamples] : [],
1705
+ ...!includeKanjiFormExamples ? readingExamples : []
1713
1706
  ];
1714
1707
  const glossSpecificExamples = [];
1715
1708
  const seenPhrases = /* @__PURE__ */ new Set();
1716
1709
  for (let i = 0; i < word.translations.length; i++) {
1717
1710
  outer: for (const example of wordExamples) {
1718
- if (seenPhrases.has(example.phrase)) continue;
1719
- for (const part of example.parts)
1720
- if (part.glossNumber === i + 1 && (partParts.has(part.baseForm) || includeReadingExamples && (part.reading && partParts.has(part.reading) || part.inflectedForm && partParts.has(part.inflectedForm) || part.referenceID && partParts.has(part.referenceID)))) {
1721
- example.glossNumber = {
1711
+ if (seenPhrases.has(example.ex.phrase)) continue;
1712
+ for (let j = 0; j < example.ex.parts.length; i++) {
1713
+ const part = example.ex.parts[j];
1714
+ if (j === example.partIndex && part.glossNumber === i + 1) {
1715
+ example.ex.glossNumber = {
1722
1716
  wordId: word.id,
1723
1717
  glossNumber: i + 1
1724
1718
  };
1725
1719
  glossSpecificExamples.push(example);
1726
- seenPhrases.add(example.phrase);
1720
+ seenPhrases.add(example.ex.phrase);
1727
1721
  break outer;
1728
1722
  }
1723
+ }
1729
1724
  }
1730
1725
  if (glossSpecificExamples.length === 5) break;
1731
1726
  }
@@ -1734,14 +1729,16 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
1734
1729
  else if (glossSpecificExamples.length > 0)
1735
1730
  wordExamples = [
1736
1731
  ...glossSpecificExamples,
1737
- ...wordExamples.filter((ex) => !seenPhrases.has(ex.phrase)).slice(0, 5 - glossSpecificExamples.length)
1732
+ ...wordExamples.filter(
1733
+ (ex) => !seenPhrases.has(ex.ex.phrase)
1734
+ ).slice(0, 5 - glossSpecificExamples.length)
1738
1735
  ];
1739
1736
  if (wordExamples.length > 0)
1740
1737
  word.phrases = (wordExamples.length > 5 ? wordExamples.slice(0, 5) : wordExamples).map((ex) => ({
1741
- phrase: ex.furigana ?? ex.phrase,
1742
- translation: ex.translation,
1743
- originalPhrase: ex.phrase,
1744
- ...ex.glossNumber ? { glossNumber: ex.glossNumber } : {}
1738
+ phrase: ex.ex.furigana ?? ex.ex.phrase,
1739
+ translation: ex.ex.translation,
1740
+ originalPhrase: ex.ex.phrase,
1741
+ ...ex.ex.glossNumber ? { glossNumber: ex.ex.glossNumber } : {}
1745
1742
  }));
1746
1743
  }
1747
1744
  return word;
@@ -1945,34 +1942,17 @@ function getKanjiExtended(kanjiChar, info, dict, useJpdbWords, jmDict, svgList,
1945
1942
  throw err;
1946
1943
  }
1947
1944
  }
1948
- async function synthesizeSpeech(textOrSSML, apiKey, options) {
1945
+ async function synthesizeSpeech(client, input, options) {
1949
1946
  return await new Promise(
1950
1947
  async (resolve, reject) => {
1951
1948
  try {
1952
- const res = await fetch("https://ttsfree.com/api/v1/tts", {
1953
- method: "POST",
1954
- body: JSON.stringify({
1955
- text: textOrSSML,
1956
- ...options
1957
- }),
1958
- headers: {
1959
- "Content-Type": "application/json",
1960
- apikey: apiKey
1961
- }
1949
+ const command = new SynthesizeSpeechCommand({
1950
+ Text: input,
1951
+ ...options
1962
1952
  });
1963
- if (!res.ok)
1964
- throw new Error(
1965
- `TTS request failed:
1966
- ${res.status}: ${res.statusText}`
1967
- );
1968
- const data = await res.json();
1969
- if (data.status !== "success" || data.mess !== "success" || data.audioData.length === 0)
1970
- throw new Error("Invalid TTS response data");
1971
- const mp3Buffer = Buffer.from(
1972
- data.audioData,
1973
- "base64"
1974
- );
1975
- resolve(mp3Buffer);
1953
+ const response = await client.send(command);
1954
+ const stream = response.AudioStream ? Buffer.from(await response.AudioStream.transformToByteArray()) : null;
1955
+ resolve(stream);
1976
1956
  } catch (err) {
1977
1957
  reject(err);
1978
1958
  }
@@ -1995,7 +1975,7 @@ function isGrammar(entry) {
1995
1975
  return entry.point !== void 0 && entry.meaning !== void 0;
1996
1976
  }
1997
1977
  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>" : ""}`;
1998
- var createEntry = (entry, notes, phrase) => `<div class="entry">${entry}${notes && notes.length > 0 ? createNotes(notes, phrase) : ""}</div>`;
1978
+ var createEntry = (entry, notes, phrase, glossSpecific) => `<div class="entry${glossSpecific ? " gloss-specific" : ""}">${entry}${notes && notes.length > 0 ? createNotes(notes, phrase) : ""}</div>`;
1999
1979
  var noKanjiForms = '<span class="word word-kanjiform">(no kanji forms)</span>';
2000
1980
  function generateAnkiNote(entry) {
2001
1981
  if (!entry.noteID) throw new Error("Invalid note ID");
@@ -2019,7 +1999,7 @@ function generateAnkiNote(entry) {
2019
1999
  ).join("") : noKanjiForms
2020
2000
  ],
2021
2001
  entry.translations.map(
2022
- (translationEntry, index) => `<span class="word word-index${entry.phrases && entry.phrases.some((phrase, index2) => index === index2 && phrase.glossNumber && phrase.glossNumber.wordId === entry.id && phrase.glossNumber.glossNumber === index + 1) ? " gloss-specific" : ""}">${index + 1}</span>${index > 2 ? "<details><summary>Show translation</summary>" : ""}${createEntry(`<span class="word word-translation">${translationEntry.translation}</span>`, translationEntry.notes)}${index > 2 ? "</details>" : ""}`
2002
+ (translationEntry, index) => `${index > 2 ? "<details><summary>Show translation</summary>" : ""}${createEntry(`<span class="word word-translation">${translationEntry.translation}</span>`, translationEntry.notes, void 0, entry.phrases && entry.phrases.some((phrase, index2) => index === index2 && phrase.glossNumber && phrase.glossNumber.wordId === entry.id && phrase.glossNumber.glossNumber === index + 1) ? true : void 0)}${index > 2 ? "</details>" : ""}`
2023
2003
  ).join(""),
2024
2004
  entry.kanji ? entry.kanji.map(
2025
2005
  (kanjiEntry) => createEntry(
@@ -2028,11 +2008,14 @@ function generateAnkiNote(entry) {
2028
2008
  )
2029
2009
  ).join("") : '<span class="word word-kanji">(no kanji)</span>',
2030
2010
  entry.phrases ? entry.phrases.map(
2031
- (phraseEntry, index) => `<span class="word word-index${entry.translations.some((_translation, index2) => index === index2 && phraseEntry.glossNumber && phraseEntry.glossNumber.wordId === entry.id && phraseEntry.glossNumber.glossNumber === index2 + 1) ? " gloss-specific" : ""}">${index + 1}</span>${createEntry(
2011
+ (phraseEntry, index) => createEntry(
2032
2012
  `<span class="word word-phrase"><span class="word word-phrase-original">${phraseEntry.originalPhrase}</span><span class="word word-phrase-furigana">${phraseEntry.phrase}</span></span>`,
2033
2013
  [phraseEntry.translation],
2034
- true
2035
- )}`
2014
+ true,
2015
+ entry.translations.some(
2016
+ (_translation, index2) => index === index2 && phraseEntry.glossNumber && phraseEntry.glossNumber.wordId === entry.id && phraseEntry.glossNumber.glossNumber === index2 + 1
2017
+ ) ? true : void 0
2018
+ )
2036
2019
  ).join("") : '<span class="word word-phrase">(no phrases) (Search on dictionaries!)</span>',
2037
2020
  ...entry.tags && entry.tags.length > 0 ? [
2038
2021
  entry.tags.map(