Clean up the syntax highlighter class
This commit is contained in:
@@ -397,7 +397,7 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self._checkDocSize(docSize)
|
self._checkDocSize(docSize)
|
||||||
spTemp = self.highLight.spellCheck
|
spTemp = self.highLight.spellCheck
|
||||||
if self._bigDoc:
|
if self._bigDoc:
|
||||||
self.highLight.spellCheck = False
|
self.highLight.setSpellCheck(False)
|
||||||
|
|
||||||
bfTime = time()
|
bfTime = time()
|
||||||
self._allowAutoReplace(False)
|
self._allowAutoReplace(False)
|
||||||
@@ -418,7 +418,7 @@ class GuiDocEditor(QTextEdit):
|
|||||||
self.docHeader.setTitleFromHandle(self._docHandle)
|
self.docHeader.setTitleFromHandle(self._docHandle)
|
||||||
self.docFooter.setHandle(self._docHandle)
|
self.docFooter.setHandle(self._docHandle)
|
||||||
self.updateDocMargins()
|
self.updateDocMargins()
|
||||||
self.highLight.spellCheck = spTemp
|
self.highLight.setSpellCheck(spTemp)
|
||||||
|
|
||||||
if tLine is None and self._nwItem is not None:
|
if tLine is None and self._nwItem is not None:
|
||||||
# For large documents, we queue the repositioning until the
|
# For large documents, we queue the repositioning until the
|
||||||
|
|||||||
+180
-175
@@ -51,24 +51,27 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
|
|
||||||
logger.debug("Create: GuiDocHighlighter")
|
logger.debug("Create: GuiDocHighlighter")
|
||||||
|
|
||||||
self.theHandle = None
|
self._tHandle = None
|
||||||
self.spellCheck = False
|
self._spellCheck = False
|
||||||
self.spellRx = None
|
self._spellRx = QRegularExpression()
|
||||||
self.hRules = []
|
|
||||||
self.hStyles = {}
|
|
||||||
|
|
||||||
self.colHead = QColor(0, 0, 0)
|
self._hRules: list[tuple[str, dict]] = []
|
||||||
self.colHeadH = QColor(0, 0, 0)
|
self._hStyles: dict[str, QTextCharFormat] = {}
|
||||||
self.colEmph = QColor(0, 0, 0)
|
|
||||||
self.colDialN = QColor(0, 0, 0)
|
self._colHead = QColor(0, 0, 0)
|
||||||
self.colDialD = QColor(0, 0, 0)
|
self._colHeadH = QColor(0, 0, 0)
|
||||||
self.colDialS = QColor(0, 0, 0)
|
self._colEmph = QColor(0, 0, 0)
|
||||||
self.colHidden = QColor(0, 0, 0)
|
self._colDialN = QColor(0, 0, 0)
|
||||||
self.colKey = QColor(0, 0, 0)
|
self._colDialD = QColor(0, 0, 0)
|
||||||
self.colVal = QColor(0, 0, 0)
|
self._colDialS = QColor(0, 0, 0)
|
||||||
self.colSpell = QColor(0, 0, 0)
|
self._colHidden = QColor(0, 0, 0)
|
||||||
self.colError = QColor(0, 0, 0)
|
self._colKey = QColor(0, 0, 0)
|
||||||
self.colRepTag = QColor(0, 0, 0)
|
self._colVal = QColor(0, 0, 0)
|
||||||
|
self._colSpell = QColor(0, 0, 0)
|
||||||
|
self._colError = QColor(0, 0, 0)
|
||||||
|
self._colRepTag = QColor(0, 0, 0)
|
||||||
|
self._colMod = QColor(0, 0, 0)
|
||||||
|
self._colBreak = QColor(0, 0, 0)
|
||||||
|
|
||||||
self.initHighlighter()
|
self.initHighlighter()
|
||||||
|
|
||||||
@@ -76,71 +79,76 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
def initHighlighter(self):
|
@property
|
||||||
|
def spellCheck(self) -> bool:
|
||||||
|
"""Check if spell checking is enabled."""
|
||||||
|
return self._spellCheck
|
||||||
|
|
||||||
|
def initHighlighter(self) -> None:
|
||||||
"""Initialise the syntax highlighter, setting all the colour
|
"""Initialise the syntax highlighter, setting all the colour
|
||||||
rules and building the RegExes.
|
rules and building the RegExes.
|
||||||
"""
|
"""
|
||||||
logger.debug("Setting up highlighting rules")
|
logger.debug("Setting up highlighting rules")
|
||||||
|
|
||||||
self.colHead = QColor(*SHARED.theme.colHead)
|
self._colHead = QColor(*SHARED.theme.colHead)
|
||||||
self.colHeadH = QColor(*SHARED.theme.colHeadH)
|
self._colHeadH = QColor(*SHARED.theme.colHeadH)
|
||||||
self.colDialN = QColor(*SHARED.theme.colDialN)
|
self._colDialN = QColor(*SHARED.theme.colDialN)
|
||||||
self.colDialD = QColor(*SHARED.theme.colDialD)
|
self._colDialD = QColor(*SHARED.theme.colDialD)
|
||||||
self.colDialS = QColor(*SHARED.theme.colDialS)
|
self._colDialS = QColor(*SHARED.theme.colDialS)
|
||||||
self.colHidden = QColor(*SHARED.theme.colHidden)
|
self._colHidden = QColor(*SHARED.theme.colHidden)
|
||||||
self.colKey = QColor(*SHARED.theme.colKey)
|
self._colKey = QColor(*SHARED.theme.colKey)
|
||||||
self.colVal = QColor(*SHARED.theme.colVal)
|
self._colVal = QColor(*SHARED.theme.colVal)
|
||||||
self.colSpell = QColor(*SHARED.theme.colSpell)
|
self._colSpell = QColor(*SHARED.theme.colSpell)
|
||||||
self.colError = QColor(*SHARED.theme.colError)
|
self._colError = QColor(*SHARED.theme.colError)
|
||||||
self.colRepTag = QColor(*SHARED.theme.colRepTag)
|
self._colRepTag = QColor(*SHARED.theme.colRepTag)
|
||||||
self.colMod = QColor(*SHARED.theme.colMod)
|
self._colMod = QColor(*SHARED.theme.colMod)
|
||||||
self.colBreak = QColor(*SHARED.theme.colEmph)
|
self._colBreak = QColor(*SHARED.theme.colEmph)
|
||||||
self.colBreak.setAlpha(64)
|
self._colBreak.setAlpha(64)
|
||||||
|
|
||||||
self.colEmph = None
|
self._colEmph = None
|
||||||
if CONFIG.highlightEmph:
|
if CONFIG.highlightEmph:
|
||||||
self.colEmph = QColor(*SHARED.theme.colEmph)
|
self._colEmph = QColor(*SHARED.theme.colEmph)
|
||||||
|
|
||||||
self.hStyles = {
|
self._hStyles = {
|
||||||
"header1": self._makeFormat(self.colHead, "bold", 1.8),
|
"header1": self._makeFormat(self._colHead, "bold", 1.8),
|
||||||
"header2": self._makeFormat(self.colHead, "bold", 1.6),
|
"header2": self._makeFormat(self._colHead, "bold", 1.6),
|
||||||
"header3": self._makeFormat(self.colHead, "bold", 1.4),
|
"header3": self._makeFormat(self._colHead, "bold", 1.4),
|
||||||
"header4": self._makeFormat(self.colHead, "bold", 1.2),
|
"header4": self._makeFormat(self._colHead, "bold", 1.2),
|
||||||
"header1h": self._makeFormat(self.colHeadH, "bold", 1.8),
|
"header1h": self._makeFormat(self._colHeadH, "bold", 1.8),
|
||||||
"header2h": self._makeFormat(self.colHeadH, "bold", 1.6),
|
"header2h": self._makeFormat(self._colHeadH, "bold", 1.6),
|
||||||
"header3h": self._makeFormat(self.colHeadH, "bold", 1.4),
|
"header3h": self._makeFormat(self._colHeadH, "bold", 1.4),
|
||||||
"header4h": self._makeFormat(self.colHeadH, "bold", 1.2),
|
"header4h": self._makeFormat(self._colHeadH, "bold", 1.2),
|
||||||
"bold": self._makeFormat(self.colEmph, "bold"),
|
"bold": self._makeFormat(self._colEmph, "bold"),
|
||||||
"italic": self._makeFormat(self.colEmph, "italic"),
|
"italic": self._makeFormat(self._colEmph, "italic"),
|
||||||
"strike": self._makeFormat(self.colHidden, "strike"),
|
"strike": self._makeFormat(self._colHidden, "strike"),
|
||||||
"mspaces": self._makeFormat(self.colError, "errline"),
|
"mspaces": self._makeFormat(self._colError, "errline"),
|
||||||
"nobreak": self._makeFormat(self.colBreak, "background"),
|
"nobreak": self._makeFormat(self._colBreak, "background"),
|
||||||
"dialogue1": self._makeFormat(self.colDialN),
|
"dialogue1": self._makeFormat(self._colDialN),
|
||||||
"dialogue2": self._makeFormat(self.colDialD),
|
"dialogue2": self._makeFormat(self._colDialD),
|
||||||
"dialogue3": self._makeFormat(self.colDialS),
|
"dialogue3": self._makeFormat(self._colDialS),
|
||||||
"replace": self._makeFormat(self.colRepTag),
|
"replace": self._makeFormat(self._colRepTag),
|
||||||
"hidden": self._makeFormat(self.colHidden),
|
"hidden": self._makeFormat(self._colHidden),
|
||||||
"keyword": self._makeFormat(self.colKey),
|
"keyword": self._makeFormat(self._colKey),
|
||||||
"modifier": self._makeFormat(self.colMod),
|
"modifier": self._makeFormat(self._colMod),
|
||||||
"value": self._makeFormat(self.colVal, "underline"),
|
"value": self._makeFormat(self._colVal, "underline"),
|
||||||
"codevalue": self._makeFormat(self.colVal),
|
"codevalue": self._makeFormat(self._colVal),
|
||||||
"codeinval": self._makeFormat(None, "errline"),
|
"codeinval": self._makeFormat(None, "errline"),
|
||||||
}
|
}
|
||||||
|
|
||||||
self.hRules = []
|
self._hRules = []
|
||||||
|
|
||||||
# Multiple or Trailing Spaces
|
# Multiple or Trailing Spaces
|
||||||
if CONFIG.showMultiSpaces:
|
if CONFIG.showMultiSpaces:
|
||||||
self.hRules.append((
|
self._hRules.append((
|
||||||
r"[ ]{2,}|[ ]*$", {
|
r"[ ]{2,}|[ ]*$", {
|
||||||
0: self.hStyles["mspaces"],
|
0: self._hStyles["mspaces"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|
||||||
# Non-Breaking Spaces
|
# Non-Breaking Spaces
|
||||||
self.hRules.append((
|
self._hRules.append((
|
||||||
"[%s%s]+" % (nwUnicode.U_NBSP, nwUnicode.U_THNBSP), {
|
f"[{nwUnicode.U_NBSP}{nwUnicode.U_THNBSP}]+", {
|
||||||
0: self.hStyles["nobreak"],
|
0: self._hStyles["nobreak"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|
||||||
@@ -153,68 +161,68 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
|
|
||||||
# Straight Quotes
|
# Straight Quotes
|
||||||
if not (fmtDblO == fmtDblC == "\""):
|
if not (fmtDblO == fmtDblC == "\""):
|
||||||
self.hRules.append((
|
self._hRules.append((
|
||||||
"(\\B\")(.*?)(\"\\B)", {
|
"(\\B\")(.*?)(\"\\B)", {
|
||||||
0: self.hStyles["dialogue1"],
|
0: self._hStyles["dialogue1"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|
||||||
# Double Quotes
|
# Double Quotes
|
||||||
dblEnd = "|$" if CONFIG.allowOpenDQuote else ""
|
dblEnd = "|$" if CONFIG.allowOpenDQuote else ""
|
||||||
self.hRules.append((
|
self._hRules.append((
|
||||||
f"(\\B{fmtDblO})(.*?)({fmtDblC}\\B{dblEnd})", {
|
f"(\\B{fmtDblO})(.*?)({fmtDblC}\\B{dblEnd})", {
|
||||||
0: self.hStyles["dialogue2"],
|
0: self._hStyles["dialogue2"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|
||||||
# Single Quotes
|
# Single Quotes
|
||||||
sngEnd = "|$" if CONFIG.allowOpenSQuote else ""
|
sngEnd = "|$" if CONFIG.allowOpenSQuote else ""
|
||||||
self.hRules.append((
|
self._hRules.append((
|
||||||
f"(\\B{fmtSngO})(.*?)({fmtSngC}\\B{sngEnd})", {
|
f"(\\B{fmtSngO})(.*?)({fmtSngC}\\B{sngEnd})", {
|
||||||
0: self.hStyles["dialogue3"],
|
0: self._hStyles["dialogue3"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|
||||||
# Markdown Syntax
|
# Markdown Syntax
|
||||||
self.hRules.append((
|
self._hRules.append((
|
||||||
nwRegEx.FMT_EI, {
|
nwRegEx.FMT_EI, {
|
||||||
1: self.hStyles["hidden"],
|
1: self._hStyles["hidden"],
|
||||||
2: self.hStyles["italic"],
|
2: self._hStyles["italic"],
|
||||||
3: self.hStyles["hidden"],
|
3: self._hStyles["hidden"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
self.hRules.append((
|
self._hRules.append((
|
||||||
nwRegEx.FMT_EB, {
|
nwRegEx.FMT_EB, {
|
||||||
1: self.hStyles["hidden"],
|
1: self._hStyles["hidden"],
|
||||||
2: self.hStyles["bold"],
|
2: self._hStyles["bold"],
|
||||||
3: self.hStyles["hidden"],
|
3: self._hStyles["hidden"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
self.hRules.append((
|
self._hRules.append((
|
||||||
nwRegEx.FMT_ST, {
|
nwRegEx.FMT_ST, {
|
||||||
1: self.hStyles["hidden"],
|
1: self._hStyles["hidden"],
|
||||||
2: self.hStyles["strike"],
|
2: self._hStyles["strike"],
|
||||||
3: self.hStyles["hidden"],
|
3: self._hStyles["hidden"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|
||||||
# Alignment Tags
|
# Alignment Tags
|
||||||
self.hRules.append((
|
self._hRules.append((
|
||||||
r"(^>{1,2}|<{1,2}$)", {
|
r"(^>{1,2}|<{1,2}$)", {
|
||||||
1: self.hStyles["hidden"],
|
1: self._hStyles["hidden"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|
||||||
# Auto-Replace Tags
|
# Auto-Replace Tags
|
||||||
self.hRules.append((
|
self._hRules.append((
|
||||||
r"<(\S+?)>", {
|
r"<(\S+?)>", {
|
||||||
0: self.hStyles["replace"],
|
0: self._hStyles["replace"],
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
|
|
||||||
# Build a QRegExp for each highlight pattern
|
# Build a QRegExp for each highlight pattern
|
||||||
self.rxRules = []
|
self.rxRules = []
|
||||||
for regEx, regRules in self.hRules:
|
for regEx, regRules in self._hRules:
|
||||||
hReg = QRegularExpression(regEx)
|
hReg = QRegularExpression(regEx)
|
||||||
hReg.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
|
hReg.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
|
||||||
self.rxRules.append((hReg, regRules))
|
self.rxRules.append((hReg, regRules))
|
||||||
@@ -223,68 +231,65 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
# Include additional characters that the highlighter should
|
# Include additional characters that the highlighter should
|
||||||
# consider to be word separators
|
# consider to be word separators
|
||||||
uCode = nwUnicode.U_ENDASH + nwUnicode.U_EMDASH
|
uCode = nwUnicode.U_ENDASH + nwUnicode.U_EMDASH
|
||||||
self.spellRx = QRegularExpression(r"\b[^\s\-\+\/" + uCode + r"]+\b")
|
self._spellRx = QRegularExpression(r"\b[^\s\-\+\/" + uCode + r"]+\b")
|
||||||
self.spellRx.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
|
self._spellRx.setPatternOptions(QRegularExpression.UseUnicodePropertiesOption)
|
||||||
|
|
||||||
return True
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
# Setters
|
# Setters
|
||||||
##
|
##
|
||||||
|
|
||||||
def setSpellCheck(self, theMode):
|
def setSpellCheck(self, state: bool) -> None:
|
||||||
"""Enable/disable the real time spell checker.
|
"""Enable/disable the real time spell checker."""
|
||||||
"""
|
self._spellCheck = state
|
||||||
self.spellCheck = theMode
|
return
|
||||||
return True
|
|
||||||
|
|
||||||
def setHandle(self, theHandle):
|
def setHandle(self, tHandle: str) -> None:
|
||||||
"""Set the handle of the currently highlighted document. This is
|
"""Set the handle of the currently highlighted document."""
|
||||||
needed for the index lookup for validating tags and references.
|
self._tHandle = tHandle
|
||||||
"""
|
return
|
||||||
self.theHandle = theHandle
|
|
||||||
return True
|
|
||||||
|
|
||||||
##
|
##
|
||||||
# Methods
|
# Methods
|
||||||
##
|
##
|
||||||
|
|
||||||
def rehighlightByType(self, theType):
|
def rehighlightByType(self, cType: int) -> None:
|
||||||
"""Loop through all blocks and re-highlight those of a given
|
"""Loop through all blocks and re-highlight those of a given
|
||||||
content type.
|
content type.
|
||||||
"""
|
"""
|
||||||
qDoc = self.document()
|
qDoc = self.document()
|
||||||
nBlocks = qDoc.blockCount()
|
nBlocks = qDoc.blockCount()
|
||||||
bfTime = time()
|
tStart = time()
|
||||||
for i in range(nBlocks):
|
for i in range(nBlocks):
|
||||||
theBlock = qDoc.findBlockByNumber(i)
|
theBlock = qDoc.findBlockByNumber(i)
|
||||||
if theBlock.userState() & theType > 0:
|
if theBlock.userState() & cType > 0:
|
||||||
self.rehighlightBlock(theBlock)
|
self.rehighlightBlock(theBlock)
|
||||||
afTime = time()
|
logger.debug("Document highlighted in %.3f ms" % (1000*(time() - tStart)))
|
||||||
logger.debug(
|
|
||||||
"Document highlighted in %.3f ms" % (1000*(afTime-bfTime))
|
|
||||||
)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
##
|
##
|
||||||
# Highlight Block
|
# Highlight Block
|
||||||
##
|
##
|
||||||
|
|
||||||
def highlightBlock(self, theText):
|
def highlightBlock(self, text: str) -> None:
|
||||||
"""Highlight a single block. Prefer to check first character for
|
"""Highlight a single block. Prefer to check first character for
|
||||||
all formats that are defined by their initial characters. This
|
all formats that are defined by their initial characters. This
|
||||||
is significantly faster than running the regex checks used for
|
is significantly faster than running the regex checks used for
|
||||||
text paragraphs.
|
text paragraphs.
|
||||||
"""
|
"""
|
||||||
self.setCurrentBlockState(self.BLOCK_NONE)
|
self.setCurrentBlockState(self.BLOCK_NONE)
|
||||||
if self.theHandle is None or not theText:
|
if self._tHandle is None or not text:
|
||||||
return
|
return
|
||||||
|
|
||||||
if theText.startswith("@"): # Keywords and commands
|
if text.startswith("@"): # Keywords and commands
|
||||||
self.setCurrentBlockState(self.BLOCK_META)
|
self.setCurrentBlockState(self.BLOCK_META)
|
||||||
pIndex = SHARED.project.index
|
pIndex = SHARED.project.index
|
||||||
tItem = SHARED.project.tree[self.theHandle]
|
tItem = SHARED.project.tree[self._tHandle]
|
||||||
isValid, theBits, thePos = pIndex.scanThis(theText)
|
if tItem is None:
|
||||||
|
return
|
||||||
|
|
||||||
|
isValid, theBits, thePos = pIndex.scanThis(text)
|
||||||
isGood = pIndex.checkThese(theBits, tItem)
|
isGood = pIndex.checkThese(theBits, tItem)
|
||||||
if isValid:
|
if isValid:
|
||||||
for n, theBit in enumerate(theBits):
|
for n, theBit in enumerate(theBits):
|
||||||
@@ -292,12 +297,12 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
xLen = len(theBit)
|
xLen = len(theBit)
|
||||||
if isGood[n]:
|
if isGood[n]:
|
||||||
if n == 0:
|
if n == 0:
|
||||||
self.setFormat(xPos, xLen, self.hStyles["keyword"])
|
self.setFormat(xPos, xLen, self._hStyles["keyword"])
|
||||||
else:
|
else:
|
||||||
self.setFormat(xPos, xLen, self.hStyles["value"])
|
self.setFormat(xPos, xLen, self._hStyles["value"])
|
||||||
else:
|
else:
|
||||||
kwFmt = self.format(xPos)
|
kwFmt = self.format(xPos)
|
||||||
kwFmt.setUnderlineColor(self.colError)
|
kwFmt.setUnderlineColor(self._colError)
|
||||||
kwFmt.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
|
kwFmt.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
|
||||||
self.setFormat(xPos, xLen, kwFmt)
|
self.setFormat(xPos, xLen, kwFmt)
|
||||||
|
|
||||||
@@ -305,69 +310,67 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
# so we force a return here
|
# so we force a return here
|
||||||
return
|
return
|
||||||
|
|
||||||
elif theText.startswith(("# ", "#! ", "## ", "##! ", "### ", "#### ")):
|
elif text.startswith(("# ", "#! ", "## ", "##! ", "### ", "#### ")):
|
||||||
self.setCurrentBlockState(self.BLOCK_TITLE)
|
self.setCurrentBlockState(self.BLOCK_TITLE)
|
||||||
|
|
||||||
if theText.startswith("# "): # Header 1
|
if text.startswith("# "): # Header 1
|
||||||
self.setFormat(0, 1, self.hStyles["header1h"])
|
self.setFormat(0, 1, self._hStyles["header1h"])
|
||||||
self.setFormat(1, len(theText), self.hStyles["header1"])
|
self.setFormat(1, len(text), self._hStyles["header1"])
|
||||||
|
|
||||||
elif theText.startswith("## "): # Header 2
|
elif text.startswith("## "): # Header 2
|
||||||
self.setFormat(0, 2, self.hStyles["header2h"])
|
self.setFormat(0, 2, self._hStyles["header2h"])
|
||||||
self.setFormat(2, len(theText), self.hStyles["header2"])
|
self.setFormat(2, len(text), self._hStyles["header2"])
|
||||||
|
|
||||||
elif theText.startswith("### "): # Header 3
|
elif text.startswith("### "): # Header 3
|
||||||
self.setFormat(0, 3, self.hStyles["header3h"])
|
self.setFormat(0, 3, self._hStyles["header3h"])
|
||||||
self.setFormat(3, len(theText), self.hStyles["header3"])
|
self.setFormat(3, len(text), self._hStyles["header3"])
|
||||||
|
|
||||||
elif theText.startswith("#### "): # Header 4
|
elif text.startswith("#### "): # Header 4
|
||||||
self.setFormat(0, 4, self.hStyles["header4h"])
|
self.setFormat(0, 4, self._hStyles["header4h"])
|
||||||
self.setFormat(4, len(theText), self.hStyles["header4"])
|
self.setFormat(4, len(text), self._hStyles["header4"])
|
||||||
|
|
||||||
if theText.startswith("#! "): # Title
|
if text.startswith("#! "): # Title
|
||||||
self.setFormat(0, 2, self.hStyles["header1h"])
|
self.setFormat(0, 2, self._hStyles["header1h"])
|
||||||
self.setFormat(2, len(theText), self.hStyles["header1"])
|
self.setFormat(2, len(text), self._hStyles["header1"])
|
||||||
|
|
||||||
elif theText.startswith("##! "): # Unnumbered
|
elif text.startswith("##! "): # Unnumbered
|
||||||
self.setFormat(0, 3, self.hStyles["header2h"])
|
self.setFormat(0, 3, self._hStyles["header2h"])
|
||||||
self.setFormat(3, len(theText), self.hStyles["header2"])
|
self.setFormat(3, len(text), self._hStyles["header2"])
|
||||||
|
|
||||||
elif theText.startswith("%"): # Comments
|
elif text.startswith("%"): # Comments
|
||||||
self.setCurrentBlockState(self.BLOCK_TEXT)
|
self.setCurrentBlockState(self.BLOCK_TEXT)
|
||||||
toCheck = theText[1:].lstrip()
|
toCheck = text[1:].lstrip()
|
||||||
synTag = toCheck[:9].lower()
|
synTag = toCheck[:9].lower()
|
||||||
tLen = len(theText)
|
tLen = len(text)
|
||||||
cLen = len(toCheck)
|
cLen = len(toCheck)
|
||||||
cOff = tLen - cLen
|
cOff = tLen - cLen
|
||||||
if synTag == "synopsis:":
|
if synTag == "synopsis:":
|
||||||
self.setFormat(0, cOff+9, self.hStyles["modifier"])
|
self.setFormat(0, cOff+9, self._hStyles["modifier"])
|
||||||
self.setFormat(cOff+9, tLen, self.hStyles["hidden"])
|
self.setFormat(cOff+9, tLen, self._hStyles["hidden"])
|
||||||
else:
|
else:
|
||||||
self.setFormat(0, tLen, self.hStyles["hidden"])
|
self.setFormat(0, tLen, self._hStyles["hidden"])
|
||||||
|
|
||||||
else: # Text Paragraph
|
else: # Text Paragraph
|
||||||
|
|
||||||
if theText.startswith("["): # Special Command
|
if text.startswith("["): # Special Command
|
||||||
sText = theText.rstrip()
|
sText = text.rstrip()
|
||||||
if sText in ("[NEWPAGE]", "[NEW PAGE]", "[VSPACE]"):
|
if sText in ("[NEWPAGE]", "[NEW PAGE]", "[VSPACE]"):
|
||||||
self.setFormat(0, len(theText), self.hStyles["keyword"])
|
self.setFormat(0, len(text), self._hStyles["keyword"])
|
||||||
return
|
return
|
||||||
|
|
||||||
elif sText.startswith("[VSPACE:") and sText.endswith("]"):
|
elif sText.startswith("[VSPACE:") and sText.endswith("]"):
|
||||||
tLen = len(sText)
|
tLen = len(sText)
|
||||||
tVal = checkInt(sText[8:-1], 0)
|
tVal = checkInt(sText[8:-1], 0)
|
||||||
self.setFormat(0, 8, self.hStyles["keyword"])
|
cVal = "codevalue" if tVal > 0 else "codeinval"
|
||||||
if tVal > 0:
|
self.setFormat(0, 8, self._hStyles["keyword"])
|
||||||
self.setFormat(8, tLen-9, self.hStyles["codevalue"])
|
self.setFormat(8, tLen-9, self._hStyles[cVal])
|
||||||
else:
|
self.setFormat(tLen-1, tLen, self._hStyles["keyword"])
|
||||||
self.setFormat(8, tLen-9, self.hStyles["codeinval"])
|
|
||||||
self.setFormat(tLen-1, tLen, self.hStyles["keyword"])
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# Regular text
|
# Regular text
|
||||||
self.setCurrentBlockState(self.BLOCK_TEXT)
|
self.setCurrentBlockState(self.BLOCK_TEXT)
|
||||||
for rX, xFmt in self.rxRules:
|
for rX, xFmt in self.rxRules:
|
||||||
rxItt = rX.globalMatch(theText, 0)
|
rxItt = rX.globalMatch(text, 0)
|
||||||
while rxItt.hasNext():
|
while rxItt.hasNext():
|
||||||
rxMatch = rxItt.next()
|
rxMatch = rxItt.next()
|
||||||
for xM in xFmt:
|
for xM in xFmt:
|
||||||
@@ -375,14 +378,14 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
xLen = rxMatch.capturedLength(xM)
|
xLen = rxMatch.capturedLength(xM)
|
||||||
for x in range(xPos, xPos+xLen):
|
for x in range(xPos, xPos+xLen):
|
||||||
spFmt = self.format(x)
|
spFmt = self.format(x)
|
||||||
if spFmt != self.hStyles["hidden"]:
|
if spFmt != self._hStyles["hidden"]:
|
||||||
spFmt.merge(xFmt[xM])
|
spFmt.merge(xFmt[xM])
|
||||||
self.setFormat(x, 1, spFmt)
|
self.setFormat(x, 1, spFmt)
|
||||||
|
|
||||||
if not self.spellCheck:
|
if not self._spellCheck:
|
||||||
return
|
return
|
||||||
|
|
||||||
rxSpell = self.spellRx.globalMatch(theText.replace("_", " "), 0)
|
rxSpell = self._spellRx.globalMatch(text.replace("_", " "), 0)
|
||||||
while rxSpell.hasNext():
|
while rxSpell.hasNext():
|
||||||
rxMatch = rxSpell.next()
|
rxMatch = rxSpell.next()
|
||||||
if not SHARED.spelling.checkWord(rxMatch.captured(0)):
|
if not SHARED.spelling.checkWord(rxMatch.captured(0)):
|
||||||
@@ -392,7 +395,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
xLen = rxMatch.capturedLength(0)
|
xLen = rxMatch.capturedLength(0)
|
||||||
for x in range(xPos, xPos+xLen):
|
for x in range(xPos, xPos+xLen):
|
||||||
spFmt = self.format(x)
|
spFmt = self.format(x)
|
||||||
spFmt.setUnderlineColor(self.colSpell)
|
spFmt.setUnderlineColor(self._colSpell)
|
||||||
spFmt.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
|
spFmt.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
|
||||||
self.setFormat(x, 1, spFmt)
|
self.setFormat(x, 1, spFmt)
|
||||||
|
|
||||||
@@ -402,33 +405,35 @@ class GuiDocHighlighter(QSyntaxHighlighter):
|
|||||||
# Internal Functions
|
# Internal Functions
|
||||||
##
|
##
|
||||||
|
|
||||||
def _makeFormat(self, fmtCol=None, fmtStyle=None, fmtSize=None):
|
def _makeFormat(self, color: QColor | None = None, style: str | None = None,
|
||||||
|
size: float | None = None) -> QTextCharFormat:
|
||||||
"""Generate a valid character format to be applied to the text
|
"""Generate a valid character format to be applied to the text
|
||||||
that is to be highlighted.
|
that is to be highlighted.
|
||||||
"""
|
"""
|
||||||
theFormat = QTextCharFormat()
|
charFormat = QTextCharFormat()
|
||||||
|
|
||||||
if fmtCol is not None:
|
if color is not None:
|
||||||
theFormat.setForeground(fmtCol)
|
charFormat.setForeground(color)
|
||||||
|
|
||||||
if fmtStyle is not None:
|
if style is not None:
|
||||||
if "bold" in fmtStyle:
|
styles = style.split(",")
|
||||||
theFormat.setFontWeight(QFont.Bold)
|
if "bold" in styles:
|
||||||
if "italic" in fmtStyle:
|
charFormat.setFontWeight(QFont.Bold)
|
||||||
theFormat.setFontItalic(True)
|
if "italic" in styles:
|
||||||
if "strike" in fmtStyle:
|
charFormat.setFontItalic(True)
|
||||||
theFormat.setFontStrikeOut(True)
|
if "strike" in styles:
|
||||||
if "errline" in fmtStyle:
|
charFormat.setFontStrikeOut(True)
|
||||||
theFormat.setUnderlineColor(self.colError)
|
if "errline" in styles:
|
||||||
theFormat.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
|
charFormat.setUnderlineColor(self._colError)
|
||||||
if "underline" in fmtStyle:
|
charFormat.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
|
||||||
theFormat.setFontUnderline(True)
|
if "underline" in styles:
|
||||||
if "background" in fmtStyle:
|
charFormat.setFontUnderline(True)
|
||||||
theFormat.setBackground(QBrush(fmtCol, Qt.SolidPattern))
|
if "background" in styles and color is not None:
|
||||||
|
charFormat.setBackground(QBrush(color, Qt.SolidPattern))
|
||||||
|
|
||||||
if fmtSize is not None:
|
if size is not None:
|
||||||
theFormat.setFontPointSize(int(round(fmtSize*CONFIG.textSize)))
|
charFormat.setFontPointSize(int(round(size*CONFIG.textSize)))
|
||||||
|
|
||||||
return theFormat
|
return charFormat
|
||||||
|
|
||||||
# END Class DocHighlighter
|
# END Class DocHighlighter
|
||||||
|
|||||||
Reference in New Issue
Block a user