Skip to content

Commit

Permalink
Update tests and word counter
Browse files Browse the repository at this point in the history
  • Loading branch information
vkbo committed Nov 6, 2023
1 parent 5e41dd9 commit b03603c
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 53 deletions.
7 changes: 6 additions & 1 deletion novelwriter/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
"""
from __future__ import annotations

import re

from PyQt5.QtCore import QCoreApplication, QT_TRANSLATE_NOOP

from novelwriter.enum import nwBuildFmt, nwItemClass, nwItemLayout, nwOutline
Expand Down Expand Up @@ -59,9 +61,12 @@ class nwRegEx:
FMT_EI = r"(?<![\w\\])(_)(?![\s_])(.+?)(?<![\s\\])(\1)(?!\w)"
FMT_EB = r"(?<![\w\\])([\*]{2})(?![\s\*])(.+?)(?<![\s\\])(\1)(?!\w)"
FMT_ST = r"(?<![\w\\])([~]{2})(?![\s~])(.+?)(?<![\s\\])(\1)(?!\w)"
FMT_SC = r"(?<!\\)(\[[\/\!]?(?i)(?:i|b|s|u|sup|sub)\])"
FMT_SC = r"(?i)(?<!\\)(\[[\/\!]?(?:i|b|s|u|sup|sub)\])"
FMT_SV = r"(?<!\\)(\[(?i)(?:fn|footnote):)(.+?)(?<!\\)(\])"

# Pre-Compiled RegEx
RX_SC = re.compile(FMT_SC)

# END Class nwRegEx


Expand Down
11 changes: 8 additions & 3 deletions novelwriter/core/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
from novelwriter.enum import nwItemClass, nwItemType, nwItemLayout
from novelwriter.error import logException
from novelwriter.common import checkInt, isHandle, isItemClass, isTitleTag, jsonEncode
from novelwriter.constants import nwFiles, nwKeyWords, nwUnicode, nwHeaders
from novelwriter.constants import nwFiles, nwKeyWords, nwRegEx, nwUnicode, nwHeaders

if TYPE_CHECKING: # pragma: no cover
from novelwriter.core.item import NWItem
Expand Down Expand Up @@ -1229,6 +1229,10 @@ def countWords(text: str) -> tuple[int, int, int]:
if nwUnicode.U_EMDASH in text:
text = text.replace(nwUnicode.U_EMDASH, " ")

# Strip shortcodes
if "[" in text:
text = nwRegEx.RX_SC.sub("", text)

for line in text.splitlines():

countPara = True
Expand All @@ -1241,9 +1245,10 @@ def countWords(text: str) -> tuple[int, int, int]:
continue

if line[0] == "[":
if line.startswith(("[NEWPAGE]", "[NEW PAGE]", "[VSPACE]")):
check = line.lower()
if check.startswith(("[newpage]", "[new page]", "[vspace]")):
continue
elif line.startswith("[VSPACE:") and line.endswith("]"):
elif check.startswith("[vspace:") and line.endswith("]"):
continue

elif line[0] == "#":
Expand Down
37 changes: 15 additions & 22 deletions novelwriter/gui/doceditor.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
from novelwriter.common import minmax, transferCase
from novelwriter.constants import nwKeyWords, nwUnicode
from novelwriter.core.index import countWords
from novelwriter.core.document import NWDocument
from novelwriter.gui.dochighlight import GuiDocHighlighter
from novelwriter.gui.editordocument import GuiTextDocument
from novelwriter.extensions.wheeleventfilter import WheelEventFilter
Expand Down Expand Up @@ -408,12 +409,6 @@ def updateTagHighLighting(self) -> None:
self._qDocument.syntaxHighlighter.rehighlightByType(GuiDocHighlighter.BLOCK_META)
return

def redrawText(self) -> None:
"""Redraw the text by marking the document content as dirty."""
self._qDocument.markContentsDirty(0, self._qDocument.characterCount())
self.updateDocMargins()
return

def replaceText(self, text: str) -> None:
"""Replace the text of the current document with the provided
text. This also clears undo history.
Expand Down Expand Up @@ -735,19 +730,17 @@ def revealLocation(self) -> None:
"""Tell the user where on the file system the file in the editor
is saved.
"""
if self._nwDocument is None:
logger.error("No document open")
return
SHARED.info(
"<br>".join([
self.tr("Document Details"),
"–"*40,
self.tr("Created: {0}").format(self._nwDocument.createdDate),
self.tr("Updated: {0}").format(self._nwDocument.updatedDate),
]),
details=self.tr("File Location: {0}").format(self._nwDocument.fileLocation),
log=False
)
if isinstance(self._nwDocument, NWDocument):
SHARED.info(
"<br>".join([
self.tr("Document Details"),
"–"*40,
self.tr("Created: {0}").format(self._nwDocument.createdDate),
self.tr("Updated: {0}").format(self._nwDocument.updatedDate),
]),
details=self.tr("File Location: {0}").format(self._nwDocument.fileLocation),
log=False
)
return

