Move the remanining two functions in the tools.py file to other source files

This commit is contained in:
Veronica K. B. Olsen
2021-02-17 16:31:37 +01:00
parent 185974a3ea
commit 5a685474ff
9 changed files with 149 additions and 211 deletions
+23
View File
@@ -311,3 +311,26 @@ def getGuiItem(theName):
if qWidget.objectName() == theName:
return qWidget
return None
def numberToRoman(numVal, isLower=False):
"""Convert an integer to a roman number.
"""
if not isinstance(numVal, int):
return "NAN"
if numVal < 1 or numVal > 4999:
return "OOR"
theValues = [
(1000, "M"), (900, "CM"), (500, "D"), (400, "CD"), (100, "C"), (90, "XC"),
(50, "L"), (40, "XL"), (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I"),
]
romNum = ""
for theDiv, theSym in theValues:
n = numVal//theDiv
romNum += n*theSym
numVal -= n*theDiv
if numVal <= 0:
break
return romNum.lower() if isLower else romNum
+1 -3
View File
@@ -1,17 +1,15 @@
# -*- coding: utf-8 -*-
from nw.core.document import NWDoc
from nw.core.index import NWIndex
from nw.core.index import NWIndex, countWords
from nw.core.project import NWProject
from nw.core.spellcheck import NWSpellCheck, NWSpellEnchant, NWSpellSimple
from nw.core.tohtml import ToHtml
from nw.core.toodt import ToOdt
from nw.core.tomd import ToMarkdown
from nw.core.tools import countWords, numberToRoman
__all__ = [
"countWords",
"numberToRoman",
"NWDoc",
"NWIndex",
"NWProject",
+63 -3
View File
@@ -5,7 +5,8 @@ novelWriter Project Index
Data class for the project index of tags, headers and references
File History:
Created: 2019-05-27 [0.1.4]
Created: 2019-04-22 [0.0.1] countWords
Created: 2019-05-27 [0.1.4] NWIndex
This file is a part of novelWriter
Copyright 20182021, Veronica Berglyd Olsen
@@ -32,10 +33,10 @@ import os
from time import time
from nw.constants import (
nwFiles, nwKeyWords, nwItemType, nwItemClass, nwItemLayout, nwAlert
nwFiles, nwKeyWords, nwItemType, nwItemClass, nwItemLayout, nwAlert,
nwUnicode
)
from nw.core.document import NWDoc
from nw.core.tools import countWords
from nw.common import isHandle, isTitleTag, isItemClass, isItemLayout
logger = logging.getLogger(__name__)
@@ -906,3 +907,62 @@ class NWIndex():
return
# END Class NWIndex
# =============================================================================================== #
# Simple Word Counter
# =============================================================================================== #
def countWords(theText):
"""Count words in a piece of text, skipping special syntax and
comments.
"""
charCount = 0
wordCount = 0
paraCount = 0
prevEmpty = True
# We need to treat dashes as word separators for counting words.
# The check+replace apprach is much faster that direct replace for
# large texts, and a bit slower for small texts, but in the latter
# case it doesn't matter.
if nwUnicode.U_ENDASH in theText:
theText = theText.replace(nwUnicode.U_ENDASH, " ")
if nwUnicode.U_EMDASH in theText:
theText = theText.replace(nwUnicode.U_EMDASH, " ")
for aLine in theText.splitlines():
countPara = True
theLen = len(aLine)
if theLen == 0:
prevEmpty = True
continue
if aLine[0] == "@" or aLine[0] == "%":
continue
if aLine[0:5] == "#### ":
wordCount -= 1
charCount -= 5
countPara = False
elif aLine[0:4] == "### ":
wordCount -= 1
charCount -= 4
countPara = False
elif aLine[0:3] == "## ":
wordCount -= 1
charCount -= 3
countPara = False
elif aLine[0:2] == "# ":
wordCount -= 1
charCount -= 2
countPara = False
wordCount += len(aLine.split())
charCount += theLen
if countPara and prevEmpty:
paraCount += 1
prevEmpty = not countPara
return charCount, wordCount, paraCount
+1 -1
View File
@@ -33,7 +33,7 @@ from functools import partial
from PyQt5.QtCore import QCoreApplication, QRegularExpression
from nw.core.document import NWDoc
from nw.core.tools import numberToRoman
from nw.common import numberToRoman
from nw.constants import nwConst, nwUnicode, nwItemLayout, nwItemType, nwRegEx
logger = logging.getLogger(__name__)
-118
View File
@@ -1,118 +0,0 @@
# -*- coding: utf-8 -*-
"""
novelWriter Various Tools
===========================
Various core tool functions
File History:
Created: 2019-04-22 [0.0.1] countWords
Created: 2020-07-05 [0.10.0] numberToRoman
This file is a part of novelWriter
Copyright 20182021, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import logging
from nw.constants import nwUnicode
logger = logging.getLogger(__name__)
# =============================================================================================== #
# Simple Word Counter
# =============================================================================================== #
def countWords(theText):
"""Count words in a piece of text, skipping special syntax and
comments.
"""
charCount = 0
wordCount = 0
paraCount = 0
prevEmpty = True
# We need to treat dashes as word separators for counting words.
# The check+replace apprach is much faster that direct replace for
# large texts, and a bit slower for small texts, but in the latter
# case it doesn't matter.
if nwUnicode.U_ENDASH in theText:
theText = theText.replace(nwUnicode.U_ENDASH, " ")
if nwUnicode.U_EMDASH in theText:
theText = theText.replace(nwUnicode.U_EMDASH, " ")
for aLine in theText.splitlines():
countPara = True
theLen = len(aLine)
if theLen == 0:
prevEmpty = True
continue
if aLine[0] == "@" or aLine[0] == "%":
continue
if aLine[0:5] == "#### ":
wordCount -= 1
charCount -= 5
countPara = False
elif aLine[0:4] == "### ":
wordCount -= 1
charCount -= 4
countPara = False
elif aLine[0:3] == "## ":
wordCount -= 1
charCount -= 3
countPara = False
elif aLine[0:2] == "# ":
wordCount -= 1
charCount -= 2
countPara = False
wordCount += len(aLine.split())
charCount += theLen
if countPara and prevEmpty:
paraCount += 1
prevEmpty = not countPara
return charCount, wordCount, paraCount
# =============================================================================================== #
# Convert an Integer to a Roman Number
# =============================================================================================== #
def numberToRoman(numVal, isLower=False):
"""Convert an integer to a roman number.
"""
if not isinstance(numVal, int):
return "NAN"
if numVal < 1 or numVal > 4999:
return "OOR"
theValues = [
(1000, "M"), (900, "CM"), (500, "D"), (400, "CD"), (100, "C"), (90, "XC"),
(50, "L"), (40, "XL"), (10, "X"), (9, "IX"), (5, "V"), (4, "IV"), (1, "I"),
]
romNum = ""
for theDiv, theSym in theValues:
n = numVal//theDiv
romNum += n*theSym
numVal -= n*theDiv
if numVal <= 0:
break
return romNum.lower() if isLower else romNum
+1 -1
View File
@@ -37,7 +37,7 @@ from PyQt5.QtWidgets import (
from nw.gui.custom import PagedDialog, QSwitch
from nw.constants import nwUnicode
from nw.core import numberToRoman
from nw.common import numberToRoman
logger = logging.getLogger(__name__)
+28 -1
View File
@@ -27,7 +27,7 @@ from nw.common import (
checkString, checkBool, checkInt, colRange, formatInt, transferCase,
fuzzyTime, checkHandle, formatTimeStamp, formatTime, hexToInt,
makeFileNameSafe, isHandle, isTitleTag, isItemClass, isItemType,
isItemLayout
isItemLayout, numberToRoman
)
from tools import cmpList
@@ -325,3 +325,30 @@ def testBaseCommon_MakeFileNameSafe():
assert makeFileNameSafe("aaaa bbbb") == "aaaa bbbb"
# END Test testBaseCommon_MakeFileNameSafe
@pytest.mark.core
def testBaseCommon_RomanNumbers():
"""Test conversion of integers to Roman numbers.
"""
assert numberToRoman(None, False) == "NAN"
assert numberToRoman(0, False) == "OOR"
assert numberToRoman(1, False) == "I"
assert numberToRoman(2, False) == "II"
assert numberToRoman(3, False) == "III"
assert numberToRoman(4, False) == "IV"
assert numberToRoman(5, False) == "V"
assert numberToRoman(6, False) == "VI"
assert numberToRoman(7, False) == "VII"
assert numberToRoman(8, False) == "VIII"
assert numberToRoman(9, False) == "IX"
assert numberToRoman(10, False) == "X"
assert numberToRoman(14, False) == "XIV"
assert numberToRoman(42, False) == "XLII"
assert numberToRoman(99, False) == "XCIX"
assert numberToRoman(142, False) == "CXLII"
assert numberToRoman(542, False) == "DXLII"
assert numberToRoman(999, False) == "CMXCIX"
assert numberToRoman(2010, False) == "MMX"
assert numberToRoman(999, True) == "cmxcix"
# END Test testBaseCommon_RomanNumbers
+32 -1
View File
@@ -29,7 +29,7 @@ from shutil import copyfile
from tools import cmpFiles
from nw.core.project import NWProject
from nw.core.index import NWIndex
from nw.core.index import NWIndex, countWords
from nw.constants import nwItemClass, nwItemLayout
@pytest.mark.core
@@ -1161,3 +1161,34 @@ def testCoreIndex_CheckTextCounts(dummyGUI):
theIndex._checkTextCounts()
# END Test testCoreIndex_CheckTextCounts
@pytest.mark.core
def testCoreIndex_CountWords():
"""Test the word counter and the exclusion filers.
"""
testText = (
"# Heading One\n"
"## Heading Two\n"
"### Heading Three\n"
"#### Heading Four\n"
"\n"
"@tag: value\n"
"\n"
"% A comment that should n ot be counted.\n"
"\n"
"The first paragraph.\n"
"\n"
"The second paragraph.\n"
"\n"
"\n"
"The third paragraph.\n"
"\n"
"Dashes\u2013and even longer\u2014dashes."
)
cC, wC, pC = countWords(testText)
assert cC == 138
assert wC == 22
assert pC == 4
# END Test testCoreIndex_CountWords
-83
View File
@@ -1,83 +0,0 @@
# -*- coding: utf-8 -*-
"""
novelWriter Core Tools Tester
===============================
This file is a part of novelWriter
Copyright 20182021, Veronica Berglyd Olsen
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
"""
import pytest
from nw.core.tools import countWords, numberToRoman
@pytest.mark.core
def testCoreTools_CountWords():
"""Test the word counter and the exclusion filers.
"""
testText = (
"# Heading One\n"
"## Heading Two\n"
"### Heading Three\n"
"#### Heading Four\n"
"\n"
"@tag: value\n"
"\n"
"% A comment that should n ot be counted.\n"
"\n"
"The first paragraph.\n"
"\n"
"The second paragraph.\n"
"\n"
"\n"
"The third paragraph.\n"
"\n"
"Dashes\u2013and even longer\u2014dashes."
)
cC, wC, pC = countWords(testText)
assert cC == 138
assert wC == 22
assert pC == 4
# END Test testCoreTools_CountWords
@pytest.mark.core
def testCoreTools_RomanNumbers():
"""Test conversion of integers to Roman numbers.
"""
assert numberToRoman(None, False) == "NAN"
assert numberToRoman(0, False) == "OOR"
assert numberToRoman(1, False) == "I"
assert numberToRoman(2, False) == "II"
assert numberToRoman(3, False) == "III"
assert numberToRoman(4, False) == "IV"
assert numberToRoman(5, False) == "V"
assert numberToRoman(6, False) == "VI"
assert numberToRoman(7, False) == "VII"
assert numberToRoman(8, False) == "VIII"
assert numberToRoman(9, False) == "IX"
assert numberToRoman(10, False) == "X"
assert numberToRoman(14, False) == "XIV"
assert numberToRoman(42, False) == "XLII"
assert numberToRoman(99, False) == "XCIX"
assert numberToRoman(142, False) == "CXLII"
assert numberToRoman(542, False) == "DXLII"
assert numberToRoman(999, False) == "CMXCIX"
assert numberToRoman(2010, False) == "MMX"
assert numberToRoman(999, True) == "cmxcix"
# END Test testCoreTools_RomanNumbers