diff --git a/nw/constants/constants.py b/nw/constants/constants.py index 5c483657..9bd47110 100644 --- a/nw/constants/constants.py +++ b/nw/constants/constants.py @@ -39,6 +39,7 @@ class nwRegEx(): FMT_B = r"(?", - self.FMT_B_E : "", - self.FMT_I_B : "", - self.FMT_I_E : "", - self.FMT_S_B : "", - self.FMT_S_E : "", - } + if self.genMode == self.M_PREVIEW: + htmlTags = { # HTML4 + CSS2 + self.FMT_B_B : "", + self.FMT_B_E : "", + self.FMT_I_B : "", + self.FMT_I_E : "", + self.FMT_S_B : "", + self.FMT_S_E : "", + self.FMT_D_B : "", + self.FMT_D_E : "", + } + else: + htmlTags = { # HTML5 + self.FMT_B_B : "", + self.FMT_B_E : "", + self.FMT_I_B : "", + self.FMT_I_E : "", + self.FMT_S_B : "", + self.FMT_S_E : "", + self.FMT_D_B : "", + self.FMT_D_E : "", + } if self.isNovel and self.genMode != self.M_PREVIEW: # For novel files for export, we bump the titles one level diff --git a/nw/core/tokenizer.py b/nw/core/tokenizer.py index b9c283cc..e13feb0e 100644 --- a/nw/core/tokenizer.py +++ b/nw/core/tokenizer.py @@ -46,6 +46,8 @@ class Tokenizer(): FMT_I_E = 4 # End italics FMT_S_B = 5 # Begin bold italic FMT_S_E = 6 # End bold italic + FMT_D_B = 7 # Begin strikeout + FMT_D_E = 8 # End strikeout T_EMPTY = 1 # Empty line (new paragraph) T_SYNOPSIS = 2 # Synopsis comment @@ -292,16 +294,18 @@ class Tokenizer(): The format of the token list is an entry with a four-tuple for each line in the file. The tuple is as follows: 1: The type of the block, self.T_* - 2: The text content of the block, without leading tags - 3: The internal formatting map of the text, self.FMT_* - 4: The style of the block, self.A_* + 2: The line in file where this block occurred + 3: The text content of the block, without leading tags + 4: The internal formatting map of the text, self.FMT_* + 5: The style of the block, self.A_* """ # RegExes for adding formatting tags within text lines rxFormats = [ - (QRegularExpression(nwRegEx.FMT_BI), [None, self.FMT_S_B, None, self.FMT_S_E]), - (QRegularExpression(nwRegEx.FMT_B), [None, self.FMT_B_B, None, self.FMT_B_E]), (QRegularExpression(nwRegEx.FMT_I), [None, self.FMT_I_B, None, self.FMT_I_E]), + (QRegularExpression(nwRegEx.FMT_B), [None, self.FMT_B_B, None, self.FMT_B_E]), + (QRegularExpression(nwRegEx.FMT_BI), [None, self.FMT_S_B, None, self.FMT_S_E]), + (QRegularExpression(nwRegEx.FMT_ST), [None, self.FMT_D_B, None, self.FMT_D_E]), ] self.theTokens = [] diff --git a/nw/gui/build.py b/nw/gui/build.py index 02841833..70ea0703 100644 --- a/nw/gui/build.py +++ b/nw/gui/build.py @@ -982,7 +982,9 @@ class GuiBuildNovelDocView(QTextBrowser): """ if isinstance(theText, list): theText = "".join(theText) - theText = theText.replace(" "," "*4) + theText = theText.replace(" ", " "*4) + theText = theText.replace("", "") + theText = theText.replace("", "") self.setHtml(theText) return diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 26e64c82..4c5d5ce7 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -515,6 +515,8 @@ class GuiDocEditor(QTextEdit): self._toggleEmph(2) elif theAction == nwDocAction.BOLDITALIC: self._toggleEmph(3) + elif theAction == nwDocAction.STRIKE: + self._toggleStrike() elif theAction == nwDocAction.S_QUOTE: self._wrapSelection(self.typSQOpen, self.typSQClose) elif theAction == nwDocAction.D_QUOTE: @@ -1000,6 +1002,36 @@ class GuiDocEditor(QTextEdit): return + def _toggleStrike(self): + """Toggle strikethrough text. + """ + theCursor = self._autoSelect() + if theCursor.hasSelection(): + posS = theCursor.selectionStart() + posE = theCursor.selectionEnd() + + numB = 0 + for n in range(2): + if self.qDocument.characterAt(posS-n-1) == "~": + numB += 1 + else: + break + + numA = 0 + for n in range(2): + if self.qDocument.characterAt(posE+n) == "~": + numA += 1 + else: + break + + cLevel = min(numB, numA) + if cLevel == 2: + self._clearSurrounding(theCursor, 2) + else: + self._wrapSelection("~~") + + return + def _formatBlock(self, docAction): """Changes the block format of the block under the cursor. """ diff --git a/nw/gui/dochighlight.py b/nw/gui/dochighlight.py index e81d9bca..4754110d 100644 --- a/nw/gui/dochighlight.py +++ b/nw/gui/dochighlight.py @@ -160,6 +160,13 @@ class GuiDocHighlighter(QSyntaxHighlighter): 3 : self.hStyles["hidden"], } )) + self.hRules.append(( + nwRegEx.FMT_ST, { + 1 : self.hStyles["hidden"], + 2 : self.hStyles["strike"], + 3 : self.hStyles["hidden"], + } + )) # Quoted Strings if self.mainConf.highlightQuotes: diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py index 086261d1..3ea9a85d 100644 --- a/nw/gui/mainmenu.py +++ b/nw/gui/mainmenu.py @@ -536,6 +536,13 @@ class GuiMainMenu(QMenuBar): self.aFmtBoldIt.triggered.connect(lambda: self._docAction(nwDocAction.BOLDITALIC)) self.fmtMenu.addAction(self.aFmtBoldIt) + # Format > Strikethrough + self.aFmtStrike = QAction("Strikethrough Text", self) + self.aFmtStrike.setStatusTip("Strikethrough selected text") + self.aFmtStrike.setShortcut("Ctrl+-") + self.aFmtStrike.triggered.connect(lambda: self._docAction(nwDocAction.STRIKE)) + self.fmtMenu.addAction(self.aFmtStrike) + # Edit > Separator self.fmtMenu.addSeparator() diff --git a/sample/content/636b6aa9b697b.nwd b/sample/content/636b6aa9b697b.nwd index 7b2d92c6..4916b753 100644 --- a/sample/content/636b6aa9b697b.nwd +++ b/sample/content/636b6aa9b697b.nwd @@ -7,7 +7,7 @@ A scene is defined by a level three heading, like the one at the top of this page. The scene will be assigned to the chapter preceding it in the project tree. -Each paragraph in the scene is separated by a blank line. The text supports minimal formatting, like **bold**, *italic* and ***bold italic***. +Each paragraph in the scene is separated by a blank line. The text supports minimal formatting, like **bold**, *italic* and ***bold italic***. You can also ~~strike through~~ text. In addition, the editor supports automatic formatting of “quotes”, both double and ‘single’. Depending on the syntax highlighter, these can be in different colours. diff --git a/sample/nwProject.nwx b/sample/nwProject.nwx index a603b373..aeba369e 100644 --- a/sample/nwProject.nwx +++ b/sample/nwProject.nwx @@ -1,13 +1,13 @@ - + Sample Project Sample Project Jane Smith Jay Doh - 319 - 49 - 9675 + 332 + 56 + 10692 False @@ -15,7 +15,7 @@ True 636b6aa9b697b 636b6aa9b697b - 921 + 927 B E @@ -114,10 +114,10 @@ 1st Draft True SCENE - 1202 - 217 + 1240 + 223 7 - 248 + 403 Another Scene