def insertText(self, insert: str | nwDocInsert) -> bool:
Expand Down Expand Up @@ -775,15 +768,15 @@ def insertText(self, insert: str | nwDocInsert) -> bool:
newBlock = True
goAfter = True
elif insert == nwDocInsert.NEW_PAGE:
text = "[NEW PAGE]"
text = "[newpage]"
newBlock = True
goAfter = False
elif insert == nwDocInsert.VSPACE_S:
text = "[VSPACE]"
text = "[vspace]"
newBlock = True
goAfter = False
elif insert == nwDocInsert.VSPACE_M:
text = "[VSPACE:2]"
text = "[vspace:2]"
newBlock = True
goAfter = False
else:
Expand Down
10 changes: 5 additions & 5 deletions sample/content/974e400180a99.nwd
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
%%~name: Page
%%~path: 7031beac91f75/974e400180a99
%%~kind: NOVEL/DOCUMENT
%%~hash: 7547809e972205eb2a55dd988595e0aa1d01e139
%%~date: Unknown/2023-08-25 16:51:54
[NEW PAGE]
[VSPACE:2]
%%~hash: a0b0719e19763bf505bcf797bea0968c505c9b4a
%%~date: Unknown/2023-11-06 11:19:33
[newpage]
[vspace:2]

This is a plain page with some text on it.

