Mostly functional in the new format

This commit is contained in:
Christopher T. Johnson
2024-04-12 11:18:39 -04:00
parent ad5904f3ae
commit a3d3e71bf8
3 changed files with 331 additions and 453 deletions

View File

@@ -37,7 +37,7 @@ class Fragment:
self._color = QColor()
self._background = QColor()
self._asis = asis
self._left = 0
self._indent = 0
self._target = "word"
return
@@ -243,8 +243,8 @@ class Fragment:
def setBackground(self, color: QColor) -> None:
self._background = color
return
def setLeft(self, left: int) -> None:
self._left = left
def setIndent(self, indent: int) -> None:
self._indent = indent
return
#
@@ -292,8 +292,8 @@ class Fragment:
def asis(self) -> bool:
return self._asis
def left(self) -> int:
return self._left
def indent(self) -> int:
return self._indent
class Line:
def __init__(self) -> None:
@@ -322,7 +322,7 @@ class Line:
def parseText(self, frag: Fragment) -> list[Fragment]:
org = frag.text()
if frag.asis():
if frag.asis() or True:
return [frag]
#
# Needed Fonts
@@ -537,8 +537,11 @@ class Line:
self._leading = leading
x = 0
for frag in self._fragments:
if x < frag.left():
x = frag.left()
left = frag.indent() * 30
if left > 0:
print(frag.indent(), frag.text())
if x < left:
x = left
#
# We need to calculate the location to draw the
# text. We also need to calculate the bounding Rectangle

View File

