2019-04-12
Christiaan Erwich, Gyusang Jin and Cody Kingham spotted weird behaviour in displaying certain verses.
Look here in Psalm 18:49 :
The dashed circles enclose the words that are in this verse, the other words belong to the previous part.
When displaying the sentence atom, which started in the previous part, Text-Fabric forgot to remember to cutoff this sentence atom at the verse boundary.
And why was that?
The root cause is in a few lines in the generic TF display library, not in the BHSA TF-app.
getBoundary(api, n) if d.condenseType is None else
Here TF computes the boundary slots of the node in question. The thing is, if there is a condense type active, we should not take the boundary of the node itself, but its container of the condense type.
However, in our case we have the situation that d.condenseType
appeared to be verse
.
Yet, there is no condensing, because d.condensed
is False
.
So this part of the condition was wrong and should be:
getBoundary(api, n) if not d.condensed or not d.condenseType else
This indeed fixed the bug, as you see below.
%load_ext autoreload
%autoreload 2
from tf.applib.helpers import dm
from tf.app import use
Note that we are developing/debugging code. We do not want to download code/data from github, and we want to look in our own github clone of the TF app.
Hence 'bhsa:clone'
and checkout='local'
.
A = use('bhsa:clone', checkout='local', hoist=globals())
Using TF-app in /Users/dirk/github/annotation/app-bhsa/code: repo clone offline under ~/github (local github) Using data in /Users/dirk/text-fabric-data/etcbc/bhsa/tf/c: rv1.6 offline under ~/text-fabric-data (local release) Using data in /Users/dirk/text-fabric-data/etcbc/phono/tf/c: r1.2 offline under ~/text-fabric-data (local release) Using data in /Users/dirk/text-fabric-data/etcbc/parallels/tf/c: r1.2 offline under ~/text-fabric-data (local release)
BHSA = Biblia Hebraica Stuttgartensia Amstelodamensis: book book@ll chapter code det freq_lex function g_word g_word_utf8 gloss gn label language lex lex_utf8 ls nametype nu number otype pdp prs_gn prs_nu prs_ps ps qere qere_trailer qere_trailer_utf8 qere_utf8 rank_lex rela sp st trailer trailer_utf8 txt typ verse voc_lex voc_lex_utf8 vs vt mother oslots
Parallel Passages: crossref
Phonetic Transcriptions: phono phono_trailer
Before we knew what was the matter we made a lens to have a detailed view of our data:
We gathered all word nodes of Ps 18:47 - 49 and made a table of the objects they are contained in.
v0 = T.nodeFromSection(('Psalms', 18, 47))
v1 = T.nodeFromSection(('Psalms', 18, 49))
w0 = L.d(v0, otype='word')[0]
w1 = L.d(v1, otype='word')[-1]
allWords = range(w0, w1 + 1)
We are only interested in certain kind of objects.
skipTypes = {'book', 'chapter', 'half_verse', 'lex', 'subphrase', 'word'}
nodeTypes = [x[0] for x in C.levels.data if x[0] not in skipTypes]
nodeTypes
['verse', 'sentence', 'sentence_atom', 'clause', 'clause_atom', 'phrase', 'phrase_atom']
We represent the nodes of different types in slightly different ways.
repNode = dict(
verse=lambda n: '{} {}:{}'.format(*T.sectionFromNode(n)),
sentence=lambda n: F.number.v(n),
sentence_atom=lambda n: F.number.v(n),
clause=lambda n: F.number.v(n),
clause_atom=lambda n: F.number.v(n),
phrase=lambda n: F.number.v(n),
phrase_atom=lambda n: F.number.v(n),
)
And we make a markdown table.
rows = []
rows.append(' | '.join(nodeTypes))
rows.append(' | '.join(['---'] * len(nodeTypes)))
for w in allWords:
parents = {F.otype.v(p): repNode[F.otype.v(p)](p) for p in L.u(w) if F.otype.v(p) in nodeTypes}
rows.append(' | '.join(str(parents.get(nType, 'x')) for nType in nodeTypes))
dm('\n'.join(rows))
verse | sentence | sentence_atom | clause | clause_atom | phrase | phrase_atom |
---|---|---|---|---|---|---|
Psalms 18:47 | 93 | 511 | 1 | 761 | 1 | 1818 |
Psalms 18:47 | 93 | 511 | 1 | 761 | 2 | 1819 |
Psalms 18:47 | 94 | 512 | 1 | 762 | 1 | 1820 |
Psalms 18:47 | 94 | 512 | 1 | 762 | 2 | 1821 |
Psalms 18:47 | 94 | 512 | 1 | 762 | 3 | 1822 |
Psalms 18:47 | 95 | 513 | 1 | 763 | 1 | 1823 |
Psalms 18:47 | 95 | 513 | 1 | 763 | 2 | 1824 |
Psalms 18:47 | 95 | 513 | 1 | 763 | 3 | 1825 |
Psalms 18:47 | 95 | 513 | 1 | 763 | 3 | 1825 |
Psalms 18:48 | 93 | 514 | 2 | 764 | 1 | 1826 |
Psalms 18:48 | 93 | 514 | 2 | 764 | 1 | 1826 |
Psalms 18:48 | 93 | 514 | 3 | 765 | 1 | 1827 |
Psalms 18:48 | 93 | 514 | 3 | 765 | 2 | 1828 |
Psalms 18:48 | 93 | 514 | 3 | 765 | 3 | 1829 |
Psalms 18:48 | 93 | 514 | 3 | 765 | 4 | 1830 |
Psalms 18:48 | 93 | 514 | 4 | 766 | 1 | 1831 |
Psalms 18:48 | 93 | 514 | 4 | 766 | 2 | 1832 |
Psalms 18:48 | 93 | 514 | 4 | 766 | 3 | 1833 |
Psalms 18:48 | 93 | 514 | 4 | 766 | 4 | 1834 |
Psalms 18:49 | 93 | 514 | 5 | 767 | 1 | 1835 |
Psalms 18:49 | 93 | 514 | 5 | 767 | 2 | 1836 |
Psalms 18:49 | 93 | 514 | 5 | 767 | 2 | 1836 |
Psalms 18:49 | 96 | 515 | 1 | 768 | 1 | 1837 |
Psalms 18:49 | 96 | 515 | 1 | 768 | 1 | 1837 |
Psalms 18:49 | 96 | 515 | 1 | 768 | 1 | 1837 |
Psalms 18:49 | 96 | 515 | 1 | 768 | 2 | 1838 |
Psalms 18:49 | 97 | 516 | 1 | 769 | 1 | 1839 |
Psalms 18:49 | 97 | 516 | 1 | 769 | 1 | 1839 |
Psalms 18:49 | 97 | 516 | 1 | 769 | 1 | 1839 |
Psalms 18:49 | 97 | 516 | 1 | 769 | 2 | 1840 |
This gave us the clue that we had a bunch of objects that crossed the verse boundary.
We show the verse after the fix.
n = T.nodeFromSection(('Psalms', 18, 49))
A.plain(n)
Other example: