To get started: consult start
Search in Text-Fabric is a template based way of looking for structural patterns in your dataset.
It is inspired by the idea of topographic query.
Within Text-Fabric we have the unique possibility to combine the ease of formulating search templates for complicated patterns with the power of programmatically processing the results.
This notebook will show you how to get up and running.
Search is a powerful feature for a wide range of purposes.
Quite a bit of the implementation work has been dedicated to optimize performance. Yet I do not pretend to have found optimal strategies for all possible search templates. Some search tasks may turn out to be somewhat costly or even very costly.
That being said, I think search might turn out helpful in many cases, especially by reducing the amount of hand-coding needed to work with special subsets of your data.
Search is as simple as saying (just an example)
results = A.search(template)
A.show(results)
See all ins and outs in the search template docs.
%load_ext autoreload
%autoreload 2
from tf.app import use
A = use("etcbc/dss", checkout="clone", hoist=globals())
This is Text-Fabric 9.2.0 Api reference : https://annotation.github.io/text-fabric/tf/cheatsheet.html 67 features found and 1 ignored
We start with the most simple form of issuing a query.
Let's look for the verbs in the hitpael
with an uncertain character in it.
All work involved in searching takes place under the hood.
query = """
word vs=hitpael
sign unc
"""
results = A.search(query)
A.table(results, end=10)
We have multiple uncertain signs per word, and for each sign we see the whole word repeated.
We can condense our results to words:
A.table(results, end=10, condensed=True, condenseType="word")
We can show them in rich layout as well:
A.table(results, end=10, condensed=True, condenseType="word", fmt="layout-orig-full")
Note that we can choose start and/or end points in the results list.
A.table(
results,
start=100,
end=110,
condensed=True,
condenseType="word",
fmt="layout-orig-full",
)
n | p | word | sign | sign | |||
---|---|---|---|---|---|---|---|
100 | 4Q405 f23i:11 | יתכונו | ו | י | |||
101 | 4Q405 f25:3 | מתהלכים | מ | ת | ה | כ | ם |
102 | 4Q415 f12:4 | התששו # | ש | ו | |||
103 | 4Q417 f1i:12 | התהלכ׳ו | ו | ||||
104 | 4Q417 f1i:23 | תתחזק | ח | ז | ת | ||
105 | 4Q417 f2i:8 | תתהלך | ת | ה | |||
106 | 4Q417 f19:4 | יתהלך | ך | י | ת | ה | |
107 | 4Q418 f2+2a_c:4 | יתר | ר | ||||
108 | 4Q418 f9+9a_c:9 | תתהלך | ת | ל | ך | ת | |
109 | 4Q418 f9+9a_c:10 | תתהלך | ת | ת | ה | ||
110 | 4Q418 f43_45i:8 | התהלך | ה |
We can show the results more fully with show()
.
A.show(results, fmt="layout-orig-full", start=1, end=3)
result 1
result 2
result 3
or even more fully by showing the signs as well:
A.show(results, fmt="layout-orig-full", start=1, end=1, baseTypes="sign")
There are two fundamentally different ways of presenting the results: condensed and uncondensed.
In uncondensed view, all results are listed individually. You can keep track of which parts belong to which results. The display can become unwieldy.
This is the default view, because it is the straightest, most logical, answer to your query.
In condensed view all nodes of all results are grouped in containers first (e.g. lines), and then presented container by container. You loose the information of what parts belong to what result.
As an example of the difference, we look for all proper nouns, but only in lines where there is also
a word marked with paleohebrew
script.
query = """
line
word sp=subs cl=prp
word script=paleohebrew
% NB: the order of both words is not specified
% NB: both 'word' items may be instantiated by the same word
"""
Note that you can have comments in a search template. Comment lines start with a %
.
results = A.search(query)
A.table(results, start=22, end=25, fmt="layout-orig-full")
0.98s 731 results
n | p | line | word | word |
---|---|---|---|---|
22 | 4Q171 f1_2ii:12 | זומם רשע לצדיק וחורק עלי׳ו שני׳ו ׃ יהוה ישחק ל׳ו כיא ראה | יהוה | יהוה |
23 | 4Q171 f1_2ii:24 | יהוה יודע יהוה ימי תמימים ונחלת׳ם לעולם תהיה ׃ פשר׳ו על אנשי | יהוה | יהוה |
24 | 4Q171 f1_2ii:24 | יהוה יודע יהוה ימי תמימים ונחלת׳ם לעולם תהיה ׃ פשר׳ו על אנשי | יהוה | יהוה |
25 | 4Q171 f1+3_4iii:14 | כיא מיהוה מצעדי גבר כוננו בכול דרכ׳ו יחפץ ׃ כיא יפול לוא | יהוה | יהוה |
Note result 23: here both words in the query are instantiated by the same word, which satisfies both criteria!
A.table(results, start=30, end=40, fmt="layout-orig-full")
n | p | line | word | word |
---|---|---|---|---|
30 | 4Q183 f3:1 | ε יהוה ε ׃ | יהוה | יהוה |
31 | 4Q267 f9v:4 | יהודה ׃ וכול המתהלכים באלה ברית אל נאמנת | יהודה | אל |
32 | 4Q318 4:9 | תשרי בא֜ ובא֜א֜ עקרבא בא֜א֜א֜ ובא֜א֜א֜אׄ קשתא ובא֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜א֜ גדיא בא֜א֜א֜אׄא֜א֜א֜אׄ ׃ | תשרי | א֜ |
33 | 4Q318 4:9 | תשרי בא֜ ובא֜א֜ עקרבא בא֜א֜א֜ ובא֜א֜א֜אׄ קשתא ובא֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜א֜ גדיא בא֜א֜א֜אׄא֜א֜א֜אׄ ׃ | תשרי | א֜א֜ |
34 | 4Q318 4:9 | תשרי בא֜ ובא֜א֜ עקרבא בא֜א֜א֜ ובא֜א֜א֜אׄ קשתא ובא֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜א֜ גדיא בא֜א֜א֜אׄא֜א֜א֜אׄ ׃ | תשרי | א֜א֜א֜ |
35 | 4Q318 4:9 | תשרי בא֜ ובא֜א֜ עקרבא בא֜א֜א֜ ובא֜א֜א֜אׄ קשתא ובא֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜א֜ גדיא בא֜א֜א֜אׄא֜א֜א֜אׄ ׃ | תשרי | א֜א֜א֜אׄ |
36 | 4Q318 4:9 | תשרי בא֜ ובא֜א֜ עקרבא בא֜א֜א֜ ובא֜א֜א֜אׄ קשתא ובא֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜א֜ גדיא בא֜א֜א֜אׄא֜א֜א֜אׄ ׃ | תשרי | א֜א֜א֜א֜א֜ |
37 | 4Q318 4:9 | תשרי בא֜ ובא֜א֜ עקרבא בא֜א֜א֜ ובא֜א֜א֜אׄ קשתא ובא֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜א֜ גדיא בא֜א֜א֜אׄא֜א֜א֜אׄ ׃ | תשרי | א֜א֜א֜א֜א֜א֜ |
38 | 4Q318 4:9 | תשרי בא֜ ובא֜א֜ עקרבא בא֜א֜א֜ ובא֜א֜א֜אׄ קשתא ובא֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜א֜ גדיא בא֜א֜א֜אׄא֜א֜א֜אׄ ׃ | תשרי | א֜א֜א֜א֜א֜א֜א֜ |
39 | 4Q318 4:9 | תשרי בא֜ ובא֜א֜ עקרבא בא֜א֜א֜ ובא֜א֜א֜אׄ קשתא ובא֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜א֜ גדיא בא֜א֜א֜אׄא֜א֜א֜אׄ ׃ | תשרי | א֜א֜א֜אׄא֜א֜א֜אׄ |
40 | 4Q318 7:4 | ובך֜י֜ דולא ׃ שבט בא֜ ובא֜א֜ נוניא בא֜א֜א֜ ובא֜א֜א֜אׄ | שבט | ך֜י֜ |
Note in passing that numerals are also marked in as paleohebrew
.
Note results 32-39, all in the same line. Let's switch to condensed view. Because results are counted differently now, we narrow down our search as well.
query = """
line scroll=4Q318 fragment=4 line=9
word sp=subs cl=prp
word script=paleohebrew
"""
results = A.search(query)
A.table(results, fmt="layout-orig-full", condensed=True)
1.02s 8 results
n | p | line | word | word | word | word | word | word | word | word | word |
---|---|---|---|---|---|---|---|---|---|---|---|
1 | 4Q318 4:9 | תשרי בא֜ ובא֜א֜ עקרבא בא֜א֜א֜ ובא֜א֜א֜אׄ קשתא ובא֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜ ובא֜א֜א֜א֜א֜א֜א֜ גדיא בא֜א֜א֜אׄא֜א֜א֜אׄ ׃ | תשרי | א֜ | א֜א֜ | א֜א֜א֜ | א֜א֜א֜אׄ | א֜א֜א֜א֜א֜ | א֜א֜א֜א֜א֜א֜ | א֜א֜א֜א֜א֜א֜א֜ | א֜א֜א֜אׄא֜א֜א֜אׄ |
Let's expand the results display, first uncondensed, which takes a lot of space, so we show only two results:
A.show(results, end=2, withNodes=True, fmt="layout-orig-full")
result 1
result 2
As you see, the results are listed per result tuple, even if they occur all in the same line. This way you can keep track of what exactly belongs to each result.
Now in condensed mode, and let's forget about the rich layout for a while:
A.show(results, condensed=True)
line 1
This line has 8 results, and all of them are highlighted in the same line display.
We can modify the container in which we see our results.
By default, it is line
, but we can make it fragment
as well:
A.show(results, condensed=True, condenseType="fragment")
fragment 1
We now see the the displays of the whole fragment, with the line with the proper names in it highlighted and the proper names themselves highlighted as well.
Let us make a new search where we look for different things in the same line.
query = """
line
word sp=verb
word sp=subs cl=prp
sign cor
"""
results = A.search(query)
A.table(results, end=10, fmt="layout-orig-full", skipCols="1")
1.94s 2886 results
n | p | word | word | sign |
---|---|---|---|---|
1 | CD 5:4 | עבדו | יושוע | ו |
2 | CD 5:4 | יטמון | יושוע | ו |
3 | 1Q20 21:29 | דבקו | זומזמי | מ |
4 | 4Q201 f1i:1 | ברך | חנוך | ו |
5 | 4Q201 f1i:1 | להוון | חנוך | ו |
6 | 4Q201 f1i:1 | אעדיה | חנוך | ו |
7 | 4Q201 f1i:1 | סניה | חנוך | ו |
8 | 4Q252 3:7 | יקח | אברהם | ה |
9 | 4Q259 3:3 | נסוגה | יל | י |
10 | 4Q259 3:3 | נסוגה | יל | ל |
We can apply different highlight colours to different parts of the result.
The line is member 1. the words are members 2 and 3, and the sign is member 4.
We do not give a colour to the line, the verb will have the default color, the proper name cyan, and the sign magenta.
NB: You can choose your colours from the CSS specification.
colorMap = {2: "", 3: "cyan", 4: "magenta"}
A.table(results, end=10, fmt="layout-orig-full", colorMap=colorMap)
n | p | line | word | word | sign |
---|---|---|---|---|---|
1 | CD 5:4 | ויהושע ויושוע והזקנים אשר עבדו את העשתרת ׃ ויטמון | עבדו | יושוע | ו |
2 | CD 5:4 | ויהושע ויושוע והזקנים אשר עבדו את העשתרת ׃ ויטמון | יטמון | יושוע | ו |
3 | 1Q20 21:29 | דקרנין ולזומזמיא די בעמן ולאימיא די בשוה הקריות ולחוריא די בטורי גבל עד דבקו לאיל | דבקו | זומזמי | מ |
4 | 4Q201 f1i:1 | מלי ברכתה די ברך ב׳הן חנוך לבחירין קשיטין די להוון ביום עקתה לאעדיה כל סניה | ברך | חנוך | ו |
5 | 4Q201 f1i:1 | מלי ברכתה די ברך ב׳הן חנוך לבחירין קשיטין די להוון ביום עקתה לאעדיה כל סניה | להוון | חנוך | ו |
6 | 4Q201 f1i:1 | מלי ברכתה די ברך ב׳הן חנוך לבחירין קשיטין די להוון ביום עקתה לאעדיה כל סניה | אעדיה | חנוך | ו |
7 | 4Q201 f1i:1 | מלי ברכתה די ברך ב׳הן חנוך לבחירין קשיטין די להוון ביום עקתה לאעדיה כל סניה | סניה | חנוך | ו |
8 | 4Q252 3:7 | אברהם את יד׳ו ויקח ε השמים | יקח | אברהם | ה |
9 | 4Q259 3:3 | מאלה מיראת רוח נסוגה ׃ ובהיות אלה לביחד ביל יבדלו ממושב | נסוגה | יל | י |
10 | 4Q259 3:3 | מאלה מיראת רוח נסוגה ׃ ובהיות אלה לביחד ביל יבדלו ממושב | נסוגה | יל | ל |
A.show(results, end=3, fmt="layout-orig-full", colorMap=colorMap)
result 1
result 2
result 3
Color mapping works best for uncondensed results. If you condense results, some nodes may occupy different positions in different results. It is unpredictable which color will be used for such nodes:
You can stipulate an order on the things in your template. You only have to put a relational operator between them. Say we want only lines where a proper noun with an ancient correction precedes a verb
query = """
line
word sp=subs cl=prp
sign cor
< word sp=verb
"""
results = A.search(query)
A.table(results, end=10, fmt="layout-orig-full")
1.88s 1555 results
n | p | line | word | sign | word |
---|---|---|---|---|---|
1 | CD 5:4 | ויהושע ויושוע והזקנים אשר עבדו את העשתרת ׃ ויטמון | יושוע | ו | עבדו |
2 | CD 5:4 | ויהושע ויושוע והזקנים אשר עבדו את העשתרת ׃ ויטמון | יושוע | ו | יטמון |
3 | 1Q20 21:29 | דקרנין ולזומזמיא די בעמן ולאימיא די בשוה הקריות ולחוריא די בטורי גבל עד דבקו לאיל | זומזמי | מ | דבקו |
4 | 4Q201 f1i:1 | מלי ברכתה די ברך ב׳הן חנוך לבחירין קשיטין די להוון ביום עקתה לאעדיה כל סניה | חנוך | ו | להוון |
5 | 4Q201 f1i:1 | מלי ברכתה די ברך ב׳הן חנוך לבחירין קשיטין די להוון ביום עקתה לאעדיה כל סניה | חנוך | ו | אעדיה |
6 | 4Q201 f1i:1 | מלי ברכתה די ברך ב׳הן חנוך לבחירין קשיטין די להוון ביום עקתה לאעדיה כל סניה | חנוך | ו | סניה |
7 | 4Q252 3:7 | אברהם את יד׳ו ויקח ε השמים | אברהם | ה | יקח |
8 | 4Q259 3:3 | מאלה מיראת רוח נסוגה ׃ ובהיות אלה לביחד ביל יבדלו ממושב | יל | י | יבדלו |
9 | 4Q259 3:3 | מאלה מיראת רוח נסוגה ׃ ובהיות אלה לביחד ביל יבדלו ממושב | יל | ל | יבדלו |
10 | 4Q266 f3ii:10 | אל ברית רישונים ויקם מאהרון נבונים ומישראל חכמים ׃ וישמיע׳ם ויחפורו את הבאר אשר אמר מושה באר | ישראל | י | יחפורו |
We can also require the things to be adjacent.
query = """
line
word sp=subs cl=prp
sign cor
<: word sp=verb
"""
results = A.search(query)
colorMap = {2: "cyan", 3: "magenta", 4: ""}
A.table(results, end=10, colorMap=colorMap, fmt="layout-orig-full")
A.show(results, end=3, colorMap=colorMap, fmt="layout-orig-full")
1.84s 40 results
n | p | line | word | sign | word |
---|---|---|---|---|---|
1 | 4Q259 3:3 | מאלה מיראת רוח נסוגה ׃ ובהיות אלה לביחד ביל יבדלו ממושב | יל | י | יבדלו |
2 | 4Q259 3:3 | מאלה מיראת רוח נסוגה ׃ ובהיות אלה לביחד ביל יבדלו ממושב | יל | ל | יבדלו |
3 | 4Q364 f11:2 | ולבנימים נתן שלוש מאות כסף וחמש חליפות שמלות ׃ ולאבי׳הו שלח כזואת | בנימים | י | נתן |
4 | 1Qisaa 33:7 | השדה ׃ יבש חציר נבל ציצ כי רוח יייי נשבה ב׳וא הכן חציר העם ׃ יבש חציל נבל ציצ ודבר אלוהי׳נו ודבר אלוהי׳נו יקום לעולם ׃ | יייי | י | נשבה |
5 | 1Qisaa 33:7 | השדה ׃ יבש חציר נבל ציצ כי רוח יייי נשבה ב׳וא הכן חציר העם ׃ יבש חציל נבל ציצ ודבר אלוהי׳נו ודבר אלוהי׳נו יקום לעולם ׃ | יייי | י | נשבה |
6 | 1Qisaa 33:7 | השדה ׃ יבש חציר נבל ציצ כי רוח יייי נשבה ב׳וא הכן חציר העם ׃ יבש חציל נבל ציצ ודבר אלוהי׳נו ודבר אלוהי׳נו יקום לעולם ׃ | יייי | י | נשבה |
7 | 1Qisaa 33:7 | השדה ׃ יבש חציר נבל ציצ כי רוח יייי נשבה ב׳וא הכן חציר העם ׃ יבש חציל נבל ציצ ודבר אלוהי׳נו ודבר אלוהי׳נו יקום לעולם ׃ | יייי | י | נשבה |
8 | 1Qisaa 38:17 | מה תחולי׳ן ׃ כוה אמר יהוה קדוש ישראל יוצר האותות שאלו׳ני על בנ׳י ועל פועל | ישראל | י | יוצר |
9 | 1Qisaa 38:17 | מה תחולי׳ן ׃ כוה אמר יהוה קדוש ישראל יוצר האותות שאלו׳ני על בנ׳י ועל פועל | ישראל | ש | יוצר |
10 | 1Qisaa 38:17 | מה תחולי׳ן ׃ כוה אמר יהוה קדוש ישראל יוצר האותות שאלו׳ני על בנ׳י ועל פועל | ישראל | ר | יוצר |
result 1
result 2
result 3
Finally, we want the proper name start near the start of the line, i.e. nut further away than three signs.
query = """
line
=3: word sp=subs cl=prp
sign cor
<: word sp=verb
"""
results = A.search(query)
colorMap = {2: "cyan", 3: "magenta", 4: ""}
A.table(results, end=10, colorMap=colorMap, fmt="layout-orig-full")
A.show(results, end=3, colorMap=colorMap, fmt="layout-orig-full")
1.99s 5 results
n | p | line | word | sign | word |
---|---|---|---|---|---|
1 | 4Q364 f11:2 | ולבנימים נתן שלוש מאות כסף וחמש חליפות שמלות ׃ ולאבי׳הו שלח כזואת | בנימים | י | נתן |
2 | 1Qisaa 43:14 | עוז ציון לבשי בגדי תפארת׳ך ירושלם עיר הקודש כיא לוא יוסיף ויבוא | ציון | צ | לבשי |
3 | 1Qisaa 43:14 | עוז ציון לבשי בגדי תפארת׳ך ירושלם עיר הקודש כיא לוא יוסיף ויבוא | ציון | י | לבשי |
4 | 1Qisaa 43:14 | עוז ציון לבשי בגדי תפארת׳ך ירושלם עיר הקודש כיא לוא יוסיף ויבוא | ציון | ו | לבשי |
5 | 1Qisaa 43:14 | עוז ציון לבשי בגדי תפארת׳ך ירושלם עיר הקודש כיא לוא יוסיף ויבוא | ציון | ן | לבשי |
result 1
result 2
result 3
We would like to see the original Abegg code with the marks and brackets.
They are in the feature fullo
on words.
The way to do that, is to perform a A.prettySetup(features)
first.
We concentrate on one specific result.
A.displaySetup(extraFeatures="fullo")
A.show(results, end=1, colorMap=colorMap, fmt="layout-orig-full")
result 1
The features without meaningful values have been left out. We can also change that by passing a set of values we think are not meaningful. The default set is
{None, 'NA', 'none', 'unknown'}
A.displaySetup(noneValues=set())
A.show(results, end=1, colorMap=colorMap, fmt="layout-orig-full")
result 1
This makes clear that it is convenient to keep None
in the noneValues
:
A.displaySetup(noneValues={None})
A.show(results, end=1, colorMap=colorMap, fmt="layout-orig-full")
result 1
We can even choose to suppress other values, e.g. the value 1.
That will remove all the features such as rec
.
A.displaySetup(noneValues={None, "NA", "unknown", 1})
A.show(results, end=1, colorMap=colorMap, fmt="layout-orig-full")
result 1
In the rest of the notebook we stick to our normal setup, so we reset the extra features.
A.displayReset()
A.show(results, end=1, colorMap=colorMap, fmt="layout-orig-full")
In earlier displays we saw the types of signs, because the query mentioned it.
Suppose we want to display the type also here, then we can modify the query by mentioning the feature type
.
But we do not want to impose extra limitations, so we say type*
, meaning: no conditions on type whatsoever.
query = """
line
=3: word sp=subs cl=prp
sign cor type*
<: word sp=verb
"""
results = A.search(query)
A.show(results, end=1, colorMap=colorMap, fmt="layout-orig-full")
2.10s 5 results
result 1
So far we have shown the results of searches. But you can also construct your own tuples and show them.
Whereas you can use search to get a pretty good approximation of what you want, most of the times you do not arrive precisely at your destination.
Here is an example where we use search to come close, and then work our way to produce the end result.
We look for lines that have more reconstructed/uncertain consonants than certain consonants.
In our search templates we cannot formulate that a feature has different values on two nodes in the template. We could spell out all possible combinations of values and make a search template for each of them, but that is needlessly complex.
Let's first use search to find all lines containing reconstructed/uncertain/certain consonants.
query = """
line
/with/
sign type=cons rec
/or/
sign type=cons unc
/-/
/with/
sign type=cons rec# unc#
/-/
"""
results = A.search(query)
2.95s 34455 results
That is a lot, how does that compare to the total number of lines?
queryl = """
line
"""
resultsl = A.search(queryl)
0.06s 52895 results
or, by hand-coding:
len(F.otype.s("line"))
52895
Now the real hand-coding begins. We are going to extract the tuples we want. How are they structured?
for (i, tup) in enumerate(results[0:5]):
print(f"tuple {i}")
for (j, n) in enumerate(tup):
print(f"\tmember {j} = {F.otype.v(n)} {n}")
tuple 0 member 0 = line 1552976 tuple 1 member 0 = line 1553005 tuple 2 member 0 = line 1553010 tuple 3 member 0 = line 1553011 tuple 4 member 0 = line 1553015
Very simple indeed!
Now we have all lines with hypothetical and certain consonants.
For each line we make a set with its hypothetical consonants and one with its certain consonants.
We filter in order to retain the lines with more hypothetical than certain consonants. We put all hypothetical consonants in one big set and all certain consonants in one big set.
answer = []
hypo = set()
cert = set()
for (line,) in results:
signs = L.d(line, otype="sign")
myHypo = set()
myCert = set()
for s in signs:
if F.type.v(s) != "cons":
continue
if F.rec.v(s) or F.unc.v(s):
myHypo.add(s)
else:
myCert.add(s)
if len(myHypo) > len(myCert):
answer.append((line, *myHypo, *myCert))
hypo |= myHypo
cert |= myCert
len(answer)
16060
One third of the lines is more than half uncertain!
answer[0]
(1553248, 11299, 11300, 11301, 11302, 11308, 11309, 11310, 11316, 11317, 11318, 11319, 11322, 11323, 11324, 11325, 11326, 11327, 11328, 11329, 11330, 11333, 11334, 11291, 11292, 11293, 11294, 11295, 11296, 11297, 11298, 11303, 11304, 11305, 11306, 11307, 11311, 11312, 11313, 11314, 11315, 11331, 11332)
We are going to make a dictionary of highlights: one color for the hypothetical signs and one for the certain.
highlights = {}
colorH = "lightsalmon"
colorC = "mediumaquamarine"
for s in hypo:
highlights[s] = colorH
for s in cert:
highlights[s] = colorC
And now we can show them (note that we descend from the word level to the sign level by passing baseType="sign"
:
A.show(answer, start=1, end=5, highlights=highlights, baseTypes="sign")
result 1
result 2
result 3
result 4
result 5
As you see, you have total control.
All chapters:
See the cookbook for recipes for small, concrete tasks.
CC-BY Dirk Roorda