From 57bc837056499e9820c17a447b599b0ec3969317 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Mon, 28 Oct 2019 21:30:46 +0100
Subject: [PATCH 1/2] Added support for hard line breaks, with higlighting and
export support
---
nw/convert/text/tohtml.py | 8 ++++++--
nw/convert/text/tolatex.py | 5 ++++-
nw/convert/text/totext.py | 3 ++-
nw/convert/tokenizer.py | 3 +--
nw/gui/dochighlight.py | 15 +++++++++++++--
sample/sampleNovel/data_b/a8a28a246524_main.nwd | 16 ++++++++--------
sample/sampleNovel/nwProject.nwx | 8 ++++----
7 files changed, 38 insertions(+), 20 deletions(-)
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 += "\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..50512d2a 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/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
+ 628
101
3
- 633
+ 583
-
A Note on Ipsums
From 62254e1ec0cc649e34c8d5d717bb0f5ad5ea8949 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Mon, 28 Oct 2019 21:43:05 +0100
Subject: [PATCH 2/2] Added Ctrl+Enter as a shortcut for hard line break
---
nw/convert/text/totext.py | 2 +-
nw/gui/doceditor.py | 10 +++++++++-
sample/sampleNovel/data_b/a8a28a246524_main.nwd | 2 ++
sample/sampleNovel/nwProject.nwx | 4 ++--
4 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/nw/convert/text/totext.py b/nw/convert/text/totext.py
index 50512d2a..fc21163e 100644
--- a/nw/convert/text/totext.py
+++ b/nw/convert/text/totext.py
@@ -81,7 +81,7 @@ class ToText(Tokenizer):
if tType == self.T_EMPTY:
if len(thisPar) > 0:
tTemp = " ".join(thisPar)
- self.theResult += "%s\n\n" % tTemp.rstrip())
+ self.theResult += "%s\n\n" % tTemp.rstrip()
thisPar = []
elif tType == self.T_HEAD1:
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/sample/sampleNovel/data_b/a8a28a246524_main.nwd b/sample/sampleNovel/data_b/a8a28a246524_main.nwd
index 55685694..24790377 100644
--- a/sample/sampleNovel/data_b/a8a28a246524_main.nwd
+++ b/sample/sampleNovel/data_b/a8a28a246524_main.nwd
@@ -14,3 +14,5 @@ With many cheerful facts about the square of the hypotenuse
With many cheerful facts about the square of the hypotenuse
With many cheerful facts about the square of the hypotepotenuse
+
+
diff --git a/sample/sampleNovel/nwProject.nwx b/sample/sampleNovel/nwProject.nwx
index b5ec63b8..1412184e 100644
--- a/sample/sampleNovel/nwProject.nwx
+++ b/sample/sampleNovel/nwProject.nwx
@@ -1,5 +1,5 @@
-
+
Sample Project
Sample Project
@@ -103,7 +103,7 @@
Finished
False
UNNUMBERED
- 628
+ 626
101
3
583