Merge pull request #355 from vkbo/markdown-fixes

Markdown fixes
This commit is contained in:
Veronica K. Berglyd Olsen
2020-06-29 17:04:12 +02:00
committed by GitHub
16 changed files with 131 additions and 201 deletions
+11 -8
View File
@@ -33,8 +33,9 @@ Markdown Format
===============
The document editor uses a simplified markdown format.
That is, it supports basic formatting like bold, italics and strikethrough, as well as four levels of headings.
The preference of novelWriter is to use `*` for wrapping emphasised text, but `_` is partially supported when typed, but not by the automatic formatting features and keyboard shortcuts.
That is, it supports basic formatting like emphasis (italic), strong emphasis (bold) and strikethrough text, as well as four levels of headings.
It is commonly recommended style to differentiate between strong emphasis and emphasis by using ``**`` for strong emphasis and ``_`` for emphasis, although Markdown generally supports also ``__`` for strong emphasis and ``*`` fdr emphasis.
However, since the differentiation makes the highlighting and conversion significantly simpler and faster, in novelWriter this is a rule, not just a recommendation.
In addition to these standard markdown features, the editor also allows for comments, that is text that is ignored by the word counter and not exported or, optionally, hidden in the document viewer.
If the first word of a comment is "Synopsis:" (with the colon), the comment is treated specially, and will show up in the Outline View.
@@ -48,19 +49,21 @@ The editor also has a minimal set of keywords used for setting tags and referenc
"``## Title``", "Heading level two. The space after the # is mandatory."
"``### Title``", "Heading level three. The space after the # is mandatory."
"``#### Title``", "Heading level four. The space after the # is mandatory."
"``*text*``", "The text is rendered as emphasised text (italicised)."
"``_text_``", "The text is rendered as emphasised text (italicised)."
"``**text**``", "The text is rendered as strongly emphasised text (bold)."
"``***text***``", "The text is rendered as very strongly emphasised text (italicised, bold)."
"``_text_``", "Alternative format for emphasised text."
"``__text__``", "Alternative format for strongly emphasised text."
"``~~text~~``", "Strikethrough text."
"``% text...``", "A comment. The text is not exported by default, seen in viewer, or counted towards word counts."
"``% Synopsis: text...``", "A synopsis comment. Shows up in the Synopsis column of the Outline View, but is otherwise treated as a comment."
"``@keyword: value``", "A keyword argument followed by a value, or a comma separated list of values."
.. note::
The emphasis and strikethrough formatting tags do not allow spaces between the words and the tag itself.
Some additional rules:
1. The emphasis and strikethrough formatting tags do not allow spaces between the words and the tag itself.
That is, ``**text**`` is valid, ``**text **`` is not.
2. More generally, the delimiters must be on the outer edge of words.
That is, ``some **text in bold** here`` is valid, ``some** text in bold** here`` is not.
3. If using both ``**`` and ``_`` to wrap the same text, the underscore must be the inner wrapper.
This is due to the underscore also being a valid word character, so if they are on the outside, they violate rule 2.
The editor and viewer also supports markdown standard hard line breaks, and preserves non-breaking spaces.
A hard line break is achieved by leaving two or more spaces at the end of the line.
+3 -4
View File
@@ -37,10 +37,9 @@ class nwConst():
class nwRegEx():
FMT_B = r"(?<![\w|\*|_|\\])([\*|_]{2})(?!\s|\*|_)(.+?)(?<![\s|\\])(\1)(?!\w)"
FMT_I = r"(?<![\w|\*|_|\\])([\*|_])(?!\s|\*|_)(.+?)(?<![\s|\\])(\1)(?!\w)"
FMT_BI = r"(?<![\w|\*|\\])([\*]{3})(?!\s|\*)(.+?)(?<![\s|\\])(\1)(?!\w)"
FMT_ST = r"(?<![\w|~|\\])([~]{2})(?!\s|~)(.+?)(?<![\s|\\])(\1)(?!\w)"
FMT_I = r"(?<![\w\\])(_)(?![\s_])(.+?)(?<![\s\\])(\1)(?!\w)"
FMT_B = r"(?<![\w\\])([\*]{2})(?![\s\*])(.+?)(?<![\s\\])(\1)(?!\w)"
FMT_ST = r"(?<![\w\\])([~]{2})(?![\s~])(.+?)(?<![\s\\])(\1)(?!\w)"
# END Class nwRegEx
+18 -19
View File
@@ -76,25 +76,24 @@ class nwDocAction(Enum):
PASTE = 5
EMPH = 6
STRONG = 7
STRONGEMPH = 8
STRIKE = 9
S_QUOTE = 10
D_QUOTE = 11
SEL_ALL = 12
SEL_PARA = 13
FIND = 14
REPLACE = 15
GO_NEXT = 16
GO_PREV = 17
REPL_NEXT = 18
BLOCK_H1 = 19
BLOCK_H2 = 20
BLOCK_H3 = 21
BLOCK_H4 = 22
BLOCK_COM = 23
BLOCK_TXT = 24
REPL_SNG = 25
REPL_DBL = 26
STRIKE = 8
S_QUOTE = 9
D_QUOTE = 10
SEL_ALL = 11
SEL_PARA = 12
FIND = 13
REPLACE = 14
GO_NEXT = 15
GO_PREV = 16
REPL_NEXT = 17
BLOCK_H1 = 18
BLOCK_H2 = 19
BLOCK_H3 = 20
BLOCK_H4 = 21
BLOCK_COM = 22
BLOCK_TXT = 23
REPL_SNG = 24
REPL_DBL = 25
# END Enum nwDocAction
+1 -4
View File
@@ -107,6 +107,7 @@ class ToHtml(Tokenizer):
"""Reverse the html entities replacement on the markdown text.
Otherwise, all the &something; bits will also be in there.
"""
Tokenizer.doPostProcessing(self)
if self.genMode == self.M_PREVIEW:
# Doesn't matter for preview as we don't use the markdown
return
@@ -125,8 +126,6 @@ class ToHtml(Tokenizer):
self.FMT_B_E : "</b>",
self.FMT_I_B : "<i>",
self.FMT_I_E : "</i>",
self.FMT_S_B : "<b><i>",
self.FMT_S_E : "</i></b>",
self.FMT_D_B : "<span style='text-decoration: line-through;'>",
self.FMT_D_E : "</span>",
}
@@ -136,8 +135,6 @@ class ToHtml(Tokenizer):
self.FMT_B_E : "</strong>",
self.FMT_I_B : "<em>",
self.FMT_I_E : "</em>",
self.FMT_S_B : "<strong><em>",
self.FMT_S_E : "</em></strong>",
self.FMT_D_B : "<del>",
self.FMT_D_E : "</del>",
}
+15 -7
View File
@@ -44,10 +44,8 @@ class Tokenizer():
FMT_B_E = 2 # End bold
FMT_I_B = 3 # Begin italics
FMT_I_E = 4 # End italics
FMT_S_B = 5 # Begin bold italic
FMT_S_E = 6 # End bold italic
FMT_D_B = 7 # Begin strikeout
FMT_D_E = 8 # End strikeout
FMT_D_B = 5 # Begin strikeout
FMT_D_E = 6 # End strikeout
T_EMPTY = 1 # Empty line (new paragraph)
T_SYNOPSIS = 2 # Synopsis comment
@@ -269,7 +267,6 @@ class Tokenizer():
def doAutoReplace(self):
"""Run through the user's auto-replace dictionary.
"""
if len(self.theProject.autoReplace) > 0:
repDict = {}
for aKey, aVal in self.theProject.autoReplace.items():
@@ -280,8 +277,20 @@ class Tokenizer():
return
def doPostProcessing(self):
"""Do some postprocessing. Overloaded by subclasses.
"""Do some postprocessing. Overloaded by subclasses. This just
does the standard escaped characters.
"""
escapeDict = {
"\*" : "*",
"\~" : "~",
"\_" : "_",
}
escReplace = re.compile(
"|".join([re.escape(k) for k in escapeDict.keys()]), flags=re.DOTALL
)
self.theResult = escReplace.sub(
lambda x: escapeDict[x.group(0)], self.theResult
)
return
def tokenizeText(self):
@@ -304,7 +313,6 @@ class Tokenizer():
rxFormats = [
(QRegularExpression(nwRegEx.FMT_I), [None, self.FMT_I_B, None, self.FMT_I_E]),
(QRegularExpression(nwRegEx.FMT_B), [None, self.FMT_B_B, None, self.FMT_B_E]),
(QRegularExpression(nwRegEx.FMT_BI), [None, self.FMT_S_B, None, self.FMT_S_E]),
(QRegularExpression(nwRegEx.FMT_ST), [None, self.FMT_D_B, None, self.FMT_D_E]),
]
+8
View File
@@ -34,6 +34,10 @@ from os import path, unlink, rmdir
logger = logging.getLogger(__name__)
# =========================================================================== #
# Simple Word Counter
# =========================================================================== #
def countWords(theText):
"""Count words in a piece of text, skipping special syntax and
comments.
@@ -80,6 +84,10 @@ def countWords(theText):
return charCount, wordCount, paraCount
# =========================================================================== #
# Convert an Integer to a Word Number
# =========================================================================== #
def numberToWord(numVal, theLanguage):
"""Wrapper for converting numbers to words for chapter headings.
"""
+26 -70
View File
@@ -515,13 +515,11 @@ class GuiDocEditor(QTextEdit):
elif theAction == nwDocAction.PASTE:
self.paste()
elif theAction == nwDocAction.EMPH:
self._toggleEmph(1)
self._toggleFormat(1, "_")
elif theAction == nwDocAction.STRONG:
self._toggleEmph(2)
elif theAction == nwDocAction.STRONGEMPH:
self._toggleEmph(3)
self._toggleFormat(2, "*")
elif theAction == nwDocAction.STRIKE:
self._toggleStrike()
self._toggleFormat(2, "~")
elif theAction == nwDocAction.S_QUOTE:
self._wrapSelection(self.typSQOpen, self.typSQClose)
elif theAction == nwDocAction.D_QUOTE:
@@ -998,69 +996,27 @@ class GuiDocEditor(QTextEdit):
theCursor = self.textCursor()
if self.mainConf.autoSelect and not theCursor.hasSelection():
theCursor.select(QTextCursor.WordUnderCursor)
self.setTextCursor(theCursor)
return theCursor
def _toggleEmph(self, eLevel):
"""Toggle emphasis of a given level between 1 and 3, where 1 is
italic, 2 is bold, and 3 is bold italic. The current level in
the text is cLevel. The rules are as follows:
cLevel | eLevel | Result
============+============+============
None | Italic | Italic
None | Bold | Bold
None | BoldItalic | BoldItalic
------------+------------+------------
Italic | Italic | None
Italic | Bold | BoldItalic
Italic | BoldItalic | BoldItalic
------------+------------+------------
Bold | Italic | BoldItalic
Bold | Bold | None
Bold | BoldItalic | BoldItalic
------------+------------+------------
BoldItalic | Italic | Bold
BoldItalic | Bold | Italic
BoldItalic | BoldItalic | None
"""
theCursor = self._autoSelect()
if theCursor.hasSelection():
posS = theCursor.selectionStart()
posE = theCursor.selectionEnd()
numB = 0
for n in range(3):
if self.qDocument.characterAt(posS-n-1) == "*":
numB += 1
else:
break
# Underscore counts as a part of the word, so check that the
# selection isn't wrapped in italics markers.
reSelect = False
if self.qDocument.characterAt(posS) == "_":
posS += 1
reSelect = True
if self.qDocument.characterAt(posE) == "_":
posE -= 1
reSelect = True
if reSelect:
theCursor.clearSelection()
theCursor.setPosition(posE-1)
theCursor.movePosition(QTextCursor.Left, QTextCursor.KeepAnchor, posE-posS-1)
numA = 0
for n in range(3):
if self.qDocument.characterAt(posE+n) == "*":
numA += 1
else:
break
self.setTextCursor(theCursor)
return theCursor
cLevel = min(numB, numA)
if cLevel == 0:
# Has no emphasis, set to desired level
self._wrapSelection("*"*eLevel)
elif cLevel == 3:
# Has max, so reduce by desired level
self._clearSurrounding(theCursor, eLevel)
elif cLevel == eLevel:
# Toggle mode, so clear what we had set
self._clearSurrounding(theCursor, cLevel)
else:
# Already at 1 or 2, increase to 3
self._wrapSelection("*"*(3 - cLevel))
return
def _toggleStrike(self):
def _toggleFormat(self, fLen, fChar):
"""Toggle strikethrough text.
"""
theCursor = self._autoSelect()
@@ -1069,24 +1025,24 @@ class GuiDocEditor(QTextEdit):
posE = theCursor.selectionEnd()
numB = 0
for n in range(2):
if self.qDocument.characterAt(posS-n-1) == "~":
for n in range(fLen):
if self.qDocument.characterAt(posS-n-1) == fChar:
numB += 1
else:
break
numA = 0
for n in range(2):
if self.qDocument.characterAt(posE+n) == "~":
for n in range(fLen):
if self.qDocument.characterAt(posE+n) == fChar:
numA += 1
else:
break
cLevel = min(numB, numA)
if cLevel == 2:
self._clearSurrounding(theCursor, 2)
if cLevel == fLen:
self._clearSurrounding(theCursor, fLen)
else:
self._wrapSelection("~~")
self._wrapSelection(fChar*fLen)
return
+32 -36
View File
@@ -107,7 +107,6 @@ class GuiDocHighlighter(QSyntaxHighlighter):
"header4h" : self._makeFormat(self.colHeadH, "bold", 1.2),
"bold" : self._makeFormat(self.colEmph, "bold"),
"italic" : self._makeFormat(self.colEmph, "italic"),
"bolditalic" : self._makeFormat(self.colEmph, ("bold","italic")),
"strike" : self._makeFormat(self.colEmph, "strike"),
"trailing" : self._makeFormat(self.colTrail, "background"),
"nobreak" : self._makeFormat(self.colTrail, "background"),
@@ -137,36 +136,6 @@ class GuiDocHighlighter(QSyntaxHighlighter):
}
))
# Markdown
self.hRules.append((
nwRegEx.FMT_I, {
1 : self.hStyles["hidden"],
2 : self.hStyles["italic"],
3 : self.hStyles["hidden"],
}
))
self.hRules.append((
nwRegEx.FMT_B, {
1 : self.hStyles["hidden"],
2 : self.hStyles["bold"],
3 : self.hStyles["hidden"],
}
))
self.hRules.append((
nwRegEx.FMT_BI, {
1 : self.hStyles["hidden"],
2 : self.hStyles["bolditalic"],
3 : self.hStyles["hidden"],
}
))
self.hRules.append((
nwRegEx.FMT_ST, {
1 : self.hStyles["hidden"],
2 : self.hStyles["strike"],
3 : self.hStyles["hidden"],
}
))
# Quoted Strings
if self.mainConf.highlightQuotes:
self.hRules.append((
@@ -185,6 +154,29 @@ class GuiDocHighlighter(QSyntaxHighlighter):
}
))
# Markdown
self.hRules.append((
nwRegEx.FMT_I, {
1 : self.hStyles["hidden"],
2 : self.hStyles["italic"],
3 : self.hStyles["hidden"],
}
))
self.hRules.append((
nwRegEx.FMT_B, {
1 : self.hStyles["hidden"],
2 : self.hStyles["bold"],
3 : self.hStyles["hidden"],
}
))
self.hRules.append((
nwRegEx.FMT_ST, {
1 : self.hStyles["hidden"],
2 : self.hStyles["strike"],
3 : self.hStyles["hidden"],
}
))
# Auto-Replace Tags
self.hRules.append((
r"<(\S+?)>", {
@@ -302,10 +294,14 @@ class GuiDocHighlighter(QSyntaxHighlighter):
rxItt = rX.globalMatch(theText, 0)
while rxItt.hasNext():
rxMatch = rxItt.next()
for xM in xFmt.keys():
for xM in xFmt:
xPos = rxMatch.capturedStart(xM)
xLen = rxMatch.capturedLength(xM)
self.setFormat(xPos, xLen, xFmt[xM])
for x in range(xPos, xPos+xLen):
spFmt = self.format(x)
if spFmt != self.hStyles["hidden"]:
spFmt.merge(xFmt[xM])
self.setFormat(x, 1, spFmt)
if self.theDict is None or not self.spellCheck:
return
@@ -318,11 +314,11 @@ class GuiDocHighlighter(QSyntaxHighlighter):
continue
xPos = rxMatch.capturedStart(0)
xLen = rxMatch.capturedLength(0)
for x in range(xLen):
spFmt = self.format(xPos+x)
for x in range(xPos, xPos+xLen):
spFmt = self.format(x)
spFmt.setUnderlineColor(self.colSpell)
spFmt.setUnderlineStyle(QTextCharFormat.SpellCheckUnderline)
self.setFormat(xPos+x, 1, spFmt)
self.setFormat(x, 1, spFmt)
return
-7
View File
@@ -540,13 +540,6 @@ class GuiMainMenu(QMenuBar):
self.aFmtStrong.triggered.connect(lambda: self._docAction(nwDocAction.STRONG))
self.fmtMenu.addAction(self.aFmtStrong)
# Format > Very Strong Emphasis
self.aFmtStrongEmph = QAction("Very Strong Emphasis", self)
self.aFmtStrongEmph.setStatusTip("Add very strong emphasis to selected text (bold and italic)")
self.aFmtStrongEmph.setShortcut("Ctrl+Shift+B")
self.aFmtStrongEmph.triggered.connect(lambda: self._docAction(nwDocAction.STRONGEMPH))
self.fmtMenu.addAction(self.aFmtStrongEmph)
# Format > Strikethrough
self.aFmtStrike = QAction("Strikethrough", self)
self.aFmtStrike.setStatusTip("Add strikethrough to selected text")
-1
View File
@@ -1008,7 +1008,6 @@ class GuiMain(QMainWindow):
# Format
self.addAction(self.mainMenu.aFmtEmph)
self.addAction(self.mainMenu.aFmtStrong)
self.addAction(self.mainMenu.aFmtStrongEmph)
self.addAction(self.mainMenu.aFmtStrike)
self.addAction(self.mainMenu.aFmtDQuote)
self.addAction(self.mainMenu.aFmtSQuote)
+2 -2
View File
@@ -7,9 +7,9 @@
A scene is defined by a level three heading, like the one at the top of this page. The scene will be assigned to the chapter preceding it in the project tree.
Each paragraph in the scene is separated by a blank line. The text supports minimal formatting, like **bold**, *italic* and ***bold italic***. You can also ~~strike through~~ text.
Each paragraph in the scene is separated by a blank line. The text supports minimal formatting, like **bold**, _italic_ and **_bold italic_**. You can also ~~strike through~~ text. There is **some support for _nested_ emphasis**, but it isnt fully Markdown compliant. If the syntax highlighter doesnt show it correctly, the export tool will not either.
In addition, the editor supports automatic formatting of “quotes”, both double and single. Depending on the syntax highlighter, these can be in different colours.
In addition, the editor supports automatic formatting of “quotes”, both double and single. Depending on the syntax highlighter, these can be in different colours. “You can of course use **bold** and _italic_ text inside of quotes too.”
If you have the need for it, you can also add text that can be automatically replaced by other text when you generate a preview or export the project. Now, lets auto-replace this A with <A>, and this C with <C>. While <E> is just <E>. Press Ctrl+R to see what this looks like in the view pane.
+11 -11
View File
@@ -1,22 +1,22 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="0.10.0rc1" hexVersion="0x001000c1" fileVersion="1.2" timeStamp="2020-06-27 17:29:20">
<novelWriterXML appVersion="0.10.0rc1" hexVersion="0x001000c1" fileVersion="1.2" timeStamp="2020-06-29 13:27:47">
<project>
<name>Sample Project</name>
<title>Sample Project</title>
<author>Jane Smith</author>
<author>Jay Doh</author>
<saveCount>593</saveCount>
<autoCount>103</autoCount>
<editTime>24563</editTime>
<saveCount>652</saveCount>
<autoCount>122</autoCount>
<editTime>32716</editTime>
</project>
<settings>
<doBackup>False</doBackup>
<spellCheck>True</spellCheck>
<spellCheck>False</spellCheck>
<autoOutline>True</autoOutline>
<lastEdited>636b6aa9b697b</lastEdited>
<lastViewed>b3e74dbc1f584</lastViewed>
<lastWordCount>982</lastWordCount>
<novelWordCount>606</novelWordCount>
<lastViewed>636b6aa9b697b</lastViewed>
<lastWordCount>1022</lastWordCount>
<novelWordCount>646</novelWordCount>
<notesWordCount>376</notesWordCount>
<autoReplace>
<entry key="A">B</entry>
@@ -116,10 +116,10 @@
<status>1st Draft</status>
<exported>True</exported>
<layout>SCENE</layout>
<charCount>1564</charCount>
<wordCount>278</wordCount>
<charCount>1811</charCount>
<wordCount>318</wordCount>
<paraCount>8</paraCount>
<cursorPos>1633</cursorPos>
<cursorPos>1143</cursorPos>
</item>
<item handle="bc0cbd2a407f3" order="2" parent="e7ded148d6e4a">
<name>Another Scene</name>
+1 -1
View File
@@ -3,4 +3,4 @@
% Synopsis:Explanation from the lipsum.com website.
*Lorem Ipsum* is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
_Lorem Ipsum_ is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
+1 -1
View File
@@ -14,7 +14,7 @@ The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for t
## Prologue
*Lorem Ipsum* is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
_Lorem Ipsum_ is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
# Act One
+1 -1
View File
@@ -16,7 +16,7 @@ The standard chunk of Lorem Ipsum used since the 1500s is reproduced below for t
% Synopsis:Explanation from the lipsum.com website.
*Lorem Ipsum* is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
_Lorem Ipsum_ is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
# Act One
+1 -29
View File
@@ -746,17 +746,6 @@ def testDocAction(qtbot, nwTempGUI, nwLipsum, nwRef, nwTemp):
assert nwGUI.openProject(nwLipsum)
qtbot.wait(stepDelay)
# CUT = 3
# COPY = 4
# PASTE = 5
# SEL_ALL = 12
# SEL_PARA = 13
# FIND = 14
# REPLACE = 15
# GO_NEXT = 16
# GO_PREV = 17
# REPL_NEXT = 18
# Split By Chapter
assert nwGUI.openDocument("4c4f28287af27")
assert nwGUI.docEditor.setCursorPosition(30)
@@ -773,20 +762,12 @@ def testDocAction(qtbot, nwTempGUI, nwLipsum, nwRef, nwTemp):
# Italic
assert nwGUI.passDocumentAction(nwDocAction.EMPH)
assert nwGUI.docEditor.getText()[27:76] == "*Pellentesque* nec erat ut nulla posuere commodo."
assert nwGUI.docEditor.getText()[27:76] == "_Pellentesque_ nec erat ut nulla posuere commodo."
qtbot.wait(stepDelay)
assert nwGUI.passDocumentAction(nwDocAction.EMPH)
assert nwGUI.docEditor.getText()[27:74] == cleanText
qtbot.wait(stepDelay)
# Bold-Italic
assert nwGUI.passDocumentAction(nwDocAction.STRONGEMPH)
assert nwGUI.docEditor.getText()[27:80] == "***Pellentesque*** nec erat ut nulla posuere commodo."
qtbot.wait(stepDelay)
assert nwGUI.passDocumentAction(nwDocAction.STRONGEMPH)
assert nwGUI.docEditor.getText()[27:74] == cleanText
qtbot.wait(stepDelay)
# Strikethrough
assert nwGUI.passDocumentAction(nwDocAction.STRIKE)
assert nwGUI.docEditor.getText()[27:78] == "~~Pellentesque~~ nec erat ut nulla posuere commodo."
@@ -806,15 +787,6 @@ def testDocAction(qtbot, nwTempGUI, nwLipsum, nwRef, nwTemp):
assert nwGUI.docEditor.getText()[27:74] == cleanText
qtbot.wait(stepDelay)
# Equivalent of the above
assert nwGUI.passDocumentAction(nwDocAction.STRONGEMPH)
qtbot.wait(stepDelay)
assert nwGUI.passDocumentAction(nwDocAction.EMPH)
qtbot.wait(stepDelay)
assert nwGUI.passDocumentAction(nwDocAction.STRONG)
assert nwGUI.docEditor.getText()[27:74] == cleanText
qtbot.wait(stepDelay)
# Double Quotes
assert nwGUI.passDocumentAction(nwDocAction.D_QUOTE)
assert nwGUI.docEditor.getText()[27:76] == "“Pellentesque” nec erat ut nulla posuere commodo."