DKL9 GitList
Repositories
DKL9 home
site_root
Code
Commits
Branches
Tags
Search
Tree:
993e20c
Branches
Tags
master
site_root
tools
tanakh_reading.html
Initial commit: track much site content
dkl9
commited
993e20c
at 2025-352 15:27:28
tanakh_reading.html
Blame
History
Raw
<!doctype html> <html> <head> <meta charset="utf-8"> <title>Assisted Hebrew Bible (Tanakh) reading</title> <link rel="stylesheet" href="/style.css"> <link rel="icon" type="image/png" href="/favicon.png"> </head> <body> <noscript>Enable JavaScript, or use a different browser</noscript> <label>Book: <select id="booksel"> <option value="genesis.50">Genesis / בראשית</option> <option value="exodus.40">Exodus / שמות</option> <option value="leviticus.27">Leviticus / ויקרא</option> <option value="numbers.36">Numbers / במדבר</option> <option value="deuteronomy.34">Deuteronomy / דברים</option> </select></label> <label>Chapter: <input id="chapsel" type="range" min="1" max="27"> <span id="curchap"></span></label> <button id="startbtn" type="button">Go</button> <label>Hebrew dictionary: <select id="dictsel"> <option value="morfix">Morfix</option> <option value="pealim">Pealim</option> <option value="wikt">Wiktionary</option> </select></label> <div id="vocab"></div> <div id="verses" tabindex="0"></div> <p>Press A, with the text focused, to show the English translation of the last line. Press S likewise to show the next line of Hebrew. Highlight a word in the last shown line of Hebrew to look it up. Text extracted from <a href="https://www.the-iconoclast.org/resources/tanakh/tanakh.php"><em>The Iconoclast</em> by R.M. Pill</a> (Leningrad Codex). Comments and questions are welcome. Email them to <a href="mailto:contact@dkl9.net">contact@dkl9.net</a>. <span style="display: none;">And not <a href="mailto:sucrose@dkl9.net">sucrose@dkl9.net</a>, unless you are a spambot.</span></p> <p><a href="/">dkl9 home</a></p> <script> const textHe = {}; const textEn = {}; </script> <script src="texts/genesis.js"></script> <script src="texts/exodus.js"></script> <script src="texts/leviticus.js"></script> <script src="texts/numbers.js"></script> <script src="texts/deuteronomy.js"></script> <script> ["booksel", "chapsel", "curchap", "startbtn", "dictsel", "vocab", "verses"].forEach(n => window[n] = document.getElementById(n)); const readerState = { book: null, chapter: null, verse: null, translated: false, }; const getVerse = (t, rs) => t[rs.book][rs.chapter - 1][rs.verse - 1]; const verseHe = rs => `${rs.chapter}:${rs.verse} ${getVerse(textHe, rs)}`; const paragraph = s => { const v = document.createElement("p"); v.append(s); return v; }; const dictURLs = { morfix: "https://www.morfix.co.il/%s", pealim: "https://www.pealim.com/search/?q=%s", wikt: "https://en.wiktionary.org/wiki/%s", }; const vowelPattern = /[\u05B0-\u05C7]/g; const lookupWord = s => window.open(dictURLs[dictsel.value].replace("%s", s.replaceAll(vowelPattern, "")), "_blank"); booksel.onchange = () => { const max = parseInt(booksel.value.split(".")[1]); chapsel.max = max; if (chapsel.value > max) curchap.textContent = chapsel.value = max; }; chapsel.oninput = () => (curchap.textContent = chapsel.value); startbtn.onclick = () => { startbtn.disabled = chapsel.disabled = booksel.disabled = true; readerState.book = booksel.value.split(".")[0]; readerState.chapter = parseInt(chapsel.value); readerState.verse = 1; verses.append(paragraph(verseHe(readerState))); }; verses.onkeyup = ev => { chapterLength = textHe[readerState.book][readerState.chapter - 1].length; switch (ev.key) { case "A": case "a": if (!readerState.translated && readerState.verse <= chapterLength) { readerState.translated = true; verses.append(paragraph(getVerse(textEn, readerState))); } break; case "S": case "s": if (readerState.verse < chapterLength) { readerState.verse++; if (readerState.translated) verses.lastElementChild.textContent = verseHe(readerState); else verses.append(paragraph(verseHe(readerState))); readerState.translated = false; } break; } }; verses.onmouseup = ev => { const ch = verses.children; if (ch.length < 2) return; const t = ch[readerState.translated ? ch.length - 2 : ch.length - 1]; if (t.contains(ev.target)) { const sel = window.getSelection(); if (!sel.isCollapsed && t.contains(sel.anchorNode) && t.contains(sel.focusNode)) lookupWord(sel.toString().trim()); } }; </script> </body> </html>