Removed the nw/tools folder and moved or merged the code in elsewhere
This commit is contained in:
@@ -1,15 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from nw.tools.analyse import TextAnalysis
|
||||
from nw.tools.legacy import projectMaintenance
|
||||
from nw.tools.optionstate import OptionState
|
||||
from nw.tools.translate import numberToWord
|
||||
from nw.tools.wordcount import countWords
|
||||
|
||||
__all__ = [
|
||||
"TextAnalysis",
|
||||
"projectMaintenance",
|
||||
"OptionState",
|
||||
"numberToWord",
|
||||
"countWords",
|
||||
]
|
||||
@@ -1,186 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
novelWriter – Text Analysis Class
|
||||
===================================
|
||||
Class for analysing bits of text.
|
||||
|
||||
File History:
|
||||
Created: 2018-09-22 [0.0.1]
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2020, 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
|
||||
import nw
|
||||
|
||||
from time import time
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class TextAnalysis():
|
||||
|
||||
def __init__(self, theText, langCode):
|
||||
self.theText = theText
|
||||
self.langCode = langCode
|
||||
return
|
||||
|
||||
def getStats(self):
|
||||
tStart = time()
|
||||
wordCount = self._countWords()
|
||||
tEnd = time()-tStart
|
||||
logger.verbose("Words: %7d in %8.3f ms" % (wordCount,tEnd*1e3))
|
||||
tStart = time()
|
||||
sentCount = self._countSentences()
|
||||
tEnd = time()-tStart
|
||||
logger.verbose("Sentences: %7d in %8.3f ms" % (sentCount,tEnd*1e3))
|
||||
tStart = time()
|
||||
paraCount = self._countParagraphs()
|
||||
tEnd = time()-tStart
|
||||
logger.verbose("Paragraphs: %7d in %8.3f ms" % (paraCount,tEnd*1e3))
|
||||
return wordCount, sentCount, paraCount
|
||||
|
||||
def getReadabilityScore(self):
|
||||
"""Calculate Flesch--Kincaid Readability Score.
|
||||
"""
|
||||
tStart = time()
|
||||
wordCount = self._countWords()
|
||||
sentCount = self._countSentences()
|
||||
if self.langCode[:3] == "en_":
|
||||
ratSyllWord = self._countSyllablesEN()
|
||||
else:
|
||||
ratSyllWord = -1.0
|
||||
rScore = 206.835 - 1.015*(wordCount/sentCount) - 84.6*(ratSyllWord)
|
||||
gLevel = -15.59 + 0.390*(wordCount/sentCount) + 11.8*(ratSyllWord)
|
||||
tEnd = time()-tStart
|
||||
logger.verbose("Readability: %7.3f in %8.3f ms" % (rScore,tEnd*1e3))
|
||||
logger.verbose("Grade Level: %7.3f in %8.3f ms" % (gLevel,tEnd*1e3))
|
||||
logger.verbose("Assessment: %s" % self.getReadabilityText(rScore))
|
||||
|
||||
return rScore, gLevel
|
||||
|
||||
def getReadabilityText(self, rScore):
|
||||
if rScore >= 90.0:
|
||||
return "Very Easy"
|
||||
elif rScore >= 80.0:
|
||||
return "Easy"
|
||||
elif rScore >= 70.0:
|
||||
return "Fairly Easy"
|
||||
elif rScore >= 60.0:
|
||||
return "Average"
|
||||
elif rScore >= 50.0:
|
||||
return "Fairly Difficult"
|
||||
elif rScore >= 30.0:
|
||||
return "Difficult"
|
||||
else:
|
||||
return "Very Difficult"
|
||||
|
||||
#
|
||||
# Internal Functions
|
||||
#
|
||||
|
||||
def _countWords(self):
|
||||
"""Counts the number of words in a text by simply splitting on
|
||||
all white spaces.
|
||||
"""
|
||||
return len(self.theText.strip().split())
|
||||
|
||||
def _countSentences(self):
|
||||
"""Counts the number of non-repeated sentence endings seen in
|
||||
the text. Note: This will count filenames and urls as multiple
|
||||
sentences.
|
||||
"""
|
||||
nSent = 0
|
||||
sawEnd = False
|
||||
for ch in self.theText.strip():
|
||||
if ch in ".!?":
|
||||
if not sawEnd:
|
||||
sawEnd = True
|
||||
nSent += 1
|
||||
else:
|
||||
sawEnd = False
|
||||
return nSent
|
||||
|
||||
def _countParagraphs(self, pThreshold=2):
|
||||
"""Counts the number of paragraphs by counting repeated line
|
||||
breaks.
|
||||
"""
|
||||
nPara = 1
|
||||
sawEnd = 0
|
||||
for ch in self.theText.strip():
|
||||
if ch == "\r": # Ignore Windows line end chars
|
||||
continue
|
||||
if ch == "\n": # Count endlines
|
||||
sawEnd += 1
|
||||
else: # If non-endline is encountered, check condition for paragraph
|
||||
if sawEnd >= pThreshold:
|
||||
nPara += 1
|
||||
sawEnd = 0
|
||||
return nPara
|
||||
|
||||
def _countSyllablesEN(self):
|
||||
"""Attempt to count the syllables in a piece of English language
|
||||
text. This function tends to slightly over-estimate the number
|
||||
of syllables as it doesn't handle the complexity of silent
|
||||
vowels in endings very well. It will count them all.
|
||||
"""
|
||||
|
||||
cleanText = ""
|
||||
for ch in self.theText:
|
||||
if ch in "abcdefghijklmnopqrstuvwxyz'’":
|
||||
cleanText += ch
|
||||
else:
|
||||
cleanText += " "
|
||||
|
||||
asVow = "aeiouy'’"
|
||||
dExept = ("ei","ie","ua","ia","eo")
|
||||
theWords = cleanText.lower().split()
|
||||
allSylls = 0
|
||||
for inWord in theWords:
|
||||
nChar = len(inWord)
|
||||
nSyll = 0
|
||||
wasVow = False
|
||||
wasY = False
|
||||
if nChar == 0:
|
||||
continue
|
||||
if inWord[0] in asVow:
|
||||
nSyll += 1
|
||||
wasVow = True
|
||||
wasY = inWord[0] == "y"
|
||||
for c in range(1,nChar):
|
||||
isVow = False
|
||||
if inWord[c] in asVow:
|
||||
nSyll += 1
|
||||
isVow = True
|
||||
if isVow and wasVow:
|
||||
nSyll -= 1
|
||||
if isVow and wasY:
|
||||
nSyll -= 1
|
||||
if inWord[c:c+2] in dExept:
|
||||
nSyll += 1
|
||||
wasVow = isVow
|
||||
wasY = inWord[c] == "y"
|
||||
if inWord.endswith(("e")):
|
||||
nSyll -= 1
|
||||
if inWord.endswith(("le","ea","io")):
|
||||
nSyll += 1
|
||||
if nSyll < 1:
|
||||
nSyll = 1
|
||||
allSylls += nSyll
|
||||
|
||||
return allSylls/len(theWords)
|
||||
|
||||
# END Class TextAnalysis
|
||||
@@ -1,78 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""novelWriter Legacy Tools
|
||||
|
||||
novelWriter – Legacy Tools
|
||||
============================
|
||||
Various functions to handle old projects
|
||||
|
||||
File History:
|
||||
Created: 2020-02-13 [0.4.3]
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2020, 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
|
||||
import nw
|
||||
|
||||
from os import path, unlink, rmdir
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def projectMaintenance(theProject):
|
||||
"""Wrapper class for handling various tasks related to managing old
|
||||
projects with content from older versions of novelWriter.
|
||||
"""
|
||||
|
||||
# Remove no longer used project cache folder
|
||||
if path.isdir(theProject.projPath):
|
||||
cacheDir = path.join(theProject.projPath, "cache")
|
||||
if path.isdir(cacheDir):
|
||||
logger.info("Deprecated cache folder found")
|
||||
rmList = []
|
||||
for i in range(10):
|
||||
rmList.append(path.join(cacheDir, "nwProject.nwx.%d" % i))
|
||||
rmList.append(path.join(cacheDir, "projCount.txt"))
|
||||
for rmFile in rmList:
|
||||
if path.isfile(rmFile):
|
||||
logger.info("Deleting: %s" % rmFile)
|
||||
try:
|
||||
unlink(rmFile)
|
||||
except Exception as e:
|
||||
logger.error(str(e))
|
||||
logger.info("Deleting: %s" % cacheDir)
|
||||
try:
|
||||
rmdir(cacheDir)
|
||||
except Exception as e:
|
||||
logger.error(str(e))
|
||||
|
||||
# Remove no longer used meta files
|
||||
rmList = []
|
||||
rmList.append(path.join(theProject.projMeta, "mainOptions.json"))
|
||||
rmList.append(path.join(theProject.projMeta, "exportOptions.json"))
|
||||
rmList.append(path.join(theProject.projMeta, "outlineOptions.json"))
|
||||
rmList.append(path.join(theProject.projMeta, "timelineOptions.json"))
|
||||
rmList.append(path.join(theProject.projMeta, "docMergeOptions.json"))
|
||||
rmList.append(path.join(theProject.projMeta, "sessionLogOptions.json"))
|
||||
for rmFile in rmList:
|
||||
if path.isfile(rmFile):
|
||||
logger.info("Deleting: %s" % rmFile)
|
||||
try:
|
||||
unlink(rmFile)
|
||||
except Exception as e:
|
||||
logger.error(str(e))
|
||||
|
||||
return
|
||||
@@ -1,183 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""novelWriter Options State
|
||||
|
||||
novelWriter – Options State
|
||||
=============================
|
||||
Class holding the last state of GUI options
|
||||
|
||||
File History:
|
||||
Created: 2019-10-21 [0.3.1] - Original version meant to be sub classed
|
||||
Created: 2020-02-19 [0.4.5] - Rewritten from superclass to single file tool
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2020, 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
|
||||
import json
|
||||
import nw
|
||||
|
||||
from os import path
|
||||
|
||||
from nw.common import checkString, checkBool, checkInt
|
||||
from nw.constants import nwFiles
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class OptionState():
|
||||
|
||||
def __init__(self, theProject):
|
||||
|
||||
self.theProject = theProject
|
||||
self.theState = {}
|
||||
self.stringOpt = ()
|
||||
self.boolOpt = ()
|
||||
self.intOpt = ()
|
||||
|
||||
return
|
||||
|
||||
def loadSettings(self):
|
||||
"""Load the options dictionary from the project settings file.
|
||||
"""
|
||||
|
||||
if self.theProject.projMeta is None:
|
||||
return False
|
||||
|
||||
stateFile = path.join(self.theProject.projMeta, nwFiles.OPTS_FILE)
|
||||
theState = {}
|
||||
|
||||
if path.isfile(stateFile):
|
||||
logger.debug("Loading GUI options file")
|
||||
try:
|
||||
with open(stateFile,mode="r",encoding="utf8") as inFile:
|
||||
theJson = inFile.read()
|
||||
theState = json.loads(theJson)
|
||||
except Exception as e:
|
||||
logger.error("Failed to load GUI options file")
|
||||
logger.error(str(e))
|
||||
return False
|
||||
for anOpt in theState:
|
||||
self.theState[anOpt] = theState[anOpt]
|
||||
|
||||
return True
|
||||
|
||||
def saveSettings(self):
|
||||
"""Save the options dictionary to the project settings file.
|
||||
"""
|
||||
|
||||
if self.theProject.projMeta is None:
|
||||
return False
|
||||
|
||||
stateFile = path.join(self.theProject.projMeta, nwFiles.OPTS_FILE)
|
||||
logger.debug("Saving GUI options file")
|
||||
|
||||
try:
|
||||
with open(stateFile,mode="w+",encoding="utf8") as outFile:
|
||||
outFile.write(json.dumps(self.theState, indent=2))
|
||||
except Exception as e:
|
||||
logger.error("Failed to save GUI options file")
|
||||
logger.error(str(e))
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def setValue(self, setGroup, setName, setValue):
|
||||
"""Saves a value, with a given group and name.
|
||||
"""
|
||||
if not setGroup in self.theState:
|
||||
self.theState[setGroup] = {}
|
||||
self.theState[setGroup][setName] = setValue
|
||||
return True
|
||||
|
||||
def getValue(self, getGroup, getName, defaultValue):
|
||||
"""Return an arbitrary type value, if it exists. Otherwise,
|
||||
return the default value.
|
||||
"""
|
||||
if getGroup in self.theState:
|
||||
if getName in self.theState[getGroup]:
|
||||
try:
|
||||
return self.theState[getGroup][getName]
|
||||
except:
|
||||
return defaultValue
|
||||
return defaultValue
|
||||
|
||||
def getString(self, getGroup, getName, defaultValue):
|
||||
"""Return the value as a string, if it exists. Otherwise, return
|
||||
the default value.
|
||||
"""
|
||||
if getGroup in self.theState:
|
||||
if getName in self.theState[getGroup]:
|
||||
try:
|
||||
return str(self.theState[getGroup][getName])
|
||||
except:
|
||||
return defaultValue
|
||||
return defaultValue
|
||||
|
||||
def getInt(self, getGroup, getName, defaultValue):
|
||||
"""Return the value as an int, if it exists. Otherwise, return
|
||||
the default value.
|
||||
"""
|
||||
if getGroup in self.theState:
|
||||
if getName in self.theState[getGroup]:
|
||||
try:
|
||||
return int(self.theState[getGroup][getName])
|
||||
except:
|
||||
return defaultValue
|
||||
return defaultValue
|
||||
|
||||
def getFloat(self, getGroup, getName, defaultValue):
|
||||
"""Return the value as a float, if it exists. Otherwise, return
|
||||
the default value.
|
||||
"""
|
||||
if getGroup in self.theState:
|
||||
if getName in self.theState[getGroup]:
|
||||
try:
|
||||
return float(self.theState[getGroup][getName])
|
||||
except:
|
||||
return defaultValue
|
||||
return defaultValue
|
||||
|
||||
def getBool(self, getGroup, getName, defaultValue):
|
||||
"""Return the value as a bool, if it exists. Otherwise, return
|
||||
the default value.
|
||||
"""
|
||||
if getGroup in self.theState:
|
||||
if getName in self.theState[getGroup]:
|
||||
try:
|
||||
return bool(self.theState[getGroup][getName])
|
||||
except:
|
||||
return defaultValue
|
||||
return defaultValue
|
||||
|
||||
def validIntRange(self, theValue, intA, intB, intDefault):
|
||||
"""Check that an int is in a given range. If it isn't, return
|
||||
the default value.
|
||||
"""
|
||||
if isinstance(theValue, int):
|
||||
if theValue >= intA and theValue <= intB:
|
||||
return theValue
|
||||
return intDefault
|
||||
|
||||
def validIntTuple(self, theValue, theTuple, intDefault):
|
||||
"""Check that an int is an element of a tuple. If it isn't,
|
||||
return the default value.
|
||||
"""
|
||||
if isinstance(theValue, int):
|
||||
if theValue in theTuple:
|
||||
return theValue
|
||||
return intDefault
|
||||
|
||||
# END Class OptionState
|
||||
@@ -1,106 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""novelWriter Translate Tools
|
||||
|
||||
novelWriter – Translate Tools
|
||||
===============================
|
||||
Various translate tools
|
||||
|
||||
File History:
|
||||
Created: 2019-10-13 [0.2.3]
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2020, 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
|
||||
import nw
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def numberToWord(numVal, theLanguage):
|
||||
numWord = ""
|
||||
if theLanguage == "en":
|
||||
numWord = _numberToWordEN(numVal)
|
||||
else:
|
||||
numWord = _numberToWordEN(numVal)
|
||||
# print("%4d : %s" % (numVal, numWord))
|
||||
return numWord
|
||||
|
||||
def _numberToWordEN(numVal):
|
||||
|
||||
numWord = ""
|
||||
oneWord = ""
|
||||
tenWord = ""
|
||||
hunWord = ""
|
||||
|
||||
if numVal == 0:
|
||||
return "Zero"
|
||||
|
||||
oneVal = numVal % 10
|
||||
tenVal = (numVal-oneVal) % 100
|
||||
hunVal = (numVal-tenVal-oneVal) % 1000
|
||||
|
||||
if hunVal == 100: hunWord = "One Hundred"
|
||||
if hunVal == 200: hunWord = "Two Hundred"
|
||||
if hunVal == 300: hunWord = "Three Hundred"
|
||||
if hunVal == 400: hunWord = "Four Hundred"
|
||||
if hunVal == 500: hunWord = "Five Hundred"
|
||||
if hunVal == 600: hunWord = "Six Hundred"
|
||||
if hunVal == 700: hunWord = "Seven Hundred"
|
||||
if hunVal == 800: hunWord = "Eight Hundred"
|
||||
if hunVal == 900: hunWord = "Nine Hundred"
|
||||
|
||||
if tenVal == 20: tenWord = "Twenty"
|
||||
if tenVal == 30: tenWord = "Thirty"
|
||||
if tenVal == 40: tenWord = "Forty"
|
||||
if tenVal == 50: tenWord = "Fifty"
|
||||
if tenVal == 60: tenWord = "Sixty"
|
||||
if tenVal == 70: tenWord = "Seventy"
|
||||
if tenVal == 80: tenWord = "Eighty"
|
||||
if tenVal == 90: tenWord = "Ninety"
|
||||
|
||||
if tenVal == 10:
|
||||
if oneVal == 0: oneWord = "Ten"
|
||||
if oneVal == 1: oneWord = "Eleven"
|
||||
if oneVal == 2: oneWord = "Twelve"
|
||||
if oneVal == 3: oneWord = "Thirteen"
|
||||
if oneVal == 4: oneWord = "Fourteen"
|
||||
if oneVal == 5: oneWord = "Fifteen"
|
||||
if oneVal == 6: oneWord = "Sixteen"
|
||||
if oneVal == 7: oneWord = "Seventeen"
|
||||
if oneVal == 8: oneWord = "Eighteen"
|
||||
if oneVal == 9: oneWord = "Nineteen"
|
||||
numWord = ("%s %s" % (hunWord, oneWord)).strip()
|
||||
else:
|
||||
if oneVal == 0: oneWord = ""
|
||||
if oneVal == 1: oneWord = "One"
|
||||
if oneVal == 2: oneWord = "Two"
|
||||
if oneVal == 3: oneWord = "Three"
|
||||
if oneVal == 4: oneWord = "Four"
|
||||
if oneVal == 5: oneWord = "Five"
|
||||
if oneVal == 6: oneWord = "Six"
|
||||
if oneVal == 7: oneWord = "Seven"
|
||||
if oneVal == 8: oneWord = "Eight"
|
||||
if oneVal == 9: oneWord = "Nine"
|
||||
if tenVal == 0:
|
||||
numWord = ("%s %s" % (hunWord, oneWord)).strip()
|
||||
else:
|
||||
if oneVal == 0:
|
||||
numWord = ("%s %s" % (hunWord, tenWord)).strip()
|
||||
else:
|
||||
numWord = ("%s %s-%s" % (hunWord, tenWord, oneWord)).strip()
|
||||
|
||||
return numWord
|
||||
@@ -1,76 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""novelWriter Word Counter
|
||||
|
||||
novelWriter – Word Counter
|
||||
============================
|
||||
Simple word counter
|
||||
|
||||
File History:
|
||||
Created: 2019-04-22 [0.0.1]
|
||||
Moved: 2019-05-30 [0.1.4]
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2020, 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
|
||||
import nw
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def countWords(theText):
|
||||
|
||||
charCount = 0
|
||||
wordCount = 0
|
||||
paraCount = 0
|
||||
prevEmpty = True
|
||||
|
||||
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
|
||||
|
||||
theBuff = aLine.replace("–"," ").replace("—"," ")
|
||||
wordCount += len(theBuff.split())
|
||||
charCount += theLen
|
||||
if countPara and prevEmpty:
|
||||
paraCount += 1
|
||||
prevEmpty = countPara == False
|
||||
|
||||
return charCount, wordCount, paraCount
|
||||
Reference in New Issue
Block a user