From 3cc5e4cc7a18c2bed102629c5dce71c8247d03d9 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Mon, 21 Oct 2024 18:54:19 +0200 Subject: [PATCH] Handle text justify in Tokenizer instead --- novelwriter/formats/todocx.py | 11 +- novelwriter/formats/tohtml.py | 2 +- novelwriter/formats/tokenizer.py | 10 +- novelwriter/formats/toodt.py | 13 +- novelwriter/formats/toqdoc.py | 2 +- .../mBuildDocBuild_HTML5_Lorem_Ipsum.htm | 84 ++++----- .../mBuildDocBuild_HTML5_Lorem_Ipsum.json | 88 ++++----- ...uildDocBuild_OpenDocument_Lorem_Ipsum.fodt | 175 +++++++++--------- tests/test_formats/test_fmt_tohtml.py | 4 - tests/test_formats/test_fmt_toodt.py | 25 +-- 10 files changed, 195 insertions(+), 219 deletions(-) diff --git a/novelwriter/formats/todocx.py b/novelwriter/formats/todocx.py index e417d0ae..274a218b 100644 --- a/novelwriter/formats/todocx.py +++ b/novelwriter/formats/todocx.py @@ -255,8 +255,6 @@ class ToDocX(Tokenizer): # Process Text Types if tType == self.T_TEXT: - if self._doJustify and "\n" in tText: - par.overrideJustify(self._defaultAlign) self._processFragments(par, S_NORM, tText, tFormat) elif tType == self.T_TITLE: @@ -544,7 +542,6 @@ class ToDocX(Tokenizer): fSz2 = (nwStyles.H_SIZES[2] * fSz) if hScale else fSz fSz3 = (nwStyles.H_SIZES[3] * fSz) if hScale else fSz fSz4 = (nwStyles.H_SIZES[4] * fSz) if hScale else fSz - align = "both" if self._doJustify else "left" # Add Normal Style styles.append(DocXParStyle( @@ -556,7 +553,7 @@ class ToDocX(Tokenizer): after=fSz * self._marginText[1], line=fSz * self._lineHeight, indentFirst=fSz * self._firstWidth, - align=align, + align=self._defaultAlign, )) # Add Title @@ -1085,12 +1082,6 @@ class DocXParagraph: # Methods ## - def overrideJustify(self, default: str) -> None: - """Override inherited justify setting if None is set.""" - if self._textAlign is None: - self.setAlignment(default) - return - def addContent(self, run: ET.Element) -> None: """Add a run segment to the paragraph.""" self._content.append(run) diff --git a/novelwriter/formats/tohtml.py b/novelwriter/formats/tohtml.py index 54827a2a..9012e24c 100644 --- a/novelwriter/formats/tohtml.py +++ b/novelwriter/formats/tohtml.py @@ -372,7 +372,7 @@ class ToHtml(Tokenizer): "margin-top: {2:.2f}em; margin-bottom: {3:.2f}em;" "}}" ).format( - "justify" if self._doJustify else self._defaultAlign, + self._defaultAlign, round(100 * self._lineHeight), mScale * self._marginText[0], mScale * self._marginText[1], diff --git a/novelwriter/formats/tokenizer.py b/novelwriter/formats/tokenizer.py index 04ce876a..a7af39a9 100644 --- a/novelwriter/formats/tokenizer.py +++ b/novelwriter/formats/tokenizer.py @@ -622,6 +622,9 @@ class Tokenizer(ABC): if aLine.startswith("%~"): continue + if self._doJustify and not sAlign & self.M_ALIGNED: + sAlign |= self.A_JUSTIFY + cStyle, cKey, cText, _, _ = processComment(aLine) if cStyle == nwComment.SYNOPSIS: tLine, tFmt = self._extractFormats(cText) @@ -935,8 +938,11 @@ class Tokenizer(ABC): cStyle |= self.A_IND_T if nLines == 1: - # The paragraph contains a single line, so we just - # save that directly to the token list + # The paragraph contains a single line, so we just save + # that directly to the token list. If justify is + # enabled, and there is no alignment, we apply it. + if self._doJustify and not cStyle & self.M_ALIGNED: + cStyle |= self.A_JUSTIFY self._tokens.append(( self.T_TEXT, pLines[0][1], pLines[0][2], pLines[0][3], cStyle )) diff --git a/novelwriter/formats/toodt.py b/novelwriter/formats/toodt.py index fdacf287..d39d5e12 100644 --- a/novelwriter/formats/toodt.py +++ b/novelwriter/formats/toodt.py @@ -183,7 +183,6 @@ class ToOdt(Tokenizer): self._fLineHeight = "115%" self._fBlockIndent = "1.693cm" self._fTextIndent = "0.499cm" - self._textAlign = "left" self._dLanguage = "en" self._dCountry = "GB" @@ -327,7 +326,6 @@ class ToOdt(Tokenizer): self._fLineHeight = f"{round(100 * self._lineHeight):d}%" self._fBlockIndent = self._emToCm(self._blockIndent) self._fTextIndent = self._emToCm(self._firstWidth) - self._textAlign = "justify" if self._doJustify else self._defaultAlign # Clear Errors self._errData = [] @@ -457,9 +455,6 @@ class ToOdt(Tokenizer): # Process Text Types if tType == self.T_TEXT: - if self._doJustify and "\n" in tText: - oStyle.overrideJustify(self._defaultAlign) - # Text indentation is processed here because there is a # dedicated pre-defined style for it if tStyle & self.A_IND_T: @@ -906,7 +901,7 @@ class ToOdt(Tokenizer): style.setMarginTop(self._mTopText) style.setMarginBottom(self._mBotText) style.setLineHeight(self._fLineHeight) - style.setTextAlign(self._textAlign) + style.setTextAlign(self._defaultAlign) style.setFontName(self._fontFamily) style.setFontFamily(self._fontFamily) style.setFontSize(self._fSizeText) @@ -1316,12 +1311,6 @@ class ODTParagraphStyle: # Methods ## - def overrideJustify(self, default: str) -> None: - """Override inherited justify setting if None is set.""" - if self._pAttr["text-align"][1] is None: - self.setTextAlign(default) - return - def checkNew(self, style: ODTParagraphStyle) -> bool: """Check if there are new settings in style that differ from those in this object. Unset styles are ignored as they can be diff --git a/novelwriter/formats/toqdoc.py b/novelwriter/formats/toqdoc.py index 627b4722..ef4508f9 100644 --- a/novelwriter/formats/toqdoc.py +++ b/novelwriter/formats/toqdoc.py @@ -170,7 +170,7 @@ class ToQTextDocument(Tokenizer): self._blockFmt = QTextBlockFormat() self._blockFmt.setTopMargin(self._mText[0]) self._blockFmt.setBottomMargin(self._mText[1]) - self._blockFmt.setAlignment(QtAlignJustify if self._doJustify else QtAlignAbsolute) + self._blockFmt.setAlignment(QtAlignAbsolute) self._blockFmt.setLineHeight( 100*self._lineHeight, QTextBlockFormat.LineHeightTypes.ProportionalHeight ) diff --git a/tests/reference/mBuildDocBuild_HTML5_Lorem_Ipsum.htm b/tests/reference/mBuildDocBuild_HTML5_Lorem_Ipsum.htm index 565158a1..794071e8 100644 --- a/tests/reference/mBuildDocBuild_HTML5_Lorem_Ipsum.htm +++ b/tests/reference/mBuildDocBuild_HTML5_Lorem_Ipsum.htm @@ -6,7 +6,7 @@