henkan 0.6.0 → 0.7.0
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 +54 -33
- package/dist/index.cjs.js.map +3 -3
- package/dist/index.mjs +54 -35
- package/dist/index.mjs.map +2 -2
- package/dist/types/types.d.ts +21 -0
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/utils.d.ts +13 -10
- package/dist/types/utils.d.ts.map +1 -1
- package/docs/api/README.md +1 -0
- 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 +3 -3
- package/docs/api/functions/convertRadkFile.md +3 -3
- 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/makeSSML.md +1 -1
- package/docs/api/functions/shuffleArray.md +1 -1
- package/docs/api/functions/synthesizeSpeech.md +25 -13
- 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 +31 -0
- 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 +16 -4
- 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 +16 -6
- package/docs/api/interfaces/Translation.md +3 -3
- package/docs/api/interfaces/UsefulRegExps.md +9 -9
- 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 +5 -5
package/dist/index.mjs
CHANGED
|
@@ -1131,9 +1131,7 @@ var noteMap = /* @__PURE__ */ new Map([
|
|
|
1131
1131
|
import libxml from "libxmljs2";
|
|
1132
1132
|
import xml from "xml2js";
|
|
1133
1133
|
import iconv from "iconv-lite";
|
|
1134
|
-
import
|
|
1135
|
-
SynthesizeSpeechCommand
|
|
1136
|
-
} from "@aws-sdk/client-polly";
|
|
1134
|
+
import fetch from "node-fetch";
|
|
1137
1135
|
var Kuroshiro = __require("kuroshiro");
|
|
1138
1136
|
var KuromojiAnalyzer = __require("kuroshiro-analyzer-kuromoji");
|
|
1139
1137
|
function capitalizeString(value) {
|
|
@@ -1279,11 +1277,9 @@ function convertJMdict(xmlString, examples) {
|
|
|
1279
1277
|
).map((reading) => reading.reading)
|
|
1280
1278
|
);
|
|
1281
1279
|
const kanjiForms2 = entryObj.kanjiForms ? new Set(
|
|
1282
|
-
entryObj.kanjiForms.
|
|
1283
|
-
(kanjiForm) =>
|
|
1284
|
-
|
|
1285
|
-
)) && (entryObj.isCommon === void 0 || kanjiForm.commonness && kanjiForm.commonness.length > 0)
|
|
1286
|
-
).map((kanjiForm) => kanjiForm.form)
|
|
1280
|
+
entryObj.kanjiForms.map(
|
|
1281
|
+
(kanjiForm) => kanjiForm.form
|
|
1282
|
+
)
|
|
1287
1283
|
) : void 0;
|
|
1288
1284
|
let existsExample = false;
|
|
1289
1285
|
if (kanjiForms2 && kanjiForms2.size > 0 && tanakaParts) {
|
|
@@ -1465,13 +1461,13 @@ function convertRadkFile(radkBuffer, kanjiDic) {
|
|
|
1465
1461
|
try {
|
|
1466
1462
|
const fileParsed = iconv.decode(radkBuffer, "euc-jp").split("\n").filter((line) => !line.startsWith("#"));
|
|
1467
1463
|
const radicals = [];
|
|
1468
|
-
for (let i = 0; i
|
|
1464
|
+
for (let i = 0; i < fileParsed.length; i++) {
|
|
1469
1465
|
const line = fileParsed[i];
|
|
1470
1466
|
if (!line) continue;
|
|
1471
1467
|
if (line.startsWith("$ ")) {
|
|
1472
1468
|
const radical = {
|
|
1473
|
-
radical: line.charAt(2),
|
|
1474
|
-
strokes: line.substring(4)
|
|
1469
|
+
radical: line.charAt(2).trim(),
|
|
1470
|
+
strokes: line.substring(4).trim()
|
|
1475
1471
|
};
|
|
1476
1472
|
let j = i + 1;
|
|
1477
1473
|
let kanjiLine = fileParsed[j];
|
|
@@ -1484,6 +1480,7 @@ function convertRadkFile(radkBuffer, kanjiDic) {
|
|
|
1484
1480
|
(dictKanji) => dictKanji.kanji === kanji
|
|
1485
1481
|
);
|
|
1486
1482
|
if (foundKanji) kanjiList.push(foundKanji);
|
|
1483
|
+
else kanjiList.push({ kanji, readingMeaning: [] });
|
|
1487
1484
|
}
|
|
1488
1485
|
j++;
|
|
1489
1486
|
kanjiLine = fileParsed[j];
|
|
@@ -1510,7 +1507,7 @@ function convertKradFile(kradBuffer, kanjiDic, katakanaList) {
|
|
|
1510
1507
|
const split = line.split(" : ");
|
|
1511
1508
|
const kanjiChar = split[0];
|
|
1512
1509
|
const radicalsRow = split[1];
|
|
1513
|
-
if (!kanjiChar || !radicalsRow)
|
|
1510
|
+
if (!kanjiChar || !radicalsRow) continue;
|
|
1514
1511
|
const kanji = {
|
|
1515
1512
|
...kanjiChar && radicalsRow && kanjiChar.length === 1 && radicalsRow.length > 0 ? { kanji: kanjiChar } : { kanji: "" },
|
|
1516
1513
|
radicals: []
|
|
@@ -1721,11 +1718,9 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1721
1718
|
).map((reading) => reading.reading)
|
|
1722
1719
|
);
|
|
1723
1720
|
const kanjiForms = word.kanjiForms ? new Set(
|
|
1724
|
-
word.kanjiForms.
|
|
1725
|
-
(kanjiForm) =>
|
|
1726
|
-
|
|
1727
|
-
)) && (word.common === void 0 || kanjiForm.common === true)
|
|
1728
|
-
).map((kanjiForm) => kanjiForm.kanjiForm)
|
|
1721
|
+
word.kanjiForms.map(
|
|
1722
|
+
(kanjiForm) => kanjiForm.kanjiForm
|
|
1723
|
+
)
|
|
1729
1724
|
) : void 0;
|
|
1730
1725
|
const kanjiFormExamples = [];
|
|
1731
1726
|
const readingMatchingKanjiFormExamples = [];
|
|
@@ -1733,7 +1728,7 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1733
1728
|
const partParts = /* @__PURE__ */ new Set();
|
|
1734
1729
|
for (const example of examples)
|
|
1735
1730
|
for (const part of example.parts) {
|
|
1736
|
-
const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading);
|
|
1731
|
+
const readingAsReadingMatch = part.reading !== void 0 && readings.has(part.reading) || part.inflectedForm !== void 0 && readings.has(part.inflectedForm);
|
|
1737
1732
|
if (kanjiForms && kanjiForms.size > 0 && kanjiForms.has(part.baseForm)) {
|
|
1738
1733
|
if (readingAsReadingMatch) {
|
|
1739
1734
|
readingMatchingKanjiFormExamples.push(example);
|
|
@@ -1746,17 +1741,20 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1746
1741
|
}
|
|
1747
1742
|
const readingAsBaseFormMatch = readings.has(part.baseForm);
|
|
1748
1743
|
const referenceIDMatch = part.referenceID !== void 0 && word.id !== void 0 && part.referenceID === word.id;
|
|
1749
|
-
if (
|
|
1744
|
+
if (readingAsBaseFormMatch || referenceIDMatch) {
|
|
1750
1745
|
readingExamples.push(example);
|
|
1751
|
-
if (readingAsReadingMatch) partParts.add(part.reading);
|
|
1752
1746
|
if (readingAsBaseFormMatch) partParts.add(part.baseForm);
|
|
1753
1747
|
if (referenceIDMatch) partParts.add(part.referenceID);
|
|
1754
1748
|
break;
|
|
1755
1749
|
}
|
|
1756
1750
|
}
|
|
1757
1751
|
const exampleSize = readingMatchingKanjiFormExamples.length + kanjiFormExamples.length + readingExamples.length;
|
|
1758
|
-
const
|
|
1759
|
-
|
|
1752
|
+
const includeReadingThreshold = Math.max(
|
|
1753
|
+
10,
|
|
1754
|
+
Math.round(exampleSize * 0.5)
|
|
1755
|
+
);
|
|
1756
|
+
const includeKanjiFormExamples = word.kanjiForms !== void 0;
|
|
1757
|
+
const includeReadingExamples = readingExamples.length >= includeReadingThreshold && readingExamples.length >= readingMatchingKanjiFormExamples.length && readingExamples.length >= kanjiFormExamples.length || readingExamples.length >= includeReadingThreshold && word.usuallyInKana === true || word.kanjiForms === void 0;
|
|
1760
1758
|
let wordExamples = [
|
|
1761
1759
|
...readingMatchingKanjiFormExamples,
|
|
1762
1760
|
...includeKanjiFormExamples ? kanjiFormExamples : [],
|
|
@@ -1768,7 +1766,11 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1768
1766
|
outer: for (const example of wordExamples) {
|
|
1769
1767
|
if (seenPhrases.has(example.phrase)) continue;
|
|
1770
1768
|
for (const part of example.parts)
|
|
1771
|
-
if (part.glossNumber === i + 1 && (partParts.has(part.baseForm) || part.reading && partParts.has(part.reading) || part.referenceID && partParts.has(part.referenceID))) {
|
|
1769
|
+
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)))) {
|
|
1770
|
+
example.glossNumber = {
|
|
1771
|
+
wordId: word.id,
|
|
1772
|
+
glossNumber: i + 1
|
|
1773
|
+
};
|
|
1772
1774
|
glossSpecificExamples.push(example);
|
|
1773
1775
|
seenPhrases.add(example.phrase);
|
|
1774
1776
|
break outer;
|
|
@@ -1787,7 +1789,8 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1787
1789
|
word.phrases = (wordExamples.length > 5 ? wordExamples.slice(0, 5) : wordExamples).map((ex) => ({
|
|
1788
1790
|
phrase: ex.furigana ?? ex.phrase,
|
|
1789
1791
|
translation: ex.translation,
|
|
1790
|
-
originalPhrase: ex.phrase
|
|
1792
|
+
originalPhrase: ex.phrase,
|
|
1793
|
+
...ex.glossNumber ? { glossNumber: ex.glossNumber } : {}
|
|
1791
1794
|
}));
|
|
1792
1795
|
}
|
|
1793
1796
|
return word;
|
|
@@ -2065,18 +2068,34 @@ function makeSSML(formText, fullReading) {
|
|
|
2065
2068
|
}
|
|
2066
2069
|
return ssml;
|
|
2067
2070
|
}
|
|
2068
|
-
async function synthesizeSpeech(
|
|
2071
|
+
async function synthesizeSpeech(ssmlText, apiKey, options) {
|
|
2069
2072
|
return await new Promise(
|
|
2070
2073
|
async (resolve, reject) => {
|
|
2071
2074
|
try {
|
|
2072
|
-
const
|
|
2073
|
-
|
|
2074
|
-
|
|
2075
|
-
|
|
2075
|
+
const res = await fetch("https://ttsfree.com/api/v1/tts", {
|
|
2076
|
+
method: "POST",
|
|
2077
|
+
body: JSON.stringify({
|
|
2078
|
+
text: ssmlText,
|
|
2079
|
+
...options
|
|
2080
|
+
}),
|
|
2081
|
+
headers: {
|
|
2082
|
+
"Content-Type": "application/json",
|
|
2083
|
+
apikey: apiKey
|
|
2084
|
+
}
|
|
2076
2085
|
});
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2086
|
+
if (!res.ok)
|
|
2087
|
+
throw new Error(
|
|
2088
|
+
`TTS request failed:
|
|
2089
|
+
${res.status}: ${res.statusText}`
|
|
2090
|
+
);
|
|
2091
|
+
const data = await res.json();
|
|
2092
|
+
if (data.status !== "success" || data.mess !== "success" || data.audioData.length === 0)
|
|
2093
|
+
throw new Error("Invalid TTS response data");
|
|
2094
|
+
const mp3Buffer = Buffer.from(
|
|
2095
|
+
data.audioData,
|
|
2096
|
+
"base64"
|
|
2097
|
+
);
|
|
2098
|
+
resolve(mp3Buffer);
|
|
2080
2099
|
} catch (err) {
|
|
2081
2100
|
reject(err);
|
|
2082
2101
|
}
|
|
@@ -2123,7 +2142,7 @@ function generateAnkiNote(entry) {
|
|
|
2123
2142
|
).join("") : noKanjiForms
|
|
2124
2143
|
],
|
|
2125
2144
|
entry.translations.map(
|
|
2126
|
-
(translationEntry, index) =>
|
|
2145
|
+
(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>" : ""}`
|
|
2127
2146
|
).join(""),
|
|
2128
2147
|
entry.kanji ? entry.kanji.map(
|
|
2129
2148
|
(kanjiEntry) => createEntry(
|
|
@@ -2132,11 +2151,11 @@ function generateAnkiNote(entry) {
|
|
|
2132
2151
|
)
|
|
2133
2152
|
).join("") : '<span class="word word-kanji">(no kanji)</span>',
|
|
2134
2153
|
entry.phrases ? entry.phrases.map(
|
|
2135
|
-
(phraseEntry) => createEntry(
|
|
2154
|
+
(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(
|
|
2136
2155
|
`<span class="word word-phrase"><span class="word word-phrase-original">${phraseEntry.originalPhrase}</span><span class="word word-phrase-furigana">${phraseEntry.phrase}</span></span>`,
|
|
2137
2156
|
[phraseEntry.translation],
|
|
2138
2157
|
true
|
|
2139
|
-
)
|
|
2158
|
+
)}`
|
|
2140
2159
|
).join("") : '<span class="word word-phrase">(no phrases) (Search on dictionaries!)</span>',
|
|
2141
2160
|
...entry.tags && entry.tags.length > 0 ? [
|
|
2142
2161
|
entry.tags.map(
|