Convert format codes to enums
This commit is contained in:
@@ -39,7 +39,7 @@ from novelwriter import __version__
|
|||||||
from novelwriter.common import firstFloat, xmlSubElem
|
from novelwriter.common import firstFloat, xmlSubElem
|
||||||
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, nwStyles
|
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, nwStyles
|
||||||
from novelwriter.core.project import NWProject
|
from novelwriter.core.project import NWProject
|
||||||
from novelwriter.formats.tokenizer import T_Formats, Tokenizer
|
from novelwriter.formats.tokenizer import BlockFmt, BlockTyp, T_Formats, TextFmt, Tokenizer
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -227,75 +227,75 @@ class ToDocX(Tokenizer):
|
|||||||
|
|
||||||
# Styles
|
# Styles
|
||||||
if tStyle is not None:
|
if tStyle is not None:
|
||||||
if tStyle & self.A_LEFT:
|
if tStyle & BlockFmt.LEFT:
|
||||||
par.setAlignment("left")
|
par.setAlignment("left")
|
||||||
elif tStyle & self.A_RIGHT:
|
elif tStyle & BlockFmt.RIGHT:
|
||||||
par.setAlignment("right")
|
par.setAlignment("right")
|
||||||
elif tStyle & self.A_CENTRE:
|
elif tStyle & BlockFmt.CENTRE:
|
||||||
par.setAlignment("center")
|
par.setAlignment("center")
|
||||||
elif tStyle & self.A_JUSTIFY:
|
elif tStyle & BlockFmt.JUSTIFY:
|
||||||
par.setAlignment("both")
|
par.setAlignment("both")
|
||||||
|
|
||||||
if tStyle & self.A_PBB:
|
if tStyle & BlockFmt.PBB:
|
||||||
par.setPageBreakBefore(True)
|
par.setPageBreakBefore(True)
|
||||||
if tStyle & self.A_PBA:
|
if tStyle & BlockFmt.PBA:
|
||||||
par.setPageBreakAfter(True)
|
par.setPageBreakAfter(True)
|
||||||
|
|
||||||
if tStyle & self.A_Z_BTMMRG:
|
if tStyle & BlockFmt.Z_BTMMRG:
|
||||||
par.setMarginBottom(0.0)
|
par.setMarginBottom(0.0)
|
||||||
if tStyle & self.A_Z_TOPMRG:
|
if tStyle & BlockFmt.Z_TOPMRG:
|
||||||
par.setMarginTop(0.0)
|
par.setMarginTop(0.0)
|
||||||
|
|
||||||
if tStyle & self.A_IND_T:
|
if tStyle & BlockFmt.IND_T:
|
||||||
par.setIndentFirst(True)
|
par.setIndentFirst(True)
|
||||||
if tStyle & self.A_IND_L:
|
if tStyle & BlockFmt.IND_L:
|
||||||
par.setMarginLeft(bIndent)
|
par.setMarginLeft(bIndent)
|
||||||
if tStyle & self.A_IND_R:
|
if tStyle & BlockFmt.IND_R:
|
||||||
par.setMarginRight(bIndent)
|
par.setMarginRight(bIndent)
|
||||||
|
|
||||||
# Process Text Types
|
# Process Text Types
|
||||||
if tType == self.T_TEXT:
|
if tType == BlockTyp.TEXT:
|
||||||
self._processFragments(par, S_NORM, tText, tFormat)
|
self._processFragments(par, S_NORM, tText, tFormat)
|
||||||
|
|
||||||
elif tType == self.T_TITLE:
|
elif tType == BlockTyp.TITLE:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
self._processFragments(par, S_TITLE, tHead, tFormat)
|
self._processFragments(par, S_TITLE, tHead, tFormat)
|
||||||
|
|
||||||
elif tType == self.T_HEAD1:
|
elif tType == BlockTyp.HEAD1:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
self._processFragments(par, S_HEAD1, tHead, tFormat)
|
self._processFragments(par, S_HEAD1, tHead, tFormat)
|
||||||
|
|
||||||
elif tType == self.T_HEAD2:
|
elif tType == BlockTyp.HEAD2:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
self._processFragments(par, S_HEAD2, tHead, tFormat)
|
self._processFragments(par, S_HEAD2, tHead, tFormat)
|
||||||
|
|
||||||
elif tType == self.T_HEAD3:
|
elif tType == BlockTyp.HEAD3:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
self._processFragments(par, S_HEAD3, tHead, tFormat)
|
self._processFragments(par, S_HEAD3, tHead, tFormat)
|
||||||
|
|
||||||
elif tType == self.T_HEAD4:
|
elif tType == BlockTyp.HEAD4:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
self._processFragments(par, S_HEAD4, tHead, tFormat)
|
self._processFragments(par, S_HEAD4, tHead, tFormat)
|
||||||
|
|
||||||
elif tType == self.T_SEP:
|
elif tType == BlockTyp.SEP:
|
||||||
self._processFragments(par, S_SEP, tText)
|
self._processFragments(par, S_SEP, tText)
|
||||||
|
|
||||||
elif tType == self.T_SKIP:
|
elif tType == BlockTyp.SKIP:
|
||||||
self._processFragments(par, S_NORM, "")
|
self._processFragments(par, S_NORM, "")
|
||||||
|
|
||||||
elif tType == self.T_SYNOPSIS and self._doSynopsis:
|
elif tType == BlockTyp.SYNOPSIS and self._doSynopsis:
|
||||||
tTemp, tFmt = self._formatSynopsis(tText, tFormat, True)
|
tTemp, tFmt = self._formatSynopsis(tText, tFormat, True)
|
||||||
self._processFragments(par, S_META, tTemp, tFmt)
|
self._processFragments(par, S_META, tTemp, tFmt)
|
||||||
|
|
||||||
elif tType == self.T_SHORT and self._doSynopsis:
|
elif tType == BlockTyp.SHORT and self._doSynopsis:
|
||||||
tTemp, tFmt = self._formatSynopsis(tText, tFormat, False)
|
tTemp, tFmt = self._formatSynopsis(tText, tFormat, False)
|
||||||
self._processFragments(par, S_META, tTemp, tFmt)
|
self._processFragments(par, S_META, tTemp, tFmt)
|
||||||
|
|
||||||
elif tType == self.T_COMMENT and self._doComments:
|
elif tType == BlockTyp.COMMENT and self._doComments:
|
||||||
tTemp, tFmt = self._formatComments(tText, tFormat)
|
tTemp, tFmt = self._formatComments(tText, tFormat)
|
||||||
self._processFragments(par, S_META, tTemp, tFmt)
|
self._processFragments(par, S_META, tTemp, tFmt)
|
||||||
|
|
||||||
elif tType == self.T_KEYWORD and self._doKeywords:
|
elif tType == BlockTyp.KEYWORD and self._doKeywords:
|
||||||
tTemp, tFmt = self._formatKeywords(tText)
|
tTemp, tFmt = self._formatKeywords(tText)
|
||||||
self._processFragments(par, S_META, tTemp, tFmt)
|
self._processFragments(par, S_META, tTemp, tFmt)
|
||||||
|
|
||||||
@@ -378,7 +378,7 @@ class ToDocX(Tokenizer):
|
|||||||
name = self._localLookup("Synopsis" if synopsis else "Short Description")
|
name = self._localLookup("Synopsis" if synopsis else "Short Description")
|
||||||
shift = len(name) + 2
|
shift = len(name) + 2
|
||||||
rTxt = f"{name}: {text}"
|
rTxt = f"{name}: {text}"
|
||||||
rFmt: T_Formats = [(0, self.FMT_B_B, ""), (len(name) + 1, self.FMT_B_E, "")]
|
rFmt: T_Formats = [(0, TextFmt.B_B, ""), (len(name) + 1, TextFmt.B_E, "")]
|
||||||
rFmt.extend((p + shift, f, d) for p, f, d in fmt)
|
rFmt.extend((p + shift, f, d) for p, f, d in fmt)
|
||||||
return rTxt, rFmt
|
return rTxt, rFmt
|
||||||
|
|
||||||
@@ -387,7 +387,7 @@ class ToDocX(Tokenizer):
|
|||||||
name = self._localLookup("Comment")
|
name = self._localLookup("Comment")
|
||||||
shift = len(name) + 2
|
shift = len(name) + 2
|
||||||
rTxt = f"{name}: {text}"
|
rTxt = f"{name}: {text}"
|
||||||
rFmt: T_Formats = [(0, self.FMT_B_B, ""), (len(name) + 1, self.FMT_B_E, "")]
|
rFmt: T_Formats = [(0, TextFmt.B_B, ""), (len(name) + 1, TextFmt.B_E, "")]
|
||||||
rFmt.extend((p + shift, f, d) for p, f, d in fmt)
|
rFmt.extend((p + shift, f, d) for p, f, d in fmt)
|
||||||
return rTxt, rFmt
|
return rTxt, rFmt
|
||||||
|
|
||||||
@@ -398,7 +398,7 @@ class ToDocX(Tokenizer):
|
|||||||
return "", []
|
return "", []
|
||||||
|
|
||||||
rTxt = f"{self._localLookup(nwLabels.KEY_NAME[bits[0]])}: "
|
rTxt = f"{self._localLookup(nwLabels.KEY_NAME[bits[0]])}: "
|
||||||
rFmt: T_Formats = [(0, self.FMT_B_B, ""), (len(rTxt) - 1, self.FMT_B_E, "")]
|
rFmt: T_Formats = [(0, TextFmt.B_B, ""), (len(rTxt) - 1, TextFmt.B_E, "")]
|
||||||
if len(bits) > 1:
|
if len(bits) > 1:
|
||||||
if bits[0] == nwKeyWords.TAG_KEY:
|
if bits[0] == nwKeyWords.TAG_KEY:
|
||||||
rTxt += bits[1]
|
rTxt += bits[1]
|
||||||
@@ -424,45 +424,45 @@ class ToDocX(Tokenizer):
|
|||||||
if temp := text[fStart:fPos]:
|
if temp := text[fStart:fPos]:
|
||||||
par.addContent(self._textRunToXml(temp, xFmt))
|
par.addContent(self._textRunToXml(temp, xFmt))
|
||||||
|
|
||||||
if fFmt == self.FMT_B_B:
|
if fFmt == TextFmt.B_B:
|
||||||
xFmt |= X_BLD
|
xFmt |= X_BLD
|
||||||
elif fFmt == self.FMT_B_E:
|
elif fFmt == TextFmt.B_E:
|
||||||
xFmt &= M_BLD
|
xFmt &= M_BLD
|
||||||
elif fFmt == self.FMT_I_B:
|
elif fFmt == TextFmt.I_B:
|
||||||
xFmt |= X_ITA
|
xFmt |= X_ITA
|
||||||
elif fFmt == self.FMT_I_E:
|
elif fFmt == TextFmt.I_E:
|
||||||
xFmt &= M_ITA
|
xFmt &= M_ITA
|
||||||
elif fFmt == self.FMT_D_B:
|
elif fFmt == TextFmt.D_B:
|
||||||
xFmt |= X_DEL
|
xFmt |= X_DEL
|
||||||
elif fFmt == self.FMT_D_E:
|
elif fFmt == TextFmt.D_E:
|
||||||
xFmt &= M_DEL
|
xFmt &= M_DEL
|
||||||
elif fFmt == self.FMT_U_B:
|
elif fFmt == TextFmt.U_B:
|
||||||
xFmt |= X_UND
|
xFmt |= X_UND
|
||||||
elif fFmt == self.FMT_U_E:
|
elif fFmt == TextFmt.U_E:
|
||||||
xFmt &= M_UND
|
xFmt &= M_UND
|
||||||
elif fFmt == self.FMT_M_B:
|
elif fFmt == TextFmt.M_B:
|
||||||
xFmt |= X_MRK
|
xFmt |= X_MRK
|
||||||
elif fFmt == self.FMT_M_E:
|
elif fFmt == TextFmt.M_E:
|
||||||
xFmt &= M_MRK
|
xFmt &= M_MRK
|
||||||
elif fFmt == self.FMT_SUP_B:
|
elif fFmt == TextFmt.SUP_B:
|
||||||
xFmt |= X_SUP
|
xFmt |= X_SUP
|
||||||
elif fFmt == self.FMT_SUP_E:
|
elif fFmt == TextFmt.SUP_E:
|
||||||
xFmt &= M_SUP
|
xFmt &= M_SUP
|
||||||
elif fFmt == self.FMT_SUB_B:
|
elif fFmt == TextFmt.SUB_B:
|
||||||
xFmt |= X_SUB
|
xFmt |= X_SUB
|
||||||
elif fFmt == self.FMT_SUB_E:
|
elif fFmt == TextFmt.SUB_E:
|
||||||
xFmt &= M_SUB
|
xFmt &= M_SUB
|
||||||
elif fFmt == self.FMT_DL_B:
|
elif fFmt == TextFmt.DL_B:
|
||||||
xFmt |= X_DLG
|
xFmt |= X_DLG
|
||||||
elif fFmt == self.FMT_DL_E:
|
elif fFmt == TextFmt.DL_E:
|
||||||
xFmt &= M_DLG
|
xFmt &= M_DLG
|
||||||
elif fFmt == self.FMT_ADL_B:
|
elif fFmt == TextFmt.ADL_B:
|
||||||
xFmt |= X_DLA
|
xFmt |= X_DLA
|
||||||
elif fFmt == self.FMT_ADL_E:
|
elif fFmt == TextFmt.ADL_E:
|
||||||
xFmt &= M_DLA
|
xFmt &= M_DLA
|
||||||
elif fFmt == self.FMT_FNOTE:
|
elif fFmt == TextFmt.FNOTE:
|
||||||
xNode = self._generateFootnote(fData)
|
xNode = self._generateFootnote(fData)
|
||||||
elif fFmt == self.FMT_STRIP:
|
elif fFmt == TextFmt.STRIP:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Move pos for next pass
|
# Move pos for next pass
|
||||||
|
|||||||
@@ -32,35 +32,37 @@ from time import time
|
|||||||
from novelwriter.common import formatTimeStamp
|
from novelwriter.common import formatTimeStamp
|
||||||
from novelwriter.constants import nwHeadFmt, nwHtmlUnicode, nwKeyWords, nwLabels
|
from novelwriter.constants import nwHeadFmt, nwHtmlUnicode, nwKeyWords, nwLabels
|
||||||
from novelwriter.core.project import NWProject
|
from novelwriter.core.project import NWProject
|
||||||
from novelwriter.formats.tokenizer import T_Formats, Tokenizer, stripEscape
|
from novelwriter.formats.tokenizer import (
|
||||||
|
BlockFmt, BlockTyp, T_Formats, TextFmt, Tokenizer, stripEscape
|
||||||
|
)
|
||||||
from novelwriter.types import FONT_STYLE, FONT_WEIGHTS
|
from novelwriter.types import FONT_STYLE, FONT_WEIGHTS
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
# Each opener tag, with the id of its corresponding closer and tag format
|
# Each opener tag, with the id of its corresponding closer and tag format
|
||||||
HTML_OPENER: dict[int, tuple[int, str]] = {
|
HTML_OPENER: dict[int, tuple[int, str]] = {
|
||||||
Tokenizer.FMT_B_B: (Tokenizer.FMT_B_E, "<strong>"),
|
TextFmt.B_B: (TextFmt.B_E, "<strong>"),
|
||||||
Tokenizer.FMT_I_B: (Tokenizer.FMT_I_E, "<em>"),
|
TextFmt.I_B: (TextFmt.I_E, "<em>"),
|
||||||
Tokenizer.FMT_D_B: (Tokenizer.FMT_D_E, "<del>"),
|
TextFmt.D_B: (TextFmt.D_E, "<del>"),
|
||||||
Tokenizer.FMT_U_B: (Tokenizer.FMT_U_E, "<span style='text-decoration: underline;'>"),
|
TextFmt.U_B: (TextFmt.U_E, "<span style='text-decoration: underline;'>"),
|
||||||
Tokenizer.FMT_M_B: (Tokenizer.FMT_M_E, "<mark>"),
|
TextFmt.M_B: (TextFmt.M_E, "<mark>"),
|
||||||
Tokenizer.FMT_SUP_B: (Tokenizer.FMT_SUP_E, "<sup>"),
|
TextFmt.SUP_B: (TextFmt.SUP_E, "<sup>"),
|
||||||
Tokenizer.FMT_SUB_B: (Tokenizer.FMT_SUB_E, "<sub>"),
|
TextFmt.SUB_B: (TextFmt.SUB_E, "<sub>"),
|
||||||
Tokenizer.FMT_DL_B: (Tokenizer.FMT_DL_E, "<span class='dialog'>"),
|
TextFmt.DL_B: (TextFmt.DL_E, "<span class='dialog'>"),
|
||||||
Tokenizer.FMT_ADL_B: (Tokenizer.FMT_ADL_E, "<span class='altdialog'>"),
|
TextFmt.ADL_B: (TextFmt.ADL_E, "<span class='altdialog'>"),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Each closer tag, with the id of its corresponding opener and tag format
|
# Each closer tag, with the id of its corresponding opener and tag format
|
||||||
HTML_CLOSER: dict[int, tuple[int, str]] = {
|
HTML_CLOSER: dict[int, tuple[int, str]] = {
|
||||||
Tokenizer.FMT_B_E: (Tokenizer.FMT_B_B, "</strong>"),
|
TextFmt.B_E: (TextFmt.B_B, "</strong>"),
|
||||||
Tokenizer.FMT_I_E: (Tokenizer.FMT_I_B, "</em>"),
|
TextFmt.I_E: (TextFmt.I_B, "</em>"),
|
||||||
Tokenizer.FMT_D_E: (Tokenizer.FMT_D_B, "</del>"),
|
TextFmt.D_E: (TextFmt.D_B, "</del>"),
|
||||||
Tokenizer.FMT_U_E: (Tokenizer.FMT_U_B, "</span>"),
|
TextFmt.U_E: (TextFmt.U_B, "</span>"),
|
||||||
Tokenizer.FMT_M_E: (Tokenizer.FMT_M_B, "</mark>"),
|
TextFmt.M_E: (TextFmt.M_B, "</mark>"),
|
||||||
Tokenizer.FMT_SUP_E: (Tokenizer.FMT_SUP_B, "</sup>"),
|
TextFmt.SUP_E: (TextFmt.SUP_B, "</sup>"),
|
||||||
Tokenizer.FMT_SUB_E: (Tokenizer.FMT_SUB_B, "</sub>"),
|
TextFmt.SUB_E: (TextFmt.SUB_B, "</sub>"),
|
||||||
Tokenizer.FMT_DL_E: (Tokenizer.FMT_DL_B, "</span>"),
|
TextFmt.DL_E: (TextFmt.DL_B, "</span>"),
|
||||||
Tokenizer.FMT_ADL_E: (Tokenizer.FMT_ADL_B, "</span>"),
|
TextFmt.ADL_E: (TextFmt.ADL_B, "</span>"),
|
||||||
}
|
}
|
||||||
|
|
||||||
# Empty HTML tag record
|
# Empty HTML tag record
|
||||||
@@ -183,30 +185,30 @@ class ToHtml(Tokenizer):
|
|||||||
# Styles
|
# Styles
|
||||||
aStyle = []
|
aStyle = []
|
||||||
if tStyle is not None and self._cssStyles:
|
if tStyle is not None and self._cssStyles:
|
||||||
if tStyle & self.A_LEFT:
|
if tStyle & BlockFmt.LEFT:
|
||||||
aStyle.append("text-align: left;")
|
aStyle.append("text-align: left;")
|
||||||
elif tStyle & self.A_RIGHT:
|
elif tStyle & BlockFmt.RIGHT:
|
||||||
aStyle.append("text-align: right;")
|
aStyle.append("text-align: right;")
|
||||||
elif tStyle & self.A_CENTRE:
|
elif tStyle & BlockFmt.CENTRE:
|
||||||
aStyle.append("text-align: center;")
|
aStyle.append("text-align: center;")
|
||||||
elif tStyle & self.A_JUSTIFY:
|
elif tStyle & BlockFmt.JUSTIFY:
|
||||||
aStyle.append("text-align: justify;")
|
aStyle.append("text-align: justify;")
|
||||||
|
|
||||||
if tStyle & self.A_PBB:
|
if tStyle & BlockFmt.PBB:
|
||||||
aStyle.append("page-break-before: always;")
|
aStyle.append("page-break-before: always;")
|
||||||
if tStyle & self.A_PBA:
|
if tStyle & BlockFmt.PBA:
|
||||||
aStyle.append("page-break-after: always;")
|
aStyle.append("page-break-after: always;")
|
||||||
|
|
||||||
if tStyle & self.A_Z_BTMMRG:
|
if tStyle & BlockFmt.Z_BTMMRG:
|
||||||
aStyle.append("margin-bottom: 0;")
|
aStyle.append("margin-bottom: 0;")
|
||||||
if tStyle & self.A_Z_TOPMRG:
|
if tStyle & BlockFmt.Z_TOPMRG:
|
||||||
aStyle.append("margin-top: 0;")
|
aStyle.append("margin-top: 0;")
|
||||||
|
|
||||||
if tStyle & self.A_IND_L:
|
if tStyle & BlockFmt.IND_L:
|
||||||
aStyle.append(f"margin-left: {self._blockIndent:.2f}em;")
|
aStyle.append(f"margin-left: {self._blockIndent:.2f}em;")
|
||||||
if tStyle & self.A_IND_R:
|
if tStyle & BlockFmt.IND_R:
|
||||||
aStyle.append(f"margin-right: {self._blockIndent:.2f}em;")
|
aStyle.append(f"margin-right: {self._blockIndent:.2f}em;")
|
||||||
if tStyle & self.A_IND_T:
|
if tStyle & BlockFmt.IND_T:
|
||||||
aStyle.append(f"text-indent: {self._firstWidth:.2f}em;")
|
aStyle.append(f"text-indent: {self._firstWidth:.2f}em;")
|
||||||
|
|
||||||
if aStyle:
|
if aStyle:
|
||||||
@@ -221,45 +223,45 @@ class ToHtml(Tokenizer):
|
|||||||
aNm = ""
|
aNm = ""
|
||||||
|
|
||||||
# Process Text Type
|
# Process Text Type
|
||||||
if tType == self.T_TEXT:
|
if tType == BlockTyp.TEXT:
|
||||||
lines.append(f"<p{hStyle}>{self._formatText(tText, tFormat)}</p>\n")
|
lines.append(f"<p{hStyle}>{self._formatText(tText, tFormat)}</p>\n")
|
||||||
|
|
||||||
elif tType == self.T_TITLE:
|
elif tType == BlockTyp.TITLE:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "<br>")
|
tHead = tText.replace(nwHeadFmt.BR, "<br>")
|
||||||
lines.append(f"<h1 class='title'{hStyle}>{aNm}{tHead}</h1>\n")
|
lines.append(f"<h1 class='title'{hStyle}>{aNm}{tHead}</h1>\n")
|
||||||
|
|
||||||
elif tType == self.T_HEAD1:
|
elif tType == BlockTyp.HEAD1:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "<br>")
|
tHead = tText.replace(nwHeadFmt.BR, "<br>")
|
||||||
lines.append(f"<{h1}{h1Cl}{hStyle}>{aNm}{tHead}</{h1}>\n")
|
lines.append(f"<{h1}{h1Cl}{hStyle}>{aNm}{tHead}</{h1}>\n")
|
||||||
|
|
||||||
elif tType == self.T_HEAD2:
|
elif tType == BlockTyp.HEAD2:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "<br>")
|
tHead = tText.replace(nwHeadFmt.BR, "<br>")
|
||||||
lines.append(f"<{h2}{hStyle}>{aNm}{tHead}</{h2}>\n")
|
lines.append(f"<{h2}{hStyle}>{aNm}{tHead}</{h2}>\n")
|
||||||
|
|
||||||
elif tType == self.T_HEAD3:
|
elif tType == BlockTyp.HEAD3:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "<br>")
|
tHead = tText.replace(nwHeadFmt.BR, "<br>")
|
||||||
lines.append(f"<{h3}{hStyle}>{aNm}{tHead}</{h3}>\n")
|
lines.append(f"<{h3}{hStyle}>{aNm}{tHead}</{h3}>\n")
|
||||||
|
|
||||||
elif tType == self.T_HEAD4:
|
elif tType == BlockTyp.HEAD4:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "<br>")
|
tHead = tText.replace(nwHeadFmt.BR, "<br>")
|
||||||
lines.append(f"<{h4}{hStyle}>{aNm}{tHead}</{h4}>\n")
|
lines.append(f"<{h4}{hStyle}>{aNm}{tHead}</{h4}>\n")
|
||||||
|
|
||||||
elif tType == self.T_SEP:
|
elif tType == BlockTyp.SEP:
|
||||||
lines.append(f"<p class='sep'{hStyle}>{tText}</p>\n")
|
lines.append(f"<p class='sep'{hStyle}>{tText}</p>\n")
|
||||||
|
|
||||||
elif tType == self.T_SKIP:
|
elif tType == BlockTyp.SKIP:
|
||||||
lines.append(f"<p class='skip'{hStyle}> </p>\n")
|
lines.append(f"<p class='skip'{hStyle}> </p>\n")
|
||||||
|
|
||||||
elif tType == self.T_SYNOPSIS and self._doSynopsis:
|
elif tType == BlockTyp.SYNOPSIS and self._doSynopsis:
|
||||||
lines.append(self._formatSynopsis(self._formatText(tText, tFormat), True))
|
lines.append(self._formatSynopsis(self._formatText(tText, tFormat), True))
|
||||||
|
|
||||||
elif tType == self.T_SHORT and self._doSynopsis:
|
elif tType == BlockTyp.SHORT and self._doSynopsis:
|
||||||
lines.append(self._formatSynopsis(self._formatText(tText, tFormat), False))
|
lines.append(self._formatSynopsis(self._formatText(tText, tFormat), False))
|
||||||
|
|
||||||
elif tType == self.T_COMMENT and self._doComments:
|
elif tType == BlockTyp.COMMENT and self._doComments:
|
||||||
lines.append(self._formatComments(self._formatText(tText, tFormat)))
|
lines.append(self._formatComments(self._formatText(tText, tFormat)))
|
||||||
|
|
||||||
elif tType == self.T_KEYWORD and self._doKeywords:
|
elif tType == BlockTyp.KEYWORD and self._doKeywords:
|
||||||
tag, text = self._formatKeywords(tText)
|
tag, text = self._formatKeywords(tText)
|
||||||
kClass = f" class='meta meta-{tag}'" if tag else ""
|
kClass = f" class='meta meta-{tag}'" if tag else ""
|
||||||
tTemp = f"<p{kClass}{hStyle}>{text}</p>\n"
|
tTemp = f"<p{kClass}{hStyle}>{text}</p>\n"
|
||||||
@@ -469,7 +471,7 @@ class ToHtml(Tokenizer):
|
|||||||
if state.get(m[0], False):
|
if state.get(m[0], False):
|
||||||
tags.append((pos, m[1]))
|
tags.append((pos, m[1]))
|
||||||
state[m[0]] = False
|
state[m[0]] = False
|
||||||
elif fmt == self.FMT_FNOTE:
|
elif fmt == TextFmt.FNOTE:
|
||||||
if data in self._footnotes:
|
if data in self._footnotes:
|
||||||
index = len(self._usedNotes) + 1
|
index = len(self._usedNotes) + 1
|
||||||
self._usedNotes[data] = index
|
self._usedNotes[data] = index
|
||||||
|
|||||||
+170
-153
@@ -29,6 +29,7 @@ import logging
|
|||||||
import re
|
import re
|
||||||
|
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
|
from enum import Flag, IntEnum
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from time import time
|
from time import time
|
||||||
@@ -51,10 +52,6 @@ logger = logging.getLogger(__name__)
|
|||||||
ESCAPES = {r"\*": "*", r"\~": "~", r"\_": "_", r"\[": "[", r"\]": "]", r"\ ": ""}
|
ESCAPES = {r"\*": "*", r"\~": "~", r"\_": "_", r"\[": "[", r"\]": "]", r"\ ": ""}
|
||||||
RX_ESC = re.compile("|".join([re.escape(k) for k in ESCAPES.keys()]), flags=re.DOTALL)
|
RX_ESC = re.compile("|".join([re.escape(k) for k in ESCAPES.keys()]), flags=re.DOTALL)
|
||||||
|
|
||||||
T_Formats = list[tuple[int, int, str]]
|
|
||||||
T_Comment = tuple[str, T_Formats]
|
|
||||||
T_Token = tuple[int, int, str, T_Formats, int]
|
|
||||||
|
|
||||||
|
|
||||||
def stripEscape(text: str) -> str:
|
def stripEscape(text: str) -> str:
|
||||||
"""Strip escaped Markdown characters from paragraph text."""
|
"""Strip escaped Markdown characters from paragraph text."""
|
||||||
@@ -63,6 +60,68 @@ def stripEscape(text: str) -> str:
|
|||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
|
class TextFmt(IntEnum):
|
||||||
|
|
||||||
|
B_B = 1 # Begin bold
|
||||||
|
B_E = 2 # End bold
|
||||||
|
I_B = 3 # Begin italics
|
||||||
|
I_E = 4 # End italics
|
||||||
|
D_B = 5 # Begin strikeout
|
||||||
|
D_E = 6 # End strikeout
|
||||||
|
U_B = 7 # Begin underline
|
||||||
|
U_E = 8 # End underline
|
||||||
|
M_B = 9 # Begin mark
|
||||||
|
M_E = 10 # End mark
|
||||||
|
SUP_B = 11 # Begin superscript
|
||||||
|
SUP_E = 12 # End superscript
|
||||||
|
SUB_B = 13 # Begin subscript
|
||||||
|
SUB_E = 14 # End subscript
|
||||||
|
DL_B = 15 # Begin dialogue
|
||||||
|
DL_E = 16 # End dialogue
|
||||||
|
ADL_B = 17 # Begin alt dialogue
|
||||||
|
ADL_E = 18 # End alt dialogue
|
||||||
|
FNOTE = 19 # Footnote marker
|
||||||
|
STRIP = 20 # Strip the format code
|
||||||
|
|
||||||
|
|
||||||
|
class BlockTyp(IntEnum):
|
||||||
|
|
||||||
|
EMPTY = 1 # Empty line (new paragraph)
|
||||||
|
SYNOPSIS = 2 # Synopsis comment
|
||||||
|
SHORT = 3 # Short description comment
|
||||||
|
COMMENT = 4 # Comment line
|
||||||
|
KEYWORD = 5 # Command line
|
||||||
|
TITLE = 6 # Title
|
||||||
|
HEAD1 = 7 # Heading 1
|
||||||
|
HEAD2 = 8 # Heading 2
|
||||||
|
HEAD3 = 9 # Heading 3
|
||||||
|
HEAD4 = 10 # Heading 4
|
||||||
|
TEXT = 11 # Text line
|
||||||
|
SEP = 12 # Scene separator
|
||||||
|
SKIP = 13 # Paragraph break
|
||||||
|
|
||||||
|
|
||||||
|
class BlockFmt(Flag):
|
||||||
|
|
||||||
|
NONE = 0x0000 # No special style
|
||||||
|
LEFT = 0x0001 # Left aligned
|
||||||
|
RIGHT = 0x0002 # Right aligned
|
||||||
|
CENTRE = 0x0004 # Centred
|
||||||
|
JUSTIFY = 0x0008 # Justified
|
||||||
|
PBB = 0x0010 # Page break before
|
||||||
|
PBA = 0x0020 # Page break after
|
||||||
|
Z_TOPMRG = 0x0040 # Zero top margin
|
||||||
|
Z_BTMMRG = 0x0080 # Zero bottom margin
|
||||||
|
IND_L = 0x0100 # Left indentation
|
||||||
|
IND_R = 0x0200 # Right indentation
|
||||||
|
IND_T = 0x0400 # Text indentation
|
||||||
|
|
||||||
|
|
||||||
|
T_Formats = list[tuple[int, TextFmt, str]]
|
||||||
|
T_Comment = tuple[str, T_Formats]
|
||||||
|
T_Token = tuple[BlockTyp, int, str, T_Formats, BlockFmt]
|
||||||
|
|
||||||
|
|
||||||
class Tokenizer(ABC):
|
class Tokenizer(ABC):
|
||||||
"""Core: Text Tokenizer Abstract Base Class
|
"""Core: Text Tokenizer Abstract Base Class
|
||||||
|
|
||||||
@@ -72,64 +131,18 @@ class Tokenizer(ABC):
|
|||||||
subclasses.
|
subclasses.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# In-Text Format
|
|
||||||
FMT_B_B = 1 # Begin bold
|
|
||||||
FMT_B_E = 2 # End bold
|
|
||||||
FMT_I_B = 3 # Begin italics
|
|
||||||
FMT_I_E = 4 # End italics
|
|
||||||
FMT_D_B = 5 # Begin strikeout
|
|
||||||
FMT_D_E = 6 # End strikeout
|
|
||||||
FMT_U_B = 7 # Begin underline
|
|
||||||
FMT_U_E = 8 # End underline
|
|
||||||
FMT_M_B = 9 # Begin mark
|
|
||||||
FMT_M_E = 10 # End mark
|
|
||||||
FMT_SUP_B = 11 # Begin superscript
|
|
||||||
FMT_SUP_E = 12 # End superscript
|
|
||||||
FMT_SUB_B = 13 # Begin subscript
|
|
||||||
FMT_SUB_E = 14 # End subscript
|
|
||||||
FMT_DL_B = 15 # Begin dialogue
|
|
||||||
FMT_DL_E = 16 # End dialogue
|
|
||||||
FMT_ADL_B = 17 # Begin alt dialogue
|
|
||||||
FMT_ADL_E = 18 # End alt dialogue
|
|
||||||
FMT_FNOTE = 19 # Footnote marker
|
|
||||||
FMT_STRIP = 20 # Strip the format code
|
|
||||||
|
|
||||||
# Block Type
|
|
||||||
T_EMPTY = 1 # Empty line (new paragraph)
|
|
||||||
T_SYNOPSIS = 2 # Synopsis comment
|
|
||||||
T_SHORT = 3 # Short description comment
|
|
||||||
T_COMMENT = 4 # Comment line
|
|
||||||
T_KEYWORD = 5 # Command line
|
|
||||||
T_TITLE = 6 # Title
|
|
||||||
T_HEAD1 = 7 # Heading 1
|
|
||||||
T_HEAD2 = 8 # Heading 2
|
|
||||||
T_HEAD3 = 9 # Heading 3
|
|
||||||
T_HEAD4 = 10 # Heading 4
|
|
||||||
T_TEXT = 11 # Text line
|
|
||||||
T_SEP = 12 # Scene separator
|
|
||||||
T_SKIP = 13 # Paragraph break
|
|
||||||
|
|
||||||
# Block Style
|
|
||||||
A_NONE = 0x0000 # No special style
|
|
||||||
A_LEFT = 0x0001 # Left aligned
|
|
||||||
A_RIGHT = 0x0002 # Right aligned
|
|
||||||
A_CENTRE = 0x0004 # Centred
|
|
||||||
A_JUSTIFY = 0x0008 # Justified
|
|
||||||
A_PBB = 0x0010 # Page break before
|
|
||||||
A_PBA = 0x0020 # Page break after
|
|
||||||
A_Z_TOPMRG = 0x0040 # Zero top margin
|
|
||||||
A_Z_BTMMRG = 0x0080 # Zero bottom margin
|
|
||||||
A_IND_L = 0x0100 # Left indentation
|
|
||||||
A_IND_R = 0x0200 # Right indentation
|
|
||||||
A_IND_T = 0x0400 # Text indentation
|
|
||||||
|
|
||||||
# Masks
|
# Masks
|
||||||
M_ALIGNED = A_LEFT | A_RIGHT | A_CENTRE | A_JUSTIFY
|
M_ALIGNED = BlockFmt.LEFT | BlockFmt.RIGHT | BlockFmt.CENTRE | BlockFmt.JUSTIFY
|
||||||
|
|
||||||
# Lookups
|
# Lookups
|
||||||
L_HEADINGS = [T_TITLE, T_HEAD1, T_HEAD2, T_HEAD3, T_HEAD4]
|
L_HEADINGS = [
|
||||||
L_SKIP_INDENT = [T_TITLE, T_HEAD1, T_HEAD2, T_HEAD2, T_HEAD3, T_HEAD4, T_SEP, T_SKIP]
|
BlockTyp.TITLE, BlockTyp.HEAD1, BlockTyp.HEAD2, BlockTyp.HEAD3, BlockTyp.HEAD4,
|
||||||
L_SUMMARY = [T_SYNOPSIS, T_SHORT]
|
]
|
||||||
|
L_SKIP_INDENT = [
|
||||||
|
BlockTyp.TITLE, BlockTyp.HEAD1, BlockTyp.HEAD2, BlockTyp.HEAD2, BlockTyp.HEAD3,
|
||||||
|
BlockTyp.HEAD4, BlockTyp.SEP, BlockTyp.SKIP,
|
||||||
|
]
|
||||||
|
L_SUMMARY = [BlockTyp.SYNOPSIS, BlockTyp.SHORT]
|
||||||
|
|
||||||
def __init__(self, project: NWProject) -> None:
|
def __init__(self, project: NWProject) -> None:
|
||||||
|
|
||||||
@@ -197,10 +210,10 @@ class Tokenizer(ABC):
|
|||||||
|
|
||||||
self._linkHeadings = False # Add an anchor before headings
|
self._linkHeadings = False # Add an anchor before headings
|
||||||
|
|
||||||
self._titleStyle = self.A_CENTRE | self.A_PBB
|
self._titleStyle = BlockFmt.CENTRE | BlockFmt.PBB
|
||||||
self._partStyle = self.A_CENTRE | self.A_PBB
|
self._partStyle = BlockFmt.CENTRE | BlockFmt.PBB
|
||||||
self._chapterStyle = self.A_PBB
|
self._chapterStyle = BlockFmt.PBB
|
||||||
self._sceneStyle = self.A_NONE
|
self._sceneStyle = BlockFmt.NONE
|
||||||
|
|
||||||
# Instance Variables
|
# Instance Variables
|
||||||
self._hFormatter = HeadingFormatter(self._project)
|
self._hFormatter = HeadingFormatter(self._project)
|
||||||
@@ -220,24 +233,24 @@ class Tokenizer(ABC):
|
|||||||
|
|
||||||
# Format RegEx
|
# Format RegEx
|
||||||
self._rxMarkdown = [
|
self._rxMarkdown = [
|
||||||
(REGEX_PATTERNS.markdownItalic, [0, self.FMT_I_B, 0, self.FMT_I_E]),
|
(REGEX_PATTERNS.markdownItalic, [0, TextFmt.I_B, 0, TextFmt.I_E]),
|
||||||
(REGEX_PATTERNS.markdownBold, [0, self.FMT_B_B, 0, self.FMT_B_E]),
|
(REGEX_PATTERNS.markdownBold, [0, TextFmt.B_B, 0, TextFmt.B_E]),
|
||||||
(REGEX_PATTERNS.markdownStrike, [0, self.FMT_D_B, 0, self.FMT_D_E]),
|
(REGEX_PATTERNS.markdownStrike, [0, TextFmt.D_B, 0, TextFmt.D_E]),
|
||||||
]
|
]
|
||||||
self._rxShortCodes = REGEX_PATTERNS.shortcodePlain
|
self._rxShortCodes = REGEX_PATTERNS.shortcodePlain
|
||||||
self._rxShortCodeVals = REGEX_PATTERNS.shortcodeValue
|
self._rxShortCodeVals = REGEX_PATTERNS.shortcodeValue
|
||||||
|
|
||||||
self._shortCodeFmt = {
|
self._shortCodeFmt = {
|
||||||
nwShortcode.ITALIC_O: self.FMT_I_B, nwShortcode.ITALIC_C: self.FMT_I_E,
|
nwShortcode.ITALIC_O: TextFmt.I_B, nwShortcode.ITALIC_C: TextFmt.I_E,
|
||||||
nwShortcode.BOLD_O: self.FMT_B_B, nwShortcode.BOLD_C: self.FMT_B_E,
|
nwShortcode.BOLD_O: TextFmt.B_B, nwShortcode.BOLD_C: TextFmt.B_E,
|
||||||
nwShortcode.STRIKE_O: self.FMT_D_B, nwShortcode.STRIKE_C: self.FMT_D_E,
|
nwShortcode.STRIKE_O: TextFmt.D_B, nwShortcode.STRIKE_C: TextFmt.D_E,
|
||||||
nwShortcode.ULINE_O: self.FMT_U_B, nwShortcode.ULINE_C: self.FMT_U_E,
|
nwShortcode.ULINE_O: TextFmt.U_B, nwShortcode.ULINE_C: TextFmt.U_E,
|
||||||
nwShortcode.MARK_O: self.FMT_M_B, nwShortcode.MARK_C: self.FMT_M_E,
|
nwShortcode.MARK_O: TextFmt.M_B, nwShortcode.MARK_C: TextFmt.M_E,
|
||||||
nwShortcode.SUP_O: self.FMT_SUP_B, nwShortcode.SUP_C: self.FMT_SUP_E,
|
nwShortcode.SUP_O: TextFmt.SUP_B, nwShortcode.SUP_C: TextFmt.SUP_E,
|
||||||
nwShortcode.SUB_O: self.FMT_SUB_B, nwShortcode.SUB_C: self.FMT_SUB_E,
|
nwShortcode.SUB_O: TextFmt.SUB_B, nwShortcode.SUB_C: TextFmt.SUB_E,
|
||||||
}
|
}
|
||||||
self._shortCodeVals = {
|
self._shortCodeVals = {
|
||||||
nwShortcode.FOOTNOTE_B: self.FMT_FNOTE,
|
nwShortcode.FOOTNOTE_B: TextFmt.FNOTE,
|
||||||
}
|
}
|
||||||
|
|
||||||
self._rxDialogue: list[tuple[re.Pattern, int, int]] = []
|
self._rxDialogue: list[tuple[re.Pattern, int, int]] = []
|
||||||
@@ -316,28 +329,32 @@ class Tokenizer(ABC):
|
|||||||
def setTitleStyle(self, center: bool, pageBreak: bool) -> None:
|
def setTitleStyle(self, center: bool, pageBreak: bool) -> None:
|
||||||
"""Set the title heading style."""
|
"""Set the title heading style."""
|
||||||
self._titleStyle = (
|
self._titleStyle = (
|
||||||
(self.A_CENTRE if center else self.A_NONE) | (self.A_PBB if pageBreak else self.A_NONE)
|
(BlockFmt.CENTRE if center else BlockFmt.NONE)
|
||||||
|
| (BlockFmt.PBB if pageBreak else BlockFmt.NONE)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
def setPartitionStyle(self, center: bool, pageBreak: bool) -> None:
|
def setPartitionStyle(self, center: bool, pageBreak: bool) -> None:
|
||||||
"""Set the partition heading style."""
|
"""Set the partition heading style."""
|
||||||
self._partStyle = (
|
self._partStyle = (
|
||||||
(self.A_CENTRE if center else self.A_NONE) | (self.A_PBB if pageBreak else self.A_NONE)
|
(BlockFmt.CENTRE if center else BlockFmt.NONE)
|
||||||
|
| (BlockFmt.PBB if pageBreak else BlockFmt.NONE)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
def setChapterStyle(self, center: bool, pageBreak: bool) -> None:
|
def setChapterStyle(self, center: bool, pageBreak: bool) -> None:
|
||||||
"""Set the chapter heading style."""
|
"""Set the chapter heading style."""
|
||||||
self._chapterStyle = (
|
self._chapterStyle = (
|
||||||
(self.A_CENTRE if center else self.A_NONE) | (self.A_PBB if pageBreak else self.A_NONE)
|
(BlockFmt.CENTRE if center else BlockFmt.NONE)
|
||||||
|
| (BlockFmt.PBB if pageBreak else BlockFmt.NONE)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
def setSceneStyle(self, center: bool, pageBreak: bool) -> None:
|
def setSceneStyle(self, center: bool, pageBreak: bool) -> None:
|
||||||
"""Set the scene heading style."""
|
"""Set the scene heading style."""
|
||||||
self._sceneStyle = (
|
self._sceneStyle = (
|
||||||
(self.A_CENTRE if center else self.A_NONE) | (self.A_PBB if pageBreak else self.A_NONE)
|
(BlockFmt.CENTRE if center else BlockFmt.NONE)
|
||||||
|
| (BlockFmt.PBB if pageBreak else BlockFmt.NONE)
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -383,19 +400,19 @@ class Tokenizer(ABC):
|
|||||||
if state:
|
if state:
|
||||||
if CONFIG.dialogStyle > 0:
|
if CONFIG.dialogStyle > 0:
|
||||||
self._rxDialogue.append((
|
self._rxDialogue.append((
|
||||||
REGEX_PATTERNS.dialogStyle, self.FMT_DL_B, self.FMT_DL_E
|
REGEX_PATTERNS.dialogStyle, TextFmt.DL_B, TextFmt.DL_E
|
||||||
))
|
))
|
||||||
if CONFIG.dialogLine:
|
if CONFIG.dialogLine:
|
||||||
self._rxDialogue.append((
|
self._rxDialogue.append((
|
||||||
REGEX_PATTERNS.dialogLine, self.FMT_DL_B, self.FMT_DL_E
|
REGEX_PATTERNS.dialogLine, TextFmt.DL_B, TextFmt.DL_E
|
||||||
))
|
))
|
||||||
if CONFIG.narratorBreak:
|
if CONFIG.narratorBreak:
|
||||||
self._rxDialogue.append((
|
self._rxDialogue.append((
|
||||||
REGEX_PATTERNS.narratorBreak, self.FMT_DL_E, self.FMT_DL_B
|
REGEX_PATTERNS.narratorBreak, TextFmt.DL_E, TextFmt.DL_B
|
||||||
))
|
))
|
||||||
if CONFIG.altDialogOpen and CONFIG.altDialogClose:
|
if CONFIG.altDialogOpen and CONFIG.altDialogClose:
|
||||||
self._rxDialogue.append((
|
self._rxDialogue.append((
|
||||||
REGEX_PATTERNS.altDialogStyle, self.FMT_ADL_B, self.FMT_ADL_E
|
REGEX_PATTERNS.altDialogStyle, TextFmt.ADL_B, TextFmt.ADL_E
|
||||||
))
|
))
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -494,16 +511,16 @@ class Tokenizer(ABC):
|
|||||||
if (tItem := self._project.tree[tHandle]) and tItem.isRootType():
|
if (tItem := self._project.tree[tHandle]) and tItem.isRootType():
|
||||||
self._handle = tHandle
|
self._handle = tHandle
|
||||||
if self._isFirst:
|
if self._isFirst:
|
||||||
textAlign = self.A_CENTRE
|
textAlign = BlockFmt.CENTRE
|
||||||
self._isFirst = False
|
self._isFirst = False
|
||||||
else:
|
else:
|
||||||
textAlign = self.A_PBB | self.A_CENTRE
|
textAlign = BlockFmt.PBB | BlockFmt.CENTRE
|
||||||
|
|
||||||
trNotes = self._localLookup("Notes")
|
trNotes = self._localLookup("Notes")
|
||||||
title = f"{trNotes}: {tItem.itemName}"
|
title = f"{trNotes}: {tItem.itemName}"
|
||||||
self._tokens = []
|
self._tokens = []
|
||||||
self._tokens.append((
|
self._tokens.append((
|
||||||
self.T_TITLE, 1, title, [], textAlign
|
BlockTyp.TITLE, 1, title, [], textAlign
|
||||||
))
|
))
|
||||||
if self._keepRaw:
|
if self._keepRaw:
|
||||||
self._markdown.append(f"#! {title}\n\n")
|
self._markdown.append(f"#! {title}\n\n")
|
||||||
@@ -548,11 +565,11 @@ class Tokenizer(ABC):
|
|||||||
|
|
||||||
The format of the token list is an entry with a five-tuple for
|
The format of the token list is an entry with a five-tuple for
|
||||||
each line in the file. The tuple is as follows:
|
each line in the file. The tuple is as follows:
|
||||||
1: The type of the block, self.T_*
|
1: The type of the block, BlockType.*
|
||||||
2: The heading number under which the text is placed
|
2: The heading number under which the text is placed
|
||||||
3: The text content of the block, without leading tags
|
3: The text content of the block, without leading tags
|
||||||
4: The internal formatting map of the text, self.FMT_*
|
4: The internal formatting map of the text, TxtFmt.*
|
||||||
5: The style of the block, self.A_*
|
5: The style of the block, BlockFmt.*
|
||||||
"""
|
"""
|
||||||
if self._isNovel:
|
if self._isNovel:
|
||||||
self._hFormatter.setHandle(self._handle)
|
self._hFormatter.setHandle(self._handle)
|
||||||
@@ -568,7 +585,7 @@ class Tokenizer(ABC):
|
|||||||
# Check for blank lines
|
# Check for blank lines
|
||||||
if len(sLine) == 0:
|
if len(sLine) == 0:
|
||||||
tokens.append((
|
tokens.append((
|
||||||
self.T_EMPTY, nHead, "", [], self.A_NONE
|
BlockTyp.EMPTY, nHead, "", [], BlockFmt.NONE
|
||||||
))
|
))
|
||||||
if self._keepRaw:
|
if self._keepRaw:
|
||||||
tmpMarkdown.append("\n")
|
tmpMarkdown.append("\n")
|
||||||
@@ -576,10 +593,10 @@ class Tokenizer(ABC):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if breakNext:
|
if breakNext:
|
||||||
sAlign = self.A_PBB
|
sAlign = BlockFmt.PBB
|
||||||
breakNext = False
|
breakNext = False
|
||||||
else:
|
else:
|
||||||
sAlign = self.A_NONE
|
sAlign = BlockFmt.NONE
|
||||||
|
|
||||||
# Check Line Format
|
# Check Line Format
|
||||||
# =================
|
# =================
|
||||||
@@ -597,7 +614,7 @@ class Tokenizer(ABC):
|
|||||||
|
|
||||||
elif sLine == "[vspace]":
|
elif sLine == "[vspace]":
|
||||||
tokens.append(
|
tokens.append(
|
||||||
(self.T_SKIP, nHead, "", [], sAlign)
|
(BlockTyp.SKIP, nHead, "", [], sAlign)
|
||||||
)
|
)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -605,11 +622,11 @@ class Tokenizer(ABC):
|
|||||||
nSkip = checkInt(sLine[8:-1], 0)
|
nSkip = checkInt(sLine[8:-1], 0)
|
||||||
if nSkip >= 1:
|
if nSkip >= 1:
|
||||||
tokens.append(
|
tokens.append(
|
||||||
(self.T_SKIP, nHead, "", [], sAlign)
|
(BlockTyp.SKIP, nHead, "", [], sAlign)
|
||||||
)
|
)
|
||||||
if nSkip > 1:
|
if nSkip > 1:
|
||||||
tokens += (nSkip - 1) * [
|
tokens += (nSkip - 1) * [
|
||||||
(self.T_SKIP, nHead, "", [], self.A_NONE)
|
(BlockTyp.SKIP, nHead, "", [], BlockFmt.NONE)
|
||||||
]
|
]
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -623,32 +640,32 @@ class Tokenizer(ABC):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
if self._doJustify and not sAlign & self.M_ALIGNED:
|
if self._doJustify and not sAlign & self.M_ALIGNED:
|
||||||
sAlign |= self.A_JUSTIFY
|
sAlign |= BlockFmt.JUSTIFY
|
||||||
|
|
||||||
cStyle, cKey, cText, _, _ = processComment(aLine)
|
cStyle, cKey, cText, _, _ = processComment(aLine)
|
||||||
if cStyle == nwComment.SYNOPSIS:
|
if cStyle == nwComment.SYNOPSIS:
|
||||||
tLine, tFmt = self._extractFormats(cText)
|
tLine, tFmt = self._extractFormats(cText)
|
||||||
tokens.append((
|
tokens.append((
|
||||||
self.T_SYNOPSIS, nHead, tLine, tFmt, sAlign
|
BlockTyp.SYNOPSIS, nHead, tLine, tFmt, sAlign
|
||||||
))
|
))
|
||||||
if self._doSynopsis and self._keepRaw:
|
if self._doSynopsis and self._keepRaw:
|
||||||
tmpMarkdown.append(f"{aLine}\n")
|
tmpMarkdown.append(f"{aLine}\n")
|
||||||
elif cStyle == nwComment.SHORT:
|
elif cStyle == nwComment.SHORT:
|
||||||
tLine, tFmt = self._extractFormats(cText)
|
tLine, tFmt = self._extractFormats(cText)
|
||||||
tokens.append((
|
tokens.append((
|
||||||
self.T_SHORT, nHead, tLine, tFmt, sAlign
|
BlockTyp.SHORT, nHead, tLine, tFmt, sAlign
|
||||||
))
|
))
|
||||||
if self._doSynopsis and self._keepRaw:
|
if self._doSynopsis and self._keepRaw:
|
||||||
tmpMarkdown.append(f"{aLine}\n")
|
tmpMarkdown.append(f"{aLine}\n")
|
||||||
elif cStyle == nwComment.FOOTNOTE:
|
elif cStyle == nwComment.FOOTNOTE:
|
||||||
tLine, tFmt = self._extractFormats(cText, skip=self.FMT_FNOTE)
|
tLine, tFmt = self._extractFormats(cText, skip=TextFmt.FNOTE)
|
||||||
self._footnotes[f"{tHandle}:{cKey}"] = (tLine, tFmt)
|
self._footnotes[f"{tHandle}:{cKey}"] = (tLine, tFmt)
|
||||||
if self._keepRaw:
|
if self._keepRaw:
|
||||||
tmpMarkdown.append(f"{aLine}\n")
|
tmpMarkdown.append(f"{aLine}\n")
|
||||||
else:
|
else:
|
||||||
tLine, tFmt = self._extractFormats(cText)
|
tLine, tFmt = self._extractFormats(cText)
|
||||||
tokens.append((
|
tokens.append((
|
||||||
self.T_COMMENT, nHead, tLine, tFmt, sAlign
|
BlockTyp.COMMENT, nHead, tLine, tFmt, sAlign
|
||||||
))
|
))
|
||||||
if self._doComments and self._keepRaw:
|
if self._doComments and self._keepRaw:
|
||||||
tmpMarkdown.append(f"{aLine}\n")
|
tmpMarkdown.append(f"{aLine}\n")
|
||||||
@@ -665,7 +682,7 @@ class Tokenizer(ABC):
|
|||||||
and bits[0] not in self._skipKeywords
|
and bits[0] not in self._skipKeywords
|
||||||
):
|
):
|
||||||
tokens.append((
|
tokens.append((
|
||||||
self.T_KEYWORD, nHead, aLine[1:].strip(), [], sAlign
|
BlockTyp.KEYWORD, nHead, aLine[1:].strip(), [], sAlign
|
||||||
))
|
))
|
||||||
if self._doKeywords and self._keepRaw:
|
if self._doKeywords and self._keepRaw:
|
||||||
tmpMarkdown.append(f"{aLine}\n")
|
tmpMarkdown.append(f"{aLine}\n")
|
||||||
@@ -683,14 +700,14 @@ class Tokenizer(ABC):
|
|||||||
|
|
||||||
nHead += 1
|
nHead += 1
|
||||||
tText = aLine[2:].strip()
|
tText = aLine[2:].strip()
|
||||||
tType = self.T_HEAD1 if isPlain else self.T_TITLE
|
tType = BlockTyp.HEAD1 if isPlain else BlockTyp.TITLE
|
||||||
tStyle = self.A_NONE if isPlain else self._titleStyle
|
tStyle = BlockFmt.NONE if isPlain else self._titleStyle
|
||||||
sHide = self._hidePart if isPlain else False
|
sHide = self._hidePart if isPlain else False
|
||||||
if self._isNovel:
|
if self._isNovel:
|
||||||
if sHide:
|
if sHide:
|
||||||
tText = ""
|
tText = ""
|
||||||
tType = self.T_EMPTY
|
tType = BlockTyp.EMPTY
|
||||||
tStyle = self.A_NONE
|
tStyle = BlockFmt.NONE
|
||||||
elif isPlain:
|
elif isPlain:
|
||||||
tText = self._hFormatter.apply(self._fmtPart, tText, nHead)
|
tText = self._hFormatter.apply(self._fmtPart, tText, nHead)
|
||||||
tStyle = self._partStyle
|
tStyle = self._partStyle
|
||||||
@@ -719,8 +736,8 @@ class Tokenizer(ABC):
|
|||||||
|
|
||||||
nHead += 1
|
nHead += 1
|
||||||
tText = aLine[3:].strip()
|
tText = aLine[3:].strip()
|
||||||
tType = self.T_HEAD2
|
tType = BlockTyp.HEAD2
|
||||||
tStyle = self.A_NONE
|
tStyle = BlockFmt.NONE
|
||||||
sHide = self._hideChapter if isPlain else self._hideUnNum
|
sHide = self._hideChapter if isPlain else self._hideUnNum
|
||||||
tFormat = self._fmtChapter if isPlain else self._fmtUnNum
|
tFormat = self._fmtChapter if isPlain else self._fmtUnNum
|
||||||
if self._isNovel:
|
if self._isNovel:
|
||||||
@@ -728,7 +745,7 @@ class Tokenizer(ABC):
|
|||||||
self._hFormatter.incChapter()
|
self._hFormatter.incChapter()
|
||||||
if sHide:
|
if sHide:
|
||||||
tText = ""
|
tText = ""
|
||||||
tType = self.T_EMPTY
|
tType = BlockTyp.EMPTY
|
||||||
else:
|
else:
|
||||||
tText = self._hFormatter.apply(tFormat, tText, nHead)
|
tText = self._hFormatter.apply(tFormat, tText, nHead)
|
||||||
tStyle = self._chapterStyle
|
tStyle = self._chapterStyle
|
||||||
@@ -756,24 +773,24 @@ class Tokenizer(ABC):
|
|||||||
|
|
||||||
nHead += 1
|
nHead += 1
|
||||||
tText = aLine[4:].strip()
|
tText = aLine[4:].strip()
|
||||||
tType = self.T_HEAD3
|
tType = BlockTyp.HEAD3
|
||||||
tStyle = self.A_NONE
|
tStyle = BlockFmt.NONE
|
||||||
sHide = self._hideScene if isPlain else self._hideHScene
|
sHide = self._hideScene if isPlain else self._hideHScene
|
||||||
tFormat = self._fmtScene if isPlain else self._fmtHScene
|
tFormat = self._fmtScene if isPlain else self._fmtHScene
|
||||||
if self._isNovel:
|
if self._isNovel:
|
||||||
self._hFormatter.incScene()
|
self._hFormatter.incScene()
|
||||||
if sHide:
|
if sHide:
|
||||||
tText = ""
|
tText = ""
|
||||||
tType = self.T_EMPTY
|
tType = BlockTyp.EMPTY
|
||||||
else:
|
else:
|
||||||
tText = self._hFormatter.apply(tFormat, tText, nHead)
|
tText = self._hFormatter.apply(tFormat, tText, nHead)
|
||||||
tStyle = self._sceneStyle
|
tStyle = self._sceneStyle
|
||||||
if tText == "": # Empty Format
|
if tText == "": # Empty Format
|
||||||
tType = self.T_EMPTY if self._noSep else self.T_SKIP
|
tType = BlockTyp.EMPTY if self._noSep else BlockTyp.SKIP
|
||||||
elif tText == tFormat: # Static Format
|
elif tText == tFormat: # Static Format
|
||||||
tText = "" if self._noSep else tText
|
tText = "" if self._noSep else tText
|
||||||
tType = self.T_EMPTY if self._noSep else self.T_SEP
|
tType = BlockTyp.EMPTY if self._noSep else BlockTyp.SEP
|
||||||
tStyle = self.A_NONE if self._noSep else self.A_CENTRE
|
tStyle = BlockFmt.NONE if self._noSep else BlockFmt.CENTRE
|
||||||
self._noSep = False
|
self._noSep = False
|
||||||
|
|
||||||
tokens.append((
|
tokens.append((
|
||||||
@@ -792,19 +809,19 @@ class Tokenizer(ABC):
|
|||||||
|
|
||||||
nHead += 1
|
nHead += 1
|
||||||
tText = aLine[5:].strip()
|
tText = aLine[5:].strip()
|
||||||
tType = self.T_HEAD4
|
tType = BlockTyp.HEAD4
|
||||||
tStyle = self.A_NONE
|
tStyle = BlockFmt.NONE
|
||||||
if self._isNovel:
|
if self._isNovel:
|
||||||
if self._hideSection:
|
if self._hideSection:
|
||||||
tText = ""
|
tText = ""
|
||||||
tType = self.T_EMPTY
|
tType = BlockTyp.EMPTY
|
||||||
else:
|
else:
|
||||||
tText = self._hFormatter.apply(self._fmtSection, tText, nHead)
|
tText = self._hFormatter.apply(self._fmtSection, tText, nHead)
|
||||||
if tText == "": # Empty Format
|
if tText == "": # Empty Format
|
||||||
tType = self.T_SKIP
|
tType = BlockTyp.SKIP
|
||||||
elif tText == self._fmtSection: # Static Format
|
elif tText == self._fmtSection: # Static Format
|
||||||
tType = self.T_SEP
|
tType = BlockTyp.SEP
|
||||||
tStyle = self.A_CENTRE
|
tStyle = BlockFmt.CENTRE
|
||||||
|
|
||||||
tokens.append((
|
tokens.append((
|
||||||
tType, nHead, tText, [], tStyle
|
tType, nHead, tText, [], tStyle
|
||||||
@@ -841,21 +858,21 @@ class Tokenizer(ABC):
|
|||||||
aLine = aLine[:-1].rstrip(" ")
|
aLine = aLine[:-1].rstrip(" ")
|
||||||
|
|
||||||
if alnLeft and alnRight:
|
if alnLeft and alnRight:
|
||||||
sAlign |= self.A_CENTRE
|
sAlign |= BlockFmt.CENTRE
|
||||||
elif alnLeft:
|
elif alnLeft:
|
||||||
sAlign |= self.A_LEFT
|
sAlign |= BlockFmt.LEFT
|
||||||
elif alnRight:
|
elif alnRight:
|
||||||
sAlign |= self.A_RIGHT
|
sAlign |= BlockFmt.RIGHT
|
||||||
|
|
||||||
if indLeft:
|
if indLeft:
|
||||||
sAlign |= self.A_IND_L
|
sAlign |= BlockFmt.IND_L
|
||||||
if indRight:
|
if indRight:
|
||||||
sAlign |= self.A_IND_R
|
sAlign |= BlockFmt.IND_R
|
||||||
|
|
||||||
# Process formats
|
# Process formats
|
||||||
tLine, tFmt = self._extractFormats(aLine, hDialog=self._isNovel)
|
tLine, tFmt = self._extractFormats(aLine, hDialog=self._isNovel)
|
||||||
tokens.append((
|
tokens.append((
|
||||||
self.T_TEXT, nHead, tLine, tFmt, sAlign
|
BlockTyp.TEXT, nHead, tLine, tFmt, sAlign
|
||||||
))
|
))
|
||||||
if self._keepRaw:
|
if self._keepRaw:
|
||||||
tmpMarkdown.append(f"{aLine}\n")
|
tmpMarkdown.append(f"{aLine}\n")
|
||||||
@@ -866,15 +883,15 @@ class Tokenizer(ABC):
|
|||||||
|
|
||||||
# Make sure the token array doesn't start with a page break
|
# Make sure the token array doesn't start with a page break
|
||||||
# on the very first page, adding a blank first page.
|
# on the very first page, adding a blank first page.
|
||||||
if tokens[0][4] & self.A_PBB:
|
if tokens[0][4] & BlockFmt.PBB:
|
||||||
cToken = tokens[0]
|
cToken = tokens[0]
|
||||||
tokens[0] = (
|
tokens[0] = (
|
||||||
cToken[0], cToken[1], cToken[2], cToken[3], cToken[4] & ~self.A_PBB
|
cToken[0], cToken[1], cToken[2], cToken[3], cToken[4] & ~BlockFmt.PBB
|
||||||
)
|
)
|
||||||
|
|
||||||
# Always add an empty line at the end of the file
|
# Always add an empty line at the end of the file
|
||||||
tokens.append((
|
tokens.append((
|
||||||
self.T_EMPTY, nHead, "", [], self.A_NONE
|
BlockTyp.EMPTY, nHead, "", [], BlockFmt.NONE
|
||||||
))
|
))
|
||||||
if self._keepRaw:
|
if self._keepRaw:
|
||||||
tmpMarkdown.append("\n")
|
tmpMarkdown.append("\n")
|
||||||
@@ -888,8 +905,8 @@ class Tokenizer(ABC):
|
|||||||
# meta data lines for formats that has spacing.
|
# meta data lines for formats that has spacing.
|
||||||
|
|
||||||
self._tokens = []
|
self._tokens = []
|
||||||
pToken: T_Token = (self.T_EMPTY, 0, "", [], self.A_NONE)
|
pToken: T_Token = (BlockTyp.EMPTY, 0, "", [], BlockFmt.NONE)
|
||||||
nToken: T_Token = (self.T_EMPTY, 0, "", [], self.A_NONE)
|
nToken: T_Token = (BlockTyp.EMPTY, 0, "", [], BlockFmt.NONE)
|
||||||
|
|
||||||
lineSep = "\n" if self._keepBreaks else " "
|
lineSep = "\n" if self._keepBreaks else " "
|
||||||
pLines: list[T_Token] = []
|
pLines: list[T_Token] = []
|
||||||
@@ -908,26 +925,26 @@ class Tokenizer(ABC):
|
|||||||
# specific type
|
# specific type
|
||||||
self._noIndent = True
|
self._noIndent = True
|
||||||
|
|
||||||
if cToken[0] == self.T_EMPTY:
|
if cToken[0] == BlockTyp.EMPTY:
|
||||||
# We don't need to keep the empty lines after this pass
|
# We don't need to keep the empty lines after this pass
|
||||||
pass
|
pass
|
||||||
|
|
||||||
elif cToken[0] == self.T_KEYWORD:
|
elif cToken[0] == BlockTyp.KEYWORD:
|
||||||
# Adjust margins for lines in a list of keyword lines
|
# Adjust margins for lines in a list of keyword lines
|
||||||
aStyle = cToken[4]
|
aStyle = cToken[4]
|
||||||
if pToken[0] == self.T_KEYWORD:
|
if pToken[0] == BlockTyp.KEYWORD:
|
||||||
aStyle |= self.A_Z_TOPMRG
|
aStyle |= BlockFmt.Z_TOPMRG
|
||||||
if nToken[0] == self.T_KEYWORD:
|
if nToken[0] == BlockTyp.KEYWORD:
|
||||||
aStyle |= self.A_Z_BTMMRG
|
aStyle |= BlockFmt.Z_BTMMRG
|
||||||
self._tokens.append((
|
self._tokens.append((
|
||||||
cToken[0], cToken[1], cToken[2], cToken[3], aStyle
|
cToken[0], cToken[1], cToken[2], cToken[3], aStyle
|
||||||
))
|
))
|
||||||
|
|
||||||
elif cToken[0] == self.T_TEXT:
|
elif cToken[0] == BlockTyp.TEXT:
|
||||||
# Combine lines from the same paragraph
|
# Combine lines from the same paragraph
|
||||||
pLines.append(cToken)
|
pLines.append(cToken)
|
||||||
|
|
||||||
if nToken[0] != self.T_TEXT:
|
if nToken[0] != BlockTyp.TEXT:
|
||||||
# Next token is not text, so we add the buffer to tokens
|
# Next token is not text, so we add the buffer to tokens
|
||||||
nLines = len(pLines)
|
nLines = len(pLines)
|
||||||
cStyle = pLines[0][4]
|
cStyle = pLines[0][4]
|
||||||
@@ -935,16 +952,16 @@ class Tokenizer(ABC):
|
|||||||
# If paragraph indentation is enabled, not temporarily
|
# If paragraph indentation is enabled, not temporarily
|
||||||
# turned off, and the block is not aligned, we add the
|
# turned off, and the block is not aligned, we add the
|
||||||
# text indentation flag
|
# text indentation flag
|
||||||
cStyle |= self.A_IND_T
|
cStyle |= BlockFmt.IND_T
|
||||||
|
|
||||||
if nLines == 1:
|
if nLines == 1:
|
||||||
# The paragraph contains a single line, so we just save
|
# The paragraph contains a single line, so we just save
|
||||||
# that directly to the token list. If justify is
|
# that directly to the token list. If justify is
|
||||||
# enabled, and there is no alignment, we apply it.
|
# enabled, and there is no alignment, we apply it.
|
||||||
if self._doJustify and not cStyle & self.M_ALIGNED:
|
if self._doJustify and not cStyle & self.M_ALIGNED:
|
||||||
cStyle |= self.A_JUSTIFY
|
cStyle |= BlockFmt.JUSTIFY
|
||||||
self._tokens.append((
|
self._tokens.append((
|
||||||
self.T_TEXT, pLines[0][1], pLines[0][2], pLines[0][3], cStyle
|
BlockTyp.TEXT, pLines[0][1], pLines[0][2], pLines[0][3], cStyle
|
||||||
))
|
))
|
||||||
elif nLines > 1:
|
elif nLines > 1:
|
||||||
# The paragraph contains multiple lines, so we need to
|
# The paragraph contains multiple lines, so we need to
|
||||||
@@ -957,7 +974,7 @@ class Tokenizer(ABC):
|
|||||||
tTxt += f"{aToken[2]}{lineSep}"
|
tTxt += f"{aToken[2]}{lineSep}"
|
||||||
tFmt.extend((p+tLen, fmt, key) for p, fmt, key in aToken[3])
|
tFmt.extend((p+tLen, fmt, key) for p, fmt, key in aToken[3])
|
||||||
self._tokens.append((
|
self._tokens.append((
|
||||||
self.T_TEXT, pLines[0][1], tTxt[:-1], tFmt, cStyle
|
BlockTyp.TEXT, pLines[0][1], tTxt[:-1], tFmt, cStyle
|
||||||
))
|
))
|
||||||
|
|
||||||
# Reset buffer and make sure text indent is on for next pass
|
# Reset buffer and make sure text indent is on for next pass
|
||||||
@@ -974,13 +991,13 @@ class Tokenizer(ABC):
|
|||||||
tHandle = self._handle or ""
|
tHandle = self._handle or ""
|
||||||
isNovel = self._isNovel
|
isNovel = self._isNovel
|
||||||
for tType, nHead, tText, _, _ in self._tokens:
|
for tType, nHead, tText, _, _ in self._tokens:
|
||||||
if tType == self.T_TITLE:
|
if tType == BlockTyp.TITLE:
|
||||||
prefix = "TT"
|
prefix = "TT"
|
||||||
elif tType == self.T_HEAD1:
|
elif tType == BlockTyp.HEAD1:
|
||||||
prefix = "PT" if isNovel else "H1"
|
prefix = "PT" if isNovel else "H1"
|
||||||
elif tType == self.T_HEAD2:
|
elif tType == BlockTyp.HEAD2:
|
||||||
prefix = "CH" if isNovel else "H2"
|
prefix = "CH" if isNovel else "H2"
|
||||||
elif tType == self.T_HEAD3:
|
elif tType == BlockTyp.HEAD3:
|
||||||
prefix = "SC" if isNovel else "H3"
|
prefix = "SC" if isNovel else "H3"
|
||||||
else:
|
else:
|
||||||
continue
|
continue
|
||||||
@@ -1017,7 +1034,7 @@ class Tokenizer(ABC):
|
|||||||
nChars = len(tText)
|
nChars = len(tText)
|
||||||
nWChars = len("".join(tWords))
|
nWChars = len("".join(tWords))
|
||||||
|
|
||||||
if tType == self.T_TEXT:
|
if tType == BlockTyp.TEXT:
|
||||||
tPWords = tText.split()
|
tPWords = tText.split()
|
||||||
nPWords = len(tPWords)
|
nPWords = len(tPWords)
|
||||||
nPChars = len(tText)
|
nPChars = len(tText)
|
||||||
@@ -1040,33 +1057,33 @@ class Tokenizer(ABC):
|
|||||||
titleChars += nChars
|
titleChars += nChars
|
||||||
titleWordChars += nWChars
|
titleWordChars += nWChars
|
||||||
|
|
||||||
elif tType == self.T_SEP:
|
elif tType == BlockTyp.SEP:
|
||||||
allWords += nWords
|
allWords += nWords
|
||||||
allChars += nChars
|
allChars += nChars
|
||||||
allWordChars += nWChars
|
allWordChars += nWChars
|
||||||
|
|
||||||
elif tType == self.T_SYNOPSIS and self._doSynopsis:
|
elif tType == BlockTyp.SYNOPSIS and self._doSynopsis:
|
||||||
text = "{0}: {1}".format(self._localLookup("Synopsis"), tText)
|
text = "{0}: {1}".format(self._localLookup("Synopsis"), tText)
|
||||||
words = text.split()
|
words = text.split()
|
||||||
allWords += len(words)
|
allWords += len(words)
|
||||||
allChars += len(text)
|
allChars += len(text)
|
||||||
allWordChars += len("".join(words))
|
allWordChars += len("".join(words))
|
||||||
|
|
||||||
elif tType == self.T_SHORT and self._doSynopsis:
|
elif tType == BlockTyp.SHORT and self._doSynopsis:
|
||||||
text = "{0}: {1}".format(self._localLookup("Short Description"), tText)
|
text = "{0}: {1}".format(self._localLookup("Short Description"), tText)
|
||||||
words = text.split()
|
words = text.split()
|
||||||
allWords += len(words)
|
allWords += len(words)
|
||||||
allChars += len(text)
|
allChars += len(text)
|
||||||
allWordChars += len("".join(words))
|
allWordChars += len("".join(words))
|
||||||
|
|
||||||
elif tType == self.T_COMMENT and self._doComments:
|
elif tType == BlockTyp.COMMENT and self._doComments:
|
||||||
text = "{0}: {1}".format(self._localLookup("Comment"), tText)
|
text = "{0}: {1}".format(self._localLookup("Comment"), tText)
|
||||||
words = text.split()
|
words = text.split()
|
||||||
allWords += len(words)
|
allWords += len(words)
|
||||||
allChars += len(text)
|
allChars += len(text)
|
||||||
allWordChars += len("".join(words))
|
allWordChars += len("".join(words))
|
||||||
|
|
||||||
elif tType == self.T_KEYWORD and self._doKeywords:
|
elif tType == BlockTyp.KEYWORD and self._doKeywords:
|
||||||
valid, bits, _ = self._project.index.scanThis("@"+tText)
|
valid, bits, _ = self._project.index.scanThis("@"+tText)
|
||||||
if valid and bits:
|
if valid and bits:
|
||||||
key = self._localLookup(nwLabels.KEY_NAME[bits[0]])
|
key = self._localLookup(nwLabels.KEY_NAME[bits[0]])
|
||||||
@@ -1155,7 +1172,7 @@ class Tokenizer(ABC):
|
|||||||
kind = self._shortCodeVals.get(res.group(1).lower(), 0)
|
kind = self._shortCodeVals.get(res.group(1).lower(), 0)
|
||||||
temp.append((
|
temp.append((
|
||||||
res.start(0), res.end(0),
|
res.start(0), res.end(0),
|
||||||
self.FMT_STRIP if kind == skip else kind,
|
TextFmt.STRIP if kind == skip else kind,
|
||||||
f"{tHandle}:{res.group(2)}",
|
f"{tHandle}:{res.group(2)}",
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|||||||
@@ -29,47 +29,47 @@ from pathlib import Path
|
|||||||
|
|
||||||
from novelwriter.constants import nwHeadFmt, nwLabels, nwUnicode
|
from novelwriter.constants import nwHeadFmt, nwLabels, nwUnicode
|
||||||
from novelwriter.core.project import NWProject
|
from novelwriter.core.project import NWProject
|
||||||
from novelwriter.formats.tokenizer import T_Formats, Tokenizer
|
from novelwriter.formats.tokenizer import BlockFmt, BlockTyp, T_Formats, TextFmt, Tokenizer
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
# Standard Markdown
|
# Standard Markdown
|
||||||
STD_MD = {
|
STD_MD = {
|
||||||
Tokenizer.FMT_B_B: "**",
|
TextFmt.B_B: "**",
|
||||||
Tokenizer.FMT_B_E: "**",
|
TextFmt.B_E: "**",
|
||||||
Tokenizer.FMT_I_B: "_",
|
TextFmt.I_B: "_",
|
||||||
Tokenizer.FMT_I_E: "_",
|
TextFmt.I_E: "_",
|
||||||
Tokenizer.FMT_D_B: "",
|
TextFmt.D_B: "",
|
||||||
Tokenizer.FMT_D_E: "",
|
TextFmt.D_E: "",
|
||||||
Tokenizer.FMT_U_B: "",
|
TextFmt.U_B: "",
|
||||||
Tokenizer.FMT_U_E: "",
|
TextFmt.U_E: "",
|
||||||
Tokenizer.FMT_M_B: "",
|
TextFmt.M_B: "",
|
||||||
Tokenizer.FMT_M_E: "",
|
TextFmt.M_E: "",
|
||||||
Tokenizer.FMT_SUP_B: "",
|
TextFmt.SUP_B: "",
|
||||||
Tokenizer.FMT_SUP_E: "",
|
TextFmt.SUP_E: "",
|
||||||
Tokenizer.FMT_SUB_B: "",
|
TextFmt.SUB_B: "",
|
||||||
Tokenizer.FMT_SUB_E: "",
|
TextFmt.SUB_E: "",
|
||||||
Tokenizer.FMT_STRIP: "",
|
TextFmt.STRIP: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Extended Markdown
|
# Extended Markdown
|
||||||
EXT_MD = {
|
EXT_MD = {
|
||||||
Tokenizer.FMT_B_B: "**",
|
TextFmt.B_B: "**",
|
||||||
Tokenizer.FMT_B_E: "**",
|
TextFmt.B_E: "**",
|
||||||
Tokenizer.FMT_I_B: "_",
|
TextFmt.I_B: "_",
|
||||||
Tokenizer.FMT_I_E: "_",
|
TextFmt.I_E: "_",
|
||||||
Tokenizer.FMT_D_B: "~~",
|
TextFmt.D_B: "~~",
|
||||||
Tokenizer.FMT_D_E: "~~",
|
TextFmt.D_E: "~~",
|
||||||
Tokenizer.FMT_U_B: "",
|
TextFmt.U_B: "",
|
||||||
Tokenizer.FMT_U_E: "",
|
TextFmt.U_E: "",
|
||||||
Tokenizer.FMT_M_B: "==",
|
TextFmt.M_B: "==",
|
||||||
Tokenizer.FMT_M_E: "==",
|
TextFmt.M_E: "==",
|
||||||
Tokenizer.FMT_SUP_B: "^",
|
TextFmt.SUP_B: "^",
|
||||||
Tokenizer.FMT_SUP_E: "^",
|
TextFmt.SUP_E: "^",
|
||||||
Tokenizer.FMT_SUB_B: "~",
|
TextFmt.SUB_B: "~",
|
||||||
Tokenizer.FMT_SUB_E: "~",
|
TextFmt.SUB_E: "~",
|
||||||
Tokenizer.FMT_STRIP: "",
|
TextFmt.STRIP: "",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -119,49 +119,49 @@ class ToMarkdown(Tokenizer):
|
|||||||
lines = []
|
lines = []
|
||||||
for tType, _, tText, tFormat, tStyle in self._tokens:
|
for tType, _, tText, tFormat, tStyle in self._tokens:
|
||||||
|
|
||||||
if tType == self.T_TEXT:
|
if tType == BlockTyp.TEXT:
|
||||||
tTemp = self._formatText(tText, tFormat, mTags).replace("\n", " \n")
|
tTemp = self._formatText(tText, tFormat, mTags).replace("\n", " \n")
|
||||||
lines.append(f"{tTemp}\n\n")
|
lines.append(f"{tTemp}\n\n")
|
||||||
|
|
||||||
elif tType == self.T_TITLE:
|
elif tType == BlockTyp.TITLE:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
lines.append(f"# {tHead}\n\n")
|
lines.append(f"# {tHead}\n\n")
|
||||||
|
|
||||||
elif tType == self.T_HEAD1:
|
elif tType == BlockTyp.HEAD1:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
lines.append(f"# {tHead}\n\n")
|
lines.append(f"# {tHead}\n\n")
|
||||||
|
|
||||||
elif tType == self.T_HEAD2:
|
elif tType == BlockTyp.HEAD2:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
lines.append(f"## {tHead}\n\n")
|
lines.append(f"## {tHead}\n\n")
|
||||||
|
|
||||||
elif tType == self.T_HEAD3:
|
elif tType == BlockTyp.HEAD3:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
lines.append(f"### {tHead}\n\n")
|
lines.append(f"### {tHead}\n\n")
|
||||||
|
|
||||||
elif tType == self.T_HEAD4:
|
elif tType == BlockTyp.HEAD4:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
lines.append(f"#### {tHead}\n\n")
|
lines.append(f"#### {tHead}\n\n")
|
||||||
|
|
||||||
elif tType == self.T_SEP:
|
elif tType == BlockTyp.SEP:
|
||||||
lines.append(f"{tText}\n\n")
|
lines.append(f"{tText}\n\n")
|
||||||
|
|
||||||
elif tType == self.T_SKIP:
|
elif tType == BlockTyp.SKIP:
|
||||||
lines.append(f"{cSkip}\n\n")
|
lines.append(f"{cSkip}\n\n")
|
||||||
|
|
||||||
elif tType == self.T_SYNOPSIS and self._doSynopsis:
|
elif tType == BlockTyp.SYNOPSIS and self._doSynopsis:
|
||||||
label = self._localLookup("Synopsis")
|
label = self._localLookup("Synopsis")
|
||||||
lines.append(f"**{label}:** {self._formatText(tText, tFormat, mTags)}\n\n")
|
lines.append(f"**{label}:** {self._formatText(tText, tFormat, mTags)}\n\n")
|
||||||
|
|
||||||
elif tType == self.T_SHORT and self._doSynopsis:
|
elif tType == BlockTyp.SHORT and self._doSynopsis:
|
||||||
label = self._localLookup("Short Description")
|
label = self._localLookup("Short Description")
|
||||||
lines.append(f"**{label}:** {self._formatText(tText, tFormat, mTags)}\n\n")
|
lines.append(f"**{label}:** {self._formatText(tText, tFormat, mTags)}\n\n")
|
||||||
|
|
||||||
elif tType == self.T_COMMENT and self._doComments:
|
elif tType == BlockTyp.COMMENT and self._doComments:
|
||||||
label = self._localLookup("Comment")
|
label = self._localLookup("Comment")
|
||||||
lines.append(f"**{label}:** {self._formatText(tText, tFormat, mTags)}\n\n")
|
lines.append(f"**{label}:** {self._formatText(tText, tFormat, mTags)}\n\n")
|
||||||
|
|
||||||
elif tType == self.T_KEYWORD and self._doKeywords:
|
elif tType == BlockTyp.KEYWORD and self._doKeywords:
|
||||||
lines.append(self._formatKeywords(tText, tStyle))
|
lines.append(self._formatKeywords(tText, tStyle))
|
||||||
|
|
||||||
self._result = "".join(lines)
|
self._result = "".join(lines)
|
||||||
@@ -207,12 +207,12 @@ class ToMarkdown(Tokenizer):
|
|||||||
# Internal Functions
|
# Internal Functions
|
||||||
##
|
##
|
||||||
|
|
||||||
def _formatText(self, text: str, tFmt: T_Formats, tags: dict[int, str]) -> str:
|
def _formatText(self, text: str, tFmt: T_Formats, tags: dict[TextFmt, str]) -> str:
|
||||||
"""Apply formatting tags to text."""
|
"""Apply formatting tags to text."""
|
||||||
temp = text
|
temp = text
|
||||||
for pos, fmt, data in reversed(tFmt):
|
for pos, fmt, data in reversed(tFmt):
|
||||||
md = ""
|
md = ""
|
||||||
if fmt == self.FMT_FNOTE:
|
if fmt == TextFmt.FNOTE:
|
||||||
if data in self._footnotes:
|
if data in self._footnotes:
|
||||||
index = len(self._usedNotes) + 1
|
index = len(self._usedNotes) + 1
|
||||||
self._usedNotes[data] = index
|
self._usedNotes[data] = index
|
||||||
@@ -224,7 +224,7 @@ class ToMarkdown(Tokenizer):
|
|||||||
temp = f"{temp[:pos]}{md}{temp[pos:]}"
|
temp = f"{temp[:pos]}{md}{temp[pos:]}"
|
||||||
return temp
|
return temp
|
||||||
|
|
||||||
def _formatKeywords(self, text: str, style: int) -> str:
|
def _formatKeywords(self, text: str, style: BlockFmt) -> str:
|
||||||
"""Apply Markdown formatting to keywords."""
|
"""Apply Markdown formatting to keywords."""
|
||||||
valid, bits, _ = self._project.index.scanThis("@"+text)
|
valid, bits, _ = self._project.index.scanThis("@"+text)
|
||||||
if not valid or not bits:
|
if not valid or not bits:
|
||||||
@@ -236,6 +236,6 @@ class ToMarkdown(Tokenizer):
|
|||||||
if len(bits) > 1:
|
if len(bits) > 1:
|
||||||
result += ", ".join(bits[1:])
|
result += ", ".join(bits[1:])
|
||||||
|
|
||||||
result += " \n" if style & self.A_Z_BTMMRG else "\n\n"
|
result += " \n" if style & BlockFmt.Z_BTMMRG else "\n\n"
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ from novelwriter import __version__
|
|||||||
from novelwriter.common import xmlIndent, xmlSubElem
|
from novelwriter.common import xmlIndent, xmlSubElem
|
||||||
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, nwStyles
|
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, nwStyles
|
||||||
from novelwriter.core.project import NWProject
|
from novelwriter.core.project import NWProject
|
||||||
from novelwriter.formats.tokenizer import T_Formats, Tokenizer, stripEscape
|
from novelwriter.formats.tokenizer import (
|
||||||
|
BlockFmt, BlockTyp, T_Formats, TextFmt, Tokenizer, stripEscape
|
||||||
|
)
|
||||||
from novelwriter.types import FONT_STYLE, FONT_WEIGHTS
|
from novelwriter.types import FONT_STYLE, FONT_WEIGHTS
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -429,79 +431,79 @@ class ToOdt(Tokenizer):
|
|||||||
# Styles
|
# Styles
|
||||||
oStyle = ODTParagraphStyle("New")
|
oStyle = ODTParagraphStyle("New")
|
||||||
if tStyle is not None:
|
if tStyle is not None:
|
||||||
if tStyle & self.A_LEFT:
|
if tStyle & BlockFmt.LEFT:
|
||||||
oStyle.setTextAlign("left")
|
oStyle.setTextAlign("left")
|
||||||
elif tStyle & self.A_RIGHT:
|
elif tStyle & BlockFmt.RIGHT:
|
||||||
oStyle.setTextAlign("right")
|
oStyle.setTextAlign("right")
|
||||||
elif tStyle & self.A_CENTRE:
|
elif tStyle & BlockFmt.CENTRE:
|
||||||
oStyle.setTextAlign("center")
|
oStyle.setTextAlign("center")
|
||||||
elif tStyle & self.A_JUSTIFY:
|
elif tStyle & BlockFmt.JUSTIFY:
|
||||||
oStyle.setTextAlign("justify")
|
oStyle.setTextAlign("justify")
|
||||||
|
|
||||||
if tStyle & self.A_PBB:
|
if tStyle & BlockFmt.PBB:
|
||||||
oStyle.setBreakBefore("page")
|
oStyle.setBreakBefore("page")
|
||||||
if tStyle & self.A_PBA:
|
if tStyle & BlockFmt.PBA:
|
||||||
oStyle.setBreakAfter("page")
|
oStyle.setBreakAfter("page")
|
||||||
|
|
||||||
if tStyle & self.A_Z_BTMMRG:
|
if tStyle & BlockFmt.Z_BTMMRG:
|
||||||
oStyle.setMarginBottom("0.000cm")
|
oStyle.setMarginBottom("0.000cm")
|
||||||
if tStyle & self.A_Z_TOPMRG:
|
if tStyle & BlockFmt.Z_TOPMRG:
|
||||||
oStyle.setMarginTop("0.000cm")
|
oStyle.setMarginTop("0.000cm")
|
||||||
|
|
||||||
if tStyle & self.A_IND_L:
|
if tStyle & BlockFmt.IND_L:
|
||||||
oStyle.setMarginLeft(self._fBlockIndent)
|
oStyle.setMarginLeft(self._fBlockIndent)
|
||||||
if tStyle & self.A_IND_R:
|
if tStyle & BlockFmt.IND_R:
|
||||||
oStyle.setMarginRight(self._fBlockIndent)
|
oStyle.setMarginRight(self._fBlockIndent)
|
||||||
|
|
||||||
# Process Text Types
|
# Process Text Types
|
||||||
if tType == self.T_TEXT:
|
if tType == BlockTyp.TEXT:
|
||||||
# Text indentation is processed here because there is a
|
# Text indentation is processed here because there is a
|
||||||
# dedicated pre-defined style for it
|
# dedicated pre-defined style for it
|
||||||
if tStyle & self.A_IND_T:
|
if tStyle & BlockFmt.IND_T:
|
||||||
self._addTextPar(xText, S_FIND, oStyle, tText, tFmt=tFormat)
|
self._addTextPar(xText, S_FIND, oStyle, tText, tFmt=tFormat)
|
||||||
else:
|
else:
|
||||||
self._addTextPar(xText, S_TEXT, oStyle, tText, tFmt=tFormat)
|
self._addTextPar(xText, S_TEXT, oStyle, tText, tFmt=tFormat)
|
||||||
|
|
||||||
elif tType == self.T_TITLE:
|
elif tType == BlockTyp.TITLE:
|
||||||
# Title must be text:p
|
# Title must be text:p
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
self._addTextPar(xText, S_TITLE, oStyle, tHead, isHead=False)
|
self._addTextPar(xText, S_TITLE, oStyle, tHead, isHead=False)
|
||||||
|
|
||||||
elif tType == self.T_HEAD1:
|
elif tType == BlockTyp.HEAD1:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
self._addTextPar(xText, S_HEAD1, oStyle, tHead, isHead=True, oLevel="1")
|
self._addTextPar(xText, S_HEAD1, oStyle, tHead, isHead=True, oLevel="1")
|
||||||
|
|
||||||
elif tType == self.T_HEAD2:
|
elif tType == BlockTyp.HEAD2:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
self._addTextPar(xText, S_HEAD2, oStyle, tHead, isHead=True, oLevel="2")
|
self._addTextPar(xText, S_HEAD2, oStyle, tHead, isHead=True, oLevel="2")
|
||||||
|
|
||||||
elif tType == self.T_HEAD3:
|
elif tType == BlockTyp.HEAD3:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
self._addTextPar(xText, S_HEAD3, oStyle, tHead, isHead=True, oLevel="3")
|
self._addTextPar(xText, S_HEAD3, oStyle, tHead, isHead=True, oLevel="3")
|
||||||
|
|
||||||
elif tType == self.T_HEAD4:
|
elif tType == BlockTyp.HEAD4:
|
||||||
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
tHead = tText.replace(nwHeadFmt.BR, "\n")
|
||||||
self._addTextPar(xText, S_HEAD4, oStyle, tHead, isHead=True, oLevel="4")
|
self._addTextPar(xText, S_HEAD4, oStyle, tHead, isHead=True, oLevel="4")
|
||||||
|
|
||||||
elif tType == self.T_SEP:
|
elif tType == BlockTyp.SEP:
|
||||||
self._addTextPar(xText, S_SEP, oStyle, tText)
|
self._addTextPar(xText, S_SEP, oStyle, tText)
|
||||||
|
|
||||||
elif tType == self.T_SKIP:
|
elif tType == BlockTyp.SKIP:
|
||||||
self._addTextPar(xText, S_TEXT, oStyle, "")
|
self._addTextPar(xText, S_TEXT, oStyle, "")
|
||||||
|
|
||||||
elif tType == self.T_SYNOPSIS and self._doSynopsis:
|
elif tType == BlockTyp.SYNOPSIS and self._doSynopsis:
|
||||||
tTemp, tFmt = self._formatSynopsis(tText, tFormat, True)
|
tTemp, tFmt = self._formatSynopsis(tText, tFormat, True)
|
||||||
self._addTextPar(xText, S_META, oStyle, tTemp, tFmt=tFmt)
|
self._addTextPar(xText, S_META, oStyle, tTemp, tFmt=tFmt)
|
||||||
|
|
||||||
elif tType == self.T_SHORT and self._doSynopsis:
|
elif tType == BlockTyp.SHORT and self._doSynopsis:
|
||||||
tTemp, tFmt = self._formatSynopsis(tText, tFormat, False)
|
tTemp, tFmt = self._formatSynopsis(tText, tFormat, False)
|
||||||
self._addTextPar(xText, S_META, oStyle, tTemp, tFmt=tFmt)
|
self._addTextPar(xText, S_META, oStyle, tTemp, tFmt=tFmt)
|
||||||
|
|
||||||
elif tType == self.T_COMMENT and self._doComments:
|
elif tType == BlockTyp.COMMENT and self._doComments:
|
||||||
tTemp, tFmt = self._formatComments(tText, tFormat)
|
tTemp, tFmt = self._formatComments(tText, tFormat)
|
||||||
self._addTextPar(xText, S_META, oStyle, tTemp, tFmt=tFmt)
|
self._addTextPar(xText, S_META, oStyle, tTemp, tFmt=tFmt)
|
||||||
|
|
||||||
elif tType == self.T_KEYWORD and self._doKeywords:
|
elif tType == BlockTyp.KEYWORD and self._doKeywords:
|
||||||
tTemp, tFmt = self._formatKeywords(tText)
|
tTemp, tFmt = self._formatKeywords(tText)
|
||||||
self._addTextPar(xText, S_META, oStyle, tTemp, tFmt=tFmt)
|
self._addTextPar(xText, S_META, oStyle, tTemp, tFmt=tFmt)
|
||||||
|
|
||||||
@@ -576,7 +578,7 @@ class ToOdt(Tokenizer):
|
|||||||
name = self._localLookup("Synopsis" if synopsis else "Short Description")
|
name = self._localLookup("Synopsis" if synopsis else "Short Description")
|
||||||
shift = len(name) + 2
|
shift = len(name) + 2
|
||||||
rTxt = f"{name}: {text}"
|
rTxt = f"{name}: {text}"
|
||||||
rFmt: T_Formats = [(0, self.FMT_B_B, ""), (len(name) + 1, self.FMT_B_E, "")]
|
rFmt: T_Formats = [(0, TextFmt.B_B, ""), (len(name) + 1, TextFmt.B_E, "")]
|
||||||
rFmt.extend((p + shift, f, d) for p, f, d in fmt)
|
rFmt.extend((p + shift, f, d) for p, f, d in fmt)
|
||||||
return rTxt, rFmt
|
return rTxt, rFmt
|
||||||
|
|
||||||
@@ -585,7 +587,7 @@ class ToOdt(Tokenizer):
|
|||||||
name = self._localLookup("Comment")
|
name = self._localLookup("Comment")
|
||||||
shift = len(name) + 2
|
shift = len(name) + 2
|
||||||
rTxt = f"{name}: {text}"
|
rTxt = f"{name}: {text}"
|
||||||
rFmt: T_Formats = [(0, self.FMT_B_B, ""), (len(name) + 1, self.FMT_B_E, "")]
|
rFmt: T_Formats = [(0, TextFmt.B_B, ""), (len(name) + 1, TextFmt.B_E, "")]
|
||||||
rFmt.extend((p + shift, f, d) for p, f, d in fmt)
|
rFmt.extend((p + shift, f, d) for p, f, d in fmt)
|
||||||
return rTxt, rFmt
|
return rTxt, rFmt
|
||||||
|
|
||||||
@@ -596,7 +598,7 @@ class ToOdt(Tokenizer):
|
|||||||
return "", []
|
return "", []
|
||||||
|
|
||||||
rTxt = f"{self._localLookup(nwLabels.KEY_NAME[bits[0]])}: "
|
rTxt = f"{self._localLookup(nwLabels.KEY_NAME[bits[0]])}: "
|
||||||
rFmt: T_Formats = [(0, self.FMT_B_B, ""), (len(rTxt) - 1, self.FMT_B_E, "")]
|
rFmt: T_Formats = [(0, TextFmt.B_B, ""), (len(rTxt) - 1, TextFmt.B_E, "")]
|
||||||
if len(bits) > 1:
|
if len(bits) > 1:
|
||||||
if bits[0] == nwKeyWords.TAG_KEY:
|
if bits[0] == nwKeyWords.TAG_KEY:
|
||||||
rTxt += bits[1]
|
rTxt += bits[1]
|
||||||
@@ -654,45 +656,45 @@ class ToOdt(Tokenizer):
|
|||||||
parProc.appendSpan(tFrag, self._textStyle(xFmt))
|
parProc.appendSpan(tFrag, self._textStyle(xFmt))
|
||||||
|
|
||||||
# Calculate the change of format
|
# Calculate the change of format
|
||||||
if fFmt == self.FMT_B_B:
|
if fFmt == TextFmt.B_B:
|
||||||
xFmt |= X_BLD
|
xFmt |= X_BLD
|
||||||
elif fFmt == self.FMT_B_E:
|
elif fFmt == TextFmt.B_E:
|
||||||
xFmt &= M_BLD
|
xFmt &= M_BLD
|
||||||
elif fFmt == self.FMT_I_B:
|
elif fFmt == TextFmt.I_B:
|
||||||
xFmt |= X_ITA
|
xFmt |= X_ITA
|
||||||
elif fFmt == self.FMT_I_E:
|
elif fFmt == TextFmt.I_E:
|
||||||
xFmt &= M_ITA
|
xFmt &= M_ITA
|
||||||
elif fFmt == self.FMT_D_B:
|
elif fFmt == TextFmt.D_B:
|
||||||
xFmt |= X_DEL
|
xFmt |= X_DEL
|
||||||
elif fFmt == self.FMT_D_E:
|
elif fFmt == TextFmt.D_E:
|
||||||
xFmt &= M_DEL
|
xFmt &= M_DEL
|
||||||
elif fFmt == self.FMT_U_B:
|
elif fFmt == TextFmt.U_B:
|
||||||
xFmt |= X_UND
|
xFmt |= X_UND
|
||||||
elif fFmt == self.FMT_U_E:
|
elif fFmt == TextFmt.U_E:
|
||||||
xFmt &= M_UND
|
xFmt &= M_UND
|
||||||
elif fFmt == self.FMT_M_B:
|
elif fFmt == TextFmt.M_B:
|
||||||
xFmt |= X_MRK
|
xFmt |= X_MRK
|
||||||
elif fFmt == self.FMT_M_E:
|
elif fFmt == TextFmt.M_E:
|
||||||
xFmt &= M_MRK
|
xFmt &= M_MRK
|
||||||
elif fFmt == self.FMT_SUP_B:
|
elif fFmt == TextFmt.SUP_B:
|
||||||
xFmt |= X_SUP
|
xFmt |= X_SUP
|
||||||
elif fFmt == self.FMT_SUP_E:
|
elif fFmt == TextFmt.SUP_E:
|
||||||
xFmt &= M_SUP
|
xFmt &= M_SUP
|
||||||
elif fFmt == self.FMT_SUB_B:
|
elif fFmt == TextFmt.SUB_B:
|
||||||
xFmt |= X_SUB
|
xFmt |= X_SUB
|
||||||
elif fFmt == self.FMT_SUB_E:
|
elif fFmt == TextFmt.SUB_E:
|
||||||
xFmt &= M_SUB
|
xFmt &= M_SUB
|
||||||
elif fFmt == self.FMT_DL_B:
|
elif fFmt == TextFmt.DL_B:
|
||||||
xFmt |= X_DLG
|
xFmt |= X_DLG
|
||||||
elif fFmt == self.FMT_DL_E:
|
elif fFmt == TextFmt.DL_E:
|
||||||
xFmt &= M_DLG
|
xFmt &= M_DLG
|
||||||
elif fFmt == self.FMT_ADL_B:
|
elif fFmt == TextFmt.ADL_B:
|
||||||
xFmt |= X_DLA
|
xFmt |= X_DLA
|
||||||
elif fFmt == self.FMT_ADL_E:
|
elif fFmt == TextFmt.ADL_E:
|
||||||
xFmt &= M_DLA
|
xFmt &= M_DLA
|
||||||
elif fFmt == self.FMT_FNOTE:
|
elif fFmt == TextFmt.FNOTE:
|
||||||
xNode = self._generateFootnote(fData)
|
xNode = self._generateFootnote(fData)
|
||||||
elif fFmt == self.FMT_STRIP:
|
elif fFmt == TextFmt.STRIP:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
pErr += 1
|
pErr += 1
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ from PyQt5.QtPrintSupport import QPrinter
|
|||||||
|
|
||||||
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, nwStyles, nwUnicode
|
from novelwriter.constants import nwHeadFmt, nwKeyWords, nwLabels, nwStyles, nwUnicode
|
||||||
from novelwriter.core.project import NWProject
|
from novelwriter.core.project import NWProject
|
||||||
from novelwriter.formats.tokenizer import T_Formats, Tokenizer
|
from novelwriter.formats.tokenizer import BlockFmt, BlockTyp, T_Formats, TextFmt, Tokenizer
|
||||||
from novelwriter.types import (
|
from novelwriter.types import (
|
||||||
QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight,
|
QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight,
|
||||||
QtPageBreakAfter, QtPageBreakBefore, QtTransparent, QtVAlignNormal,
|
QtPageBreakAfter, QtPageBreakBefore, QtTransparent, QtVAlignNormal,
|
||||||
@@ -141,20 +141,20 @@ class ToQTextDocument(Tokenizer):
|
|||||||
# ============
|
# ============
|
||||||
|
|
||||||
self._mHead = {
|
self._mHead = {
|
||||||
self.T_TITLE: (mPx * self._marginTitle[0], mPx * self._marginTitle[1]),
|
BlockTyp.TITLE: (mPx * self._marginTitle[0], mPx * self._marginTitle[1]),
|
||||||
self.T_HEAD1: (mPx * self._marginHead1[0], mPx * self._marginHead1[1]),
|
BlockTyp.HEAD1: (mPx * self._marginHead1[0], mPx * self._marginHead1[1]),
|
||||||
self.T_HEAD2: (mPx * self._marginHead2[0], mPx * self._marginHead2[1]),
|
BlockTyp.HEAD2: (mPx * self._marginHead2[0], mPx * self._marginHead2[1]),
|
||||||
self.T_HEAD3: (mPx * self._marginHead3[0], mPx * self._marginHead3[1]),
|
BlockTyp.HEAD3: (mPx * self._marginHead3[0], mPx * self._marginHead3[1]),
|
||||||
self.T_HEAD4: (mPx * self._marginHead4[0], mPx * self._marginHead4[1]),
|
BlockTyp.HEAD4: (mPx * self._marginHead4[0], mPx * self._marginHead4[1]),
|
||||||
}
|
}
|
||||||
|
|
||||||
hScale = self._scaleHeads
|
hScale = self._scaleHeads
|
||||||
self._sHead = {
|
self._sHead = {
|
||||||
self.T_TITLE: (nwStyles.H_SIZES.get(0, 1.0) * fPt) if hScale else fPt,
|
BlockTyp.TITLE: (nwStyles.H_SIZES.get(0, 1.0) * fPt) if hScale else fPt,
|
||||||
self.T_HEAD1: (nwStyles.H_SIZES.get(1, 1.0) * fPt) if hScale else fPt,
|
BlockTyp.HEAD1: (nwStyles.H_SIZES.get(1, 1.0) * fPt) if hScale else fPt,
|
||||||
self.T_HEAD2: (nwStyles.H_SIZES.get(2, 1.0) * fPt) if hScale else fPt,
|
BlockTyp.HEAD2: (nwStyles.H_SIZES.get(2, 1.0) * fPt) if hScale else fPt,
|
||||||
self.T_HEAD3: (nwStyles.H_SIZES.get(3, 1.0) * fPt) if hScale else fPt,
|
BlockTyp.HEAD3: (nwStyles.H_SIZES.get(3, 1.0) * fPt) if hScale else fPt,
|
||||||
self.T_HEAD4: (nwStyles.H_SIZES.get(4, 1.0) * fPt) if hScale else fPt,
|
BlockTyp.HEAD4: (nwStyles.H_SIZES.get(4, 1.0) * fPt) if hScale else fPt,
|
||||||
}
|
}
|
||||||
|
|
||||||
self._mText = (mPx * self._marginText[0], mPx * self._marginText[1])
|
self._mText = (mPx * self._marginText[0], mPx * self._marginText[1])
|
||||||
@@ -226,33 +226,33 @@ class ToQTextDocument(Tokenizer):
|
|||||||
# Styles
|
# Styles
|
||||||
bFmt = QTextBlockFormat(self._blockFmt)
|
bFmt = QTextBlockFormat(self._blockFmt)
|
||||||
if tStyle is not None:
|
if tStyle is not None:
|
||||||
if tStyle & self.A_LEFT:
|
if tStyle & BlockFmt.LEFT:
|
||||||
bFmt.setAlignment(QtAlignLeft)
|
bFmt.setAlignment(QtAlignLeft)
|
||||||
elif tStyle & self.A_RIGHT:
|
elif tStyle & BlockFmt.RIGHT:
|
||||||
bFmt.setAlignment(QtAlignRight)
|
bFmt.setAlignment(QtAlignRight)
|
||||||
elif tStyle & self.A_CENTRE:
|
elif tStyle & BlockFmt.CENTRE:
|
||||||
bFmt.setAlignment(QtAlignCenter)
|
bFmt.setAlignment(QtAlignCenter)
|
||||||
elif tStyle & self.A_JUSTIFY:
|
elif tStyle & BlockFmt.JUSTIFY:
|
||||||
bFmt.setAlignment(QtAlignJustify)
|
bFmt.setAlignment(QtAlignJustify)
|
||||||
|
|
||||||
if tStyle & self.A_PBB:
|
if tStyle & BlockFmt.PBB:
|
||||||
bFmt.setPageBreakPolicy(QtPageBreakBefore)
|
bFmt.setPageBreakPolicy(QtPageBreakBefore)
|
||||||
if tStyle & self.A_PBA:
|
if tStyle & BlockFmt.PBA:
|
||||||
bFmt.setPageBreakPolicy(QtPageBreakAfter)
|
bFmt.setPageBreakPolicy(QtPageBreakAfter)
|
||||||
|
|
||||||
if tStyle & self.A_Z_BTMMRG:
|
if tStyle & BlockFmt.Z_BTMMRG:
|
||||||
bFmt.setBottomMargin(0.0)
|
bFmt.setBottomMargin(0.0)
|
||||||
if tStyle & self.A_Z_TOPMRG:
|
if tStyle & BlockFmt.Z_TOPMRG:
|
||||||
bFmt.setTopMargin(0.0)
|
bFmt.setTopMargin(0.0)
|
||||||
|
|
||||||
if tStyle & self.A_IND_L:
|
if tStyle & BlockFmt.IND_L:
|
||||||
bFmt.setLeftMargin(self._mIndent)
|
bFmt.setLeftMargin(self._mIndent)
|
||||||
if tStyle & self.A_IND_R:
|
if tStyle & BlockFmt.IND_R:
|
||||||
bFmt.setRightMargin(self._mIndent)
|
bFmt.setRightMargin(self._mIndent)
|
||||||
if tStyle & self.A_IND_T:
|
if tStyle & BlockFmt.IND_T:
|
||||||
bFmt.setTextIndent(self._tIndent)
|
bFmt.setTextIndent(self._tIndent)
|
||||||
|
|
||||||
if tType == self.T_TEXT:
|
if tType == BlockTyp.TEXT:
|
||||||
newBlock(cursor, bFmt)
|
newBlock(cursor, bFmt)
|
||||||
self._insertFragments(tText, tFormat, cursor, self._cText)
|
self._insertFragments(tText, tFormat, cursor, self._cText)
|
||||||
|
|
||||||
@@ -261,32 +261,32 @@ class ToQTextDocument(Tokenizer):
|
|||||||
newBlock(cursor, bFmt)
|
newBlock(cursor, bFmt)
|
||||||
cursor.insertText(tText.replace(nwHeadFmt.BR, "\n"), cFmt)
|
cursor.insertText(tText.replace(nwHeadFmt.BR, "\n"), cFmt)
|
||||||
|
|
||||||
elif tType == self.T_SEP:
|
elif tType == BlockTyp.SEP:
|
||||||
sFmt = QTextBlockFormat(bFmt)
|
sFmt = QTextBlockFormat(bFmt)
|
||||||
sFmt.setTopMargin(self._mSep[0])
|
sFmt.setTopMargin(self._mSep[0])
|
||||||
sFmt.setBottomMargin(self._mSep[1])
|
sFmt.setBottomMargin(self._mSep[1])
|
||||||
newBlock(cursor, sFmt)
|
newBlock(cursor, sFmt)
|
||||||
cursor.insertText(tText, self._cText)
|
cursor.insertText(tText, self._cText)
|
||||||
|
|
||||||
elif tType == self.T_SKIP:
|
elif tType == BlockTyp.SKIP:
|
||||||
newBlock(cursor, bFmt)
|
newBlock(cursor, bFmt)
|
||||||
cursor.insertText(nwUnicode.U_NBSP, self._cText)
|
cursor.insertText(nwUnicode.U_NBSP, self._cText)
|
||||||
|
|
||||||
elif tType in self.L_SUMMARY and self._doSynopsis:
|
elif tType in self.L_SUMMARY and self._doSynopsis:
|
||||||
newBlock(cursor, bFmt)
|
newBlock(cursor, bFmt)
|
||||||
modifier = self._localLookup(
|
modifier = self._localLookup(
|
||||||
"Short Description" if tType == self.T_SHORT else "Synopsis"
|
"Short Description" if tType == BlockTyp.SHORT else "Synopsis"
|
||||||
)
|
)
|
||||||
cursor.insertText(f"{modifier}: ", self._cModifier)
|
cursor.insertText(f"{modifier}: ", self._cModifier)
|
||||||
self._insertFragments(tText, tFormat, cursor, self._cNote)
|
self._insertFragments(tText, tFormat, cursor, self._cNote)
|
||||||
|
|
||||||
elif tType == self.T_COMMENT and self._doComments:
|
elif tType == BlockTyp.COMMENT and self._doComments:
|
||||||
newBlock(cursor, bFmt)
|
newBlock(cursor, bFmt)
|
||||||
modifier = self._localLookup("Comment")
|
modifier = self._localLookup("Comment")
|
||||||
cursor.insertText(f"{modifier}: ", self._cCommentMod)
|
cursor.insertText(f"{modifier}: ", self._cCommentMod)
|
||||||
self._insertFragments(tText, tFormat, cursor, self._cComment)
|
self._insertFragments(tText, tFormat, cursor, self._cComment)
|
||||||
|
|
||||||
elif tType == self.T_KEYWORD and self._doKeywords:
|
elif tType == BlockTyp.KEYWORD and self._doKeywords:
|
||||||
newBlock(cursor, bFmt)
|
newBlock(cursor, bFmt)
|
||||||
self._insertKeywords(tText, cursor)
|
self._insertKeywords(tText, cursor)
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@ class ToQTextDocument(Tokenizer):
|
|||||||
cursor = QTextCursor(self._document)
|
cursor = QTextCursor(self._document)
|
||||||
cursor.movePosition(QTextCursor.MoveOperation.End)
|
cursor.movePosition(QTextCursor.MoveOperation.End)
|
||||||
|
|
||||||
bFmt, cFmt = self._genHeadStyle(self.T_HEAD4, -1, self._blockFmt)
|
bFmt, cFmt = self._genHeadStyle(BlockTyp.HEAD4, -1, self._blockFmt)
|
||||||
newBlock(cursor, bFmt)
|
newBlock(cursor, bFmt)
|
||||||
cursor.insertText(self._localLookup("Footnotes"), cFmt)
|
cursor.insertText(self._localLookup("Footnotes"), cFmt)
|
||||||
|
|
||||||
@@ -351,43 +351,43 @@ class ToQTextDocument(Tokenizer):
|
|||||||
cursor.insertText(temp[start:pos], cFmt)
|
cursor.insertText(temp[start:pos], cFmt)
|
||||||
|
|
||||||
# Construct next format
|
# Construct next format
|
||||||
if fmt == self.FMT_B_B:
|
if fmt == TextFmt.B_B:
|
||||||
cFmt.setFontWeight(self._bold)
|
cFmt.setFontWeight(self._bold)
|
||||||
elif fmt == self.FMT_B_E:
|
elif fmt == TextFmt.B_E:
|
||||||
cFmt.setFontWeight(self._normal)
|
cFmt.setFontWeight(self._normal)
|
||||||
elif fmt == self.FMT_I_B:
|
elif fmt == TextFmt.I_B:
|
||||||
cFmt.setFontItalic(True)
|
cFmt.setFontItalic(True)
|
||||||
elif fmt == self.FMT_I_E:
|
elif fmt == TextFmt.I_E:
|
||||||
cFmt.setFontItalic(False)
|
cFmt.setFontItalic(False)
|
||||||
elif fmt == self.FMT_D_B:
|
elif fmt == TextFmt.D_B:
|
||||||
cFmt.setFontStrikeOut(True)
|
cFmt.setFontStrikeOut(True)
|
||||||
elif fmt == self.FMT_D_E:
|
elif fmt == TextFmt.D_E:
|
||||||
cFmt.setFontStrikeOut(False)
|
cFmt.setFontStrikeOut(False)
|
||||||
elif fmt == self.FMT_U_B:
|
elif fmt == TextFmt.U_B:
|
||||||
cFmt.setFontUnderline(True)
|
cFmt.setFontUnderline(True)
|
||||||
elif fmt == self.FMT_U_E:
|
elif fmt == TextFmt.U_E:
|
||||||
cFmt.setFontUnderline(False)
|
cFmt.setFontUnderline(False)
|
||||||
elif fmt == self.FMT_M_B:
|
elif fmt == TextFmt.M_B:
|
||||||
cFmt.setBackground(self._theme.highlight)
|
cFmt.setBackground(self._theme.highlight)
|
||||||
elif fmt == self.FMT_M_E:
|
elif fmt == TextFmt.M_E:
|
||||||
cFmt.setBackground(QtTransparent)
|
cFmt.setBackground(QtTransparent)
|
||||||
elif fmt == self.FMT_SUP_B:
|
elif fmt == TextFmt.SUP_B:
|
||||||
cFmt.setVerticalAlignment(QtVAlignSuper)
|
cFmt.setVerticalAlignment(QtVAlignSuper)
|
||||||
elif fmt == self.FMT_SUP_E:
|
elif fmt == TextFmt.SUP_E:
|
||||||
cFmt.setVerticalAlignment(QtVAlignNormal)
|
cFmt.setVerticalAlignment(QtVAlignNormal)
|
||||||
elif fmt == self.FMT_SUB_B:
|
elif fmt == TextFmt.SUB_B:
|
||||||
cFmt.setVerticalAlignment(QtVAlignSub)
|
cFmt.setVerticalAlignment(QtVAlignSub)
|
||||||
elif fmt == self.FMT_SUB_E:
|
elif fmt == TextFmt.SUB_E:
|
||||||
cFmt.setVerticalAlignment(QtVAlignNormal)
|
cFmt.setVerticalAlignment(QtVAlignNormal)
|
||||||
elif fmt == self.FMT_DL_B:
|
elif fmt == TextFmt.DL_B:
|
||||||
cFmt.setForeground(self._theme.dialog)
|
cFmt.setForeground(self._theme.dialog)
|
||||||
elif fmt == self.FMT_DL_E:
|
elif fmt == TextFmt.DL_E:
|
||||||
cFmt.setForeground(self._theme.text)
|
cFmt.setForeground(self._theme.text)
|
||||||
elif fmt == self.FMT_ADL_B:
|
elif fmt == TextFmt.ADL_B:
|
||||||
cFmt.setForeground(self._theme.altdialog)
|
cFmt.setForeground(self._theme.altdialog)
|
||||||
elif fmt == self.FMT_ADL_E:
|
elif fmt == TextFmt.ADL_E:
|
||||||
cFmt.setForeground(self._theme.text)
|
cFmt.setForeground(self._theme.text)
|
||||||
elif fmt == self.FMT_FNOTE:
|
elif fmt == TextFmt.FNOTE:
|
||||||
xFmt = QTextCharFormat(self._cCode)
|
xFmt = QTextCharFormat(self._cCode)
|
||||||
xFmt.setVerticalAlignment(QtVAlignSuper)
|
xFmt.setVerticalAlignment(QtVAlignSuper)
|
||||||
if data in self._footnotes:
|
if data in self._footnotes:
|
||||||
@@ -435,7 +435,7 @@ class ToQTextDocument(Tokenizer):
|
|||||||
cursor.insertText(", ", self._cText)
|
cursor.insertText(", ", self._cText)
|
||||||
return
|
return
|
||||||
|
|
||||||
def _genHeadStyle(self, hType: int, nHead: int, rFmt: QTextBlockFormat) -> T_TextStyle:
|
def _genHeadStyle(self, hType: BlockTyp, nHead: int, rFmt: QTextBlockFormat) -> T_TextStyle:
|
||||||
"""Generate a heading style set."""
|
"""Generate a heading style set."""
|
||||||
mTop, mBottom = self._mHead.get(hType, (0.0, 0.0))
|
mTop, mBottom = self._mHead.get(hType, (0.0, 0.0))
|
||||||
|
|
||||||
@@ -446,7 +446,7 @@ class ToQTextDocument(Tokenizer):
|
|||||||
self._cTitle = QTextCharFormat(self._cText)
|
self._cTitle = QTextCharFormat(self._cText)
|
||||||
self._cTitle.setFontWeight(self._bold if self._boldHeads else self._normal)
|
self._cTitle.setFontWeight(self._bold if self._boldHeads else self._normal)
|
||||||
|
|
||||||
hCol = self._colorHeads and hType != self.T_TITLE
|
hCol = self._colorHeads and hType != BlockTyp.TITLE
|
||||||
cFmt = QTextCharFormat(self._cText)
|
cFmt = QTextCharFormat(self._cText)
|
||||||
cFmt.setForeground(self._theme.head if hCol else self._theme.text)
|
cFmt.setForeground(self._theme.head if hCol else self._theme.text)
|
||||||
cFmt.setFontWeight(self._bold if self._boldHeads else self._normal)
|
cFmt.setFontWeight(self._bold if self._boldHeads else self._normal)
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ from novelwriter.formats.todocx import (
|
|||||||
S_FNOTE, S_HEAD1, S_HEAD2, S_HEAD3, S_HEAD4, S_META, S_NORM, S_SEP,
|
S_FNOTE, S_HEAD1, S_HEAD2, S_HEAD3, S_HEAD4, S_META, S_NORM, S_SEP,
|
||||||
S_TITLE, ToDocX, _mkTag, _wTag
|
S_TITLE, ToDocX, _mkTag, _wTag
|
||||||
)
|
)
|
||||||
|
from novelwriter.formats.tokenizer import BlockFmt, BlockTyp
|
||||||
|
|
||||||
from tests.tools import DOCX_IGNORE, cmpFiles
|
from tests.tools import DOCX_IGNORE, cmpFiles
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Normal Text
|
# Normal Text
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_TEXT, 0, "Hello World", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.TEXT, 0, "Hello World", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -80,7 +81,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Title
|
# Title
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_TITLE, 0, "Hello World", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.TITLE, 0, "Hello World", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -90,7 +91,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Heading Level 1
|
# Heading Level 1
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_HEAD1, 0, "Hello World", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.HEAD1, 0, "Hello World", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -100,7 +101,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Heading Level 2
|
# Heading Level 2
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_HEAD2, 0, "Hello World", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.HEAD2, 0, "Hello World", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -110,7 +111,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Heading Level 3
|
# Heading Level 3
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_HEAD3, 0, "Hello World", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.HEAD3, 0, "Hello World", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -120,7 +121,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Heading Level 4
|
# Heading Level 4
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_HEAD4, 0, "Hello World", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.HEAD4, 0, "Hello World", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -130,7 +131,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Separator
|
# Separator
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_SEP, 0, "* * *", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.SEP, 0, "* * *", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -140,7 +141,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Empty Paragraph
|
# Empty Paragraph
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_SKIP, 0, "* * *", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.SKIP, 0, "* * *", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -149,7 +150,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Synopsis
|
# Synopsis
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_SYNOPSIS, 0, "Hello World", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.SYNOPSIS, 0, "Hello World", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -161,7 +162,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Short
|
# Short
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_SHORT, 0, "Hello World", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.SHORT, 0, "Hello World", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -173,7 +174,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Comment
|
# Comment
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_COMMENT, 0, "Hello World", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.COMMENT, 0, "Hello World", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -185,7 +186,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Tags and References (Single)
|
# Tags and References (Single)
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_KEYWORD, 0, "tag: Stuff", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.KEYWORD, 0, "tag: Stuff", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -197,7 +198,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Tags and References (Multiple)
|
# Tags and References (Multiple)
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_KEYWORD, 0, "char: Jane, John", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.KEYWORD, 0, "char: Jane, John", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -209,7 +210,7 @@ def testFmtToDocX_ParagraphStyles(mockGUI):
|
|||||||
|
|
||||||
# Tags and References (Invalid)
|
# Tags and References (Invalid)
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_KEYWORD, 0, "stuff: Stuff", [], doc.A_NONE)]
|
doc._tokens = [(BlockTyp.KEYWORD, 0, "stuff: Stuff", [], BlockFmt.NONE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -229,7 +230,7 @@ def testFmtToDocX_ParagraphFormatting(mockGUI):
|
|||||||
|
|
||||||
# Left Align
|
# Left Align
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_TEXT, 0, "Hello World", [], doc.A_LEFT)]
|
doc._tokens = [(BlockTyp.TEXT, 0, "Hello World", [], BlockFmt.LEFT)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -239,7 +240,7 @@ def testFmtToDocX_ParagraphFormatting(mockGUI):
|
|||||||
|
|
||||||
# Right Align
|
# Right Align
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_TEXT, 0, "Hello World", [], doc.A_RIGHT)]
|
doc._tokens = [(BlockTyp.TEXT, 0, "Hello World", [], BlockFmt.RIGHT)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -249,7 +250,7 @@ def testFmtToDocX_ParagraphFormatting(mockGUI):
|
|||||||
|
|
||||||
# Center Align
|
# Center Align
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_TEXT, 0, "Hello World", [], doc.A_CENTRE)]
|
doc._tokens = [(BlockTyp.TEXT, 0, "Hello World", [], BlockFmt.CENTRE)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -259,7 +260,7 @@ def testFmtToDocX_ParagraphFormatting(mockGUI):
|
|||||||
|
|
||||||
# Justify
|
# Justify
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_TEXT, 0, "Hello World", [], doc.A_JUSTIFY)]
|
doc._tokens = [(BlockTyp.TEXT, 0, "Hello World", [], BlockFmt.JUSTIFY)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -269,7 +270,7 @@ def testFmtToDocX_ParagraphFormatting(mockGUI):
|
|||||||
|
|
||||||
# Page Break Before
|
# Page Break Before
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_TEXT, 0, "Hello World", [], doc.A_PBB)]
|
doc._tokens = [(BlockTyp.TEXT, 0, "Hello World", [], BlockFmt.PBB)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -281,7 +282,7 @@ def testFmtToDocX_ParagraphFormatting(mockGUI):
|
|||||||
|
|
||||||
# Page Break After
|
# Page Break After
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_TEXT, 0, "Hello World", [], doc.A_PBA)]
|
doc._tokens = [(BlockTyp.TEXT, 0, "Hello World", [], BlockFmt.PBA)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -293,7 +294,7 @@ def testFmtToDocX_ParagraphFormatting(mockGUI):
|
|||||||
|
|
||||||
# Zero Margins
|
# Zero Margins
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_TEXT, 0, "Hello World", [], doc.A_Z_TOPMRG | doc.A_Z_BTMMRG)]
|
doc._tokens = [(BlockTyp.TEXT, 0, "Hello World", [], BlockFmt.Z_TOPMRG | BlockFmt.Z_BTMMRG)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -304,7 +305,7 @@ def testFmtToDocX_ParagraphFormatting(mockGUI):
|
|||||||
|
|
||||||
# Indent
|
# Indent
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_TEXT, 0, "Hello World", [], doc.A_IND_L | doc.A_IND_R)]
|
doc._tokens = [(BlockTyp.TEXT, 0, "Hello World", [], BlockFmt.IND_L | BlockFmt.IND_R)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
@@ -315,7 +316,7 @@ def testFmtToDocX_ParagraphFormatting(mockGUI):
|
|||||||
|
|
||||||
# First Line Indent
|
# First Line Indent
|
||||||
xTest = ET.Element(_wTag("body"))
|
xTest = ET.Element(_wTag("body"))
|
||||||
doc._tokens = [(doc.T_TEXT, 0, "Hello World", [], doc.A_IND_T)]
|
doc._tokens = [(BlockTyp.TEXT, 0, "Hello World", [], BlockFmt.IND_T)]
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
doc._pars[-1].toXml(xTest)
|
doc._pars[-1].toXml(xTest)
|
||||||
assert xmlToText(xTest) == (
|
assert xmlToText(xTest) == (
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import pytest
|
|||||||
from novelwriter import CONFIG
|
from novelwriter import CONFIG
|
||||||
from novelwriter.core.project import NWProject
|
from novelwriter.core.project import NWProject
|
||||||
from novelwriter.formats.tohtml import ToHtml
|
from novelwriter.formats.tohtml import ToHtml
|
||||||
|
from novelwriter.formats.tokenizer import BlockFmt, BlockTyp
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.core
|
@pytest.mark.core
|
||||||
@@ -359,7 +360,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Title
|
# Title
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_TITLE, 1, "A Title", [], html.A_PBB | html.A_CENTRE),
|
(BlockTyp.TITLE, 1, "A Title", [], BlockFmt.PBB | BlockFmt.CENTRE),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == (
|
assert html.result == (
|
||||||
@@ -369,7 +370,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Unnumbered
|
# Unnumbered
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_HEAD2, 1, "Prologue", [], html.A_PBB),
|
(BlockTyp.HEAD2, 1, "Prologue", [], BlockFmt.PBB),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == (
|
assert html.result == (
|
||||||
@@ -382,14 +383,14 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Separator
|
# Separator
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_SEP, 1, "* * *", [], html.A_CENTRE),
|
(BlockTyp.SEP, 1, "* * *", [], BlockFmt.CENTRE),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == "<p class='sep' style='text-align: center;'>* * *</p>\n"
|
assert html.result == "<p class='sep' style='text-align: center;'>* * *</p>\n"
|
||||||
|
|
||||||
# Skip
|
# Skip
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_SKIP, 1, "", [], html.A_NONE),
|
(BlockTyp.SKIP, 1, "", [], BlockFmt.NONE),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == "<p class='skip'> </p>\n"
|
assert html.result == "<p class='skip'> </p>\n"
|
||||||
@@ -402,7 +403,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
# Align Left
|
# Align Left
|
||||||
html.setStyles(False)
|
html.setStyles(False)
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_HEAD1, 1, "A Title", [], html.A_LEFT),
|
(BlockTyp.HEAD1, 1, "A Title", [], BlockFmt.LEFT),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == (
|
assert html.result == (
|
||||||
@@ -413,7 +414,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Align Left
|
# Align Left
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_HEAD1, 1, "A Title", [], html.A_LEFT),
|
(BlockTyp.HEAD1, 1, "A Title", [], BlockFmt.LEFT),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == (
|
assert html.result == (
|
||||||
@@ -422,7 +423,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Align Right
|
# Align Right
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_HEAD1, 1, "A Title", [], html.A_RIGHT),
|
(BlockTyp.HEAD1, 1, "A Title", [], BlockFmt.RIGHT),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == (
|
assert html.result == (
|
||||||
@@ -431,7 +432,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Align Centre
|
# Align Centre
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_HEAD1, 1, "A Title", [], html.A_CENTRE),
|
(BlockTyp.HEAD1, 1, "A Title", [], BlockFmt.CENTRE),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == (
|
assert html.result == (
|
||||||
@@ -440,7 +441,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Align Justify
|
# Align Justify
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_HEAD1, 1, "A Title", [], html.A_JUSTIFY),
|
(BlockTyp.HEAD1, 1, "A Title", [], BlockFmt.JUSTIFY),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == (
|
assert html.result == (
|
||||||
@@ -452,7 +453,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Page Break Always
|
# Page Break Always
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_HEAD1, 1, "A Title", [], html.A_PBB | html.A_PBA),
|
(BlockTyp.HEAD1, 1, "A Title", [], BlockFmt.PBB | BlockFmt.PBA),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == (
|
assert html.result == (
|
||||||
@@ -465,7 +466,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Indent Left
|
# Indent Left
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_TEXT, 1, "Some text ...", [], html.A_IND_L),
|
(BlockTyp.TEXT, 1, "Some text ...", [], BlockFmt.IND_L),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == (
|
assert html.result == (
|
||||||
@@ -474,7 +475,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Indent Right
|
# Indent Right
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_TEXT, 1, "Some text ...", [], html.A_IND_R),
|
(BlockTyp.TEXT, 1, "Some text ...", [], BlockFmt.IND_R),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == (
|
assert html.result == (
|
||||||
@@ -483,7 +484,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Text Indent
|
# Text Indent
|
||||||
html._tokens = [
|
html._tokens = [
|
||||||
(html.T_TEXT, 1, "Some text ...", [], html.A_IND_T),
|
(BlockTyp.TEXT, 1, "Some text ...", [], BlockFmt.IND_T),
|
||||||
]
|
]
|
||||||
html.doConvert()
|
html.doConvert()
|
||||||
assert html.result == (
|
assert html.result == (
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@ from __future__ import annotations
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from novelwriter.core.project import NWProject
|
from novelwriter.core.project import NWProject
|
||||||
|
from novelwriter.formats.tokenizer import BlockFmt, BlockTyp
|
||||||
from novelwriter.formats.tomarkdown import ToMarkdown
|
from novelwriter.formats.tomarkdown import ToMarkdown
|
||||||
|
|
||||||
|
|
||||||
@@ -220,7 +221,7 @@ def testFmtToMarkdown_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Title
|
# Title
|
||||||
toMD._tokens = [
|
toMD._tokens = [
|
||||||
(toMD.T_TITLE, 1, "A Title", [], toMD.A_PBB | toMD.A_CENTRE),
|
(BlockTyp.TITLE, 1, "A Title", [], BlockFmt.PBB | BlockFmt.CENTRE),
|
||||||
]
|
]
|
||||||
toMD.doConvert()
|
toMD.doConvert()
|
||||||
assert toMD.result == "# A Title\n\n"
|
assert toMD.result == "# A Title\n\n"
|
||||||
@@ -230,14 +231,14 @@ def testFmtToMarkdown_ConvertDirect(mockGUI):
|
|||||||
|
|
||||||
# Separator
|
# Separator
|
||||||
toMD._tokens = [
|
toMD._tokens = [
|
||||||
(toMD.T_SEP, 1, "* * *", [], toMD.A_CENTRE),
|
(BlockTyp.SEP, 1, "* * *", [], BlockFmt.CENTRE),
|
||||||
]
|
]
|
||||||
toMD.doConvert()
|
toMD.doConvert()
|
||||||
assert toMD.result == "* * *\n\n"
|
assert toMD.result == "* * *\n\n"
|
||||||
|
|
||||||
# Skip
|
# Skip
|
||||||
toMD._tokens = [
|
toMD._tokens = [
|
||||||
(toMD.T_SKIP, 1, "", [], toMD.A_NONE),
|
(BlockTyp.SKIP, 1, "", [], BlockFmt.NONE),
|
||||||
]
|
]
|
||||||
toMD.doConvert()
|
toMD.doConvert()
|
||||||
assert toMD.result == "\n\n"
|
assert toMD.result == "\n\n"
|
||||||
@@ -300,7 +301,7 @@ def testFmtToMarkdown_Format(mockGUI):
|
|||||||
project = NWProject()
|
project = NWProject()
|
||||||
toMD = ToMarkdown(project, False)
|
toMD = ToMarkdown(project, False)
|
||||||
|
|
||||||
assert toMD._formatKeywords("", toMD.A_NONE) == ""
|
assert toMD._formatKeywords("", BlockFmt.NONE) == ""
|
||||||
assert toMD._formatKeywords("tag: Jane", toMD.A_NONE) == "**Tag:** Jane\n\n"
|
assert toMD._formatKeywords("tag: Jane", BlockFmt.NONE) == "**Tag:** Jane\n\n"
|
||||||
assert toMD._formatKeywords("tag: Jane, John", toMD.A_NONE) == "**Tag:** Jane, John\n\n"
|
assert toMD._formatKeywords("tag: Jane, John", BlockFmt.NONE) == "**Tag:** Jane, John\n\n"
|
||||||
assert toMD._formatKeywords("tag: Jane", toMD.A_Z_BTMMRG) == "**Tag:** Jane \n"
|
assert toMD._formatKeywords("tag: Jane", BlockFmt.Z_BTMMRG) == "**Tag:** Jane \n"
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import pytest
|
|||||||
from novelwriter.common import xmlIndent
|
from novelwriter.common import xmlIndent
|
||||||
from novelwriter.constants import nwHeadFmt
|
from novelwriter.constants import nwHeadFmt
|
||||||
from novelwriter.core.project import NWProject
|
from novelwriter.core.project import NWProject
|
||||||
|
from novelwriter.formats.tokenizer import BlockFmt, BlockTyp, TextFmt
|
||||||
from novelwriter.formats.toodt import ODTParagraphStyle, ODTTextStyle, ToOdt, XMLParagraph, _mkTag
|
from novelwriter.formats.toodt import ODTParagraphStyle, ODTTextStyle, ToOdt, XMLParagraph, _mkTag
|
||||||
|
|
||||||
from tests.tools import ODT_IGNORE, cmpFiles
|
from tests.tools import ODT_IGNORE, cmpFiles
|
||||||
@@ -183,7 +184,7 @@ def testFmtToOdt_TextFormatting(mockGUI):
|
|||||||
|
|
||||||
# Formatted Text
|
# Formatted Text
|
||||||
text = "A bold word"
|
text = "A bold word"
|
||||||
fmt = [(2, odt.FMT_B_B, ""), (6, odt.FMT_B_E, "")]
|
fmt = [(2, TextFmt.B_B, ""), (6, TextFmt.B_E, "")]
|
||||||
xTest = ET.Element(_mkTag("office", "text"))
|
xTest = ET.Element(_mkTag("office", "text"))
|
||||||
odt._addTextPar(xTest, "Standard", oStyle, text, tFmt=fmt)
|
odt._addTextPar(xTest, "Standard", oStyle, text, tFmt=fmt)
|
||||||
assert odt.errData == []
|
assert odt.errData == []
|
||||||
@@ -196,7 +197,7 @@ def testFmtToOdt_TextFormatting(mockGUI):
|
|||||||
|
|
||||||
# Incorrectly Formatted Text
|
# Incorrectly Formatted Text
|
||||||
text = "A few words"
|
text = "A few words"
|
||||||
fmt = [(2, odt.FMT_B_B, ""), (5, odt.FMT_B_E, ""), (7, 99999, "")]
|
fmt = [(2, TextFmt.B_B, ""), (5, TextFmt.B_E, ""), (7, 99999, "")]
|
||||||
xTest = ET.Element(_mkTag("office", "text"))
|
xTest = ET.Element(_mkTag("office", "text"))
|
||||||
odt._addTextPar(xTest, "Standard", oStyle, text, tFmt=fmt)
|
odt._addTextPar(xTest, "Standard", oStyle, text, tFmt=fmt)
|
||||||
assert odt.errData == ["Unknown format tag encountered"]
|
assert odt.errData == ["Unknown format tag encountered"]
|
||||||
@@ -210,7 +211,7 @@ def testFmtToOdt_TextFormatting(mockGUI):
|
|||||||
|
|
||||||
# Unclosed format
|
# Unclosed format
|
||||||
text = "A bold word"
|
text = "A bold word"
|
||||||
fmt = [(2, odt.FMT_B_B, "")]
|
fmt = [(2, TextFmt.B_B, "")]
|
||||||
xTest = ET.Element(_mkTag("office", "text"))
|
xTest = ET.Element(_mkTag("office", "text"))
|
||||||
odt._addTextPar(xTest, "Standard", oStyle, text, tFmt=fmt)
|
odt._addTextPar(xTest, "Standard", oStyle, text, tFmt=fmt)
|
||||||
assert odt.errData == []
|
assert odt.errData == []
|
||||||
@@ -245,7 +246,7 @@ def testFmtToOdt_DialogueFormatting(mockGUI):
|
|||||||
|
|
||||||
# Regular dialogue
|
# Regular dialogue
|
||||||
text = "Text with 'dialogue in it.'"
|
text = "Text with 'dialogue in it.'"
|
||||||
fmt = [(10, odt.FMT_DL_B, ""), (27, odt.FMT_DL_E, "")]
|
fmt = [(10, TextFmt.DL_B, ""), (27, TextFmt.DL_E, "")]
|
||||||
xTest = ET.Element(_mkTag("office", "text"))
|
xTest = ET.Element(_mkTag("office", "text"))
|
||||||
odt._addTextPar(xTest, "Standard", oStyle, text, tFmt=fmt)
|
odt._addTextPar(xTest, "Standard", oStyle, text, tFmt=fmt)
|
||||||
assert odt.errData == []
|
assert odt.errData == []
|
||||||
@@ -258,7 +259,7 @@ def testFmtToOdt_DialogueFormatting(mockGUI):
|
|||||||
|
|
||||||
# Alternative dialogue
|
# Alternative dialogue
|
||||||
text = "Text with ::dialogue in it.::"
|
text = "Text with ::dialogue in it.::"
|
||||||
fmt = [(10, odt.FMT_ADL_B, ""), (29, odt.FMT_ADL_E, "")]
|
fmt = [(10, TextFmt.ADL_B, ""), (29, TextFmt.ADL_E, "")]
|
||||||
xTest = ET.Element(_mkTag("office", "text"))
|
xTest = ET.Element(_mkTag("office", "text"))
|
||||||
odt._addTextPar(xTest, "Standard", oStyle, text, tFmt=fmt)
|
odt._addTextPar(xTest, "Standard", oStyle, text, tFmt=fmt)
|
||||||
assert odt.errData == []
|
assert odt.errData == []
|
||||||
@@ -719,7 +720,7 @@ def testFmtToOdt_ConvertDirect(mockGUI):
|
|||||||
# Justified
|
# Justified
|
||||||
doc = ToOdt(project, isFlat=True)
|
doc = ToOdt(project, isFlat=True)
|
||||||
doc._tokens = [
|
doc._tokens = [
|
||||||
(doc.T_TEXT, 1, "This is a paragraph", [], doc.A_JUSTIFY),
|
(BlockTyp.TEXT, 1, "This is a paragraph", [], BlockFmt.JUSTIFY),
|
||||||
]
|
]
|
||||||
doc.initDocument()
|
doc.initDocument()
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
@@ -739,7 +740,7 @@ def testFmtToOdt_ConvertDirect(mockGUI):
|
|||||||
# Page Break After
|
# Page Break After
|
||||||
doc = ToOdt(project, isFlat=True)
|
doc = ToOdt(project, isFlat=True)
|
||||||
doc._tokens = [
|
doc._tokens = [
|
||||||
(doc.T_TEXT, 1, "This is a paragraph", [], doc.A_PBA),
|
(BlockTyp.TEXT, 1, "This is a paragraph", [], BlockFmt.PBA),
|
||||||
]
|
]
|
||||||
doc.initDocument()
|
doc.initDocument()
|
||||||
doc.doConvert()
|
doc.doConvert()
|
||||||
@@ -894,28 +895,28 @@ def testFmtToOdt_SpecialFormats(mockGUI):
|
|||||||
project = NWProject()
|
project = NWProject()
|
||||||
odt = ToOdt(project, isFlat=True)
|
odt = ToOdt(project, isFlat=True)
|
||||||
|
|
||||||
assert odt._formatSynopsis("synopsis text", [(9, ToOdt.FMT_STRIP, "")], True) == (
|
assert odt._formatSynopsis("synopsis text", [(9, TextFmt.STRIP, "")], True) == (
|
||||||
"Synopsis: synopsis text", [
|
"Synopsis: synopsis text", [
|
||||||
(0, ToOdt.FMT_B_B, ""), (9, ToOdt.FMT_B_E, ""), (19, ToOdt.FMT_STRIP, "")
|
(0, TextFmt.B_B, ""), (9, TextFmt.B_E, ""), (19, TextFmt.STRIP, "")
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
assert odt._formatSynopsis("short text", [(6, ToOdt.FMT_STRIP, "")], False) == (
|
assert odt._formatSynopsis("short text", [(6, TextFmt.STRIP, "")], False) == (
|
||||||
"Short Description: short text", [
|
"Short Description: short text", [
|
||||||
(0, ToOdt.FMT_B_B, ""), (18, ToOdt.FMT_B_E, ""), (25, ToOdt.FMT_STRIP, "")
|
(0, TextFmt.B_B, ""), (18, TextFmt.B_E, ""), (25, TextFmt.STRIP, "")
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
assert odt._formatComments("comment text", [(8, ToOdt.FMT_STRIP, "")]) == (
|
assert odt._formatComments("comment text", [(8, TextFmt.STRIP, "")]) == (
|
||||||
"Comment: comment text", [
|
"Comment: comment text", [
|
||||||
(0, ToOdt.FMT_B_B, ""), (8, ToOdt.FMT_B_E, ""), (17, ToOdt.FMT_STRIP, "")
|
(0, TextFmt.B_B, ""), (8, TextFmt.B_E, ""), (17, TextFmt.STRIP, "")
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
assert odt._formatKeywords("") == ("", [])
|
assert odt._formatKeywords("") == ("", [])
|
||||||
assert odt._formatKeywords("tag: Jane") == (
|
assert odt._formatKeywords("tag: Jane") == (
|
||||||
"Tag: Jane", [(0, ToOdt.FMT_B_B, ""), (4, ToOdt.FMT_B_E, "")]
|
"Tag: Jane", [(0, TextFmt.B_B, ""), (4, TextFmt.B_E, "")]
|
||||||
)
|
)
|
||||||
assert odt._formatKeywords("char: Bod, Jane") == (
|
assert odt._formatKeywords("char: Bod, Jane") == (
|
||||||
"Characters: Bod, Jane", [(0, ToOdt.FMT_B_B, ""), (11, ToOdt.FMT_B_E, "")]
|
"Characters: Bod, Jane", [(0, TextFmt.B_B, ""), (11, TextFmt.B_E, "")]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ from PyQt5.QtGui import QTextBlock, QTextCharFormat, QTextCursor
|
|||||||
from novelwriter import CONFIG
|
from novelwriter import CONFIG
|
||||||
from novelwriter.constants import nwUnicode
|
from novelwriter.constants import nwUnicode
|
||||||
from novelwriter.core.project import NWProject
|
from novelwriter.core.project import NWProject
|
||||||
|
from novelwriter.formats.tokenizer import BlockFmt, BlockTyp
|
||||||
from novelwriter.formats.toqdoc import TextDocumentTheme, ToQTextDocument
|
from novelwriter.formats.toqdoc import TextDocumentTheme, ToQTextDocument
|
||||||
from novelwriter.types import (
|
from novelwriter.types import (
|
||||||
QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight,
|
QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight,
|
||||||
@@ -68,55 +69,55 @@ def testFmtToQTextDocument_ConvertHeaders(mockGUI):
|
|||||||
block = qdoc.document.findBlockByNumber(0)
|
block = qdoc.document.findBlockByNumber(0)
|
||||||
assert block.text() == "Title"
|
assert block.text() == "Title"
|
||||||
bFmt = block.blockFormat()
|
bFmt = block.blockFormat()
|
||||||
assert bFmt.topMargin() == qdoc._mHead[qdoc.T_TITLE][0]
|
assert bFmt.topMargin() == qdoc._mHead[BlockTyp.TITLE][0]
|
||||||
assert bFmt.bottomMargin() == qdoc._mHead[qdoc.T_TITLE][1]
|
assert bFmt.bottomMargin() == qdoc._mHead[BlockTyp.TITLE][1]
|
||||||
cFmt = charFmtInBlock(block, 1)
|
cFmt = charFmtInBlock(block, 1)
|
||||||
assert cFmt.fontWeight() == qdoc._bold
|
assert cFmt.fontWeight() == qdoc._bold
|
||||||
assert cFmt.fontPointSize() == qdoc._sHead[qdoc.T_TITLE]
|
assert cFmt.fontPointSize() == qdoc._sHead[BlockTyp.TITLE]
|
||||||
assert cFmt.foreground().color() == THEME.text
|
assert cFmt.foreground().color() == THEME.text
|
||||||
|
|
||||||
# Partition
|
# Partition
|
||||||
block = qdoc.document.findBlockByNumber(1)
|
block = qdoc.document.findBlockByNumber(1)
|
||||||
assert block.text() == "Partition"
|
assert block.text() == "Partition"
|
||||||
bFmt = block.blockFormat()
|
bFmt = block.blockFormat()
|
||||||
assert bFmt.topMargin() == qdoc._mHead[qdoc.T_HEAD1][0]
|
assert bFmt.topMargin() == qdoc._mHead[BlockTyp.HEAD1][0]
|
||||||
assert bFmt.bottomMargin() == qdoc._mHead[qdoc.T_HEAD1][1]
|
assert bFmt.bottomMargin() == qdoc._mHead[BlockTyp.HEAD1][1]
|
||||||
cFmt = charFmtInBlock(block, 1)
|
cFmt = charFmtInBlock(block, 1)
|
||||||
assert cFmt.fontWeight() == qdoc._bold
|
assert cFmt.fontWeight() == qdoc._bold
|
||||||
assert cFmt.fontPointSize() == qdoc._sHead[qdoc.T_HEAD1]
|
assert cFmt.fontPointSize() == qdoc._sHead[BlockTyp.HEAD1]
|
||||||
assert cFmt.foreground().color() == THEME.head
|
assert cFmt.foreground().color() == THEME.head
|
||||||
|
|
||||||
# Chapter
|
# Chapter
|
||||||
block = qdoc.document.findBlockByNumber(2)
|
block = qdoc.document.findBlockByNumber(2)
|
||||||
assert block.text() == "Chapter"
|
assert block.text() == "Chapter"
|
||||||
bFmt = block.blockFormat()
|
bFmt = block.blockFormat()
|
||||||
assert bFmt.topMargin() == qdoc._mHead[qdoc.T_HEAD2][0]
|
assert bFmt.topMargin() == qdoc._mHead[BlockTyp.HEAD2][0]
|
||||||
assert bFmt.bottomMargin() == qdoc._mHead[qdoc.T_HEAD2][1]
|
assert bFmt.bottomMargin() == qdoc._mHead[BlockTyp.HEAD2][1]
|
||||||
cFmt = charFmtInBlock(block, 1)
|
cFmt = charFmtInBlock(block, 1)
|
||||||
assert cFmt.fontWeight() == qdoc._bold
|
assert cFmt.fontWeight() == qdoc._bold
|
||||||
assert cFmt.fontPointSize() == qdoc._sHead[qdoc.T_HEAD2]
|
assert cFmt.fontPointSize() == qdoc._sHead[BlockTyp.HEAD2]
|
||||||
assert cFmt.foreground().color() == THEME.head
|
assert cFmt.foreground().color() == THEME.head
|
||||||
|
|
||||||
# Scene
|
# Scene
|
||||||
block = qdoc.document.findBlockByNumber(3)
|
block = qdoc.document.findBlockByNumber(3)
|
||||||
assert block.text() == "Scene"
|
assert block.text() == "Scene"
|
||||||
bFmt = block.blockFormat()
|
bFmt = block.blockFormat()
|
||||||
assert bFmt.topMargin() == qdoc._mHead[qdoc.T_HEAD3][0]
|
assert bFmt.topMargin() == qdoc._mHead[BlockTyp.HEAD3][0]
|
||||||
assert bFmt.bottomMargin() == qdoc._mHead[qdoc.T_HEAD3][1]
|
assert bFmt.bottomMargin() == qdoc._mHead[BlockTyp.HEAD3][1]
|
||||||
cFmt = charFmtInBlock(block, 1)
|
cFmt = charFmtInBlock(block, 1)
|
||||||
assert cFmt.fontWeight() == qdoc._bold
|
assert cFmt.fontWeight() == qdoc._bold
|
||||||
assert cFmt.fontPointSize() == qdoc._sHead[qdoc.T_HEAD3]
|
assert cFmt.fontPointSize() == qdoc._sHead[BlockTyp.HEAD3]
|
||||||
assert cFmt.foreground().color() == THEME.head
|
assert cFmt.foreground().color() == THEME.head
|
||||||
|
|
||||||
# Section
|
# Section
|
||||||
block = qdoc.document.findBlockByNumber(4)
|
block = qdoc.document.findBlockByNumber(4)
|
||||||
assert block.text() == "Section"
|
assert block.text() == "Section"
|
||||||
bFmt = block.blockFormat()
|
bFmt = block.blockFormat()
|
||||||
assert bFmt.topMargin() == qdoc._mHead[qdoc.T_HEAD4][0]
|
assert bFmt.topMargin() == qdoc._mHead[BlockTyp.HEAD4][0]
|
||||||
assert bFmt.bottomMargin() == qdoc._mHead[qdoc.T_HEAD4][1]
|
assert bFmt.bottomMargin() == qdoc._mHead[BlockTyp.HEAD4][1]
|
||||||
cFmt = charFmtInBlock(block, 1)
|
cFmt = charFmtInBlock(block, 1)
|
||||||
assert cFmt.fontWeight() == qdoc._bold
|
assert cFmt.fontWeight() == qdoc._bold
|
||||||
assert cFmt.fontPointSize() == qdoc._sHead[qdoc.T_HEAD4]
|
assert cFmt.fontPointSize() == qdoc._sHead[BlockTyp.HEAD4]
|
||||||
assert cFmt.foreground().color() == THEME.head
|
assert cFmt.foreground().color() == THEME.head
|
||||||
|
|
||||||
|
|
||||||
@@ -410,8 +411,8 @@ def testFmtToQTextDocument_TextBlockFormats(mockGUI):
|
|||||||
qdoc.document.clear()
|
qdoc.document.clear()
|
||||||
|
|
||||||
qdoc._tokens = [
|
qdoc._tokens = [
|
||||||
(qdoc.T_TEXT, 1, "This is justified", [], qdoc.A_JUSTIFY),
|
(BlockTyp.TEXT, 1, "This is justified", [], BlockFmt.JUSTIFY),
|
||||||
(qdoc.T_TEXT, 1, "This has a page break", [], qdoc.A_PBA),
|
(BlockTyp.TEXT, 1, "This has a page break", [], BlockFmt.PBA),
|
||||||
]
|
]
|
||||||
qdoc.doConvert()
|
qdoc.doConvert()
|
||||||
assert qdoc.document.blockCount() == 2
|
assert qdoc.document.blockCount() == 2
|
||||||
|
|||||||
Reference in New Issue
Block a user