Added unicode constants class, and support for non-breaking spaces, which aren't preserved on save.

This commit is contained in:
Veronica K. B. Olsen
2019-10-29 11:35:40 +01:00
parent 2c63d1fbf2
commit 146756a395
6 changed files with 111 additions and 35 deletions
+3 -3
View File
@@ -19,7 +19,7 @@ from os import path, mkdir, makedirs, getcwd
from appdirs import user_config_dir from appdirs import user_config_dir
from datetime import datetime from datetime import datetime
from nw.constants import nwFiles from nw.constants import nwFiles, nwUnicode
from nw.common import splitVersionNumber from nw.common import splitVersionNumber
from PyQt5.Qt import PYQT_VERSION_STR from PyQt5.Qt import PYQT_VERSION_STR
@@ -87,8 +87,8 @@ class Config:
self.doReplaceDots = True self.doReplaceDots = True
self.wordCountTimer = 5.0 self.wordCountTimer = 5.0
self.fmtSingleQuotes = ["\u2018","\u2019"] self.fmtSingleQuotes = [nwUnicode.U_LSQUO,nwUnicode.U_RSQUO]
self.fmtDoubleQuotes = ["\u201c","\u201d"] self.fmtDoubleQuotes = [nwUnicode.U_LDQUO,nwUnicode.U_RDQUO]
self.spellLanguage = "en_GB" self.spellLanguage = "en_GB"
+60 -20
View File
@@ -142,26 +142,66 @@ class nwQuotes():
"\u300e", # Left white corner bracket "\u300e", # Left white corner bracket
"\u300f", # Right white corner bracket "\u300f", # Right white corner bracket
] ]
# END Class nwQuotes
class nwUnicode:
"""Suppoted unicode character constants and translation maps.
"""
# Quotation Marks
U_QUOT = "\u0022" # Quotation mark
U_APOS = "\u0027" # Apostrophe
U_LAQUO = "\u00ab" # Left-pointing double angle quotation mark
U_RAQUO = "\u00bb" # Right-pointing double angle quotation mark
U_LSQUO = "\u2018" # Left single quotation mark
U_RSQUO = "\u2019" # Right single quotation mark
U_SBQUO = "\u201a" # Single low-9 quotation mark
U_SUQUO = "\u201b" # Single high-reversed-9 quotation mark
U_LDQUO = "\u201c" # Left double quotation mark
U_RDQUO = "\u201d" # Right double quotation mark
U_BDQUO = "\u201e" # Double low-9 quotation mark
U_UDQUO = "\u201f" # Double high-reversed-9 quotation mark
U_LSAQUO = "\u2039" # Single left-pointing angle quotation mark
U_RSAQUO = "\u203a" # Single right-pointing angle quotation mark
U_BDRQUO = "\u2e42" # Double low-reversed-9 quotation mark
U_LCQUO = "\u300c" # Left corner bracket
U_RCQUO = "\u300d" # Right corner bracket
U_LWCQUO = "\u300e" # Left white corner bracket
U_RECQUO = "\u300f" # Right white corner bracket
# Punctuation
U_NDASH = "\u2013" # Short dash
U_MDASH = "\u2014" # Long dash
U_HELLIP = "\u2026" # Ellipsis
# Other
U_NBSP = "\u00a0" # Non-breaking space
HTML = { HTML = {
"\u0022" : """, U_QUOT : """,
"\u0027" : "'", U_APOS : "'",
"\u00ab" : "«", U_LAQUO : "«",
"\u00bb" : "»", U_RAQUO : "»",
"\u2018" : "‘", U_LSQUO : "‘",
"\u2019" : "’", U_RSQUO : "’",
"\u201a" : "‚", U_SBQUO : "‚",
"\u201b" : "‛", U_SUQUO : "‛",
"\u201c" : "“", U_LDQUO : "“",
"\u201d" : "”", U_RDQUO : "”",
"\u201e" : "„", U_BDQUO : "„",
"\u201f" : "‟", U_UDQUO : "‟",
"\u2039" : "‹", U_LSAQUO : "‹",
"\u203a" : "›", U_RSAQUO : "›",
"\u2e42" : "⹂", U_BDRQUO : "⹂",
"\u300c" : "「", U_LCQUO : "「",
"\u300d" : "」", U_RCQUO : "」",
"\u300e" : "『", U_LWCQUO : "『",
"\u300f" : "』", U_LWCQUO : "『",
U_NDASH : "–",
U_MDASH : "—",
U_HELLIP : "…",
U_NBSP : " ",
} }
# END Class nwQuotes # END Class nwUnicode
+30 -6
View File
@@ -23,7 +23,7 @@ from nw.project.document import NWDoc
from nw.gui.dochighlight import GuiDocHighlighter from nw.gui.dochighlight import GuiDocHighlighter
from nw.gui.wordcounter import WordCounter from nw.gui.wordcounter import WordCounter
from nw.tools.spellcheck import NWSpellCheck from nw.tools.spellcheck import NWSpellCheck
from nw.constants import nwFiles from nw.constants import nwFiles, nwUnicode
from nw.enum import nwDocAction, nwAlert from nw.enum import nwDocAction, nwAlert
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -316,9 +316,26 @@ class GuiDocEditor(QTextEdit):
to know whether we had a selection prior to triggering the _docChange slot, as we do not to know whether we had a selection prior to triggering the _docChange slot, as we do not
want to trigger autoreplace on selections. Autoreplace on selections messes with undo/redo want to trigger autoreplace on selections. Autoreplace on selections messes with undo/redo
history. history.
We also need to intercept the Shift key modifier for certain key combinations that modifies
standard keys like enter and space. However, we don't want to spend a lot of time in this
function as it is triggered on every keypress when typing.
""" """
self.hasSelection = self.textCursor().hasSelection() self.hasSelection = self.textCursor().hasSelection()
QTextEdit.keyPressEvent(self, keyEvent)
if keyEvent.modifiers() == Qt.ShiftModifier:
theKey = keyEvent.key()
if theKey == Qt.Key_Return:
self._insertHardBreak()
elif theKey == Qt.Key_Enter:
self._insertHardBreak()
elif theKey == Qt.Key_Space:
self._insertNonBreakingSpace()
else:
QTextEdit.keyPressEvent(self, keyEvent)
else:
QTextEdit.keyPressEvent(self, keyEvent)
return return
## ##
@@ -332,6 +349,13 @@ class GuiDocEditor(QTextEdit):
theCursor.endEditBlock() theCursor.endEditBlock()
return return
def _insertNonBreakingSpace(self):
theCursor = self.textCursor()
theCursor.beginEditBlock()
theCursor.insertText(nwUnicode.U_NBSP)
theCursor.endEditBlock()
return
def _openSpellContext(self): def _openSpellContext(self):
self._openContextMenu(self.cursorRect().center()) self._openContextMenu(self.cursorRect().center())
return return
@@ -442,15 +466,15 @@ class GuiDocEditor(QTextEdit):
elif self.mainConf.doReplaceDash and theTwo == "--": elif self.mainConf.doReplaceDash and theTwo == "--":
theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 2) theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 2)
theCursor.insertText("\u2013") theCursor.insertText(nwUnicode.U_NDASH)
elif self.mainConf.doReplaceDash and theTwo == "\u2013-": elif self.mainConf.doReplaceDash and theTwo == nwUnicode.U_NDASH+"-":
theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 2) theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 2)
theCursor.insertText("\u2014") theCursor.insertText(nwUnicode.U_MDASH)
elif self.mainConf.doReplaceDots and theThree == "...": elif self.mainConf.doReplaceDots and theThree == "...":
theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 3) theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, 3)
theCursor.insertText("\u2026") theCursor.insertText(nwUnicode.U_HELLIP)
return return
+10
View File
@@ -16,6 +16,8 @@ import nw
from PyQt5.QtCore import Qt, QRegularExpression from PyQt5.QtCore import Qt, QRegularExpression
from PyQt5.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter, QBrush from PyQt5.QtGui import QColor, QTextCharFormat, QFont, QSyntaxHighlighter, QBrush
from nw.constants import nwUnicode
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class GuiDocHighlighter(QSyntaxHighlighter): class GuiDocHighlighter(QSyntaxHighlighter):
@@ -87,6 +89,7 @@ class GuiDocHighlighter(QSyntaxHighlighter):
"strike" : self._makeFormat(self.colEmph, "strike"), "strike" : self._makeFormat(self.colEmph, "strike"),
"underline" : self._makeFormat(self.colEmph, "underline"), "underline" : self._makeFormat(self.colEmph, "underline"),
"trailing" : self._makeFormat(self.colTrail,"background"), "trailing" : self._makeFormat(self.colTrail,"background"),
"nobreak" : self._makeFormat(self.colTrail,"background"),
"dialogue1" : self._makeFormat(self.colDialN), "dialogue1" : self._makeFormat(self.colDialN),
"dialogue2" : self._makeFormat(self.colDialD), "dialogue2" : self._makeFormat(self.colDialD),
"dialogue3" : self._makeFormat(self.colDialS), "dialogue3" : self._makeFormat(self.colDialS),
@@ -145,6 +148,13 @@ class GuiDocHighlighter(QSyntaxHighlighter):
} }
)) ))
# Non-breaking Space
self.hRules.append((
"[\u00a0]+", {
0 : self.hStyles["nobreak"],
}
))
# Markdown # Markdown
self.hRules.append(( self.hRules.append((
r"(?<![\w|\\])([\*]{2})(?!\s)(?m:(.+?))(?<![\s|\\])(\1)(?!\w)", { r"(?<![\w|\\])([\*]{2})(?!\s)(?m:(.+?))(?<![\s|\\])(\1)(?!\w)", {
@@ -14,5 +14,7 @@ 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 hypotenuse
With many cheerful facts about the square of the hypotepotenuse With many cheerful facts about the square of the hypotepotenuse
Typing Very Fast — too fast!
+6 -6
View File
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?> <?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.3.2" fileVersion="1.0" timeStamp="2019-10-28 21:42:26"> <novelWriterXML appVersion="0.3.2" fileVersion="1.0" timeStamp="2019-10-29 11:29:39">
<project> <project>
<name>Sample Project</name> <name>Sample Project</name>
<title>Sample Project</title> <title>Sample Project</title>
@@ -11,7 +11,7 @@
<spellCheck>True</spellCheck> <spellCheck>True</spellCheck>
<lastEdited>ba8a28a246524</lastEdited> <lastEdited>ba8a28a246524</lastEdited>
<lastViewed>ba8a28a246524</lastViewed> <lastViewed>ba8a28a246524</lastViewed>
<lastWordCount>859</lastWordCount> <lastWordCount>864</lastWordCount>
<autoReplace> <autoReplace>
<A>B</A> <A>B</A>
<B>E</B> <B>E</B>
@@ -103,10 +103,10 @@
<status>Finished</status> <status>Finished</status>
<expanded>False</expanded> <expanded>False</expanded>
<layout>UNNUMBERED</layout> <layout>UNNUMBERED</layout>
<charCount>626</charCount> <charCount>658</charCount>
<wordCount>101</wordCount> <wordCount>106</wordCount>
<paraCount>3</paraCount> <paraCount>4</paraCount>
<cursorPos>583</cursorPos> <cursorPos>678</cursorPos>
</item> </item>
<item handle="96b68994dfa3d" order="4" parent="e7ded148d6e4a"> <item handle="96b68994dfa3d" order="4" parent="e7ded148d6e4a">
<name>A Note on Ipsums</name> <name>A Note on Ipsums</name>