Tokenize dialogue with colour tag
This commit is contained in:
@@ -160,6 +160,7 @@ class NWBuildDocument:
|
||||
elif bFormat in (nwBuildFmt.HTML, nwBuildFmt.J_HTML):
|
||||
makeObj = ToHtml(self._project)
|
||||
filtered = self._setupBuild(makeObj)
|
||||
makeObj.initDocument()
|
||||
|
||||
yield from self._iterBuild(makeObj, filtered)
|
||||
|
||||
|
||||
@@ -86,12 +86,8 @@ class TextFmt(IntEnum):
|
||||
SUB_E = 14 # End subscript
|
||||
COL_B = 15 # Begin colour
|
||||
COL_E = 16 # End colour
|
||||
DL_B = 17 # Begin dialogue
|
||||
DL_E = 18 # End dialogue
|
||||
ADL_B = 19 # Begin alt dialogue
|
||||
ADL_E = 20 # End alt dialogue
|
||||
FNOTE = 21 # Footnote marker
|
||||
STRIP = 22 # Strip the format code
|
||||
FNOTE = 17 # Footnote marker
|
||||
STRIP = 18 # Strip the format code
|
||||
|
||||
|
||||
class BlockTyp(IntEnum):
|
||||
|
||||
@@ -96,8 +96,6 @@ X_MRK = 0x010 # Marked format
|
||||
X_SUP = 0x020 # Superscript
|
||||
X_SUB = 0x040 # Subscript
|
||||
X_COL = 0x080 # Coloured text
|
||||
X_DLG = 0x100 # Dialogue
|
||||
X_DLA = 0x200 # Alt. Dialogue
|
||||
|
||||
# Formatting Masks
|
||||
M_BLD = ~X_BLD
|
||||
@@ -108,8 +106,6 @@ M_MRK = ~X_MRK
|
||||
M_SUP = ~X_SUP
|
||||
M_SUB = ~X_SUB
|
||||
M_COL = ~X_COL
|
||||
M_DLG = ~X_DLG
|
||||
M_DLA = ~X_DLA
|
||||
|
||||
# DocX Styles
|
||||
S_NORM = "Normal"
|
||||
@@ -292,7 +288,7 @@ class ToDocX(Tokenizer):
|
||||
elif tType == BlockTyp.SKIP:
|
||||
self._processFragments(par, S_NORM, "")
|
||||
|
||||
elif tType in self.L_NOTES:
|
||||
elif tType == BlockTyp.COMMENT:
|
||||
self._processFragments(par, S_META, tText, tFormat)
|
||||
|
||||
elif tType == BlockTyp.KEYWORD and self._doKeywords:
|
||||
@@ -441,14 +437,6 @@ class ToDocX(Tokenizer):
|
||||
elif fFmt == TextFmt.COL_E:
|
||||
xFmt &= M_COL
|
||||
fClass = ""
|
||||
elif fFmt == TextFmt.DL_B:
|
||||
xFmt |= X_DLG
|
||||
elif fFmt == TextFmt.DL_E:
|
||||
xFmt &= M_DLG
|
||||
elif fFmt == TextFmt.ADL_B:
|
||||
xFmt |= X_DLA
|
||||
elif fFmt == TextFmt.ADL_E:
|
||||
xFmt &= M_DLA
|
||||
elif fFmt == TextFmt.FNOTE:
|
||||
xNode = self._generateFootnote(fData)
|
||||
elif fFmt == TextFmt.STRIP:
|
||||
@@ -487,10 +475,6 @@ class ToDocX(Tokenizer):
|
||||
xmlSubElem(rPr, _wTag("vertAlign"), attrib={_wTag("val"): "subscript"})
|
||||
if fmt & X_COL and (color := self._classes.get(fClass)):
|
||||
xmlSubElem(rPr, _wTag("color"), attrib={_wTag("val"): _docXCol(color)})
|
||||
if fmt & X_DLG:
|
||||
xmlSubElem(rPr, _wTag("color"), attrib={_wTag("val"): COL_DIALOG_M})
|
||||
if fmt & X_DLA:
|
||||
xmlSubElem(rPr, _wTag("color"), attrib={_wTag("val"): COL_DIALOG_A})
|
||||
|
||||
for segment in RX_TEXT.split(text):
|
||||
if segment == "\n":
|
||||
|
||||
@@ -47,8 +47,7 @@ HTML_OPENER: dict[int, tuple[int, str]] = {
|
||||
TextFmt.M_B: (TextFmt.M_E, "<mark>"),
|
||||
TextFmt.SUP_B: (TextFmt.SUP_E, "<sup>"),
|
||||
TextFmt.SUB_B: (TextFmt.SUB_E, "<sub>"),
|
||||
TextFmt.DL_B: (TextFmt.DL_E, "<span class='dialog'>"),
|
||||
TextFmt.ADL_B: (TextFmt.ADL_E, "<span class='altdialog'>"),
|
||||
TextFmt.COL_B: (TextFmt.COL_E, "<span style='color: {0}'>"),
|
||||
}
|
||||
|
||||
# Each closer tag, with the id of its corresponding opener and tag format
|
||||
@@ -60,8 +59,7 @@ HTML_CLOSER: dict[int, tuple[int, str]] = {
|
||||
TextFmt.M_E: (TextFmt.M_B, "</mark>"),
|
||||
TextFmt.SUP_E: (TextFmt.SUP_B, "</sup>"),
|
||||
TextFmt.SUB_E: (TextFmt.SUB_B, "</sub>"),
|
||||
TextFmt.DL_E: (TextFmt.DL_B, "</span>"),
|
||||
TextFmt.ADL_E: (TextFmt.ADL_B, "</span>"),
|
||||
TextFmt.COL_E: (TextFmt.COL_B, "</span>"),
|
||||
}
|
||||
|
||||
# Empty HTML tag record
|
||||
@@ -251,10 +249,7 @@ class ToHtml(Tokenizer):
|
||||
elif tType == BlockTyp.SKIP:
|
||||
lines.append(f"<p class='skip'{hStyle}> </p>\n")
|
||||
|
||||
elif tType == BlockTyp.SUMMARY:
|
||||
lines.append(f"<p class='synopsis'>{self._formatText(tText, tFormat)}</p>\n")
|
||||
|
||||
elif tType == BlockTyp.COMMENT and self._doComments:
|
||||
elif tType == BlockTyp.COMMENT:
|
||||
lines.append(f"<p class='comment'>{self._formatText(tText, tFormat)}</p>\n")
|
||||
|
||||
elif tType == BlockTyp.KEYWORD and self._doKeywords:
|
||||
@@ -439,11 +434,6 @@ class ToHtml(Tokenizer):
|
||||
styles.append("a {color: rgb(66, 113, 174);}")
|
||||
styles.append("mark {background: rgb(255, 255, 166);}")
|
||||
styles.append(".keyword {color: rgb(245, 135, 31); font-weight: bold;}")
|
||||
styles.append(".break {text-align: left;}")
|
||||
styles.append(".synopsis {font-style: italic;}")
|
||||
styles.append(".comment {font-style: italic; color: rgb(100, 100, 100);}")
|
||||
styles.append(".dialog {color: rgb(66, 113, 174);}")
|
||||
styles.append(".altdialog {color: rgb(129, 55, 9);}")
|
||||
|
||||
return styles
|
||||
|
||||
@@ -463,7 +453,10 @@ class ToHtml(Tokenizer):
|
||||
for pos, fmt, data in tFmt:
|
||||
if m := HTML_OPENER.get(fmt):
|
||||
if not state.get(fmt, True):
|
||||
tags.append((pos, m[1]))
|
||||
if fmt == TextFmt.COL_B and (color := self._classes.get(data)):
|
||||
tags.append((pos, m[1].format(color.name(QtHexRgb))))
|
||||
else:
|
||||
tags.append((pos, m[1]))
|
||||
state[fmt] = True
|
||||
elif m := HTML_CLOSER.get(fmt):
|
||||
if state.get(m[0], False):
|
||||
|
||||
@@ -58,18 +58,17 @@ class ComStyle(NamedTuple):
|
||||
label: str = ""
|
||||
labelClass: str = ""
|
||||
textClass: str = ""
|
||||
blockType: BlockTyp = BlockTyp.TEXT
|
||||
|
||||
|
||||
COMMENT_STYLE = {
|
||||
nwComment.PLAIN: ComStyle("Comment", "comment", "comment", BlockTyp.COMMENT),
|
||||
nwComment.PLAIN: ComStyle("Comment", "comment", "comment"),
|
||||
nwComment.IGNORE: ComStyle(),
|
||||
nwComment.SYNOPSIS: ComStyle("Synopsis", "modifier", "synopsis", BlockTyp.SUMMARY),
|
||||
nwComment.SHORT: ComStyle("Short Description", "modifier", "synopsis", BlockTyp.SUMMARY),
|
||||
nwComment.NOTE: ComStyle("Note", "modifier", "note", BlockTyp.NOTE),
|
||||
nwComment.SYNOPSIS: ComStyle("Synopsis", "modifier", "synopsis"),
|
||||
nwComment.SHORT: ComStyle("Short Description", "modifier", "synopsis"),
|
||||
nwComment.NOTE: ComStyle("Note", "modifier", "note"),
|
||||
nwComment.FOOTNOTE: ComStyle("", "modifier", "note"),
|
||||
nwComment.COMMENT: ComStyle(),
|
||||
nwComment.STORY: ComStyle("", "modifier", "note", BlockTyp.NOTE),
|
||||
nwComment.STORY: ComStyle("", "modifier", "note"),
|
||||
}
|
||||
|
||||
|
||||
@@ -93,7 +92,6 @@ class Tokenizer(ABC):
|
||||
BlockTyp.TITLE, BlockTyp.HEAD1, BlockTyp.HEAD2, BlockTyp.HEAD2, BlockTyp.HEAD3,
|
||||
BlockTyp.HEAD4, BlockTyp.SEP, BlockTyp.SKIP,
|
||||
]
|
||||
L_NOTES = [BlockTyp.SUMMARY, BlockTyp.NOTE, BlockTyp.COMMENT]
|
||||
|
||||
def __init__(self, project: NWProject) -> None:
|
||||
|
||||
@@ -208,7 +206,7 @@ class Tokenizer(ABC):
|
||||
nwShortcode.FOOTNOTE_B: TextFmt.FNOTE,
|
||||
}
|
||||
|
||||
self._rxDialogue: list[tuple[re.Pattern, int, int]] = []
|
||||
self._rxDialogue: list[tuple[re.Pattern, tuple[int, str], tuple[int, str]]] = []
|
||||
|
||||
return
|
||||
|
||||
@@ -352,19 +350,23 @@ class Tokenizer(ABC):
|
||||
if state:
|
||||
if CONFIG.dialogStyle > 0:
|
||||
self._rxDialogue.append((
|
||||
REGEX_PATTERNS.dialogStyle, TextFmt.DL_B, TextFmt.DL_E
|
||||
REGEX_PATTERNS.dialogStyle,
|
||||
(TextFmt.COL_B, "dialog"), (TextFmt.COL_E, ""),
|
||||
))
|
||||
if CONFIG.dialogLine:
|
||||
self._rxDialogue.append((
|
||||
REGEX_PATTERNS.dialogLine, TextFmt.DL_B, TextFmt.DL_E
|
||||
REGEX_PATTERNS.dialogLine,
|
||||
(TextFmt.COL_B, "dialog"), (TextFmt.COL_E, ""),
|
||||
))
|
||||
if CONFIG.narratorBreak:
|
||||
self._rxDialogue.append((
|
||||
REGEX_PATTERNS.narratorBreak, TextFmt.DL_E, TextFmt.DL_B
|
||||
REGEX_PATTERNS.narratorBreak,
|
||||
(TextFmt.COL_E, ""), (TextFmt.COL_B, "dialog"),
|
||||
))
|
||||
if CONFIG.altDialogOpen and CONFIG.altDialogClose:
|
||||
self._rxDialogue.append((
|
||||
REGEX_PATTERNS.altDialogStyle, TextFmt.ADL_B, TextFmt.ADL_E
|
||||
REGEX_PATTERNS.altDialogStyle,
|
||||
(TextFmt.COL_B, "altdialog"), (TextFmt.COL_E, ""),
|
||||
))
|
||||
return
|
||||
|
||||
@@ -460,6 +462,8 @@ class Tokenizer(ABC):
|
||||
self._classes["modifier"] = self._theme.modifier
|
||||
self._classes["synopsis"] = self._theme.note
|
||||
self._classes["comment"] = self._theme.comment
|
||||
self._classes["dialog"] = self._theme.dialog
|
||||
self._classes["altdialog"] = self._theme.altdialog
|
||||
return
|
||||
|
||||
def addRootHeading(self, tHandle: str) -> None:
|
||||
@@ -610,7 +614,7 @@ class Tokenizer(ABC):
|
||||
if cStyle in (nwComment.SYNOPSIS, nwComment.SHORT, nwComment.PLAIN):
|
||||
bStyle = COMMENT_STYLE[cStyle]
|
||||
tLine, tFmt = self._formatNote(bStyle, cKey, cText)
|
||||
blocks.append((bStyle.blockType, nHead, tLine, tFmt, sAlign))
|
||||
blocks.append((BlockTyp.COMMENT, nHead, tLine, tFmt, sAlign))
|
||||
if self._keepRaw:
|
||||
tmpMarkdown.append(f"{aLine}\n")
|
||||
|
||||
@@ -619,8 +623,6 @@ class Tokenizer(ABC):
|
||||
self._footnotes[f"{tHandle}:{cKey}"] = (tLine, tFmt)
|
||||
if self._keepRaw:
|
||||
tmpMarkdown.append(f"{aLine}\n")
|
||||
else:
|
||||
continue
|
||||
|
||||
elif aLine.startswith("@"):
|
||||
# Keywords
|
||||
@@ -1014,7 +1016,7 @@ class Tokenizer(ABC):
|
||||
allChars += nChars
|
||||
allWordChars += nWChars
|
||||
|
||||
elif tType in self.L_NOTES:
|
||||
elif tType == BlockTyp.COMMENT:
|
||||
words = tText.split()
|
||||
allWords += len(words)
|
||||
allChars += len(tText)
|
||||
@@ -1130,10 +1132,10 @@ class Tokenizer(ABC):
|
||||
|
||||
# Match Dialogue
|
||||
if self._rxDialogue and hDialog:
|
||||
for regEx, fmtB, fmtE in self._rxDialogue:
|
||||
for regEx, (fmtB, clsB), (fmtE, clsE) in self._rxDialogue:
|
||||
for res in regEx.finditer(text):
|
||||
temp.append((res.start(0), 0, fmtB, ""))
|
||||
temp.append((res.end(0), 0, fmtE, ""))
|
||||
temp.append((res.start(0), 0, fmtB, clsB))
|
||||
temp.append((res.end(0), 0, fmtE, clsE))
|
||||
|
||||
# Post-process text and format
|
||||
result = text
|
||||
|
||||
@@ -150,7 +150,7 @@ class ToMarkdown(Tokenizer):
|
||||
elif tType == BlockTyp.SKIP:
|
||||
lines.append(f"{cSkip}\n\n")
|
||||
|
||||
elif tType in self.L_NOTES:
|
||||
elif tType == BlockTyp.COMMENT:
|
||||
lines.append(f"{self._formatText(tText, tFormat, mTags)}\n\n")
|
||||
|
||||
elif tType == BlockTyp.KEYWORD and self._doKeywords:
|
||||
|
||||
@@ -91,8 +91,6 @@ X_MRK = 0x010 # Marked format
|
||||
X_SUP = 0x020 # Superscript
|
||||
X_SUB = 0x040 # Subscript
|
||||
X_COL = 0x080 # Coloured text
|
||||
X_DLG = 0x100 # Dialogue
|
||||
X_DLA = 0x200 # Alt. Dialogue
|
||||
|
||||
# Formatting Masks
|
||||
M_BLD = ~X_BLD
|
||||
@@ -103,8 +101,6 @@ M_MRK = ~X_MRK
|
||||
M_SUP = ~X_SUP
|
||||
M_SUB = ~X_SUB
|
||||
M_COL = ~X_COL
|
||||
M_DLG = ~X_DLG
|
||||
M_DLA = ~X_DLA
|
||||
|
||||
# ODT Styles
|
||||
S_TITLE = "Title"
|
||||
@@ -484,7 +480,7 @@ class ToOdt(Tokenizer):
|
||||
elif tType == BlockTyp.SKIP:
|
||||
self._addTextPar(xText, S_TEXT, oStyle, "")
|
||||
|
||||
elif tType in self.L_NOTES:
|
||||
elif tType == BlockTyp.COMMENT:
|
||||
self._addTextPar(xText, S_META, oStyle, tText, tFmt=tFormat)
|
||||
|
||||
elif tType == BlockTyp.KEYWORD and self._doKeywords:
|
||||
@@ -657,14 +653,6 @@ class ToOdt(Tokenizer):
|
||||
elif fFmt == TextFmt.COL_E:
|
||||
xFmt &= M_COL
|
||||
fClass = ""
|
||||
elif fFmt == TextFmt.DL_B:
|
||||
xFmt |= X_DLG
|
||||
elif fFmt == TextFmt.DL_E:
|
||||
xFmt &= M_DLG
|
||||
elif fFmt == TextFmt.ADL_B:
|
||||
xFmt |= X_DLA
|
||||
elif fFmt == TextFmt.ADL_E:
|
||||
xFmt &= M_DLA
|
||||
elif fFmt == TextFmt.FNOTE:
|
||||
xNode = self._generateFootnote(fData)
|
||||
elif fFmt == TextFmt.STRIP:
|
||||
|
||||
@@ -240,7 +240,7 @@ class ToQTextDocument(Tokenizer):
|
||||
newBlock(cursor, bFmt)
|
||||
cursor.insertText(nwUnicode.U_NBSP, self._cText)
|
||||
|
||||
elif tType in self.L_NOTES:
|
||||
elif tType == BlockTyp.COMMENT:
|
||||
newBlock(cursor, bFmt)
|
||||
self._insertFragments(tText, tFormat, cursor, self._cText)
|
||||
|
||||
@@ -337,23 +337,11 @@ class ToQTextDocument(Tokenizer):
|
||||
cFmt.setVerticalAlignment(QtVAlignSub)
|
||||
elif fmt == TextFmt.SUB_E:
|
||||
cFmt.setVerticalAlignment(QtVAlignNormal)
|
||||
elif fmt == TextFmt.SUB_B:
|
||||
cFmt.setVerticalAlignment(QtVAlignSub)
|
||||
elif fmt == TextFmt.SUB_E:
|
||||
cFmt.setVerticalAlignment(QtVAlignNormal)
|
||||
elif fmt == TextFmt.COL_B:
|
||||
if color := self._classes.get(data):
|
||||
cFmt.setForeground(color)
|
||||
elif fmt == TextFmt.COL_E:
|
||||
cFmt.setForeground(self._theme.text)
|
||||
elif fmt == TextFmt.DL_B:
|
||||
cFmt.setForeground(self._theme.dialog)
|
||||
elif fmt == TextFmt.DL_E:
|
||||
cFmt.setForeground(self._theme.text)
|
||||
elif fmt == TextFmt.ADL_B:
|
||||
cFmt.setForeground(self._theme.altdialog)
|
||||
elif fmt == TextFmt.ADL_E:
|
||||
cFmt.setForeground(self._theme.text)
|
||||
elif fmt == TextFmt.FNOTE:
|
||||
xFmt = QTextCharFormat(self._cCode)
|
||||
xFmt.setVerticalAlignment(QtVAlignSuper)
|
||||
|
||||
Reference in New Issue
Block a user