henkan 0.6.1 → 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 +53 -34
- package/dist/index.cjs.js.map +3 -3
- package/dist/index.mjs +53 -36
- 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 +9 -6
- 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 +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/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,9 +1461,9 @@ 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
|
-
if (!line)
|
|
1466
|
+
if (!line) continue;
|
|
1471
1467
|
if (line.startsWith("$ ")) {
|
|
1472
1468
|
const radical = {
|
|
1473
1469
|
radical: line.charAt(2).trim(),
|
|
@@ -1475,7 +1471,7 @@ function convertRadkFile(radkBuffer, kanjiDic) {
|
|
|
1475
1471
|
};
|
|
1476
1472
|
let j = i + 1;
|
|
1477
1473
|
let kanjiLine = fileParsed[j];
|
|
1478
|
-
if (!kanjiLine)
|
|
1474
|
+
if (!kanjiLine) continue;
|
|
1479
1475
|
const kanjiList = [];
|
|
1480
1476
|
while (kanjiLine && !kanjiLine.startsWith("$ ")) {
|
|
1481
1477
|
const kanjis = kanjiLine.split("");
|
|
@@ -1511,8 +1507,7 @@ function convertKradFile(kradBuffer, kanjiDic, katakanaList) {
|
|
|
1511
1507
|
const split = line.split(" : ");
|
|
1512
1508
|
const kanjiChar = split[0];
|
|
1513
1509
|
const radicalsRow = split[1];
|
|
1514
|
-
if (!kanjiChar || !radicalsRow)
|
|
1515
|
-
throw new Error("Invalid kradfile2 buffer");
|
|
1510
|
+
if (!kanjiChar || !radicalsRow) continue;
|
|
1516
1511
|
const kanji = {
|
|
1517
1512
|
...kanjiChar && radicalsRow && kanjiChar.length === 1 && radicalsRow.length > 0 ? { kanji: kanjiChar } : { kanji: "" },
|
|
1518
1513
|
radicals: []
|
|
@@ -1723,11 +1718,9 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1723
1718
|
).map((reading) => reading.reading)
|
|
1724
1719
|
);
|
|
1725
1720
|
const kanjiForms = word.kanjiForms ? new Set(
|
|
1726
|
-
word.kanjiForms.
|
|
1727
|
-
(kanjiForm) =>
|
|
1728
|
-
|
|
1729
|
-
)) && (word.common === void 0 || kanjiForm.common === true)
|
|
1730
|
-
).map((kanjiForm) => kanjiForm.kanjiForm)
|
|
1721
|
+
word.kanjiForms.map(
|
|
1722
|
+
(kanjiForm) => kanjiForm.kanjiForm
|
|
1723
|
+
)
|
|
1731
1724
|
) : void 0;
|
|
1732
1725
|
const kanjiFormExamples = [];
|
|
1733
1726
|
const readingMatchingKanjiFormExamples = [];
|
|
@@ -1735,7 +1728,7 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1735
1728
|
const partParts = /* @__PURE__ */ new Set();
|
|
1736
1729
|
for (const example of examples)
|
|
1737
1730
|
for (const part of example.parts) {
|
|
1738
|
-
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);
|
|
1739
1732
|
if (kanjiForms && kanjiForms.size > 0 && kanjiForms.has(part.baseForm)) {
|
|
1740
1733
|
if (readingAsReadingMatch) {
|
|
1741
1734
|
readingMatchingKanjiFormExamples.push(example);
|
|
@@ -1748,17 +1741,20 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1748
1741
|
}
|
|
1749
1742
|
const readingAsBaseFormMatch = readings.has(part.baseForm);
|
|
1750
1743
|
const referenceIDMatch = part.referenceID !== void 0 && word.id !== void 0 && part.referenceID === word.id;
|
|
1751
|
-
if (
|
|
1744
|
+
if (readingAsBaseFormMatch || referenceIDMatch) {
|
|
1752
1745
|
readingExamples.push(example);
|
|
1753
|
-
if (readingAsReadingMatch) partParts.add(part.reading);
|
|
1754
1746
|
if (readingAsBaseFormMatch) partParts.add(part.baseForm);
|
|
1755
1747
|
if (referenceIDMatch) partParts.add(part.referenceID);
|
|
1756
1748
|
break;
|
|
1757
1749
|
}
|
|
1758
1750
|
}
|
|
1759
1751
|
const exampleSize = readingMatchingKanjiFormExamples.length + kanjiFormExamples.length + readingExamples.length;
|
|
1760
|
-
const
|
|
1761
|
-
|
|
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;
|
|
1762
1758
|
let wordExamples = [
|
|
1763
1759
|
...readingMatchingKanjiFormExamples,
|
|
1764
1760
|
...includeKanjiFormExamples ? kanjiFormExamples : [],
|
|
@@ -1770,7 +1766,11 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1770
1766
|
outer: for (const example of wordExamples) {
|
|
1771
1767
|
if (seenPhrases.has(example.phrase)) continue;
|
|
1772
1768
|
for (const part of example.parts)
|
|
1773
|
-
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
|
+
};
|
|
1774
1774
|
glossSpecificExamples.push(example);
|
|
1775
1775
|
seenPhrases.add(example.phrase);
|
|
1776
1776
|
break outer;
|
|
@@ -1789,7 +1789,8 @@ function getWord(dict, id, kanjiDic, examples, dictWord, noteTypeName, deckPath)
|
|
|
1789
1789
|
word.phrases = (wordExamples.length > 5 ? wordExamples.slice(0, 5) : wordExamples).map((ex) => ({
|
|
1790
1790
|
phrase: ex.furigana ?? ex.phrase,
|
|
1791
1791
|
translation: ex.translation,
|
|
1792
|
-
originalPhrase: ex.phrase
|
|
1792
|
+
originalPhrase: ex.phrase,
|
|
1793
|
+
...ex.glossNumber ? { glossNumber: ex.glossNumber } : {}
|
|
1793
1794
|
}));
|
|
1794
1795
|
}
|
|
1795
1796
|
return word;
|
|
@@ -2067,18 +2068,34 @@ function makeSSML(formText, fullReading) {
|
|
|
2067
2068
|
}
|
|
2068
2069
|
return ssml;
|
|
2069
2070
|
}
|
|
2070
|
-
async function synthesizeSpeech(
|
|
2071
|
+
async function synthesizeSpeech(ssmlText, apiKey, options) {
|
|
2071
2072
|
return await new Promise(
|
|
2072
2073
|
async (resolve, reject) => {
|
|
2073
2074
|
try {
|
|
2074
|
-
const
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
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
|
+
}
|
|
2078
2085
|
});
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
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);
|
|
2082
2099
|
} catch (err) {
|
|
2083
2100
|
reject(err);
|
|
2084
2101
|
}
|
|
@@ -2125,7 +2142,7 @@ function generateAnkiNote(entry) {
|
|
|
2125
2142
|
).join("") : noKanjiForms
|
|
2126
2143
|
],
|
|
2127
2144
|
entry.translations.map(
|
|
2128
|
-
(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>" : ""}`
|
|
2129
2146
|
).join(""),
|
|
2130
2147
|
entry.kanji ? entry.kanji.map(
|
|
2131
2148
|
(kanjiEntry) => createEntry(
|
|
@@ -2134,11 +2151,11 @@ function generateAnkiNote(entry) {
|
|
|
2134
2151
|
)
|
|
2135
2152
|
).join("") : '<span class="word word-kanji">(no kanji)</span>',
|
|
2136
2153
|
entry.phrases ? entry.phrases.map(
|
|
2137
|
-
(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(
|
|
2138
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>`,
|
|
2139
2156
|
[phraseEntry.translation],
|
|
2140
2157
|
true
|
|
2141
|
-
)
|
|
2158
|
+
)}`
|
|
2142
2159
|
).join("") : '<span class="word word-phrase">(no phrases) (Search on dictionaries!)</span>',
|
|
2143
2160
|
...entry.tags && entry.tags.length > 0 ? [
|
|
2144
2161
|
entry.tags.map(
|