Functional version. Needs much tweaking.

This commit is contained in:
Christopher T. Johnson
2024-04-13 15:38:47 -04:00
parent a3d3e71bf8
commit 8babbe7160
2 changed files with 204 additions and 179 deletions

View File

@@ -45,7 +45,9 @@ class Fragment:
return self.__repr__()
def size(self, width: int) -> QSize:
rect = QRect(self._position, QSize(width - self._position.x(), 2000))
pos = self._position
pos.setX(self._indent * 30)
rect = QRect(pos, QSize(width - self._position.x(), 2000))
flags = (
Qt.AlignmentFlag.AlignLeft
| Qt.AlignmentFlag.AlignBaseline
@@ -87,6 +89,10 @@ class Fragment:
| Qt.TextFlag.TextWordWrap
)
bounding = painter.boundingRect(rect, flags, self._text)
#
# We need to determine if the text caused a word wrap.
# If it has wrapped. We need to locate that exact break point
#
size = bounding.size()
painter.setPen(QColor("#f00"))
@@ -296,6 +302,7 @@ class Fragment:
return self._indent
class Line:
parseText = None
def __init__(self) -> None:
self._maxHeight = -1
self._baseLine = -1
@@ -308,7 +315,12 @@ class Line:
"|".join([x.text() for x in self._fragments])
+ f"|{self._maxHeight}"
)
@classmethod
def setParseText(cls, call) -> None:
print(call)
cls.parseText = call
return
def repaintEvent(self, painter: QPainter) -> int:
#
# we do not have an event field because we are not a true widget
@@ -320,177 +332,6 @@ class Line:
lineSpacing = ls
return lineSpacing
def parseText(self, frag: Fragment) -> list[Fragment]:
org = frag.text()
if frag.asis() or True:
return [frag]
#
# Needed Fonts
# We can't use _resources because that might not be the font
# for this piece of text
#
bold = QFont(frag.font())
bold.setWeight(QFont.Weight.Bold)
italic = QFont(frag.font())
italic.setItalic(True)
smallCaps = QFont(frag.font())
smallCaps.setCapitalization(QFont.Capitalization.SmallCaps)
script = QFont(frag.font())
script.setPixelSize(int(script.pixelSize() / 4))
caps = QFont(frag.font())
caps.setCapitalization(QFont.Capitalization.AllUppercase)
results: list[Fragment] = []
while True:
text = frag.text()
start = text.find("{")
if start < 0:
results.append(frag)
return results
if start > 0:
newFrag = copy.copy(frag)
newFrag.setText(text[:start])
results.append(newFrag)
frag.setText(text[start:])
continue
#
# Start == 0
#
#
# If the token is an end-token, return now.
#
if text.startswith("{/"):
results.append(frag)
return results
#
# extract this token
#
end = text.find("}")
token = text[1:end]
frag.setText(text[end + 1 :])
newFrag = copy.copy(frag)
oldFont = QFont(frag.font())
if token == "bc":
results.append(Fragment(": ", bold, color=QColor("#fff")))
continue
if token in [
"b",
"inf",
"it",
"sc",
"sup",
"phrase",
"parahw",
"gloss",
"qword",
"wi",
"dx",
"dx_def",
"dx_ety",
"ma",
]:
if token == "b":
frag.setFont(bold)
elif token in ["it", "qword", "wi"]:
frag.setFont(italic)
elif token == "sc":
frag.setFont(smallCaps)
elif token in ["inf", "sup"]:
frag.setFont(script)
elif token == "phrase":
font = QFont(bold)
font.setItalic(True)
frag.setFont(font)
elif token == "parahw":
font = QFont(smallCaps)
font.setWeight(QFont.Weight.Bold)
frag.setFont(font)
elif token == "gloss":
frag.setText("[" + frag.text())
elif token in ["dx", "dx_ety"]:
frag.setText("\u2014" + frag.text())
elif token == "ma":
frag.setText("\u2014 more at " + frag.text())
elif token == "dx_def":
frag.setText("(" + frag.text())
else:
raise Exception(f"Unknown block marker: {token}")
results += self.parseText(frag)
frag = results.pop()
frag.setFont(oldFont)
text = frag.text()
if not text.startswith("{/" + token + "}"):
raise Exception(
f"No matching close for {token} in {org}"
)
if token == "gloss":
results[-1].setText(results[-1].text() + "]")
elif token == "dx_def":
results[-1].setText(results[-1].text() + ")")
end = text.find("}")
text = text[end + 1 :]
frag.setText(text)
continue
#
# These are codes that include all information within the token
#
fields = token.split("|")
token = fields[0]
if token in [
"a_link",
"d_link",
"dxt",
"et_link",
"i_link",
"mat",
"sx",
]:
wref = ""
htext = fields[1]
oldFont = QFont(frag.font())
target = "word"
if token == "a_link":
wref = fields[1]
elif token in ["d_link", "et_link", "mat", "sx", "i_link"]:
if fields[2] == "":
wref = fields[1]
else:
wref = fields[2]
if token == "i_link":
frag.setFont(italic)
elif token == "sx":
frag.setFont(caps)
elif token == "dxt":
if fields[3] == "illustration":
wref = fields[2]
target = "article"
elif fields[3] == "table":
wref = fields[2]
target = "table"
elif fields[3] != "":
wref = fields[3]
target = "sense"
else:
wref = fields[1]
target = "word"
elif token == "a_link":
target = "word"
wref = fields[1]
else:
raise Exception(f"Unknown code: {token} in {org}")
newFrag = copy.copy(frag)
newFrag.setText(htext)
newFrag.setWRef(wref)
newFrag.setTarget(target)
results.append(newFrag)
frag.setFont(oldFont)
text = frag.text()
continue
raise Exception(
f"Unable to locate a known token {token} in {org}"
)
def addFragment(
self,
@@ -510,8 +351,11 @@ class Line:
frag.setPadding(3, 0, 0, 5)
frag.setBorder(1)
frag.setMargin(0, 0, 0, 0)
items = self.parseText(frag)
self._fragments += items
if Line.parseText:
items = Line.parseText(frag)
self._fragments += items
else:
self._fragments.append(frag)
return
def finalizeLine(self, width: int, base: int) -> None:
@@ -538,8 +382,6 @@ class Line:
x = 0
for frag in self._fragments:
left = frag.indent() * 30
if left > 0:
print(frag.indent(), frag.text())
if x < left:
x = left
#

View File

@@ -1,5 +1,6 @@
import copy
from importlib.abc import InspectLoader
from PyQt6.QtGui import QColor
from PyQt6.QtGui import QColor, QFont
from trycast import trycast
import json
import re
@@ -350,7 +351,6 @@ def do_sense(sense: Sense|None, indent:int=3) -> tuple[list[Fragment], list[Line
frags += newFrags
lines += newLines
for k,v in sense.items():
print(k)
if k == 'dt' or k == 'sn':
continue
elif k == 'sdsense':
@@ -477,6 +477,7 @@ def do_def(entry: DefinitionSection) -> list[Line]:
return lines
def getDef(defines: Any) -> list[Line]:
Line.setParseText(parseText)
workList = restructure(defines)
workList = trycast(list[Definition], workList)
assert workList is not None
@@ -560,3 +561,185 @@ def getDef(defines: Any) -> list[Line]:
except NotImplementedError as e:
print(e)
return lines
def parseText(frag: Fragment) -> list[Fragment]:
org = frag.text()
if frag.asis():
return [frag]
#
# Get the fonts we might need.
# We can't use Resources() because we don't know the original font.
textFont = frag.font()
textFont.setWeight(QFont.Weight.Normal)
textFont.setItalic(False)
textFont.setCapitalization(QFont.Capitalization.MixedCase)
boldFont = QFont(textFont)
boldFont.setBold(True)
italicFont = QFont(textFont)
italicFont.setItalic(True)
smallCapsFont = QFont(textFont)
smallCapsFont.setCapitalization(QFont.Capitalization.SmallCaps)
scriptFont = QFont(textFont)
scriptFont.setPixelSize(int(scriptFont.pixelSize()/4))
boldItalicFont = QFont(boldFont)
boldItalicFont.setItalic(True)
boldSmallCapsFont = QFont(smallCapsFont)
boldSmallCapsFont.setBold(True)
capsFont = QFont(textFont)
capsFont.setCapitalization(QFont.Capitalization.AllUppercase)
#
# Default color:
#
baseColor = frag.color()
r = Resources()
results: list[Fragment] = []
while True:
text = frag.text()
start = text.find("{")
if start < 0:
results.append(frag)
return results
if start > 0:
newFrag = copy.copy(frag)
newFrag.setText(text[:start])
results.append(newFrag)
frag.setText(text[start:])
continue
#
# Start == 0
#
#
# If the token is an end-token, return now.
#
if text.startswith("{/"):
results.append(frag)
return results
#
# extract this token
#
end = text.find("}")
token = text[1:end]
frag.setText(text[end + 1 :])
newFrag = copy.copy(frag)
oldFont = QFont(frag.font())
if token == "bc":
results.append(Fragment(": ", boldFont, color=baseColor))
continue
if token in [
"b",
"inf",
"it",
"sc",
"sup",
"phrase",
"parahw",
"gloss",
"qword",
"wi",
"dx",
"dx_def",
"dx_ety",
"ma",
]:
if token == "b":
frag.setFont(boldFont)
elif token in ["it", "qword", "wi"]:
frag.setFont(italicFont)
elif token == "sc":
frag.setFont(smallCapsFont)
elif token in ["inf", "sup"]:
frag.setFont(scriptFont)
elif token == "phrase":
frag.setFont(boldItalicFont)
elif token == "parahw":
frag.setFont(boldSmallCapsFont)
elif token == "gloss":
frag.setText("[" + frag.text())
elif token in ["dx", "dx_ety"]:
frag.setText("\u2014" + frag.text())
elif token == "ma":
frag.setText("\u2014 more at " + frag.text())
elif token == "dx_def":
frag.setText("(" + frag.text())
else:
raise NotImplementedError(f"Unknown block marker: {token}")
results += parseText(frag)
frag = results.pop()
frag.setFont(oldFont)
text = frag.text()
if not text.startswith("{/" + token + "}"):
raise NotImplementedError(
f"No matching close for {token} in {org}"
)
if token == "gloss":
results[-1].setText(results[-1].text() + "]")
elif token == "dx_def":
results[-1].setText(results[-1].text() + ")")
end = text.find("}")
text = text[end + 1 :]
frag.setText(text)
continue
#
# These are codes that include all information within the token
#
fields = token.split("|")
token = fields[0]
if token in [
"a_link",
"d_link",
"dxt",
"et_link",
"i_link",
"mat",
"sx",
]:
wref = ""
htext = fields[1]
oldFont = QFont(frag.font())
target = "word"
if token == "a_link":
wref = fields[1]
elif token in ["d_link", "et_link", "mat", "sx", "i_link"]:
if fields[2] == "":
wref = fields[1]
else:
wref = fields[2]
if token == "i_link":
frag.setFont(italicFont)
elif token == "sx":
frag.setFont(capsFont)
elif token == "dxt":
if fields[3] == "illustration":
wref = fields[2]
target = "article"
elif fields[3] == "table":
wref = fields[2]
target = "table"
elif fields[3] != "":
wref = fields[3]
target = "sense"
else:
wref = fields[1]
target = "word"
elif token == "a_link":
target = "word"
wref = fields[1]
else:
raise NotImplementedError(f"Unknown code: {token} in {org}")
newFrag = copy.copy(frag)
newFrag.setText(htext)
newFrag.setWRef(wref)
newFrag.setTarget(target)
newFrag.setColor(r.linkColor)
results.append(newFrag)
frag.setFont(oldFont)
text = frag.text()
continue
raise NotImplementedError(
f"Unable to locate a known token {token} in {org}"
)