Versecontent
versecontent
¶
VERSECONTENT
¶
Handle a single verse.
It can retrieve word data from the database and render it in various textual formats.
Source code in modules/versecontent.py
class VERSECONTENT:
"""Handle a single verse.
It can retrieve word data from the database
and render it in various textual formats.
"""
def __init__(
self,
vr,
book_name,
chapter_num,
verse_num,
xml=None,
wordData=None,
tp=None,
tr=None,
mr=None,
lang="en",
):
self.version = vr
self.tp = tp
self.tr = tr
self.mr = mr
self.lang = lang
self.book_name = book_name
self.chapter_num = chapter_num
self.verse_num = verse_num
self.xml = xml
self.wordData = wordData
self.process()
def process(self):
vr = self.version
book_name = self.book_name
chapter_num = self.chapter_num
verse_num = self.verse_num
xml = self.xml
wordData = self.wordData
if xml is None:
xml = ""
PASSAGE_DBS = current.PASSAGE_DBS
passageDb = PASSAGE_DBS.get(vr, None)
if wordData is None and passageDb:
fieldNames = ",".join(FIELDNAMES["txtd"])
wsql = dedent(
f"""
select {fieldNames}, lexicon_id from word
inner join word_verse on word_number = word_verse.anchor
inner join verse on verse.id = word_verse.verse_id
inner join chapter on verse.chapter_id = chapter.id
inner join book on chapter.book_id = book.id
where book.name = '{book_name}'
and chapter.chapter_num = {chapter_num}
and verse.verse_num = {verse_num}
order by word_number
;
"""
)
wordRecords = passageDb.executesql(wsql, as_dict=True) if passageDb else []
wordData = []
for record in wordRecords:
wordData.append(
dict(
(
(
x,
hEsc(
str(y),
not (x.endswith("_border") or x in NOTFILLFIELDS),
),
)
for (x, y) in record.items()
),
)
)
self.xml = xml
self.wordData = wordData
self.words = []
def label(self):
return (
BOOK_TRANS[self.lang][self.book_name].replace("_", " "),
self.book_name,
self.chapter_num,
self.verse_num,
)
def getWords(self):
if len(self.words) == 0:
root = ET.fromstring(f"<verse>{self.xml}</verse>".encode("utf-8"))
i = 0
for child in root:
slotid = int(child.attrib["m"])
lexicon_id = child.attrib["l"]
text = "" if child.text is None else child.text
thisWordData = self.wordData[i]
phonoText = thisWordData["word_phono"]
phonoSep = thisWordData["word_phono_sep"]
trailer = child.get("t", "")
self.words.append(
(slotid, lexicon_id, text, trailer, phonoText, phonoSep)
)
i += 1
return self.words
def material(self):
if self.tp == "txtp":
return self.plainText()
elif self.tp == "txt1":
return self.tab1Text()
elif self.tp == "txt2":
return self.tab2Text()
elif self.tp == "txt3":
return self.tab3Text()
elif self.tp == "txtd":
return self.dataText()
def plainText(self):
"""Present text in plain Hebrew or plain phonetic text.
See [∈ text-representation][elem-text-representation]
"""
material = []
for word in self.getWords():
if self.tr == "hb":
wordText = word[2]
sep = word[3]
elif self.tr == "ph":
wordText = word[4]
sep = word[5]
material.append(
f"""<span m="{word[0]}" l="{word[1]}">{wordText}</span>{sep}"""
)
return "".join(material)
def dataText(self):
"""Present text in data format.
Linguistic features of the words will be shown,
according to the current settings of the legend.
See [∈ legend][elem-feature-legend], [∈ show-verse-data][elem-show-verse-data]
"""
material = []
for word in self.wordData:
material.append(TEXT_TPL.format(**word))
return "".join(material)
def tab1Text(self):
"""Present text in a table, mode 1.
Mode 1 is notes view, i.e. notes are viewed
interlinear with the clause atoms.
See [∈ text-presentation][elem-text-presentation]
"""
material = ["""<table class="t1_table">"""]
curNum = (0, 0, 0)
curClauseAtom = []
for word in self.wordData:
thisNum = (
word["sentence_number"],
word["clause_number"],
word["clause_atom_number"],
)
if thisNum != curNum:
material.append(self.putClauseAtom1(curClauseAtom))
curClauseAtom = []
curNum = thisNum
curClauseAtom.append(word)
material.append(self.putClauseAtom1(curClauseAtom))
material.append("</table>")
return "".join(material)
def tab2Text(self):
"""Present text in a table, mode 2.
Mode 2 is syntactic view, i.e. indentation is used to
represent linguistic embedding.
See [∈ text-presentation][elem-text-presentation]
"""
material = ['<dl class="lv2">']
curNum = (0, 0, 0)
curClauseAtom = []
for word in self.wordData:
thisNum = (
word["sentence_number"],
word["clause_number"],
word["clause_atom_number"],
)
if thisNum != curNum:
material.append(self.putClauseAtom2(curClauseAtom))
curClauseAtom = []
curNum = thisNum
curClauseAtom.append(word)
material.append(self.putClauseAtom2(curClauseAtom))
material.append("</dl>")
return "".join(material)
def tab3Text(self):
"""Present text in a table, mode 3.
Mode 3 is abstract view, i.e. letters are replaced by
abstract symbols, where many letters map to the same symbol.
represent linguistic embedding.
See [∈ text-presentation][elem-text-presentation]
"""
material = ['<dl class="lv3">']
curNum = (0, 0, 0)
curClauseAtom = []
for word in self.wordData:
thisNum = (
word["sentence_number"],
word["clause_number"],
word["clause_atom_number"],
)
if thisNum != curNum:
material.append(self.putClauseAtom3(curClauseAtom))
curClauseAtom = []
curNum = thisNum
curClauseAtom.append(word)
material.append(self.putClauseAtom3(curClauseAtom))
material.append("</dl>")
return "".join(material)
def putClauseAtom1(self, words):
if len(words) == 0:
return ""
textType = words[0]["clause_txt"].replace("?", "")
clauseType = words[0]["clause_typ"]
tabN = int(words[0]["clause_atom_tab"])
clauseAtomNumber = int(words[0]["clause_atom_number"])
tab10s = int(tabN // 10)
tab10r = tabN % 10
smalltab = "<" * tab10r
bigtab = "<" * tab10s
result = [
dedent(
f"""
<tr clause_atom="{clauseAtomNumber}">
<td colspan="3" class="t1_txt">
"""
)
]
for word in words:
if "r" in word["phrase_border"]:
result.append(
dedent(
f"""<span class="t1_phf1"
>{word["phrase_function"]}</span><span
class="t1_phfn">{word["phrase_number"]}</span>"""
)
)
if self.tr == "hb":
wordText = word["word_heb"]
elif self.tr == "ph":
wordText = word["word_phono"] + word["word_phono_sep"]
result.append(
f"""<span m="{word["word_number"]}" l="{word["lexicon_id"]}">"""
f"""{wordText}</span>"""
)
result.append(
dedent(
f"""
</td>
<td class="t1_tb1">{smalltab}</td>
<td class="t1_tb10">{bigtab}</td>
<td class="t1_txttp">{textType}</td>
<td class="t1_ctp">{clauseType}</td>
</tr>
"""
)
)
return "".join(result)
def putClauseAtom2(self, words):
if len(words) == 0:
return ""
textType = words[0]["clause_txt"]
clauseType = words[0]["clause_typ"]
code = words[0]["clause_atom_code"]
tabN = int(words[0]["clause_atom_tab"])
tab = '<span class="fa"></span>' * tabN # arrow-left
result = [
dedent(
f"""<dt class="lv2"><span class="ctxt2"
>{textType}</span>
<span class="ctp2">{clauseType}</span> <span class="ccode2"
>{code}</span></dt><dd class="lv2"
><span class="tb2">{tab}</span> """
)
]
for word in words:
if "r" in word["phrase_border"]:
result.append(f' <span class="phf2">{word["phrase_function"]}</span> ')
if self.tr == "hb":
wordText = word["word_heb"]
elif self.tr == "ph":
wordText = word["word_phono"] + word["word_phono_sep"]
result.append(
f"""<span m="{word["word_number"]}" l="{word["lexicon_id"]}">"""
f"{wordText}</span> "
)
result.append("</dd>")
return "".join(result)
def putClauseAtom3(self, words):
if len(words) == 0:
return ""
tabN = int(words[0]["clause_atom_tab"])
tab = '<span class="fa"></span>' * tabN # arrow-left
result = [
f'<dt class="lv3"><span class="tb3">{tab}</span></dt><dd class="lv3">'
]
phrb_table = dict(
rr=" ", # arrow-circle-right
r='<span class="fa"></span>', # arrow-circle-o-left
l='<span class="fa"></span>', # arrow-circle-o-right
ll=" ", # arrow-circle-left,
)
for word in words:
phraseBorders = word["phrase_border"].split()
borderSymStart = ""
borderSymEnd = ""
for phraseBorder in phraseBorders:
borderSymbols = phrb_table.get(phraseBorder, "")
if "r" in phraseBorder:
borderSymStart = borderSymbols
elif "l" in phraseBorder:
borderSymEnd = borderSymbols
if word["word_lex"] == "H":
textSymbol = "0d9" # caret-left
elif word["word_lex"] == "W":
textSymbol = "0d8" # caret-up
elif word["word_lex"] == ">LHJM/":
textSymbol = "0ed" #
elif word["word_lex"] == "JHWH/":
textSymbol = "0ee" #
elif word["word_pos"] == "nmpr":
if word["word_gender"] == "m":
textSymbol = "222" # mars
elif word["word_gender"] == "f":
textSymbol = "221" # venus
elif word["word_gender"] == "NA":
textSymbol = "1db" # genderless
elif word["word_gender"] == "unknown":
textSymbol = "1db" # genderless
elif word["word_pos"] == "verb":
textSymbol = "013" # cog
elif word["word_pos"] == "subs":
textSymbol = "146" # minus-square
else:
textSymbol = "068" # minus
result.append(
f"""{borderSymStart}<span
m="{word["word_number"]}" l="{word["lexicon_id"]}"
><span class="fa">{textSymbol};</span></span>{borderSymEnd}"""
)
result.append("</dd>")
return "".join(result)
__init__(self, vr, book_name, chapter_num, verse_num, xml=None, wordData=None, tp=None, tr=None, mr=None, lang='en')
special
¶
Source code in modules/versecontent.py
def __init__(
self,
vr,
book_name,
chapter_num,
verse_num,
xml=None,
wordData=None,
tp=None,
tr=None,
mr=None,
lang="en",
):
self.version = vr
self.tp = tp
self.tr = tr
self.mr = mr
self.lang = lang
self.book_name = book_name
self.chapter_num = chapter_num
self.verse_num = verse_num
self.xml = xml
self.wordData = wordData
self.process()
process(self)
¶
Source code in modules/versecontent.py
def process(self):
vr = self.version
book_name = self.book_name
chapter_num = self.chapter_num
verse_num = self.verse_num
xml = self.xml
wordData = self.wordData
if xml is None:
xml = ""
PASSAGE_DBS = current.PASSAGE_DBS
passageDb = PASSAGE_DBS.get(vr, None)
if wordData is None and passageDb:
fieldNames = ",".join(FIELDNAMES["txtd"])
wsql = dedent(
f"""
select {fieldNames}, lexicon_id from word
inner join word_verse on word_number = word_verse.anchor
inner join verse on verse.id = word_verse.verse_id
inner join chapter on verse.chapter_id = chapter.id
inner join book on chapter.book_id = book.id
where book.name = '{book_name}'
and chapter.chapter_num = {chapter_num}
and verse.verse_num = {verse_num}
order by word_number
;
"""
)
wordRecords = passageDb.executesql(wsql, as_dict=True) if passageDb else []
wordData = []
for record in wordRecords:
wordData.append(
dict(
(
(
x,
hEsc(
str(y),
not (x.endswith("_border") or x in NOTFILLFIELDS),
),
)
for (x, y) in record.items()
),
)
)
self.xml = xml
self.wordData = wordData
self.words = []
label(self)
¶
Source code in modules/versecontent.py
def label(self):
return (
BOOK_TRANS[self.lang][self.book_name].replace("_", " "),
self.book_name,
self.chapter_num,
self.verse_num,
)
getWords(self)
¶
Source code in modules/versecontent.py
def getWords(self):
if len(self.words) == 0:
root = ET.fromstring(f"<verse>{self.xml}</verse>".encode("utf-8"))
i = 0
for child in root:
slotid = int(child.attrib["m"])
lexicon_id = child.attrib["l"]
text = "" if child.text is None else child.text
thisWordData = self.wordData[i]
phonoText = thisWordData["word_phono"]
phonoSep = thisWordData["word_phono_sep"]
trailer = child.get("t", "")
self.words.append(
(slotid, lexicon_id, text, trailer, phonoText, phonoSep)
)
i += 1
return self.words
material(self)
¶
Source code in modules/versecontent.py
def material(self):
if self.tp == "txtp":
return self.plainText()
elif self.tp == "txt1":
return self.tab1Text()
elif self.tp == "txt2":
return self.tab2Text()
elif self.tp == "txt3":
return self.tab3Text()
elif self.tp == "txtd":
return self.dataText()
plainText(self)
¶
Present text in plain Hebrew or plain phonetic text.
Source code in modules/versecontent.py
def plainText(self):
"""Present text in plain Hebrew or plain phonetic text.
See [∈ text-representation][elem-text-representation]
"""
material = []
for word in self.getWords():
if self.tr == "hb":
wordText = word[2]
sep = word[3]
elif self.tr == "ph":
wordText = word[4]
sep = word[5]
material.append(
f"""<span m="{word[0]}" l="{word[1]}">{wordText}</span>{sep}"""
)
return "".join(material)
dataText(self)
¶
Present text in data format.
Linguistic features of the words will be shown, according to the current settings of the legend.
See ∈ legend, ∈ show-verse-data
Source code in modules/versecontent.py
def dataText(self):
"""Present text in data format.
Linguistic features of the words will be shown,
according to the current settings of the legend.
See [∈ legend][elem-feature-legend], [∈ show-verse-data][elem-show-verse-data]
"""
material = []
for word in self.wordData:
material.append(TEXT_TPL.format(**word))
return "".join(material)
tab1Text(self)
¶
Present text in a table, mode 1.
Mode 1 is notes view, i.e. notes are viewed interlinear with the clause atoms.
Source code in modules/versecontent.py
def tab1Text(self):
"""Present text in a table, mode 1.
Mode 1 is notes view, i.e. notes are viewed
interlinear with the clause atoms.
See [∈ text-presentation][elem-text-presentation]
"""
material = ["""<table class="t1_table">"""]
curNum = (0, 0, 0)
curClauseAtom = []
for word in self.wordData:
thisNum = (
word["sentence_number"],
word["clause_number"],
word["clause_atom_number"],
)
if thisNum != curNum:
material.append(self.putClauseAtom1(curClauseAtom))
curClauseAtom = []
curNum = thisNum
curClauseAtom.append(word)
material.append(self.putClauseAtom1(curClauseAtom))
material.append("</table>")
return "".join(material)
tab2Text(self)
¶
Present text in a table, mode 2.
Mode 2 is syntactic view, i.e. indentation is used to represent linguistic embedding.
Source code in modules/versecontent.py
def tab2Text(self):
"""Present text in a table, mode 2.
Mode 2 is syntactic view, i.e. indentation is used to
represent linguistic embedding.
See [∈ text-presentation][elem-text-presentation]
"""
material = ['<dl class="lv2">']
curNum = (0, 0, 0)
curClauseAtom = []
for word in self.wordData:
thisNum = (
word["sentence_number"],
word["clause_number"],
word["clause_atom_number"],
)
if thisNum != curNum:
material.append(self.putClauseAtom2(curClauseAtom))
curClauseAtom = []
curNum = thisNum
curClauseAtom.append(word)
material.append(self.putClauseAtom2(curClauseAtom))
material.append("</dl>")
return "".join(material)
tab3Text(self)
¶
Present text in a table, mode 3.
Mode 3 is abstract view, i.e. letters are replaced by abstract symbols, where many letters map to the same symbol. represent linguistic embedding.
Source code in modules/versecontent.py
def tab3Text(self):
"""Present text in a table, mode 3.
Mode 3 is abstract view, i.e. letters are replaced by
abstract symbols, where many letters map to the same symbol.
represent linguistic embedding.
See [∈ text-presentation][elem-text-presentation]
"""
material = ['<dl class="lv3">']
curNum = (0, 0, 0)
curClauseAtom = []
for word in self.wordData:
thisNum = (
word["sentence_number"],
word["clause_number"],
word["clause_atom_number"],
)
if thisNum != curNum:
material.append(self.putClauseAtom3(curClauseAtom))
curClauseAtom = []
curNum = thisNum
curClauseAtom.append(word)
material.append(self.putClauseAtom3(curClauseAtom))
material.append("</dl>")
return "".join(material)
putClauseAtom1(self, words)
¶
Source code in modules/versecontent.py
def putClauseAtom1(self, words):
if len(words) == 0:
return ""
textType = words[0]["clause_txt"].replace("?", "")
clauseType = words[0]["clause_typ"]
tabN = int(words[0]["clause_atom_tab"])
clauseAtomNumber = int(words[0]["clause_atom_number"])
tab10s = int(tabN // 10)
tab10r = tabN % 10
smalltab = "<" * tab10r
bigtab = "<" * tab10s
result = [
dedent(
f"""
<tr clause_atom="{clauseAtomNumber}">
<td colspan="3" class="t1_txt">
"""
)
]
for word in words:
if "r" in word["phrase_border"]:
result.append(
dedent(
f"""<span class="t1_phf1"
>{word["phrase_function"]}</span><span
class="t1_phfn">{word["phrase_number"]}</span>"""
)
)
if self.tr == "hb":
wordText = word["word_heb"]
elif self.tr == "ph":
wordText = word["word_phono"] + word["word_phono_sep"]
result.append(
f"""<span m="{word["word_number"]}" l="{word["lexicon_id"]}">"""
f"""{wordText}</span>"""
)
result.append(
dedent(
f"""
</td>
<td class="t1_tb1">{smalltab}</td>
<td class="t1_tb10">{bigtab}</td>
<td class="t1_txttp">{textType}</td>
<td class="t1_ctp">{clauseType}</td>
</tr>
"""
)
)
return "".join(result)
putClauseAtom2(self, words)
¶
Source code in modules/versecontent.py
def putClauseAtom2(self, words):
if len(words) == 0:
return ""
textType = words[0]["clause_txt"]
clauseType = words[0]["clause_typ"]
code = words[0]["clause_atom_code"]
tabN = int(words[0]["clause_atom_tab"])
tab = '<span class="fa"></span>' * tabN # arrow-left
result = [
dedent(
f"""<dt class="lv2"><span class="ctxt2"
>{textType}</span>
<span class="ctp2">{clauseType}</span> <span class="ccode2"
>{code}</span></dt><dd class="lv2"
><span class="tb2">{tab}</span> """
)
]
for word in words:
if "r" in word["phrase_border"]:
result.append(f' <span class="phf2">{word["phrase_function"]}</span> ')
if self.tr == "hb":
wordText = word["word_heb"]
elif self.tr == "ph":
wordText = word["word_phono"] + word["word_phono_sep"]
result.append(
f"""<span m="{word["word_number"]}" l="{word["lexicon_id"]}">"""
f"{wordText}</span> "
)
result.append("</dd>")
return "".join(result)
putClauseAtom3(self, words)
¶
Source code in modules/versecontent.py
def putClauseAtom3(self, words):
if len(words) == 0:
return ""
tabN = int(words[0]["clause_atom_tab"])
tab = '<span class="fa"></span>' * tabN # arrow-left
result = [
f'<dt class="lv3"><span class="tb3">{tab}</span></dt><dd class="lv3">'
]
phrb_table = dict(
rr=" ", # arrow-circle-right
r='<span class="fa"></span>', # arrow-circle-o-left
l='<span class="fa"></span>', # arrow-circle-o-right
ll=" ", # arrow-circle-left,
)
for word in words:
phraseBorders = word["phrase_border"].split()
borderSymStart = ""
borderSymEnd = ""
for phraseBorder in phraseBorders:
borderSymbols = phrb_table.get(phraseBorder, "")
if "r" in phraseBorder:
borderSymStart = borderSymbols
elif "l" in phraseBorder:
borderSymEnd = borderSymbols
if word["word_lex"] == "H":
textSymbol = "0d9" # caret-left
elif word["word_lex"] == "W":
textSymbol = "0d8" # caret-up
elif word["word_lex"] == ">LHJM/":
textSymbol = "0ed" #
elif word["word_lex"] == "JHWH/":
textSymbol = "0ee" #
elif word["word_pos"] == "nmpr":
if word["word_gender"] == "m":
textSymbol = "222" # mars
elif word["word_gender"] == "f":
textSymbol = "221" # venus
elif word["word_gender"] == "NA":
textSymbol = "1db" # genderless
elif word["word_gender"] == "unknown":
textSymbol = "1db" # genderless
elif word["word_pos"] == "verb":
textSymbol = "013" # cog
elif word["word_pos"] == "subs":
textSymbol = "146" # minus-square
else:
textSymbol = "068" # minus
result.append(
f"""{borderSymStart}<span
m="{word["word_number"]}" l="{word["lexicon_id"]}"
><span class="fa">{textSymbol};</span></span>{borderSymEnd}"""
)
result.append("</dd>")
return "".join(result)