diff --git a/nw/convert/text/tohtml.py b/nw/convert/text/tohtml.py index 67757574..0c086a68 100644 --- a/nw/convert/text/tohtml.py +++ b/nw/convert/text/tohtml.py @@ -67,7 +67,8 @@ class ToHtml(Tokenizer): if tType == self.T_EMPTY: if len(thisPar) > 0: - self.theResult += "%s

\n" % (hStyle," ".join(thisPar)) + tTemp = "".join(thisPar) + self.theResult += "%s

\n" % (hStyle,tTemp.rstrip()) thisPar = [] elif tType == self.T_HEAD1: @@ -92,7 +93,10 @@ class ToHtml(Tokenizer): tTemp = tText for xPos, xLen, xFmt in reversed(tFormat): tTemp = tTemp[:xPos]+htmlTags[xFmt]+tTemp[xPos+xLen:] - thisPar.append(tTemp) + if tText.endswith(" "): + thisPar.append(tTemp.rstrip()+"
") + else: + thisPar.append(tTemp.rstrip()+" ") elif tType == self.T_COMMENT and self.doComments: self.theResult += "
%s
\n" % tText diff --git a/nw/convert/text/tolatex.py b/nw/convert/text/tolatex.py index bd4e559e..cfcec012 100644 --- a/nw/convert/text/tolatex.py +++ b/nw/convert/text/tolatex.py @@ -95,7 +95,10 @@ class ToLaTeX(Tokenizer): self.theResult += "\\bigskip\n\n" elif tType == self.T_TEXT: - thisPar.append(self._escapeUnicode(tText)) + if tText.endswith(" "): + thisPar.append(self._escapeUnicode(tText.rstrip())+"\\newline") + else: + thisPar.append(self._escapeUnicode(tText.rstrip())) elif tType == self.T_PBREAK: self.theResult += "\\newpage\n\n" diff --git a/nw/convert/text/totext.py b/nw/convert/text/totext.py index e685e5be..fc21163e 100644 --- a/nw/convert/text/totext.py +++ b/nw/convert/text/totext.py @@ -80,7 +80,8 @@ class ToText(Tokenizer): # indicating a new paragraph. if tType == self.T_EMPTY: if len(thisPar) > 0: - self.theResult += "%s\n\n" % " ".join(thisPar) + tTemp = " ".join(thisPar) + self.theResult += "%s\n\n" % tTemp.rstrip() thisPar = [] elif tType == self.T_HEAD1: diff --git a/nw/convert/tokenizer.py b/nw/convert/tokenizer.py index 1b7fdd51..63abc1ae 100644 --- a/nw/convert/tokenizer.py +++ b/nw/convert/tokenizer.py @@ -171,10 +171,9 @@ class Tokenizer(): self.theTokens = [] for aLine in self.theText.splitlines(): - aLine = aLine.strip() # Tag lines starting with specific characters - if len(aLine) == 0: + if len(aLine.strip()) == 0: self.theTokens.append((self.T_EMPTY,"",None,self.A_LEFT)) elif aLine[0] == "%": self.theTokens.append((self.T_COMMENT,aLine[1:].strip(),None,self.A_LEFT)) diff --git a/nw/gui/doceditor.py b/nw/gui/doceditor.py index 9c247ae5..03d3313d 100644 --- a/nw/gui/doceditor.py +++ b/nw/gui/doceditor.py @@ -81,6 +81,8 @@ class GuiDocEditor(QTextEdit): # Custom Shortcuts QShortcut(QKeySequence("Ctrl+."), self, context=Qt.WidgetShortcut, activated=self._openSpellContext) + QShortcut(Qt.Key_Return | Qt.ControlModifier, self, context=Qt.WidgetShortcut, activated=self._insertHardBreak) + QShortcut(Qt.Key_Enter | Qt.ControlModifier, self, context=Qt.WidgetShortcut, activated=self._insertHardBreak) # Set Up Word Count Thread and Timer self.wcInterval = self.mainConf.wordCountTimer @@ -323,6 +325,13 @@ class GuiDocEditor(QTextEdit): # Internal Functions ## + def _insertHardBreak(self): + theCursor = self.textCursor() + theCursor.beginEditBlock() + theCursor.insertText(" \n") + theCursor.endEditBlock() + return + def _openSpellContext(self): self._openContextMenu(self.cursorRect().center()) return @@ -388,7 +397,6 @@ class GuiDocEditor(QTextEdit): self.wcTimer.start() if self.mainConf.doReplace and not self.hasSelection: self._docAutoReplace(self.qDocument.findBlock(thePos)) - # logger.verbose("Doc change signal took %.3f µs" % ((time()-self.lastEdit)*1e6)) return def _docAutoReplace(self, theBlock): diff --git a/nw/gui/dochighlight.py b/nw/gui/dochighlight.py index 39efb3b6..74506f71 100644 --- a/nw/gui/dochighlight.py +++ b/nw/gui/dochighlight.py @@ -13,8 +13,8 @@ import logging import nw -from PyQt5.QtCore import QRegularExpression -from PyQt5.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter +from PyQt5.QtCore import Qt, QRegularExpression +from PyQt5.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter, QBrush logger = logging.getLogger(__name__) @@ -71,6 +71,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): self.colSpell = QColor(*self.theTheme.colSpell) self.colTagErr = QColor(*self.theTheme.colTagErr) self.colRepTag = QColor(*self.theTheme.colRepTag) + self.colTrail = QColor(*self.theTheme.colEmph,64) self.hStyles = { "header1" : self._makeFormat(self.colHead, "bold",1.8), @@ -85,6 +86,7 @@ class GuiDocHighlighter(QSyntaxHighlighter): "italic" : self._makeFormat(self.colEmph, "italic"), "strike" : self._makeFormat(self.colEmph, "strike"), "underline" : self._makeFormat(self.colEmph, "underline"), + "trailing" : self._makeFormat(self.colTrail,"background"), "dialogue1" : self._makeFormat(self.colDialN), "dialogue2" : self._makeFormat(self.colDialD), "dialogue3" : self._makeFormat(self.colDialS), @@ -136,6 +138,13 @@ class GuiDocHighlighter(QSyntaxHighlighter): } )) + # Trailing Spaces, 2+ + self.hRules.append(( + r"[ ]{2,}$", { + 0 : self.hStyles["trailing"], + } + )) + # Markdown self.hRules.append(( r"(? - + Sample Project Sample Project @@ -10,7 +10,7 @@ True ba8a28a246524 - 636b6aa9b697b + ba8a28a246524 859 B @@ -103,10 +103,10 @@ Finished False UNNUMBERED - 614 + 626 101 3 - 633 + 583 A Note on Ipsums