From 981e26e1b6c728b08c04dc87fe08644d9a4dd4b8 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Mon, 11 Jan 2021 21:02:45 +0100
Subject: [PATCH] Use actual novel word count in project details, and update
index test
---
nw/core/index.py | 65 +++++++++++++++++----------------
nw/gui/projdetails.py | 5 +--
tests/test_core_index.py | 78 +++++++++++++++++++++++++++++++++++++++-
3 files changed, 114 insertions(+), 34 deletions(-)
diff --git a/nw/core/index.py b/nw/core/index.py
index 6128a177..2b14a5d4 100644
--- a/nw/core/index.py
+++ b/nw/core/index.py
@@ -292,10 +292,12 @@ class NWIndex():
"updated" : round(time()),
}
if itemLayout == nwItemLayout.NOTE:
+ self._novelIndex.pop(tHandle, None)
self._noteIndex[tHandle] = {}
isNovel = False
else:
self._novelIndex[tHandle] = {}
+ self._noteIndex.pop(tHandle, None)
isNovel = True
# Also clear references to file in tag index
@@ -580,34 +582,26 @@ class NWIndex():
they appear in the tree view and in the respective document
files, but skipping all note files.
"""
- for tItem in self.theProject.projTree:
- if tItem is None:
- continue
- if not tItem.isExported and skipExcluded:
- continue
-
- tHandle = tItem.itemHandle
- if tHandle not in self._novelIndex:
- continue
-
+ for tHandle in self._listNovelHandles(skipExcluded):
for sTitle in sorted(self._novelIndex[tHandle]):
tKey = "%s:%s" % (tHandle, sTitle)
yield tKey, tHandle, sTitle, self._novelIndex[tHandle][sTitle]
- def getNovelCounts(self, skipExcluded=True):
+ def getNovelWordCount(self, skipExcluded=True):
+ """Count the number of words in the novel project.
+ """
+ wCount = 0
+ for tHandle in self._listNovelHandles(skipExcluded):
+ for sTitle in self._novelIndex[tHandle]:
+ wCount += self._novelIndex[tHandle][sTitle]["wCount"]
+
+ return wCount
+
+ def getNovelTitleCounts(self, skipExcluded=True):
"""Count the number of titles in the novel project.
"""
hCount = [0, 0, 0, 0, 0]
- for tItem in self.theProject.projTree:
- if tItem is None:
- continue
- if not tItem.isExported and skipExcluded:
- continue
-
- tHandle = tItem.itemHandle
- if tHandle not in self._novelIndex:
- continue
-
+ for tHandle in self._listNovelHandles(skipExcluded):
for sTitle in self._novelIndex[tHandle]:
theData = self._novelIndex[tHandle][sTitle]
iLevel = self.H_LEVEL.get(theData["level"], 0)
@@ -621,16 +615,7 @@ class NWIndex():
tOrder = []
tData = {}
pKey = None
- for tItem in self.theProject.projTree:
- if tItem is None:
- continue
- if not tItem.isExported and skipExcluded:
- continue
-
- tHandle = tItem.itemHandle
- if tHandle not in self._novelIndex:
- continue
-
+ for tHandle in self._listNovelHandles(skipExcluded):
for sTitle in sorted(self._novelIndex[tHandle]):
tKey = "%s:%s" % (tHandle, sTitle)
theData = self._novelIndex[tHandle][sTitle]
@@ -740,4 +725,22 @@ class NWIndex():
return theRef[1], theRef[0], theRef[3]
return None, 0, "T000000"
+ ##
+ # Internal Functions
+ ##
+
+ def _listNovelHandles(self, skipExcluded):
+ """Return a list of all handles that exist in the novel index.
+ """
+ theHandles = []
+ for tItem in self.theProject.projTree:
+ if tItem is None:
+ continue
+ if not tItem.isExported and skipExcluded:
+ continue
+ if tItem.itemHandle in self._novelIndex:
+ theHandles.append(tItem.itemHandle)
+
+ return theHandles
+
# END Class NWIndex
diff --git a/nw/gui/projdetails.py b/nw/gui/projdetails.py
index 0270476d..ae001483 100644
--- a/nw/gui/projdetails.py
+++ b/nw/gui/projdetails.py
@@ -168,10 +168,11 @@ class GuiProjectDetailsMain(QWidget):
# Stats
# =====
- hCounts = self.theIndex.getNovelCounts()
+ hCounts = self.theIndex.getNovelTitleCounts()
+ nwCount = self.theIndex.getNovelWordCount()
self.wordCountLbl = QLabel("Words:")
- self.wordCountVal = QLabel(f"{self.theProject.currWCount:n}")
+ self.wordCountVal = QLabel(f"{nwCount:n}")
self.chapCountLbl = QLabel("Chapters:")
self.chapCountVal = QLabel(f"{hCounts[2]:n}")
diff --git a/tests/test_core_index.py b/tests/test_core_index.py
index b19af00d..d865cd41 100644
--- a/tests/test_core_index.py
+++ b/tests/test_core_index.py
@@ -276,6 +276,7 @@ def testCoreIndex_ScanText(nwMinimal, dummyGUI):
assert not theIndex.scanText(xHandle, "Hello World!")
# Make some usable items
+ pHandle = theProject.newFile("Page", nwItemClass.NOVEL, "a508bb932959c")
nHandle = theProject.newFile("Hello", nwItemClass.NOVEL, "a508bb932959c")
cHandle = theProject.newFile("Jane", nwItemClass.CHARACTER, "afb3043c7b2b3")
sHandle = theProject.newFile("Scene", nwItemClass.NOVEL, "a508bb932959c")
@@ -310,7 +311,7 @@ def testCoreIndex_ScanText(nwMinimal, dummyGUI):
"#### Title Four\n\n"
"% synopsis: Synopsis Four.\n\n"
"Paragraph Four.\n\n"
- "##### Title Five\n\n" # Not interpreted as a title, the hashes is counted as a word
+ "##### Title Five\n\n" # Not interpreted as a title, the hashes are counted as a word
"Paragraph Five.\n\n"
))
assert theIndex._refIndex[nHandle].get("T000000", None) is not None # Always there
@@ -411,6 +412,33 @@ def testCoreIndex_ScanText(nwMinimal, dummyGUI):
[[3, "@pov", "One"], [5, "@char", "Two"]]
)
+ # Page wo/Title
+ theProject.projTree[pHandle].itemLayout = nwItemLayout.PAGE
+ assert theIndex.scanText(pHandle, (
+ "This is a page with some text on it.\n\n"
+ ))
+ assert theIndex._novelIndex[pHandle]["T000000"]["level"] == "H0"
+ assert theIndex._novelIndex[pHandle]["T000000"]["title"] == "Untitled Page"
+ assert theIndex._novelIndex[pHandle]["T000000"]["layout"] == "PAGE"
+ assert theIndex._novelIndex[pHandle]["T000000"]["synopsis"] == ""
+ assert theIndex._novelIndex[pHandle]["T000000"]["cCount"] == 36
+ assert theIndex._novelIndex[pHandle]["T000000"]["wCount"] == 9
+ assert theIndex._novelIndex[pHandle]["T000000"]["pCount"] == 1
+ assert pHandle not in theIndex._noteIndex
+
+ theProject.projTree[pHandle].itemLayout = nwItemLayout.NOTE
+ assert theIndex.scanText(pHandle, (
+ "This is a page with some text on it.\n\n"
+ ))
+ assert theIndex._noteIndex[pHandle]["T000000"]["level"] == "H0"
+ assert theIndex._noteIndex[pHandle]["T000000"]["title"] == "Untitled Page"
+ assert theIndex._noteIndex[pHandle]["T000000"]["layout"] == "NOTE"
+ assert theIndex._noteIndex[pHandle]["T000000"]["synopsis"] == ""
+ assert theIndex._noteIndex[pHandle]["T000000"]["cCount"] == 36
+ assert theIndex._noteIndex[pHandle]["T000000"]["wCount"] == 9
+ assert theIndex._noteIndex[pHandle]["T000000"]["pCount"] == 1
+ assert pHandle not in theIndex._novelIndex
+
assert theProject.closeProject()
# END Test testCoreIndex_ScanText
@@ -579,6 +607,54 @@ def testCoreIndex_ExtractData(nwMinimal, dummyGUI):
assert wC == 12
assert pC == 2
+ ##
+ # Novel Stats
+ ##
+
+ hHandle = theProject.newFile("Chapter", nwItemClass.NOVEL, "a508bb932959c")
+ sHandle = theProject.newFile("Scene One", nwItemClass.NOVEL, "a508bb932959c")
+ tHandle = theProject.newFile("Scene Two", nwItemClass.NOVEL, "a508bb932959c")
+
+ theProject.projTree[hHandle].itemLayout == nwItemLayout.CHAPTER
+ theProject.projTree[sHandle].itemLayout == nwItemLayout.SCENE
+ theProject.projTree[tHandle].itemLayout == nwItemLayout.SCENE
+
+ assert theIndex.scanText(hHandle, "## Chapter One\n\n")
+ assert theIndex.scanText(sHandle, "### Scene One\n\n")
+ assert theIndex.scanText(tHandle, "### Scene Two\n\n")
+
+ assert theIndex._listNovelHandles(False) == [nHandle, hHandle, sHandle, tHandle]
+ assert theIndex._listNovelHandles(True) == [hHandle, sHandle, tHandle]
+
+ # Add a fake handle to the tree and check that it's ignored
+ theProject.projTree._treeOrder.append("0000000000000")
+ assert theIndex._listNovelHandles(False) == [nHandle, hHandle, sHandle, tHandle]
+ theProject.projTree._treeOrder.remove("0000000000000")
+
+ # Extract stats
+ assert theIndex.getNovelWordCount(False) == 30
+ assert theIndex.getNovelWordCount(True) == 6
+ assert theIndex.getNovelTitleCounts(False) == [0, 2, 1, 2, 0]
+ assert theIndex.getNovelTitleCounts(True) == [0, 0, 1, 2, 0]
+
+ # Table of Contents
+ assert theIndex.getTableOfContents(0, True) == []
+ assert theIndex.getTableOfContents(1, True) == []
+ assert theIndex.getTableOfContents(2, True) == [
+ ("%s:T000001" % hHandle, "H2", "Chapter One", 6),
+ ]
+ assert theIndex.getTableOfContents(3, True) == [
+ ("%s:T000001" % hHandle, "H2", "Chapter One", 2),
+ ("%s:T000001" % sHandle, "H3", "Scene One", 2),
+ ("%s:T000001" % tHandle, "H3", "Scene Two", 2),
+ ]
+
+ assert theIndex.getTableOfContents(0, False) == []
+ assert theIndex.getTableOfContents(1, False) == [
+ ("%s:T000001" % nHandle, "H1", "Hello World!", 12),
+ ("%s:T000011" % nHandle, "H1", "Hello World!", 18),
+ ]
+
assert theProject.closeProject()
# END Test testCoreIndex_ExtractData