If you want the text to start on a fresh page, add the [NEW PAGE] code above the text. You can also add empty paragraphs with the [VSPACE] code. The above code adds two empty paragraphs before the text starts.
If you want the text to start on a fresh page, add the [newpage] code above the text. You can also add empty paragraphs with the [vspace] code. The above code adds two empty paragraphs before the text starts.
10 changes: 5 additions & 5 deletions sample/nwProject.nwx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version='1.0' encoding='utf-8'?>
<novelWriterXML appVersion="2.2-alpha1" hexVersion="0x020200a1" fileVersion="1.5" fileRevision="1" timeStamp="2023-10-20 22:58:21">
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1605" autoCount="254" editTime="80970">
<novelWriterXML appVersion="2.2-alpha1" hexVersion="0x020200a1" fileVersion="1.5" fileRevision="1" timeStamp="2023-11-06 11:44:21">
<project id="e2be99af-f9bf-4403-857a-c3d1ac25abea" saveCount="1609" autoCount="255" editTime="81165">
<name>Sample Project</name>
<title>Sample Project</title>
<author>Jane Smith</author>
Expand Down Expand Up @@ -36,7 +36,7 @@
<entry key="i56be10" count="1" red="117" green="0" blue="175">Main</entry>
</importance>
</settings>
<content items="27" novelWords="988" notesWords="409">
<content items="27" novelWords="989" notesWords="409">
<item handle="7031beac91f75" parent="None" root="7031beac91f75" order="0" type="ROOT" class="NOVEL">
<meta expanded="yes" />
<name status="sc24b8f" import="ia857f0">Novel</name>
Expand All @@ -46,7 +46,7 @@
<name status="sc24b8f" import="ia857f0" active="yes">Title Page</name>
</item>
<item handle="974e400180a99" parent="7031beac91f75" root="7031beac91f75" order="1" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="no" heading="H0" charCount="251" wordCount="50" paraCount="2" cursorPos="10" />
<meta expanded="no" heading="H0" charCount="269" wordCount="51" paraCount="3" cursorPos="275" />
<name status="sf12341" import="ia857f0" active="yes">Page</name>
</item>
<item handle="edca4be2fcaf8" parent="7031beac91f75" root="7031beac91f75" order="2" type="FILE" class="NOVEL" layout="DOCUMENT">
Expand All @@ -58,7 +58,7 @@
<name status="sf24ce6" import="ia857f0" active="yes">Chapter One</name>
</item>
<item handle="636b6aa9b697b" parent="6a2d6d5f4f401" root="7031beac91f75" order="0" type="FILE" class="NOVEL" layout="DOCUMENT">
<meta expanded="no" heading="H3" charCount="2937" wordCount="513" paraCount="15" cursorPos="19" />
<meta expanded="no" heading="H3" charCount="2901" wordCount="513" paraCount="15" cursorPos="749" />
<name status="s90e6c9" import="ia857f0" active="yes">Making a Scene</name>
</item>
<item handle="bc0cbd2a407f3" parent="6a2d6d5f4f401" root="7031beac91f75" order="1" type="FILE" class="NOVEL" layout="DOCUMENT">
Expand Down
27 changes: 26 additions & 1 deletion tests/test_core/test_core_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -1281,7 +1281,7 @@ def testCoreIndex_CountWords():
assert wC == 9
assert pC == 4