@@ -1,23 +1,18 @@
import importlib
import pkgutil
import json
import re
from typing import Any, TypedDict, cast
from PyQt6.QtCore import (
QUrl,
Qt,
pyqtSlot,
)
from PyQt6.QtGui import (
QColor,
)
from PyQt6.QtSql import QSqlQuery
from PyQt6.QtWidgets import QScrollArea
from lib.utils import query_error, Resources
from lib.utils import query_error
from lib.sounds import SoundOff
from lib.definition import Definition, Line, Fragment
from lib.definition import Definition, Line
import plugins
def find_plugins(ns_pkg):
@@ -108,281 +103,6 @@ class Word:
except KeyError:
raise Exception(f"Unknown source: {self.current['source']}")
def mw_seq(self, seq: list[Any]) -> list[Line]:
r=Resources()
lines: list[Line] = []
outer = " "
inner = " "
for value in seq:
if value[0] == 'pseq':
continue
print(value[0])
print(value[1])
sense = value[1]
#
# The optional 'sn' field tells us what sort of labeling to do
#
sn = sense.get("sn", "")
sns = sn.split(" ")
if len(sns) == 2:
outer = sns[0]
inner = sns[1]
elif len(sns) == 1:
if inner == " ":
outer = sns[0]
else:
inner = sns[0]
try:
text = ", ".join(sense["sls"])
line = Line()
frag = Fragment(
f"{outer} {inner} ",
r.boldFont,
color=r.baseColor
)
outer = " "
line.addFragment(frag)
frag = Fragment(
text,
r.italicFont,
color=r.baseColor
)
frag.setLeft(30)
line.addFragment(frag)
except KeyError:
pass
try:
for dt in sense["dt"]:
if dt[0] == "text":
line = Line()
frag = Fragment(
f"{outer} {inner} ",
r.boldFont,
color=r.baseColor
)
outer = " "
frag.setLeft(10)
line.addFragment(frag)
frag = Fragment(
dt[1],
r.textFont,
color=r.baseColor
)
frag.setLeft(30)
line.addFragment(frag)
lines.append(line)
elif dt[0] == "vis":
for vis in dt[1]:
line = Line()
frag = Fragment(
f" ",
r.boldFont
)
frag.setLeft(45)
line.addFragment(frag)
line.addFragment(
Fragment(
vis["t"],
r.textFont,
color=QColor("#aaa"),
)
)
lines.append(line)
elif dt[0] == "uns":
for uns in dt[1]:
for seg in uns:
if seg[0] == "text":
try:
line = lines.pop()
except IndexError:
line = Line()
frag = Fragment(
"\u27F6 " + seg[1],
r.textFont,
color=r.baseColor
)
frag.setLeft(30)
line.addFragment(frag)
lines.append(line)
elif dt[0] == 'ca':
continue
else:
raise Exception(f"Unknown key {dt[0]} in {sense['dt']}")
except KeyError:
pass
return lines
def mw_def_entry(self, entry: dict[str, Any]) -> list[Line]:
r = Resources()
#
# Easy reference to colors
#
lines: list[Line] = []
line = Line()
hw = re.sub(r"\*", "", entry["hwi"]["hw"])
frag = Fragment(hw, r.headerFont, color=r.baseColor)
line.addFragment(frag)
frag = Fragment(
" " + entry["fl"], r.labelFont, color=r.linkColor
)
line.addFragment(frag)
lines.append(line)
if "vrs" in entry.keys():
line = Line()
space = ""
for vrs in entry["vrs"]:
frag = Fragment(
space + vrs["va"],
r.labelFont,
color=r.baseColor
)
space = " "
line.addFragment(frag)
lines.append(line)
if "prs" in entry["hwi"]:
line = Line()
frag = Fragment(
entry["hwi"]["hw"] + " ",
r.phonicFont,
color=r.baseColor,
)
line.addFragment(frag)
for prs in entry["hwi"]["prs"]:
audio = None
if audio is None:
audio = ""
frag = Fragment(
prs["mw"], r.phonicFont, color=r.linkColor
)
frag.setAudio(audio)
line.addFragment(frag)
lines.append(line)
if "ins" in entry.keys():
line = Line()
space = ""
for ins in entry["ins"]:
try:
frag = Fragment(
ins["il"], r.textFont, color=r.baseColor
)
line.addFragment(frag)
space = " "
except KeyError:
pass
frag = Fragment(
space + ins["if"],
r.boldFont,
color=r.baseColor
)
line.addFragment(frag)
space = "; "
lines.append(line)
if "lbs" in entry.keys():
line = Line()
frag = Fragment(
"; ".join(entry["lbs"]),
r.boldFont,
color=r.baseColor
)
line.addFragment(frag)
lines.append(line)
for value in entry["def"]: # has multiple 'sseg' or 'vd' init
for k, v in value.items():
if k == "sseq": # has multiple 'senses'
for seq in v:
rr = self.mw_seq(seq)
lines += rr
elif k == "vd":
line = Line()
line.addFragment(
Fragment(
v, r.italicFont, color=r.linkColor
)
)
lines.append(line)
return lines
def mw_html(self) -> str:
#
# Create the header, base word and its label
#
word = self.current['definition']["hwi"]["hw"]
label = self.current["fl"]
html = f'<h1 class="def-word">{word} <span class="def-label">{label}</span></h1>\n'
#
# If there are variants, then add them in an unordered list.
# CSS will make it pretty
#
if "vrs" in self.current.keys():
html += "<ul class=\"def-vrs'>\n"
html += "<li>"
html += "</li>\n<li>".join(
[vrs["va"] for vrs in self.current["vrs"]]
)
html += "</li>\n</ul>\n"
#
# If there is a pronunciation section, create it
#
if "prs" in self.current["hwi"].keys():
tmp = []
for prs in self.current["hwi"]["prs"]:
url = QUrl()
how = prs["mw"]
if url:
tmp.append(f'<a href="{url}">\\{how}\\</a>')
else:
tmp.append(f"\\{how}\\")
html += '<span class="def-phonetic">'
html += '</span><span="def-phonetic">'.join(tmp)
html += "</span>\n"
#
# If there are inflections, create a header for that.
#
if "ins" in self.current.keys():
html += '<h2 class="def-word">'
html += ", ".join([ins["if"] for ins in self.current["ins"]])
html += "</h2>\n"
#
# Start creating the definition section
#
html += "<ul class='def-outer'>\n"
for meaning in self.current["def"]:
html += f"<li>{meaning['vd']}\n"
html += '<ul class="def-inner">\n'
label = ""
for sseq in meaning["sseq"]:
for sense in sseq:
label = sense[1]["sn"]
sls = ""
if "sls" in sense[1].keys():
sls = ", ".join(sense[1]["sls"])
sls = f'<span class="def-sls">{sls}</span> '
for dt in sense[1]["dt"]:
if dt[0] == "text":
html += f'<li class="def-text"><span class="def-sn">{label}</span>{sls}{dt[1]}</li>\n'
elif dt[0] == "vis":
for vis in dt[1]:
html += (
f"<li class=\"def-vis\">{vis['t']}</li>\n"
)
else:
print(f"Do something with {dt[0]}")
html += "</ul>\n"
html += "</ul>\n"
return html
def apidictionary_html(self) -> str:
html = ""
return html
class DefinitionArea(QScrollArea):
def __init__(self, w: Word, *args: Any, **kwargs: Any) -> None:
super(DefinitionArea, self).__init__(*args, *kwargs)

