"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# load the app and data\n",
"BHSA = use (\"etcbc/BHSA\", mod=\"tonyjurg/BHSaddons/tf/\", hoist=globals())"
]
},
{
"cell_type": "markdown",
"id": "bd939a75-8253-4119-b64d-3d5c403ed096",
"metadata": {},
"source": [
"# 3 - Performing the queries \n",
"##### [Back to ToC](#TOC)\n",
"\n",
"The main engine of our queries is the use of Text-Fabric feature `crossref`, part of `Parallel Passages` module. See also [this notebook](https://nbviewer.org/github/etcbc/parallels/blob/master/programs/parallels.ipynb) explaing the concepts and how this feature was created."
]
},
{
"cell_type": "markdown",
"id": "98d90b55-8aed-4691-8a7d-e110c48d4857",
"metadata": {},
"source": [
"## 3.1 - Locate the parallels "
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "9f2d4e15-43e8-4ab6-946b-52e2178e0f21",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 0.01s 106 results\n"
]
}
],
"source": [
"# find all verse nodes for this parasha using its sequence number\n",
"parashaQuery = '''\n",
"verse parashanum=11\n",
"'''\n",
"parashaResults = BHSA.search(parashaQuery)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "c26a2bf5-bb27-4bed-a562-3c786bd3835a",
"metadata": {},
"outputs": [],
"source": [
"# Store parashname, start and end verse for future use\n",
"startNode=parashaResults[0][0]\n",
"endNode=parashaResults[-1][0]\n",
"parashaNameHebrew=F.parashahebr.v(startNode)\n",
"parashaNameEnglish=F.parashatrans.v(startNode)\n",
"bookStart,chapterStart,startVerse=T.sectionFromNode(startNode)\n",
"parashaStart=f'{bookStart} {chapterStart}:{startVerse}'\n",
"bookEnd,chapterEnd,startEnd=T.sectionFromNode(endNode)\n",
"parashaEnd=f'{chapterEnd}:{startEnd}'\n",
"htmlStart=''\n",
"htmlFooter=f'Data generated by `hapax.ipynb` at `github.com/tonyjurg/Parashot `
'"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "62c96550-4ca8-458c-8fce-3296bd733bd1",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"Lexical parallels for parasha Vayigash (Genesis 44:18-47:27) וַנֹּ֕אמֶר לֹ֥א נוּכַ֖ל לָרֶ֑דֶת אִם־יֵשׁ֩ אָחִ֨ינוּ הַקָּטֹ֤ן אִתָּ֨נוּ֙ וְיָרַ֔דְנוּ כִּי־לֹ֣א נוּכַ֗ל לִרְאֹות֙ פְּנֵ֣י הָאִ֔ישׁ וְאָחִ֥ינוּ הַקָּטֹ֖ן אֵינֶ֥נּוּ אִתָּֽנוּ׃
Reference Match Text Genesis 43:5 75% ו ְאִם־ אֵי נְךָ֥ מְשׁ ַלֵּ֖חַ לֹ֣א נ ֵרֵ֑ד כִּֽי־הָאִ֞ישׁ אָמַ֤ר אֵלֵ֨ינוּ ֙ ל ֹֽא־תִרְא ֣ וּ פָנַ ֔י בּ ִלְתִּ֖ י א ֲחִי כֶ֥ ם אִתּ ְכֶֽ ם׃
וְאֵ֨לֶּה שְׁמֹ֧ות בְּנֵֽי־יִשְׂרָאֵ֛ל הַבָּאִ֥ים מִצְרַ֖יְמָה יַעֲקֹ֣ב וּבָנָ֑יו בְּכֹ֥ר יַעֲקֹ֖ב רְאוּבֵֽן׃
Reference Match Text Exodus 1:1 81% וְאֵ ֗לֶּה שְׁמֹ ות ֙ בְּנֵ ֣י יִשְׂרָאֵ ֔ל הַבָּאִ ֖ים מִצְר ָ֑יְמָה אֵ֣ת יַעֲקֹ ֔ב אִ֥ישׁ וּב ֵי תֹ֖ו בּ ָֽאוּ ׃
וּבְנֵ֖י רְאוּבֵ֑ן חֲנֹ֥וךְ וּפַלּ֖וּא וְחֶצְרֹ֥ון וְכַרְמִֽי׃
Reference Match Text 1_Chronicles 5:3 80% בּ ְנֵ ֥י רְאוּבֵ ֖ן בְּכֹ֣ור יִשְׂרָאֵ֑ ל חֲנֹ֥וךְ וּפַלּ֖וּא חֶצְרֹ֥ון וְכַרְמִֽי׃
וּבְנֵ֣י שִׁמְעֹ֗ון יְמוּאֵ֧ל וְיָמִ֛ין וְאֹ֖הַד וְיָכִ֣ין וְצֹ֑חַר וְשָׁא֖וּל בֶּן־הַֽכְּנַעֲנִֽית׃
Reference Match Text Exodus 6:15 84% וּבְנֵ֣י שִׁמְעֹ֗ון יְמוּאֵ ֨ל וְיָמִ ֤ין וְאֹ ֨הַד ֙ וְיָכִ֣ין וְצֹ ֔חַר וְשָׁא֖וּל בֶּן־הַֽכְּנַעֲנִ ֑ית אֵ֖לֶּה מִשְׁפְּחֹ֥ת שִׁמְעֹֽון׃
וּבְנֵ֖י לֵוִ֑י גֵּרְשֹׁ֕ון קְהָ֖ת וּמְרָרִֽי׃
Reference Match Text Numbers 3:17 76% וַיִּֽהְיוּ ־אֵ֥לֶּה בְנֵ ֽי ־לֵוִ ֖י בִּשְׁמֹתָ֑ ם גֵּרְשֹׁ֕ון וּקְהָ֖ת וּמְרָרִֽי׃ 1_Chronicles 5:27 100% בּ ְנֵ֖י לֵוִ֑י גֵּרְשֹׁ֕ון קְהָ֖ת וּמְרָרִֽי׃ 1_Chronicles 6:1 94% בּ ְנֵ֖י לֵוִ֑י גֵּרְשֹׁ֕ ם קְהָ֖ת וּמְרָרִֽי׃
וּבְנֵ֖י יִשָׂשכָ֑ר תֹּולָ֥ע וּפֻוָּ֖ה וְיֹ֥וב וְשִׁמְרֹֽון׃
Reference Match Text 1_Chronicles 7:1 86% ו ְלִבְנֵ ֣י יִשָׂשכָ ֗ר תֹּולָ ֧ע וּפ וּ אָ ֛ה י ָשׁ֥ו ּב וְשִׁמְרֹ ֖ון אַרְבָּעָֽה׃ ס
וּבְנֵ֣י אָשֵׁ֗ר יִמְנָ֧ה וְיִשְׁוָ֛ה וְיִשְׁוִ֥י וּבְרִיעָ֖ה וְשֶׂ֣רַח אֲחֹתָ֑ם וּבְנֵ֣י בְרִיעָ֔ה חֶ֖בֶר וּמַלְכִּיאֵֽל׃
Reference Match Text 1_Chronicles 7:30 78% בּ ְנֵ֣י אָשֵׁ֗ר יִמְנָ֧ה וְיִשְׁוָ֛ה וְיִשְׁוִ֥י וּבְרִיעָ֖ה וְשֶׂ ֥רַח אֲחֹ ותָ ֽם ׃
אֵ֚לֶּה בְּנֵ֣י זִלְפָּ֔ה אֲשֶׁר־נָתַ֥ן לָבָ֖ן לְלֵאָ֣ה בִתֹּ֑ו וַתֵּ֤לֶד אֶת־אֵ֨לֶּה֙ לְיַעֲקֹ֔ב שֵׁ֥שׁ עֶשְׂרֵ֖ה נָֽפֶשׁ׃
Reference Match Text Genesis 46:25 82% אֵ֚לֶּה בְּנֵ֣י בִלְ הָ֔ה אֲשֶׁר־נָתַ֥ן לָבָ֖ן לְ רָחֵ֣ל ב ִּתֹּ֑ו וַתֵּ ֧לֶד אֶת־אֵ ֛לֶּה לְיַעֲקֹ ֖ב כָּל־נֶ֥ פֶשׁ שִׁבְעָֽה׃
בְּנֵ֤י רָחֵל֙ אֵ֣שֶׁת יַֽעֲקֹ֔ב יֹוסֵ֖ף וּבִנְיָמִֽן׃
Reference Match Text Genesis 35:24 80% בְּנֵ ֣י רָחֵ ֔ל יֹוסֵ֖ף וּבִנְיָמִֽן׃
וּבְנֵי־דָ֖ן חֻשִֽׁים׃
Reference Match Text Ezra 10:38 78% וּב ָנ ִ֥י וּבִנּ֖ וּי שִׁ מְעִֽי ׃
וּבְנֵ֖י נַפְתָּלִ֑י יַחְצְאֵ֥ל וְגוּנִ֖י וְיֵ֥צֶר וְשִׁלֵּֽם׃
Reference Match Text 1_Chronicles 7:13 85% בּ ְנֵ ֣י נַפְתָּלִ ֗י יַח ֲצ ִיאֵ ֧ל וְגוּנִ ֛י וְיֵ֥צֶר וְשׁ ַלּ֖וּם בְּנֵ֥י בִל ְהָֽ ה׃ פ
אֵ֚לֶּה בְּנֵ֣י בִלְהָ֔ה אֲשֶׁר־נָתַ֥ן לָבָ֖ן לְרָחֵ֣ל בִּתֹּ֑ו וַתֵּ֧לֶד אֶת־אֵ֛לֶּה לְיַעֲקֹ֖ב כָּל־נֶ֥פֶשׁ שִׁבְעָֽה׃
Reference Match Text Genesis 46:18 82% אֵ֚לֶּה בְּנֵ֣י זִלְ פָּ֔ה אֲשֶׁר־נָתַ֥ן לָבָ֖ן לְ לֵאָ ֣ ה ב ִתֹּ֑ו וַתֵּ ֤לֶד אֶת־אֵ ֨לֶּה ֙ לְיַעֲקֹ ֔ב שֵׁ֥שׁ עֶשְׂרֵ֖ה נָ ֽפֶשׁ ׃
"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"\n",
"\n",
" Download Lexical Parallels as HTML \n",
" \n"
],
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"from difflib import SequenceMatcher\n",
"from IPython.display import HTML, display\n",
"\n",
"# Function to find and highlight matching parts between two strings\n",
"def highlightMatches(baseText, comparisonText):\n",
" matcher = SequenceMatcher(None, baseText, comparisonText)\n",
" highlightedComparisonText = \"\"\n",
" \n",
" for tag, i1, i2, j1, j2 in matcher.get_opcodes():\n",
" if tag == \"equal\": # Identical parts\n",
" highlightedComparisonText += f\"{comparisonText[j1:j2]} \"\n",
" else: # Non-matching parts\n",
" highlightedComparisonText += comparisonText[j1:j2]\n",
" \n",
" return highlightedComparisonText\n",
"\n",
"# Function to process cross-references and format them into an HTML table\n",
"def generateCrossReferencesTable(verseNode):\n",
" \"\"\"\n",
" Generates an HTML table with cross-references for a single verse node, highlighting identical parts.\n",
" The main verse text will be right-aligned.\n",
" \"\"\"\n",
" # Get cross-references for the specified verseNode\n",
" crossRefs = Es(\"crossref\").f(verseNode)\n",
" tableContent = \"\"\n",
" \n",
" # Check if there are any cross-references for this verse\n",
" if crossRefs:\n",
" verseSection = T.sectionFromNode(verseNode)\n",
" mainVerseText = T.text(verseNode)\n",
" linkStepBible = (\n",
" f\"\"\n",
" f\"{verseSection[0]} {verseSection[1]}:{verseSection[2]} \"\n",
" ) \n",
" # Right-align the main verse text\n",
" tableContent += f\"Cross-references for {linkStepBible} \"\n",
" tableContent += f\"{mainVerseText}
\"\n",
" # Create table header\n",
" tableContent += f\"Reference Match Text \"\n",
" \n",
" # Process each cross-reference and add a row to the table\n",
" for target, confidence in crossRefs:\n",
" targetSection = T.sectionFromNode(target)\n",
" targetText = T.text(target)\n",
" \n",
" targetStepBible = (\n",
" f\"\"\n",
" f\"{targetSection[0]} {targetSection[1]}:{targetSection[2]} \"\n",
" ) \n",
" # Highlight identical parts in target verse\n",
" highlightedText = highlightMatches(mainVerseText, targetText)\n",
" \n",
" # Add the row for the cross-reference\n",
" tableContent += f\"{targetStepBible} {confidence}% {highlightedText} \"\n",
" \n",
" # Close the table\n",
" tableContent += \"
\"\n",
"\n",
" return tableContent\n",
"\n",
"# Initialize HTML content\n",
"htmlContent = f\"Lexical parallels for parasha {parashaNameEnglish} ({parashaStart}-{parashaEnd}) \"\n",
"\n",
"# Process each verse and generate cross-reference tables\n",
"for verse in parashaResults:\n",
" htmlContent += generateCrossReferencesTable(verse[0])\n",
"\n",
"# Save the content to an HTML file\n",
"fileName = f\"lexical_parallels({parashaNameEnglish.replace(' ','%20')}).html\"\n",
"with open(fileName, \"w\", encoding=\"utf-8\") as file:\n",
" file.write(htmlContent)\n",
"\n",
"# Display the HTML content in the notebook\n",
"display(HTML(htmlContent))\n",
"\n",
"# wrap html header and footer and display a download button\n",
"htmlContentFull = f'{htmlStart}{htmlContent}{htmlFooter}'\n",
"downloadButton = f\"\"\"\n",
"', '>').replace('\"', '"').replace(\"'\", ''')}\" target=\"_blank\">\n",
" Download Lexical Parallels as HTML \n",
" \n",
"\"\"\"\n",
"display(HTML(downloadButton))"
]
},
{
"cell_type": "markdown",
"id": "93852912-fa5c-420a-88ed-8be3b090eb3a",
"metadata": {
"tags": []
},
"source": [
"# 4 - Required libraries \n",
"##### [Back to ToC](#TOC)\n",
"\n",
"The scripts in this notebook require (beside `text-fabric`) the following Python libraries to be installed in the environment:\n",
"\n",
" difflib\n",
"\n",
"You can install any missing library from within Jupyter Notebook using either`pip` or `pip3`."
]
},
{
"cell_type": "markdown",
"id": "bc5b6c04-4855-4d2d-aa9a-a1dac0256074",
"metadata": {},
"source": [
"# 5 - Further reading \n",
"##### [Back to ToC](#TOC)\n",
"\n",
"For an elaborate treatment of parallel passages, see:\n",
"\n",
"> Willem Th. van Peursen and Eep Talstra. \"Computer-Assisted Analysis of Parallel Texts in the Bible - The Case of 2 Kings xviii-xix and its Parallels in Isaiah and Chronicles\" in *Vetus Testamentum* 57, pp. 45-72. 2007, Brill, Leiden."
]
},
{
"cell_type": "markdown",
"id": "68573424-b71f-4596-95e7-468cf9ef9c1e",
"metadata": {},
"source": [
"# 6 - Notebook version details \n",
"##### [Back to ToC](#TOC)\n",
"\n",
"\n",
"
\n",
" \n",
" Author \n",
" Tony Jurg \n",
" \n",
" \n",
" Version \n",
" 1.1 \n",
" \n",
" \n",
" Date \n",
" 18 November 2024 \n",
" \n",
"
\n",
"
"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.7"
}
},
"nbformat": 4,
"nbformat_minor": 5
}