Last active
November 29, 2019 02:03
-
-
Save Hinaser/ada41af280fc4f9706b5d45abda577da to your computer and use it in GitHub Desktop.
英辞郎 On the web Proの単語帳内の単語を解析し、オリジナルの単語リストオブジェクトをつくるためのスニペット
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function getWordWithKanaTrimmed(el) { | |
const cloneEl = el.cloneNode(true); | |
const kanaEls = Array.from(cloneEl.querySelectorAll("span.kana")); | |
kanaEls.forEach(kanaEl => { | |
cloneEl.removeChild(kanaEl); | |
}); | |
return cloneEl.innerText; | |
} | |
function generateWordList() { | |
const allRows = document.querySelectorAll("#wordlist > tbody > tr:not(:first-child)"); | |
const WordList = []; | |
const rowCount = allRows.length; | |
for (let i = 0; i < rowCount; i += 2) { | |
const wordRow = allRows[i]; | |
const meansRow = allRows[i + 1]; | |
const wordEl = wordRow.querySelector("td:nth-child(2)"); | |
const word = wordEl ? wordEl.innerText : "???"; | |
const wordClassesContainer = meansRow.querySelector("td:nth-child(2) > div > div"); | |
const wordClassEl = wordClassesContainer ? | |
Array.from(wordClassesContainer.querySelectorAll(".wordclass")) : []; | |
const wordMeans = (() => { | |
if (wordClassEl.length > 0) { | |
return wordClassEl.map(el => { | |
const wordClass = el.innerText.replace(/[【】]/g, ""); | |
const meansArray = el.nextSibling ? Array.from(el.nextSibling.querySelectorAll("li")) : []; | |
let means; | |
if (meansArray.length > 0) { | |
means = meansArray.map(meanEl => { | |
return getWordWithKanaTrimmed(meanEl); | |
}); | |
} | |
else { | |
means = el.nextSibling ? [getWordWithKanaTrimmed(el.nextSibling)] : []; | |
} | |
return means.map(m => { | |
return { | |
wordClass, | |
mean: m, | |
}; | |
}); | |
}).flat(); | |
} | |
// When not single word | |
if (/[ ]/.test(word) && wordClassesContainer && wordClassesContainer.querySelectorAll("ol").length < 1) { | |
return [{ | |
wordClass: "熟語", | |
mean: getWordWithKanaTrimmed(wordClassesContainer), | |
}]; | |
} | |
console.warn("Unrecognizable word", word); | |
return []; | |
})(); | |
const pronounceEl = meansRow.querySelector("span.attr > span.pron"); | |
const pronounce = pronounceEl ? pronounceEl.innerText.replace(/、$/, "") : ""; | |
const Word = { | |
word, | |
wordMeans, | |
pronounce, | |
}; | |
WordList.push(Word); | |
} | |
return WordList; | |
} | |
function gatherAllWordMeans(WordList) { | |
return WordList.map(wl => { | |
return wl.wordMeans; | |
}).flat(); | |
} | |
// https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array | |
function shuffleArray(array) { | |
let workingArray = [...array]; | |
for (let i = workingArray.length - 1; i > 0; i--) { | |
const j = Math.floor(Math.random() * (i + 1)); | |
[workingArray[i], workingArray[j]] = [workingArray[j], workingArray[i]]; | |
} | |
return workingArray; | |
} | |
function generateQuestionList(wordList, nChoices, nQuestions) { | |
const randomizedWordList = shuffleArray(wordList); | |
let allAnswers = gatherAllWordMeans(randomizedWordList); | |
return randomizedWordList.slice(0, nQuestions).map(wl => { | |
allAnswers = shuffleArray(allAnswers); | |
let i = 0; | |
const choices = []; | |
while (choices.length < nChoices - 1 && i < allAnswers.length) { | |
const answerCandidate = allAnswers[i]; | |
if (!wl.wordMeans.some(m => m.mean === answerCandidate.mean)) { | |
choices.push(answerCandidate); | |
} | |
i++; | |
} | |
const correctAnswer = wl.wordMeans[Math.floor(Math.random() * wl.wordMeans.length)]; | |
choices.push(correctAnswer); | |
return Object.assign(Object.assign({}, wl), { choices: shuffleArray(choices) }); | |
}); | |
} | |
function gatherAndStoreWordList() { | |
let wl = generateWordList(); | |
const savedWlStr = localStorage.getItem("wordList"); | |
if (savedWlStr) { | |
const savedWl = JSON.parse(savedWlStr); | |
wl = savedWl.concat(wl).filter((w, i, arr) => i === arr.findIndex(w2 => w2.word === w.word)); | |
} | |
const wlStr = JSON.stringify(wl); | |
localStorage.setItem("wordList", wlStr); | |
return wl; | |
} | |
async function loadEowpDataFromLocalStorage() { | |
const wordList = (() => { | |
try { | |
return JSON.parse(localStorage.getItem("wordList")) || []; | |
} | |
catch (e) { | |
return undefined; | |
} | |
})(); | |
const resultHistory = (() => { | |
try { | |
return JSON.parse(localStorage.getItem("resultHistory")) || []; | |
} | |
catch (e) { | |
return undefined; | |
} | |
})(); | |
const qaTrend = (() => { | |
try { | |
return JSON.parse(localStorage.getItem("qaTrend")) || []; | |
} | |
catch (e) { | |
return undefined; | |
} | |
})(); | |
const nChoices = (() => { | |
try { | |
const rt = JSON.parse(localStorage.getItem("nChoices")); | |
return typeof rt === "number" ? rt : undefined; | |
} | |
catch (e) { | |
return undefined; | |
} | |
})(); | |
const nQuestionsInExam = (() => { | |
try { | |
const rt = JSON.parse(localStorage.getItem("nQuestionsInExam")); | |
return typeof rt === "number" ? rt : undefined; | |
} | |
catch (e) { | |
return undefined; | |
} | |
})(); | |
return { | |
version: 0, | |
loading: false, | |
wordList, | |
resultHistory, | |
qaTrend, | |
nChoices, | |
nQuestionsInExam, | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment