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__() return self.__repr__()
def size(self, width: int) -> QSize: 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 = ( flags = (
Qt.AlignmentFlag.AlignLeft Qt.AlignmentFlag.AlignLeft
| Qt.AlignmentFlag.AlignBaseline | Qt.AlignmentFlag.AlignBaseline
@@ -87,6 +89,10 @@ class Fragment:
| Qt.TextFlag.TextWordWrap | Qt.TextFlag.TextWordWrap
) )
bounding = painter.boundingRect(rect, flags, self._text) 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() size = bounding.size()
painter.setPen(QColor("#f00")) painter.setPen(QColor("#f00"))
@@ -296,6 +302,7 @@ class Fragment:
return self._indent return self._indent
class Line: class Line:
parseText = None
def __init__(self) -> None: def __init__(self) -> None:
self._maxHeight = -1 self._maxHeight = -1
self._baseLine = -1 self._baseLine = -1
@@ -308,6 +315,11 @@ class Line:
"|".join([x.text() for x in self._fragments]) "|".join([x.text() for x in self._fragments])
+ f"|{self._maxHeight}" + f"|{self._maxHeight}"
) )
@classmethod
def setParseText(cls, call) -> None:
print(call)
cls.parseText = call
return
def repaintEvent(self, painter: QPainter) -> int: def repaintEvent(self, painter: QPainter) -> int:
# #
@@ -320,177 +332,6 @@ class Line:
lineSpacing = ls lineSpacing = ls
return lineSpacing 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( def addFragment(
self, self,
@@ -510,8 +351,11 @@ class Line:
frag.setPadding(3, 0, 0, 5) frag.setPadding(3, 0, 0, 5)
frag.setBorder(1) frag.setBorder(1)
frag.setMargin(0, 0, 0, 0) frag.setMargin(0, 0, 0, 0)
items = self.parseText(frag) if Line.parseText:
items = Line.parseText(frag)
self._fragments += items self._fragments += items
else:
self._fragments.append(frag)
return return
def finalizeLine(self, width: int, base: int) -> None: def finalizeLine(self, width: int, base: int) -> None:
@@ -538,8 +382,6 @@ class Line:
x = 0 x = 0
for frag in self._fragments: for frag in self._fragments:
left = frag.indent() * 30 left = frag.indent() * 30
if left > 0:
print(frag.indent(), frag.text())
if x < left: if x < left:
x = left x = left
# #

View File

@@ -1,5 +1,6 @@
import copy
from importlib.abc import InspectLoader from importlib.abc import InspectLoader
from PyQt6.QtGui import QColor from PyQt6.QtGui import QColor, QFont
from trycast import trycast from trycast import trycast
import json import json
import re import re
@@ -350,7 +351,6 @@ def do_sense(sense: Sense|None, indent:int=3) -> tuple[list[Fragment], list[Line
frags += newFrags frags += newFrags
lines += newLines lines += newLines
for k,v in sense.items(): for k,v in sense.items():
print(k)
if k == 'dt' or k == 'sn': if k == 'dt' or k == 'sn':
continue continue
elif k == 'sdsense': elif k == 'sdsense':
@@ -477,6 +477,7 @@ def do_def(entry: DefinitionSection) -> list[Line]:
return lines return lines
def getDef(defines: Any) -> list[Line]: def getDef(defines: Any) -> list[Line]:
Line.setParseText(parseText)
workList = restructure(defines) workList = restructure(defines)
workList = trycast(list[Definition], workList) workList = trycast(list[Definition], workList)
assert workList is not None assert workList is not None
@@ -560,3 +561,185 @@ def getDef(defines: Any) -> list[Line]:
except NotImplementedError as e: except NotImplementedError as e:
print(e) print(e)
return lines 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}"
)