# Formatting Codes
# Formatting Codes, Upper Case (Old Implementation)
cC, wC, pC = countWords((
"Some text\n\n"
"[NEWPAGE]\n\n"
Expand All @@ -1297,4 +1297,29 @@ def testCoreIndex_CountWords():
assert wC == 13
assert pC == 5

# Formatting Codes, Lower Case (Current Implementation)
cC, wC, pC = countWords((
"Some text\n\n"
"[newpage]\n\n"
"more text\n\n"
"[new page]]\n\n"
"even more text\n\n"
"[vspace]\n\n"
"and some final text\n\n"
"[vspace:4]\n\n"
"THE END\n\n"
))
assert cC == 58
assert wC == 13
assert pC == 5

# Check ShortCodes
cC, wC, pC = countWords((
"Text with [b]bold[/b] text and padded [b] bold [/b] text.\n\n"
"Text with [b][i] nested [/i] emphasis [/b] in it.\n\n"
))
assert cC == 78
assert wC == 14
assert pC == 2

# END Test testCoreIndex_CountWords
26 changes: 13 additions & 13 deletions tests/test_core/test_core_tokenizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ def testCoreToken_SpecialFormat(mockGUI):
tokens._isFirst = True
tokens._text = (
"# Title One\n\n"
"[NEWPAGE]\n\n"
"[newpage]\n\n"
"# Title Two\n\n"
)
tokens.tokenizeText()
Expand All @@ -799,7 +799,7 @@ def testCoreToken_SpecialFormat(mockGUI):
tokens._isFirst = True
tokens._text = (
"# Title One\n\n"
"[NEW PAGE]\n\n"
"[new page]\n\n"
"# Title Two\n\n"
)
tokens.tokenizeText()
Expand All @@ -809,7 +809,7 @@ def testCoreToken_SpecialFormat(mockGUI):
tokens._isFirst = True
tokens._text = (
"# Title One\n\n"
"[NEW PAGE] \t\n\n"
"[new page] \t\n\n"
"# Title Two\n\n"
)
tokens.tokenizeText()
Expand All @@ -820,7 +820,7 @@ def testCoreToken_SpecialFormat(mockGUI):

tokens._text = (
"# Title One\n\n"
"[VSPACE] \n\n"
"[vspace] \n\n"
"Some text to go here ...\n\n"
)
tokens.tokenizeText()
Expand All @@ -840,7 +840,7 @@ def testCoreToken_SpecialFormat(mockGUI):
# One Skip
tokens._text = (
"# Title One\n\n"
"[VSPACE:1] \n\n"
"[vspace:1] \n\n"
"Some text to go here ...\n\n"
)
tokens.tokenizeText()
Expand All @@ -857,7 +857,7 @@ def testCoreToken_SpecialFormat(mockGUI):
# Three Skips
tokens._text = (
"# Title One\n\n"
"[VSPACE:3] \n\n"
"[vspace:3] \n\n"
"Some text to go here ...\n\n"
)
tokens.tokenizeText()
Expand All @@ -876,7 +876,7 @@ def testCoreToken_SpecialFormat(mockGUI):
# Malformed Command, Case 1
tokens._text = (
"# Title One\n\n"
"[VSPACE:3xa] \n\n"
"[vspace:3xa] \n\n"
"Some text to go here ...\n\n"
)
tokens.tokenizeText()
Expand All @@ -892,7 +892,7 @@ def testCoreToken_SpecialFormat(mockGUI):
# Malformed Command, Case 2
tokens._text = (
"# Title One\n\n"
"[VSPACE:3.5]\n\n"
"[vspace:3.5]\n\n"
"Some text to go here ...\n\n"
)
tokens.tokenizeText()
Expand All @@ -908,7 +908,7 @@ def testCoreToken_SpecialFormat(mockGUI):
# Malformed Command, Case 3
tokens._text = (
"# Title One\n\n"
"[VSPACE:-1]\n\n"
"[vspace:-1]\n\n"
"Some text to go here ...\n\n"
)
tokens.tokenizeText()
Expand All @@ -927,8 +927,8 @@ def testCoreToken_SpecialFormat(mockGUI):
# Single Skip
tokens._text = (
"# Title One\n\n"
"[NEW PAGE]\n\n"
"[VSPACE]\n\n"
"[new page]\n\n"
"[vspace]\n\n"
"Some text to go here ...\n\n"
)
tokens.tokenizeText()
Expand All @@ -946,8 +946,8 @@ def testCoreToken_SpecialFormat(mockGUI):
# Multiple Skip
tokens._text = (
"# Title One\n\n"
"[NEW PAGE]\n\n"
"[VSPACE:3]\n\n"
"[new page]\n\n"
"[vspace:3]\n\n"
"Some text to go here ...\n\n"
)
tokens.tokenizeText()
Expand Down
6 changes: 3 additions & 3 deletions tests/test_gui/test_gui_mainmenu.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,15 +600,15 @@ def testGuiMenu_Insert(qtbot, monkeypatch, nwGUI, fncPath, projPath, mockRnd):

nwGUI.docEditor.setPlainText("### Stuff\n")
nwGUI.mainMenu.aInsNewPage.activate(QAction.Trigger)
assert nwGUI.docEditor.getText() == "[NEW PAGE]\n### Stuff\n"
assert nwGUI.docEditor.getText() == "[newpage]\n### Stuff\n"

nwGUI.docEditor.setPlainText("### Stuff\n")
nwGUI.mainMenu.aInsVSpaceS.activate(QAction.Trigger)
assert nwGUI.docEditor.getText() == "[VSPACE]\n### Stuff\n"
assert nwGUI.docEditor.getText() == "[vspace]\n### Stuff\n"

nwGUI.docEditor.setPlainText("### Stuff\n")
nwGUI.mainMenu.aInsVSpaceM.activate(QAction.Trigger)
assert nwGUI.docEditor.getText() == "[VSPACE:2]\n### Stuff\n"
assert nwGUI.docEditor.getText() == "[vspace:2]\n### Stuff\n"

nwGUI.docEditor.clear()

Expand Down

0 comments on commit b03603c

Please sign in to comment.