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.
- package/README.md +1 -1
- package/dist/index.cjs.js +47 -66
- package/dist/index.cjs.js.map +3 -3
- package/dist/index.mjs +49 -66
- package/dist/index.mjs.map +2 -2
- package/dist/types/utils.d.ts +8 -11
- package/dist/types/utils.d.ts.map +1 -1
- package/docs/api/functions/capitalizeString.md +1 -1
- package/docs/api/functions/convertJMdict.md +1 -1
- package/docs/api/functions/convertKanjiDic.md +1 -1
- package/docs/api/functions/convertKradFile.md +1 -1
- package/docs/api/functions/convertRadkFile.md +1 -1
- package/docs/api/functions/convertTanakaCorpus.md +1 -1
- package/docs/api/functions/generateAnkiNote.md +1 -1
- package/docs/api/functions/generateAnkiNotesFile.md +1 -1
- package/docs/api/functions/getKanji.md +1 -1
- package/docs/api/functions/getKanjiExtended.md +1 -1
- package/docs/api/functions/getWord.md +1 -1
- package/docs/api/functions/isStringArray.md +1 -1
- package/docs/api/functions/isValidArray.md +1 -1
- package/docs/api/functions/isValidArrayWithFirstElement.md +1 -1
- package/docs/api/functions/shuffleArray.md +1 -1
- package/docs/api/functions/synthesizeSpeech.md +13 -25
- package/docs/api/interfaces/DictKanji.md +5 -5
- package/docs/api/interfaces/DictKanjiForm.md +4 -4
- package/docs/api/interfaces/DictKanjiMisc.md +5 -5
- package/docs/api/interfaces/DictKanjiReading.md +3 -3
- package/docs/api/interfaces/DictKanjiReadingMeaning.md +3 -3
- package/docs/api/interfaces/DictKanjiReadingMeaningGroup.md +3 -3
- package/docs/api/interfaces/DictKanjiWithRadicals.md +3 -3
- package/docs/api/interfaces/DictMeaning.md +11 -11
- package/docs/api/interfaces/DictRadical.md +4 -4
- package/docs/api/interfaces/DictReading.md +5 -5
- package/docs/api/interfaces/DictWord.md +8 -8
- package/docs/api/interfaces/ExamplePart.md +7 -7
- package/docs/api/interfaces/GlossSpecificNumber.md +3 -3
- package/docs/api/interfaces/Grammar.md +15 -15
- package/docs/api/interfaces/GrammarMeaning.md +3 -3
- package/docs/api/interfaces/Kana.md +11 -11
- package/docs/api/interfaces/Kanji.md +22 -22
- package/docs/api/interfaces/KanjiComponent.md +3 -3
- package/docs/api/interfaces/KanjiForm.md +4 -4
- package/docs/api/interfaces/NoteAndTag.md +3 -3
- package/docs/api/interfaces/Phrase.md +5 -5
- package/docs/api/interfaces/Radical.md +16 -16
- package/docs/api/interfaces/Reading.md +5 -5
- package/docs/api/interfaces/ResultEntry.md +7 -7
- package/docs/api/interfaces/TanakaExample.md +7 -7
- package/docs/api/interfaces/Translation.md +3 -3
- package/docs/api/interfaces/UsefulRegExps.md +8 -8
- package/docs/api/interfaces/Word.md +14 -14
- package/docs/api/type-aliases/Dict.md +1 -1
- package/docs/api/type-aliases/DictName.md +1 -1
- package/docs/api/type-aliases/EntryType.md +1 -1
- package/docs/api/type-aliases/JLPT.md +1 -1
- package/docs/api/type-aliases/Result.md +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ pnpm add henkan
|
|
|
36
36
|
- JMdict, KANJIDIC, Tanaka Corpus, RADK and KRAD conversion
|
|
37
37
|
- User-friendly schemas for dictionary entries
|
|
38
38
|
- Anki note generation
|
|
39
|
-
- Other useful tools (
|
|
39
|
+
- Other useful tools (Amazon Polly audio generation, Japanese RegExps, array checking etc.)
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
package/dist/index.cjs.js
CHANGED
|
@@ -1134,7 +1134,7 @@ var noteMap = /* @__PURE__ */ new Map([
|
|
|
1134
1134
|
var import_libxmljs2 = __toESM(require("libxmljs2"));
|
|
1135
1135
|
var import_xml2js = __toESM(require("xml2js"));
|
|
1136
1136
|
var import_iconv_lite = __toESM(require("iconv-lite"));
|
|
1137
|
-
var
|
|
1137
|
+
var import_client_polly = require("@aws-sdk/client-polly");
|
|
1138
1138
|
var Kuroshiro = require("kuroshiro");
|
|
1139
1139
|
var KuromojiAnalyzer = require("kuroshiro-analyzer-kuromoji");
|
|
1140
1140
|
function capitalizeString(value) {
|
|
@@ -1722,7 +1722,7 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1722
1722
|
)) && (word.common === void 0 || reading.common === true)
|
|
1723
1723
|
).map((reading) => reading.reading)
|
|
1724
1724
|
);
|
|
1725
|
-
const kanjiForms = word.kanjiForms ? new Set(
|
|
1725
|
+
const kanjiForms = word.kanjiForms && word.kanjiForms.length > 0 ? new Set(
|
|
1726
1726
|
word.kanjiForms.map(
|
|
1727
1727
|
(kanjiForm) => kanjiForm.kanjiForm
|
|
1728
1728
|
)
|
|
@@ -1730,56 +1730,49 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1730
1730
|
const kanjiFormExamples = [];
|
|
1731
1731
|
const readingMatchingKanjiFormExamples = [];
|
|
1732
1732
|
const readingExamples = [];
|
|
1733
|
-
const partParts = /* @__PURE__ */ new Set();
|
|
1734
1733
|
for (const example of examples)
|
|
1735
|
-
for (
|
|
1736
|
-
const
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1734
|
+
for (let i = 0; i < example.parts.length; i++) {
|
|
1735
|
+
const part = example.parts[i];
|
|
1736
|
+
const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading);
|
|
1737
|
+
const readingAsInflectedFormMatch = part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
|
|
1738
|
+
const referenceIDMatch = part.referenceID !== void 0 && word.id !== void 0 && part.referenceID === word.id;
|
|
1739
|
+
if (kanjiForms && kanjiForms.has(part.baseForm) || referenceIDMatch) {
|
|
1740
|
+
if (readingAsReadingMatch || readingAsInflectedFormMatch)
|
|
1741
|
+
readingMatchingKanjiFormExamples.push({
|
|
1742
|
+
ex: example,
|
|
1743
|
+
partIndex: i
|
|
1744
|
+
});
|
|
1745
|
+
else kanjiFormExamples.push({ ex: example, partIndex: i });
|
|
1745
1746
|
break;
|
|
1746
1747
|
}
|
|
1747
1748
|
const readingAsBaseFormMatch = readings.has(part.baseForm);
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
readingExamples.push(example);
|
|
1751
|
-
if (readingAsBaseFormMatch) partParts.add(part.baseForm);
|
|
1752
|
-
if (referenceIDMatch) partParts.add(part.referenceID);
|
|
1749
|
+
if ((readingAsBaseFormMatch || referenceIDMatch) && kanjiForms === void 0) {
|
|
1750
|
+
readingExamples.push({ ex: example, partIndex: i });
|
|
1753
1751
|
break;
|
|
1754
1752
|
}
|
|
1755
1753
|
}
|
|
1756
|
-
const exampleSize = readingMatchingKanjiFormExamples.length + kanjiFormExamples.length + readingExamples.length;
|
|
1757
|
-
const includeReadingThreshold = Math.max(
|
|
1758
|
-
10,
|
|
1759
|
-
Math.round(exampleSize * 0.5)
|
|
1760
|
-
);
|
|
1761
1754
|
const includeKanjiFormExamples = word.kanjiForms !== void 0;
|
|
1762
|
-
const includeReadingExamples = readingExamples.length >= includeReadingThreshold && readingExamples.length >= readingMatchingKanjiFormExamples.length && readingExamples.length >= kanjiFormExamples.length || readingExamples.length >= includeReadingThreshold && word.usuallyInKana === true || word.kanjiForms === void 0;
|
|
1763
1755
|
let wordExamples = [
|
|
1764
|
-
...readingMatchingKanjiFormExamples,
|
|
1765
|
-
|
|
1766
|
-
...includeReadingExamples ? readingExamples : []
|
|
1756
|
+
...includeKanjiFormExamples ? [...readingMatchingKanjiFormExamples, ...kanjiFormExamples] : [],
|
|
1757
|
+
...!includeKanjiFormExamples ? readingExamples : []
|
|
1767
1758
|
];
|
|
1768
1759
|
const glossSpecificExamples = [];
|
|
1769
1760
|
const seenPhrases = /* @__PURE__ */ new Set();
|
|
1770
1761
|
for (let i = 0; i < word.translations.length; i++) {
|
|
1771
1762
|
outer: for (const example of wordExamples) {
|
|
1772
|
-
if (seenPhrases.has(example.phrase)) continue;
|
|
1773
|
-
for (
|
|
1774
|
-
|
|
1775
|
-
|
|
1763
|
+
if (seenPhrases.has(example.ex.phrase)) continue;
|
|
1764
|
+
for (let j = 0; j < example.ex.parts.length; i++) {
|
|
1765
|
+
const part = example.ex.parts[j];
|
|
1766
|
+
if (j === example.partIndex && part.glossNumber === i + 1) {
|
|
1767
|
+
example.ex.glossNumber = {
|
|
1776
1768
|
wordId: word.id,
|
|
1777
1769
|
glossNumber: i + 1
|
|
1778
1770
|
};
|
|
1779
1771
|
glossSpecificExamples.push(example);
|
|
1780
|
-
seenPhrases.add(example.phrase);
|
|
1772
|
+
seenPhrases.add(example.ex.phrase);
|
|
1781
1773
|
break outer;
|
|
1782
1774
|
}
|
|
1775
|
+
}
|
|
1783
1776
|
}
|
|
1784
1777
|
if (glossSpecificExamples.length === 5) break;
|
|
1785
1778
|
}
|
|
@@ -1788,16 +1781,18 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1788
1781
|
else if (glossSpecificExamples.length > 0)
|
|
1789
1782
|
wordExamples = [
|
|
1790
1783
|
...glossSpecificExamples,
|
|
1791
|
-
...wordExamples.filter(
|
|
1784
|
+
...wordExamples.filter(
|
|
1785
|
+
(ex) => !seenPhrases.has(ex.ex.phrase)
|
|
1786
|
+
).slice(0, 5 - glossSpecificExamples.length)
|
|
1792
1787
|
];
|
|
1793
1788
|
if (wordExamples.length > 0)
|
|
1794
1789
|
word.phrases = (wordExamples.length > 5 ? wordExamples.slice(0, 5) : wordExamples).map((ex) => {
|
|
1795
1790
|
var _a;
|
|
1796
1791
|
return {
|
|
1797
|
-
phrase: (_a = ex.furigana) != null ? _a : ex.phrase,
|
|
1798
|
-
translation: ex.translation,
|
|
1799
|
-
originalPhrase: ex.phrase,
|
|
1800
|
-
...ex.glossNumber ? { glossNumber: ex.glossNumber } : {}
|
|
1792
|
+
phrase: (_a = ex.ex.furigana) != null ? _a : ex.ex.phrase,
|
|
1793
|
+
translation: ex.ex.translation,
|
|
1794
|
+
originalPhrase: ex.ex.phrase,
|
|
1795
|
+
...ex.ex.glossNumber ? { glossNumber: ex.ex.glossNumber } : {}
|
|
1801
1796
|
};
|
|
1802
1797
|
});
|
|
1803
1798
|
}
|
|
@@ -2002,34 +1997,17 @@ function getKanjiExtended(kanjiChar, info, dict, useJpdbWords, jmDict, svgList,
|
|
|
2002
1997
|
throw err;
|
|
2003
1998
|
}
|
|
2004
1999
|
}
|
|
2005
|
-
async function synthesizeSpeech(
|
|
2000
|
+
async function synthesizeSpeech(client, input, options) {
|
|
2006
2001
|
return await new Promise(
|
|
2007
2002
|
async (resolve, reject) => {
|
|
2008
2003
|
try {
|
|
2009
|
-
const
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
text: textOrSSML,
|
|
2013
|
-
...options
|
|
2014
|
-
}),
|
|
2015
|
-
headers: {
|
|
2016
|
-
"Content-Type": "application/json",
|
|
2017
|
-
apikey: apiKey
|
|
2018
|
-
}
|
|
2004
|
+
const command = new import_client_polly.SynthesizeSpeechCommand({
|
|
2005
|
+
Text: input,
|
|
2006
|
+
...options
|
|
2019
2007
|
});
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
${res.status}: ${res.statusText}`
|
|
2024
|
-
);
|
|
2025
|
-
const data = await res.json();
|
|
2026
|
-
if (data.status !== "success" || data.mess !== "success" || data.audioData.length === 0)
|
|
2027
|
-
throw new Error("Invalid TTS response data");
|
|
2028
|
-
const mp3Buffer = Buffer.from(
|
|
2029
|
-
data.audioData,
|
|
2030
|
-
"base64"
|
|
2031
|
-
);
|
|
2032
|
-
resolve(mp3Buffer);
|
|
2008
|
+
const response = await client.send(command);
|
|
2009
|
+
const stream = response.AudioStream ? Buffer.from(await response.AudioStream.transformToByteArray()) : null;
|
|
2010
|
+
resolve(stream);
|
|
2033
2011
|
} catch (err) {
|
|
2034
2012
|
reject(err);
|
|
2035
2013
|
}
|
|
@@ -2052,7 +2030,7 @@ function isGrammar(entry) {
|
|
|
2052
2030
|
return entry.point !== void 0 && entry.meaning !== void 0;
|
|
2053
2031
|
}
|
|
2054
2032
|
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>" : ""}`;
|
|
2055
|
-
var createEntry = (entry, notes, phrase) => `<div class="entry">${entry}${notes && notes.length > 0 ? createNotes(notes, phrase) : ""}</div>`;
|
|
2033
|
+
var createEntry = (entry, notes, phrase, glossSpecific) => `<div class="entry${glossSpecific ? " gloss-specific" : ""}">${entry}${notes && notes.length > 0 ? createNotes(notes, phrase) : ""}</div>`;
|
|
2056
2034
|
var noKanjiForms = '<span class="word word-kanjiform">(no kanji forms)</span>';
|
|
2057
2035
|
function generateAnkiNote(entry) {
|
|
2058
2036
|
if (!entry.noteID) throw new Error("Invalid note ID");
|
|
@@ -2076,7 +2054,7 @@ function generateAnkiNote(entry) {
|
|
|
2076
2054
|
).join("") : noKanjiForms
|
|
2077
2055
|
],
|
|
2078
2056
|
entry.translations.map(
|
|
2079
|
-
(translationEntry, index) => `<span class="word word-
|
|
2057
|
+
(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>" : ""}`
|
|
2080
2058
|
).join(""),
|
|
2081
2059
|
entry.kanji ? entry.kanji.map(
|
|
2082
2060
|
(kanjiEntry) => createEntry(
|
|
@@ -2085,11 +2063,14 @@ function generateAnkiNote(entry) {
|
|
|
2085
2063
|
)
|
|
2086
2064
|
).join("") : '<span class="word word-kanji">(no kanji)</span>',
|
|
2087
2065
|
entry.phrases ? entry.phrases.map(
|
|
2088
|
-
(phraseEntry, index) =>
|
|
2066
|
+
(phraseEntry, index) => createEntry(
|
|
2089
2067
|
`<span class="word word-phrase"><span class="word word-phrase-original">${phraseEntry.originalPhrase}</span><span class="word word-phrase-furigana">${phraseEntry.phrase}</span></span>`,
|
|
2090
2068
|
[phraseEntry.translation],
|
|
2091
|
-
true
|
|
2092
|
-
|
|
2069
|
+
true,
|
|
2070
|
+
entry.translations.some(
|
|
2071
|
+
(_translation, index2) => index === index2 && phraseEntry.glossNumber && phraseEntry.glossNumber.wordId === entry.id && phraseEntry.glossNumber.glossNumber === index2 + 1
|
|
2072
|
+
) ? true : void 0
|
|
2073
|
+
)
|
|
2093
2074
|
).join("") : '<span class="word word-phrase">(no phrases) (Search on dictionaries!)</span>',
|
|
2094
2075
|
...entry.tags && entry.tags.length > 0 ? [
|
|
2095
2076
|
entry.tags.map(
|