188 lines
5.8 KiB
JavaScript
188 lines
5.8 KiB
JavaScript
|
const jishoApi = require('unofficial-jisho-api');
|
||
|
jisho = new jishoApi();
|
||
|
fs = require('fs');
|
||
|
const util = require('util');
|
||
|
|
||
|
/************************************************************************
|
||
|
***************************** Data fetching *****************************
|
||
|
************************************************************************/
|
||
|
|
||
|
async function fetchKanjiFromTxt(file) {
|
||
|
const read = util.promisify(fs.readFile);
|
||
|
const data = await read(file, 'utf8');
|
||
|
return data.split('');
|
||
|
}
|
||
|
|
||
|
async function delayedJishoCall(kanji, delay) {
|
||
|
return new Promise((res, rej) => {
|
||
|
setTimeout(() => {
|
||
|
res(jisho.searchForKanji(kanji));
|
||
|
}, delay);
|
||
|
})
|
||
|
}
|
||
|
|
||
|
/* Function to fetch jisho data for all kanjis in an array */
|
||
|
async function fetchKanjiFromJisho(kanjiArray) {
|
||
|
const promises = kanjiArray.map(async (kanji, i) => await delayedJishoCall(kanji, i*50));
|
||
|
return await Promise.all(promises);
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
***************************** Kanji tables ******************************
|
||
|
************************************************************************/
|
||
|
|
||
|
function kanjiTable(kanjiArray) {
|
||
|
const xLength = 20;
|
||
|
const yLength = Math.ceil(kanjiArray.length/xLength);
|
||
|
const sideLength = Math.ceil(Math.sqrt(kanjiArray.length));
|
||
|
|
||
|
let tableString = '';
|
||
|
for (let y_index = 0; y_index < yLength; y_index++) {
|
||
|
|
||
|
const lineArray = new Array;
|
||
|
|
||
|
for (let x_index = 0; x_index < xLength; x_index++) {
|
||
|
const indexNumber = y_index * yLength + x_index;
|
||
|
lineArray.push(kanjiArray[indexNumber] ? kanjiArray[indexNumber] : '');
|
||
|
}
|
||
|
|
||
|
tableString += `${lineArray.join(' & ')} \\\\\n`
|
||
|
}
|
||
|
|
||
|
return `\\begin{tabular}{ ${'c '.repeat(xLength)}}
|
||
|
${tableString}\\end{tabular}`
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
**************************** Page Processing ****************************
|
||
|
************************************************************************/
|
||
|
|
||
|
const yomiBrackets = ['\\textbf{\\textcolor{myGreen!80!black}{', '}}'];
|
||
|
const yomiConnector = '、 ';
|
||
|
const yomiDash = '—';
|
||
|
|
||
|
function convertKunyomi(res) {
|
||
|
|
||
|
if (res.kunyomi.length === 0) return '';
|
||
|
|
||
|
const kunyomi = JSON.stringify(res.kunyomi)
|
||
|
.replace(/"|\[|\]/g, '')
|
||
|
.replace(/\\/g, '\\\\')
|
||
|
.replace(/%/g, '\\%')
|
||
|
.replace(/&/g, '\\&')
|
||
|
.split(',');
|
||
|
|
||
|
for (const i in kunyomi) {
|
||
|
instance = kunyomi[i];
|
||
|
|
||
|
if (instance.includes('.') && instance.includes('-')) {
|
||
|
|
||
|
}
|
||
|
else if (instance.includes('.')) {
|
||
|
const words = instance.split('.');
|
||
|
words[0] = yomiBrackets[0] + words[0] + yomiBrackets[1];
|
||
|
kunyomi[i] = words.join('');
|
||
|
}
|
||
|
else if (instance.includes('-')) {
|
||
|
const words = instance.split(/(?<=\-)/);
|
||
|
if (words[0] == '-') { // ['-', 'word']
|
||
|
words[0] = yomiDash;
|
||
|
words[1] = yomiBrackets[0] + words[1] + yomiBrackets[1];
|
||
|
} else { // ['Word-', '']
|
||
|
words[1] = yomiDash;
|
||
|
words[0] = words[0].slice(0, words[0].length-1);
|
||
|
words[0] = yomiBrackets[0] + words[0] + yomiBrackets[1];
|
||
|
}
|
||
|
kunyomi[i] = words.join('');
|
||
|
}
|
||
|
else {
|
||
|
kunyomi[i] = yomiBrackets[0] + instance + yomiBrackets[1];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return kunyomi.join(yomiConnector);
|
||
|
}
|
||
|
|
||
|
function convertOnyomi(res) {
|
||
|
return JSON.stringify(res.onyomi)
|
||
|
.replace(/"|\[|\]/g, '')
|
||
|
.replace(/\\/g, '\\\\')
|
||
|
.replace(/%/g, '\\%')
|
||
|
.replace(/,/g, yomiConnector)
|
||
|
.replace(/&/g, '\\&');
|
||
|
}
|
||
|
|
||
|
function convertMeaning(res) {
|
||
|
return res.meaning
|
||
|
.replace(/\\/g, '\\\\')
|
||
|
.replace(/%/g, '\\%')
|
||
|
.replace(/&/g, '\\&');
|
||
|
}
|
||
|
|
||
|
/************************************************************************
|
||
|
**************************** Main Functions *****************************
|
||
|
************************************************************************/
|
||
|
|
||
|
/* Sort list of result array */
|
||
|
const sortKanji = (kanjiData) => kanjiData.sort((a, b) => (a.strokeCount > b.strokeCount) ? 1 : -1);
|
||
|
|
||
|
/* Process result array into object with LaTeX strings */
|
||
|
function getKanjiTexData(kanjiArray) {
|
||
|
return kanjiArray.map(kanji => {
|
||
|
|
||
|
const meaning = convertMeaning(kanji);
|
||
|
const kunyomi = convertKunyomi(kanji);
|
||
|
const onyomi = convertOnyomi(kanji);
|
||
|
|
||
|
return {
|
||
|
kanji: kanji.query,
|
||
|
kanjiPageHeader: `\\kanjiPageHeader{${kanji.query}}{${kanji.taughtIn}}{${kanji.jlptLevel}}{${kanji.strokeCount}}{${kanji.radical.symbol}}`,
|
||
|
kanjiMeaning: meaning ? `\\kanjiMeaning{${meaning}}` : '',
|
||
|
kunyomi: kunyomi ? `\\kunyomi{${kunyomi}}` : '',
|
||
|
onyomi: onyomi ? `\\onyomi{${onyomi}}` : '',
|
||
|
kanjiRow: `\\kanjiRow{${kanji.query}}`
|
||
|
}
|
||
|
|
||
|
});
|
||
|
}
|
||
|
|
||
|
/* Encapsulating main process in async function */
|
||
|
async function main(jlptLevel) {
|
||
|
|
||
|
const kanjiArray = await fetchKanjiFromTxt(`../data/txt/${jlptLevel}.txt`);
|
||
|
console.log(`Fetched txt for ${jlptLevel}`);
|
||
|
|
||
|
const results = await fetchKanjiFromJisho(kanjiArray);
|
||
|
console.log(`Fetched data from Jisho for ${jlptLevel}`);
|
||
|
|
||
|
const sortedResults = sortKanji(results);
|
||
|
const sortedKanji = sortedResults.map(result => result.query);
|
||
|
const texData = getKanjiTexData(sortedResults);
|
||
|
console.log(`Processed pages for ${jlptLevel}`);
|
||
|
|
||
|
const resultTable = kanjiTable(sortedKanji);
|
||
|
console.log(`Processed table for ${jlptLevel}`);
|
||
|
|
||
|
let resultPage = '';
|
||
|
for (kanji of texData) {
|
||
|
resultPage+=`${kanji.kanjiPageHeader}
|
||
|
${kanji.kanjiMeaning ? kanji.kanjiMeaning : ''}
|
||
|
${kanji.kunyomi ? kanji.kunyomi : ''}
|
||
|
${kanji.onyomi ? kanji.onyomi : ''}
|
||
|
${kanji.kanjiRow}
|
||
|
\\newpage\n`;
|
||
|
}
|
||
|
|
||
|
fs.writeFile(`../data/tables/${jlptLevel}.tex`, resultTable, (err) => {if (err) console.error(err)});
|
||
|
fs.writeFile(`../data/pages/${jlptLevel}.tex`, resultPage, (err) => {if (err) console.error(err)});
|
||
|
}
|
||
|
|
||
|
async function loopMain() {
|
||
|
await main('n5');
|
||
|
await main('n4');
|
||
|
await main('n3');
|
||
|
await main('n2');
|
||
|
await main('n1');
|
||
|
}
|
||
|
|
||
|
loopMain();
|