From 3bd67b4f1d098cec8dec7df678a94c966b570812 Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Tue, 27 Feb 2024 17:54:32 +0100 Subject: [PATCH] Add body text only counter --- novelwriter/text/counting.py | 33 +++++++--- tests/test_text/test_core_counting.py | 87 +++++++++++++++++++++++++-- 2 files changed, 108 insertions(+), 12 deletions(-) diff --git a/novelwriter/text/counting.py b/novelwriter/text/counting.py index e92f4dc8..b381adea 100644 --- a/novelwriter/text/counting.py +++ b/novelwriter/text/counting.py @@ -5,6 +5,7 @@ novelWriter – Text Counting Functions File History: Created: 2019-04-22 [0.0.1] standardCounter Rewritten: 2024-02-27 [2.4b1] preProcessText, standardCounter +Created: 2024-02-27 [2.4b1] bodyTextCounter This file is a part of novelWriter Copyright 2018–2024, Veronica Berglyd Olsen @@ -75,15 +76,14 @@ def standardCounter(text: str) -> tuple[int, int, int]: This is the standard counter that includes headers in the word and character counts. """ - charCount = 0 - wordCount = 0 - paraCount = 0 + cCount = 0 + wCount = 0 + pCount = 0 prevEmpty = True for line in preProcessText(text): countPara = True - if not line: prevEmpty = True continue @@ -108,11 +108,28 @@ def standardCounter(text: str) -> tuple[int, int, int]: line = line[4:] countPara = False - wordCount += len(line.split()) - charCount += len(line) + wCount += len(line.split()) + cCount += len(line) if countPara and prevEmpty: - paraCount += 1 + pCount += 1 prevEmpty = not countPara - return charCount, wordCount, paraCount + return cCount, wCount, pCount + + +def bodyTextCounter(text: str | list[str]) -> tuple[int, int, int]: + """A counter that counts body text words, characters, and characters + without white spaces. + """ + wCount = 0 + cCount = 0 + sCount = 0 + + for line in preProcessText(text, keepHeaders=False): + words = line.split() + wCount += len(words) + cCount += len(line) + sCount += len("".join(words)) + + return wCount, cCount, sCount diff --git a/tests/test_text/test_core_counting.py b/tests/test_text/test_core_counting.py index 3c4caaa3..bab0596e 100644 --- a/tests/test_text/test_core_counting.py +++ b/tests/test_text/test_core_counting.py @@ -22,18 +22,69 @@ from __future__ import annotations import pytest -from novelwriter.text.counting import standardCounter +from novelwriter.text.counting import bodyTextCounter, preProcessText, standardCounter + + +@pytest.mark.core +def testTextCounting_preProcessText(): + """Test the text preprocessor for counters.""" + # Not Text + assert preProcessText(None) == [] + + # No Text + assert preProcessText("") == [] + + text = ( + "#! Title\n" + "##! Prologue\n" + "# Heading One\n" + "## Heading Two\n" + "### Heading Three\n" + "#### Heading Four\n\n" + "@tag: value\n\n" + "% A comment.\n\n" + "A [b]paragraph[/b].\n\n" + "[vspace:3]\n\n" + "[New Page]\n\n" + "Dashes\u2013and even longer\u2014dashes.\n\n" + ) + + # Process Text, w/Headers + assert preProcessText(text) == [ + "#! Title", + "##! Prologue", + "# Heading One", + "## Heading Two", + "### Heading Three", + "#### Heading Four", + "", "", "", + "A paragraph.", "", + "", "", "", "", + "Dashes and even longer dashes.", "" + ] + + # Process Text, wo/Headers + assert preProcessText(text, keepHeaders=False) == [ + "", "", "", + "A paragraph.", "", + "", "", "", "", + "Dashes and even longer dashes.", "" + ] + +# END Test testTextCounting_preProcessText @pytest.mark.core def testTextCounting_standardCounter(): - """Test the word counter and the exclusion filers.""" + """Test the standard counter.""" # Non-Text assert standardCounter(None) == (0, 0, 0) # type: ignore assert standardCounter(1234) == (0, 0, 0) # type: ignore # General Text cC, wC, pC = standardCounter(( + "#! Title\n\n" + "##! Prologue\n\n" "# Heading One\n" "## Heading Two\n" "### Heading Three\n" @@ -45,8 +96,8 @@ def testTextCounting_standardCounter(): "The third paragraph.\n\n" "Dashes\u2013and even longer\u2014dashes." )) - assert cC == 138 - assert wC == 22 + assert cC == 151 + assert wC == 24 assert pC == 4 # Text Alignment @@ -125,3 +176,31 @@ def testTextCounting_standardCounter(): assert pC == 2 # END Test testTextCounting_standardCounter + + +@pytest.mark.core +def testTextCounting_bodyTextCounter(): + """Test the body text counter.""" + # Not Text + assert bodyTextCounter(None) == (0, 0, 0) + + # General Text + wC, cC, sC = bodyTextCounter(( + "#! Title\n\n" + "##! Prologue\n\n" + "# Heading One\n" + "## Heading Two\n" + "### Heading Three\n" + "#### Heading Four\n\n" + "@tag: value\n\n" + "% A comment that should not 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." + )) + assert wC == 14 + assert cC == 91 + assert sC == 81 + +# END Test testTextCounting_bodyTextCounter