Mostly functional in the new format
This commit is contained in:
@@ -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
|
||||
|
||||
284
lib/words.py
284
lib/words.py
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user