View File

@@ -1,8 +1,9 @@
from importlib.abc import InspectLoader
from PyQt6.QtGui import QColor
from trycast import trycast
import json
import re
from typing import Any, NamedTuple, NotRequired, TypedDict
from typing import Any, Literal, NotRequired, TypedDict, cast
from PyQt6.QtCore import QEventLoop, QUrl, Qt
from PyQt6.QtNetwork import QNetworkRequest
@@ -17,15 +18,14 @@ registration = {
API = "https://www.dictionaryapi.com/api/v3/references/collegiate/json/{word}?key={key}"
key = "51d9df34-ee13-489e-8656-478c215e846c"
class TextTuple(NamedTuple):
type_: str # 'text'
text: str
class TTuple(NamedTuple):
type_: str # 't'
text: str
class VerbalIllustration(TypedDict):
t: str
aq: str
class Meta(TypedDict):
id: str
uuid: str
sort: str
src: str
section: str
stems: list[str]
offensive: bool
class Sound(TypedDict):
audio: str
@@ -39,73 +39,70 @@ class Pronunciation(TypedDict):
pun: NotRequired[str]
sound: NotRequired[Sound]
class Meta(TypedDict):
id: str
uuid: str
sort: str
src: str
section: str
stems: list[str]
offensive: bool
class SubSource(TypedDict):
source: NotRequired[str]
aqdate: NotRequired[str]
class HeadWordInfo(TypedDict):
class AttributionOfQuote(TypedDict):
auth: NotRequired[str]
source: NotRequired[str]
aqdate: NotRequired[str]
subsource: NotRequired[SubSource]
class VerbalIllustration(TypedDict):
t: str
aq: NotRequired[AttributionOfQuote]
class HeadWordInformation(TypedDict):
hw: str
prs: NotRequired[list[Pronunciation]]
class HeadWord(TypedDict):
class AlternanteHeadword(TypedDict):
hw: str
prs: NotRequired[list[Pronunciation]]
psl: NotRequired[str]
class Variant(TypedDict):
va: str
vl: str
prs: list[Pronunciation]
spl: str
vl: NotRequired[str]
prs: NotRequired[list[Pronunciation]]
spl: NotRequired[str]
class Inflection(TypedDict):
if_: str
ifc: str
il: str
prs: list[Pronunciation]
spl: str
Inflection =TypedDict('Inflection', {
'if': NotRequired[str],
'ifc': NotRequired[str],
'il': NotRequired[str],
'prs': NotRequired[list[Pronunciation]],
'spl': NotRequired[str]
})
class CrossReferenceTarget(TypedDict):
cxl: str
cxr: NotRequired[str]
cxt: str
cxn: NotRequired[str]
class CognateCrossRef(TypedDict):
cxl: str
cxtis: list[CrossReferenceTarget]
class Pair(TypedDict):
objType: str
obj: Any
class DividedSense(TypedDict):
sd: str
et: list[str] # Not full
ins: list[Inflection]
lbs: list[str]
prs: list[Pronunciation]
sgram: str
sls: list[str]
vrs: list[Variant]
class BioGraphicalNameWrap(TypedDict):
pname: str
sname: str
altname: str
prs: list[Pronunciation]
class CalledAlsoTarget(TypedDict):
cat: str
catref: str
pn: str
prs: list[Pronunciation]
psl: str
class CalledAlso(TypedDict):
intro: str
cats: list[CalledAlsoTarget]
class RunInWrap(TypedDict):
rie: str
prs: list[Pronunciation]
text: str
vrs: list[Variant]
dt: list[list[Pair]]
et: NotRequired[list[Pair]]
ins: NotRequired[list[Inflection]]
lbs: NotRequired[list[str]]
prs: NotRequired[list[Pronunciation]]
sgram: NotRequired[str]
sls: NotRequired[list[str]]
vrs: NotRequired[list[Variant]]
class Sense(TypedDict):
dt: list[list] # not full
et: NotRequired[list[str]]
dt: list[list[Pair]]
et: NotRequired[list[Pair]]
ins: NotRequired[list[Inflection]]
lbs: NotRequired[list[str]]
prs: NotRequired[list[Pronunciation]]
@@ -115,43 +112,93 @@ class Sense(TypedDict):
sn: NotRequired[str]
vrs: NotRequired[list[Variant]]
class Definition(TypedDict):
sseq: list[list[list[Any]]]
class TruncatedSense(Sense): pass
class BindingSubstitutePair(TypedDict):
objType: Literal['bs']
obj: Sense
class SensePair(TypedDict):
objType: Literal['sense']
obj: Sense
class DefinitionSection(TypedDict):
vd: NotRequired[str]
sls: NotRequired[list[str]]
sseq: Any # list[list[Pair]]
class Pair(TypedDict):
objType: str
obj: list[Sense]|Sense|str|list[VerbalIllustration]|list[Any]
Entry = TypedDict(
'Entry',
{
'meta': Meta,
'hom': NotRequired[str],
'hwi': HeadWordInfo,
'ahws': NotRequired[list[HeadWord]],
'vrs': NotRequired[list[Variant]],
'fl': NotRequired[str],
'def': list[Definition],
}
)
class WordType(TypedDict):
word: str
source: str
definition: dict[str, Any]
Definition =TypedDict('Definition', {
'meta': Meta,
'hom': NotRequired[int],
'hwi': HeadWordInformation,
'ahws': NotRequired[list[AlternanteHeadword]],
'vrs': NotRequired[list[Variant]],
'fl': str,
'lbs': NotRequired[list[str]],
'sls': NotRequired[list[str]],
'ins': NotRequired[list[Inflection]],
'cxs': NotRequired[list[CognateCrossRef]],
'def': list[DefinitionSection],
})
def make_pairs(src: list[Any]) -> list[Pair]:
result:list[Pair] = []
iters = [iter(src)]*2
for entry in zip(*iters):
pair = { 'objType': entry[0],
pair0 = { 'objType': entry[0],
'obj': entry[1],
}
pair = trycast(Pair, pair)
assert pair is not None
result.append(pair)
if isinstance(pair0['obj'], list):
result.append(cast(Pair,pair0))
continue
pair1 = trycast(Pair, pair0)
if pair1 is None:
print(pair0['objType'], type(pair0['obj']),
json.dumps(pair0['obj'],indent=2)
)
assert pair1 is not None
result.append(pair1)
return result
Elements = [ 'dt', 'sen', 'bs', 'pseq', 'snot', 't', 'text', 'vis', 'sens', 'uns', 'sense' ]
def restructure(obj: Any) -> Any:
if isinstance(obj, list):
if len(obj) == 0:
return []
if isinstance(obj[0], str) and obj[0] in Elements:
pairs = make_pairs(obj)
result = []
for pair in pairs:
if isinstance(pair['obj'], list):
r2 = []
for item in pair['obj']:
r2.append(restructure(item))
pair['obj'] = r2
elif isinstance(pair['obj'], dict):
r2 = {}
for k,v in pair['obj'].items():
r2[k] = restructure(v)
pair['obj'] = r2
result.append(pair)
return result
result = []
for v in obj:
result.append(restructure(v))
return result
elif isinstance(obj, dict):
obj2 = cast(dict, obj)
result = {}
for k,v in obj2.items():
result[k] = restructure(v)
return result
else:
return obj
class WordType(TypedDict):
word: str
source: str
definition: Any
def fetch(word:str) -> WordType:
request = QNetworkRequest()
url = QUrl(API.format(word=word, key=key))
@@ -182,11 +229,11 @@ def soundUrl(sound:Sound, fmt='ogg') -> QUrl:
url += audio + f".{fmt}"
return QUrl(url)
def getFirstSound(definition: list[Entry]) -> QUrl:
def getFirstSound(definition: Any) -> QUrl:
# ahws, cats, dros, hwi, ins, ri, sdsense, sen, sense, uros, vrs
for entry in definition:
for v in entry.values():
hwi = trycast(HeadWordInfo, v)
hwi = v # trycast
if hwi is None:
continue
if 'prs' in hwi:
@@ -197,7 +244,7 @@ def getFirstSound(definition: list[Entry]) -> QUrl:
return url
return QUrl()
def do_prs(hwi: HeadWordInfo) -> list[Fragment]:
def do_prs(hwi: Any) -> list[Fragment]:
r = Resources()
frags: list[Fragment] = []
font = r.labelFont
@@ -226,49 +273,153 @@ def do_prs(hwi: HeadWordInfo) -> list[Fragment]:
)
return frags
def do_sense(sense: Sense|None) -> tuple[list[Fragment], list[Line]]:
def do_aq(aq: AttributionOfQuote|None) -> list[Line]:
assert aq is not None
return []
def do_vis(vis: list[VerbalIllustration]|None,indent=0) -> list[Line]:
assert vis is not None
r = Resources()
lines: list[Line] = []
for vi in vis:
line = Line()
frag = Fragment(vi['t'], r.textFont, color=r.baseColor)
if indent > 0:
frag.setIndent(indent)
line.addFragment(frag)
lines.append(line)
if 'aq' in vi:
lines += do_aq(trycast(AttributionOfQuote, vi['aq']))
return []
def do_uns(uns: list[list[list[Pair]]]|None, indent:int) -> list[Line]:
assert uns is not None
r = Resources()
lines:list[Line] = []
for note in uns:
for entry in note:
for pair in entry:
if pair['objType'] == 'text':
frag = Fragment(' \u2014'+pair['obj'], r.textFont, color=r.baseColor)
frag.setIndent(indent)
line = Line()
line.addFragment(frag)
lines.append(line)
elif pair['objType'] == 'vis':
lines += do_vis(trycast(list[VerbalIllustration], pair['obj']), indent)
elif pair['objType'] == 'ri':
raise NotImplementedError("NO ri")
return lines
def do_dt(dt: list[list[Pair]]|None, indent: int) -> tuple[list[Fragment], list[Line]]:
assert dt is not None
frags: list[Fragment] = []
lines: list[Line] = []
r = Resources()
first = True
for entry in dt:
for pair in entry:
if pair['objType'] == 'text':
frag = Fragment(pair['obj'], r.textFont, color=r.baseColor)
frag.setIndent(indent)
if first:
frags.append(frag)
else:
line = Line()
line.addFragment(frag)
lines.append(line)
elif pair['objType'] == 'vis':
lines += do_vis(trycast(list[VerbalIllustration], pair['obj']))
elif pair['objType'] == 'uns':
newLines = do_uns(trycast(list[list[list[Pair]]], pair['obj']),indent)
lines += newLines
else:
print(json.dumps(pair, indent=2))
raise NotImplementedError(f"Unknown or unimplimented element {pair['objType']}")
first = False
return (frags, lines)
def do_sense(sense: Sense|None, indent:int=3) -> tuple[list[Fragment], list[Line]]:
if sense is None:
return ([],[])
lines: list[Line] = []
frags: list[Fragment] = []
r = Resources()
if 'sn' in sense:
sn = sense['sn']
else:
sn = ''
print(f'{sn}\n\n',json.dumps(sense['dt'], indent=2))
iters = [iter(sense['dt'])]*2
for pair in zip(*iters):
pair = trycast(tuple[str, Any], pair)
assert pair is not None
print(pair[0])
if pair[0] == 'text':
dt = sense['dt']
(newFrags, newLines) = do_dt(trycast(list[list[Pair]], dt),indent)
frags += newFrags
lines += newLines
for k,v in sense.items():
print(k)
if k == 'dt' or k == 'sn':
continue
elif k == 'sdsense':
# XXX - This needs to expand to handle et, ins, lbs, prs, sgram, sls, vrs
sdsense = trycast(DividedSense, v)
assert sdsense is not None
frag = Fragment(sdsense['sd']+' ', r.italicFont, color=r.baseColor)
frag.setIndent(indent)
line = Line()
line.addFragment(
Fragment(pair[1], r.textFont, color=r.baseColor)
)
line.addFragment(frag)
(newFrags, newLines) = do_dt(trycast(list[list[Pair]], sdsense['dt']), indent=indent)
for frag in newFrags:
line.addFragment(frag)
lines.append(line)
lines += newLines
elif k == 'sls':
labels = trycast(list[str], v)
assert labels is not None
frag = Fragment(", ".join(labels)+' ', r.textFont, color=r.subduedColor)
frags.append(frag)
else:
print(k,v)
raise NotImplementedError(f"Unknown or unimplimented element {k}")
return (frags, lines)
def do_pseq(outer: int,
inner: int,
pseq: list[list[Pair]]| None ) -> tuple[list[Fragment], list[Line]]:
assert pseq is not None
pseq: list[Any] ) -> tuple[list[Fragment], list[Line]]:
lines: list[Line] = []
frags: list[Fragment] = []
count = 1
r = Resources()
first = True
for entry in pseq:
pairs = make_pairs(entry)
for pair in pairs:
for pair in entry:
if pair['objType'] == 'bs':
(newFrags, newLines) = do_sense(trycast(Sense, pair['obj']))
frags += newFrags
# TODO - bs has to be more than just a wrapper for Sense
sense = pair['obj']['sense']
(newFrags, newLines) = do_sense(trycast(Sense, sense))
if first:
frags += newFrags
first = False
else:
line = Line()
for frag in newFrags:
line.addFragment(frag)
lines.append(line)
lines += newLines
elif pair['objType'] == 'sense':
(newFrags, newLines) = do_sense(trycast(Sense, pair['obj']))
frags += newFrags
if first:
frag = Fragment(f"({count})", r.textFont, color=r.baseColor)
frag.setIndent(3)
frags.append(frag)
(newFrags, newLines) = do_sense(trycast(Sense, pair['obj']), indent=4)
frags += newFrags
first = False
else:
line = Line()
frag = Fragment(f"({count})", r.textFont, color=r.baseColor)
frag.setIndent(3)
line.addFragment(frag)
(newFrags, newLines) = do_sense(trycast(Sense, pair['obj']), indent=4)
for frag in newFrags:
line.addFragment(frag)
lines.append(line)
lines += newLines
count += 1
else:
raise Exception(f"Unknown object type {pair['objType']}")
raise NotImplementedError(f"Unknown object type {pair['objType']}")
return (frags, lines)
def do_sseq(sseq:list[list[list[Pair]]]) -> list[Line]:
@@ -276,15 +427,14 @@ def do_sseq(sseq:list[list[list[Pair]]]) -> list[Line]:
r = Resources()
for outer, item_o in enumerate(sseq):
line = Line()
line.addFragment(
Fragment(str(outer+1), r.boldFont, color=r.baseColor)
)
frag =Fragment(str(outer+1), r.boldFont, color=r.baseColor)
frag.setIndent(1)
line.addFragment(frag)
for inner, item_i in enumerate(item_o):
line.addFragment(
Fragment(chr(ord('a')+inner), r.boldFont, color=r.baseColor)
)
pairs = make_pairs(item_i)
for pair in pairs:
frag =Fragment(chr(ord('a')+inner), r.boldFont, color=r.baseColor)
frag.setIndent(2)
line.addFragment(frag)
for pair in item_i:
objType = pair['objType']
if objType == 'sense':
sense = trycast(Sense, pair['obj'])
@@ -292,26 +442,27 @@ def do_sseq(sseq:list[list[list[Pair]]]) -> list[Line]:
for frag in frags:
line.addFragment(frag)
lines.append(line)
line = Line()
lines += newlines
elif objType == 'sen':
raise Exception(f"sen unimplimented")
raise NotImplementedError(f"sen unimplimented")
elif objType == 'pseq':
pseq = trycast(list[list[Pair]], pair['obj'])
(frags, newlines) = do_pseq(inner, outer, trycast(list[list[Pair]], pair['obj']))
(frags, newlines) = do_pseq(inner, outer, pair['obj'])
for frag in frags:
line.addFragment(frag)
lines.append(line)
line = Line()
lines += newlines
elif objType == 'bs':
raise Exception(f"bs unimplimented")
raise NotImplementedError(f"bs unimplimented")
else:
raise Exception(f"Unknown object[{objType}] for \n{json.dumps(pair['obj'],indent=2)}")
raise NotImplementedError(f"Unknown object[{objType}] for \n{json.dumps(pair['obj'],indent=2)}")
return lines
def do_def(entry: Definition) -> list[Line]:
def do_def(entry: DefinitionSection) -> list[Line]:
assert entry is not None
r = Resources()
lines: list[Line] = []
assert trycast(Definition, entry) is not None
if 'vd' in entry:
line = Line()
line.addFragment(
@@ -325,67 +476,68 @@ def do_def(entry: Definition) -> list[Line]:
lines += do_sseq(sseq)
return lines
def getDef(definition: list[Entry]) -> list[Line]:
def getDef(defines: Any) -> list[Line]:
workList = restructure(defines)
workList = trycast(list[Definition], workList)
assert workList is not None
r = Resources()
lines:list[Line] = []
#
# Pull the fonts for ease of use
#
headerFont = r.headerFont
textFont = r.textFont
labelFont = r.labelFont
#
# Pull the colors for ease of use
#
baseColor = r.baseColor
linkColor = r.linkColor
subduedColor = r.subduedColor
#
# No need to figure it out each time it is used
#
entries = 0
id = definition[0]['meta']['id'].lower().split(':')[0]
id = workList[0]['meta']['id'].lower().split(':')[0]
uses: dict[str,int] = {}
for entry in definition:
for entry in workList:
testId = entry['meta']['id'].lower().split(':')[0]
if testId == id:
entries += 1
#
# If there is a Functional Lable, then we are going
# to capture the count of each FL
#
try:
uses[entry['fl']] = uses.get(entry['fl'], 0) + 1
except KeyError:
pass
del(entry)
used: dict[str, int] = {}
for k in uses.keys():
used[k] = 0
for count, entry in enumerate(definition):
testId = entry['meta']['id'].lower().split(':')[0]
for count, work in enumerate(workList):
testId = work['meta']['id'].lower().split(':')[0]
#
# Skip entries which are not part of the primary definition
#
if testId != id:
continue
#
# Create the First line from the hwi, [ahws] and fl
#
line = Line()
hwi = trycast(HeadWordInfo, entry['hwi'])
hwi = trycast(HeadWordInformation, work['hwi'])
assert hwi is not None
hw = re.sub(r'\*', '', hwi['hw'])
line.addFragment(Fragment(hw, headerFont, color=baseColor))
if 'ahws' in entry:
ahws = trycast(list[HeadWord], entry['ahws'])
line.addFragment(Fragment(hw, r.headerFont, color=r.baseColor))
if 'ahws' in work:
ahws = trycast(list[AlternanteHeadword], work['ahws'])
assert ahws is not None
for ahw in ahws:
hw = re.sub(r'\*', '', ahw['hw'])
line.addFragment(Fragment(', ' + hw, headerFont, color=baseColor))
line.addFragment(Fragment(', ' + hw, r.headerFont, color=r.baseColor))
if entries > 1:
frag = Fragment(f" {count + 1} of {entries} ", textFont, color= subduedColor)
frag = Fragment(f" {count + 1} of {entries} ", r.textFont, color= r.subduedColor)
# XXX - Use a resource color!!!
frag.setBackground(QColor(Qt.GlobalColor.gray))
line.addFragment(frag)
if 'fl' in entry:
text = entry['fl']
if 'fl' in work:
text = work['fl']
used[text] += 1
if uses[text] > 1:
text += f' ({used[text]})'
line.addFragment(Fragment(text, labelFont, color=baseColor))
line.addFragment(Fragment(text, r.labelFont, color=r.baseColor))
lines.append(line)
#
@@ -395,13 +547,16 @@ def getDef(definition: list[Entry]) -> list[Line]:
line = Line()
if hwi['hw'].find('*') >= 0:
hw = re.sub(r'\*', '\u00b7', hwi['hw'])
line.addFragment(Fragment(hw + ' ', textFont, color=subduedColor))
line.addFragment(Fragment(hw + ' ', r.textFont, color=r.subduedColor))
for frag in do_prs(hwi):
line.addFragment(frag)
if len(line.getLine()) > 0:
lines.append(line)
defines = trycast(list[Definition], entry['def'])
defines = trycast(list[DefinitionSection], work['def'])
assert defines is not None
for define in defines:
lines += do_def(define)
try:
lines += do_def(define)
except NotImplementedError as e:
print(e)
return lines