diff --git a/nw/enum.py b/nw/enum.py index 1a24a7a8..830e8953 100644 --- a/nw/enum.py +++ b/nw/enum.py @@ -89,6 +89,7 @@ class nwDocAction(Enum): BLOCK_TXT = 18 REPL_SNG = 19 REPL_DBL = 20 + RM_BREAKS = 21 # END Enum nwDocAction diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index a6b853b8..a6cc404e 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -791,6 +791,8 @@ class GuiDocEditor(QTextEdit): self._replaceQuotes("'", self._typSQOpen, self._typSQClose) elif theAction == nwDocAction.REPL_DBL: self._replaceQuotes("\"", self._typDQOpen, self._typDQClose) + elif theAction == nwDocAction.RM_BREAKS: + self._removeInParLineBreaks() else: logger.debug("Unknown or unsupported document action %s" % str(theAction)) self._allowAutoReplace(True) @@ -1785,6 +1787,54 @@ class GuiDocEditor(QTextEdit): return True + def _removeInParLineBreaks(self): + """Strip line breaks within paragraphs in the selected text. + """ + theCursor = self.textCursor() + theDoc = self.document() + + iS = 0 + iE = theDoc.blockCount() - 1 + rS = 0 + rE = theDoc.characterCount() + if theCursor.hasSelection(): + sBlock = theDoc.findBlock(theCursor.selectionStart()) + eBlock = theDoc.findBlock(theCursor.selectionEnd()) + iS = sBlock.blockNumber() + iE = eBlock.blockNumber() + rS = sBlock.position() + rE = eBlock.position() + eBlock.length() + + # Clean up the text + currPar = [] + cleanText = "" + for i in range(iS, iE+1): + cBlock = theDoc.findBlockByNumber(i) + cText = cBlock.text() + if cText.strip() == "": + if currPar: + cleanText += " ".join(currPar) + "\n\n" + else: + cleanText += "\n" + currPar = [] + elif cText.startswith(("# ", "## ", "### ", "#### ", "@", "%")): + cleanText += cText + "\n" + else: + currPar.append(cText) + + if currPar: + cleanText += " ".join(currPar) + "\n\n" + + # Replace the text with the cleaned up text + theCursor.beginEditBlock() + theCursor.clearSelection() + theCursor.setPosition(rS) + theCursor.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, rE-rS) + theCursor.insertText(cleanText.rstrip() + "\n") + theCursor.endEditBlock() + + return True + def _makeSelection(self, selMode): """Wrapper function to select text based on a selection mode. """ diff --git a/nw/gui/mainmenu.py b/nw/gui/mainmenu.py index 947b0722..d259c6cd 100644 --- a/nw/gui/mainmenu.py +++ b/nw/gui/mainmenu.py @@ -743,60 +743,6 @@ class GuiMainMenu(QMenuBar): return - def _buildSearchMenu(self): - """Assemble the Search menu. - """ - # Search - self.srcMenu = self.addMenu(self.tr("&Search")) - - # Search > Find - self.aFind = QAction(self.tr("Find"), self) - self.aFind.setStatusTip(self.tr("Find text in document")) - self.aFind.setShortcut("Ctrl+F") - self.aFind.triggered.connect(lambda: self.theParent.docEditor.beginSearch()) - self.srcMenu.addAction(self.aFind) - - # Search > Replace - self.aReplace = QAction(self.tr("Replace"), self) - self.aReplace.setStatusTip(self.tr("Replace text in document")) - if self.mainConf.osDarwin: - self.aReplace.setShortcut("Ctrl+=") - else: - self.aReplace.setShortcut("Ctrl+H") - self.aReplace.triggered.connect(lambda: self.theParent.docEditor.beginReplace()) - self.srcMenu.addAction(self.aReplace) - - # Search > Find Next - self.aFindNext = QAction(self.tr("Find Next"), self) - self.aFindNext.setStatusTip(self.tr("Find next occurrence of text in document")) - if self.mainConf.osDarwin: - self.aFindNext.setShortcuts(["Ctrl+G", "F3"]) - else: - self.aFindNext.setShortcuts(["F3", "Ctrl+G"]) - self.aFindNext.triggered.connect(lambda: self.theParent.docEditor.findNext()) - self.srcMenu.addAction(self.aFindNext) - - # Search > Find Prev - self.aFindPrev = QAction(self.tr("Find Previous"), self) - self.aFindPrev.setStatusTip(self.tr("Find previous occurrence of text in document")) - if self.mainConf.osDarwin: - self.aFindPrev.setShortcuts(["Ctrl+Shift+G", "Shift+F3"]) - else: - self.aFindPrev.setShortcuts(["Shift+F3", "Ctrl+Shift+G"]) - self.aFindPrev.triggered.connect(lambda: self.theParent.docEditor.findNext(goBack=True)) - self.srcMenu.addAction(self.aFindPrev) - - # Search > Replace Next - self.aReplaceNext = QAction(self.tr("Replace Next"), self) - self.aReplaceNext.setStatusTip( - self.tr("Find and replace next occurrence of text in document") - ) - self.aReplaceNext.setShortcut("Ctrl+Shift+1") - self.aReplaceNext.triggered.connect(lambda: self.theParent.docEditor.replaceNext()) - self.srcMenu.addAction(self.aReplaceNext) - - return - def _buildFormatMenu(self): """Assemble the Format menu. """ @@ -905,6 +851,68 @@ class GuiMainMenu(QMenuBar): self.aFmtReplDbl.triggered.connect(lambda: self._docAction(nwDocAction.REPL_DBL)) self.fmtMenu.addAction(self.aFmtReplDbl) + # Format > Remove In-Paragraph Breaks + self.aFmtRmBreaks = QAction(self.tr("Remove In-Paragraph Breaks"), self) + self.aFmtRmBreaks.setStatusTip( + self.tr("Removes all line breaks within paragraphs in the selected text") + ) + self.aFmtRmBreaks.triggered.connect(lambda: self._docAction(nwDocAction.RM_BREAKS)) + self.fmtMenu.addAction(self.aFmtRmBreaks) + + return + + def _buildSearchMenu(self): + """Assemble the Search menu. + """ + # Search + self.srcMenu = self.addMenu(self.tr("&Search")) + + # Search > Find + self.aFind = QAction(self.tr("Find"), self) + self.aFind.setStatusTip(self.tr("Find text in document")) + self.aFind.setShortcut("Ctrl+F") + self.aFind.triggered.connect(lambda: self.theParent.docEditor.beginSearch()) + self.srcMenu.addAction(self.aFind) + + # Search > Replace + self.aReplace = QAction(self.tr("Replace"), self) + self.aReplace.setStatusTip(self.tr("Replace text in document")) + if self.mainConf.osDarwin: + self.aReplace.setShortcut("Ctrl+=") + else: + self.aReplace.setShortcut("Ctrl+H") + self.aReplace.triggered.connect(lambda: self.theParent.docEditor.beginReplace()) + self.srcMenu.addAction(self.aReplace) + + # Search > Find Next + self.aFindNext = QAction(self.tr("Find Next"), self) + self.aFindNext.setStatusTip(self.tr("Find next occurrence of text in document")) + if self.mainConf.osDarwin: + self.aFindNext.setShortcuts(["Ctrl+G", "F3"]) + else: + self.aFindNext.setShortcuts(["F3", "Ctrl+G"]) + self.aFindNext.triggered.connect(lambda: self.theParent.docEditor.findNext()) + self.srcMenu.addAction(self.aFindNext) + + # Search > Find Prev + self.aFindPrev = QAction(self.tr("Find Previous"), self) + self.aFindPrev.setStatusTip(self.tr("Find previous occurrence of text in document")) + if self.mainConf.osDarwin: + self.aFindPrev.setShortcuts(["Ctrl+Shift+G", "Shift+F3"]) + else: + self.aFindPrev.setShortcuts(["Shift+F3", "Ctrl+Shift+G"]) + self.aFindPrev.triggered.connect(lambda: self.theParent.docEditor.findNext(goBack=True)) + self.srcMenu.addAction(self.aFindPrev) + + # Search > Replace Next + self.aReplaceNext = QAction(self.tr("Replace Next"), self) + self.aReplaceNext.setStatusTip( + self.tr("Find and replace next occurrence of text in document") + ) + self.aReplaceNext.setShortcut("Ctrl+Shift+1") + self.aReplaceNext.triggered.connect(lambda: self.theParent.docEditor.replaceNext()) + self.srcMenu.addAction(self.aReplaceNext) + return def _buildToolsMenu(self):