diff --git a/lib/definition.py b/lib/definition.py
index 6ed7dbe..ccbcabb 100644
--- a/lib/definition.py
+++ b/lib/definition.py
@@ -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
diff --git a/lib/words.py b/lib/words.py
index 123f6af..0ecc5ef 100644
--- a/lib/words.py
+++ b/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'
{word} {label}
\n'
-
- #
- # If there are variants, then add them in an unordered list.
- # CSS will make it pretty
- #
- if "vrs" in self.current.keys():
- html += "\n"
- html += "- "
- html += "
\n- ".join(
- [vrs["va"] for vrs in self.current["vrs"]]
- )
- html += "
\n
\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'\\{how}\\')
- else:
- tmp.append(f"\\{how}\\")
- html += ''
- html += ''.join(tmp)
- html += "\n"
-
- #
- # If there are inflections, create a header for that.
- #
- if "ins" in self.current.keys():
- html += ''
- html += ", ".join([ins["if"] for ins in self.current["ins"]])
- html += "
\n"
-
- #
- # Start creating the definition section
- #
- html += "\n"
- for meaning in self.current["def"]:
- html += f"- {meaning['vd']}\n"
- html += '
\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'{sls} '
- for dt in sense[1]["dt"]:
- if dt[0] == "text":
- html += f'- {label}{sls}{dt[1]}
\n'
- elif dt[0] == "vis":
- for vis in dt[1]:
- html += (
- f"- {vis['t']}
\n"
- )
- else:
- print(f"Do something with {dt[0]}")
- html += "
\n"
- html += "
\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)
diff --git a/plugins/merriam-webster.py b/plugins/merriam-webster.py
index a71c296..3f55057 100644
--- a/plugins/merriam-webster.py
+++ b/plugins/merriam-webster.py
@@ -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,16 +18,15 @@ 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
ref: 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]
+ 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 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]
-
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]]
@@ -114,44 +111,94 @@ class Sense(TypedDict):
sls: NotRequired[list[str]]
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