diff --git a/CHANGELOG.md b/CHANGELOG.md
index 36699c5a..35026aa7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -186,6 +186,22 @@ careful when using this version on live writing projects, and make sure you make
----
+## Version 1.4.2 [2021-08-30]
+
+### Release Notes
+
+This is a patch release fixing an issue with the auto-replace feature for single and double quotes.
+The issue appears when using the new indent and text alignment codes followed by a quote symbol,
+and quotes following a tab or non-breaking space.
+
+**Bugfixes**
+
+* Any single or double straight quote following a whitespace other than a regular space, or a left
+ indent or right align set of angle bracket codes without a space following them, would be
+ erroneously replaced by a closing quote instead of an opening quote. Issue #874.
+
+----
+
## Version 1.4.1 [2021-07-27]
### Release Notes
diff --git a/novelwriter/assets/text/release_notes_1.4.htm b/novelwriter/assets/text/release_notes_1.4.htm
index e2b2bc36..e7b250d7 100644
--- a/novelwriter/assets/text/release_notes_1.4.htm
+++ b/novelwriter/assets/text/release_notes_1.4.htm
@@ -2,14 +2,23 @@
+Release Notes for 1.4.2
+Released on 30 August 2021
+
+This is a patch release fixing an issue with the auto-replace feature for single and double
+quotes. The issue appears when using the new indent and text alignment codes followed by a quote
+symbol, and quotes following a tab or non-breaking space.
+
+See also the Releases page.
+
+
+
Release Notes for 1.4.1
Released on 27 July 2021
This release fixes a couple of minor issue with some of the dialog boxes. The fix was
accidentally left out of release 1.4.
-See also the Releases page.
-
Release Notes for 1.4
diff --git a/novelwriter/gui/doceditor.py b/novelwriter/gui/doceditor.py
index 9d066941..74fa8c1f 100644
--- a/novelwriter/gui/doceditor.py
+++ b/novelwriter/gui/doceditor.py
@@ -1807,7 +1807,7 @@ class GuiDocEditor(QTextEdit):
nDelete = 0
tInsert = theOne
- if self.mainConf.doReplaceDQuote and theTwo == ' "':
+ if self.mainConf.doReplaceDQuote and theTwo[:1].isspace() and theTwo.endswith('"'):
nDelete = 1
tInsert = self._typDQOpen
@@ -1815,10 +1815,14 @@ class GuiDocEditor(QTextEdit):
nDelete = 1
if thePos == 1:
tInsert = self._typDQOpen
+ elif thePos == 2 and theTwo == '>"':
+ tInsert = self._typDQOpen
+ elif thePos == 3 and theThree == '>>"':
+ tInsert = self._typDQOpen
else:
tInsert = self._typDQClose
- elif self.mainConf.doReplaceSQuote and theTwo == " '":
+ elif self.mainConf.doReplaceSQuote and theTwo[:1].isspace() and theTwo.endswith("'"):
nDelete = 1
tInsert = self._typSQOpen
@@ -1826,6 +1830,10 @@ class GuiDocEditor(QTextEdit):
nDelete = 1
if thePos == 1:
tInsert = self._typSQOpen
+ elif thePos == 2 and theTwo == ">'":
+ tInsert = self._typSQOpen
+ elif thePos == 3 and theThree == ">>'":
+ tInsert = self._typSQOpen
else:
tInsert = self._typSQClose
diff --git a/tests/reference/guiEditor_Main_Final_0e17daca5f3e1.nwd b/tests/reference/guiEditor_Main_Final_0e17daca5f3e1.nwd
index 2fd0b8b5..67886bc1 100644
--- a/tests/reference/guiEditor_Main_Final_0e17daca5f3e1.nwd
+++ b/tests/reference/guiEditor_Main_Final_0e17daca5f3e1.nwd
@@ -27,3 +27,15 @@ This is another paragraph of much longer nonsense text. It is in fact 1 very ver
‘Full line single quoted text.’
+ “Tab-indented text”
+
+>“Paragraph-indented text”
+
+>>“Right-aligned text”
+
+ ‘Tab-indented text’
+
+>‘Paragraph-indented text’
+
+>>‘Right-aligned text’
+
diff --git a/tests/reference/guiEditor_Main_Final_nwProject.nwx b/tests/reference/guiEditor_Main_Final_nwProject.nwx
index 8230ba92..1111c579 100644
--- a/tests/reference/guiEditor_Main_Final_nwProject.nwx
+++ b/tests/reference/guiEditor_Main_Final_nwProject.nwx
@@ -1,11 +1,11 @@
-
+
New Project
5
2
- 3
+ 4
True
@@ -15,8 +15,8 @@
True
0e17daca5f3e1
None
- 114
- 87
+ 126
+ 99
27
@@ -85,10 +85,10 @@
New
True
DOCUMENT
- 482
- 83
- 4
- 620
+ 612
+ 95
+ 10
+ 768
-
Plot
diff --git a/tests/test_gui/test_gui_guimain.py b/tests/test_gui/test_gui_guimain.py
index 0087993e..c3fe9c7c 100644
--- a/tests/test_gui/test_gui_guimain.py
+++ b/tests/test_gui/test_gui_guimain.py
@@ -286,6 +286,36 @@ def testGuiMain_Editing(qtbot, monkeypatch, nwGUI, fncProj, refDir, outDir):
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+ for c in "\t\"Tab-indented text\"":
+ qtbot.keyClick(nwGUI.docEditor, c, delay=typeDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+
+ for c in ">\"Paragraph-indented text\"":
+ qtbot.keyClick(nwGUI.docEditor, c, delay=typeDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+
+ for c in ">>\"Right-aligned text\"":
+ qtbot.keyClick(nwGUI.docEditor, c, delay=typeDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+
+ for c in "\t'Tab-indented text'":
+ qtbot.keyClick(nwGUI.docEditor, c, delay=typeDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+
+ for c in ">'Paragraph-indented text'":
+ qtbot.keyClick(nwGUI.docEditor, c, delay=typeDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+
+ for c in ">>'Right-aligned text'":
+ qtbot.keyClick(nwGUI.docEditor, c, delay=typeDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+ qtbot.keyClick(nwGUI.docEditor, Qt.Key_Return, delay=keyDelay)
+
qtbot.wait(stepDelay)
nwGUI.docEditor.wCounter.run()
qtbot.wait(stepDelay)