Generalise the manuscript stats count values
This commit is contained in:
@@ -67,7 +67,7 @@ class nwRegEx:
|
||||
FMT_EB = r"(?<![\w\\])(\*{2})(?![\s\*])(.+?)(?<![\s\\])(\1)(?!\w)"
|
||||
FMT_ST = r"(?<![\w\\])(~{2})(?![\s~])(.+?)(?<![\s\\])(\1)(?!\w)"
|
||||
FMT_SC = r"(?i)(?<!\\)(\[(?:b|/b|i|/i|s|/s|u|/u|m|/m|sup|/sup|sub|/sub|br)\])"
|
||||
FMT_SV = r"(?i)(?<!\\)(\[(?:footnote):)(.+?)(?<!\\)(\])"
|
||||
FMT_SV = r"(?i)(?<!\\)(\[(?:footnote|field):)(.+?)(?<!\\)(\])"
|
||||
|
||||
|
||||
class nwShortcode:
|
||||
@@ -95,6 +95,8 @@ class nwShortcode:
|
||||
nwComment.COMMENT: "[comment:{0}]",
|
||||
}
|
||||
|
||||
FIELD_VALUE = "[field:{0}]"
|
||||
|
||||
|
||||
class nwStyles:
|
||||
|
||||
@@ -159,11 +161,14 @@ class nwKeyWords:
|
||||
STORY_KEY = "@story"
|
||||
MENTION_KEY = "@mention"
|
||||
|
||||
# Set of Valid Keys
|
||||
VALID_KEYS = {
|
||||
# Note: The order here affects the order of menu entries
|
||||
ALL_KEYS = [
|
||||
TAG_KEY, POV_KEY, FOCUS_KEY, CHAR_KEY, PLOT_KEY, TIME_KEY, WORLD_KEY,
|
||||
OBJECT_KEY, ENTITY_KEY, CUSTOM_KEY, STORY_KEY, MENTION_KEY,
|
||||
}
|
||||
]
|
||||
|
||||
# Set of Valid Keys
|
||||
VALID_KEYS = set(ALL_KEYS)
|
||||
|
||||
# Map from Keys to Item Class
|
||||
KEY_CLASS = {
|
||||
@@ -193,6 +198,29 @@ class nwLists:
|
||||
]
|
||||
|
||||
|
||||
class nwStats:
|
||||
|
||||
CHARS_ALL = "allChars"
|
||||
CHARS_TEXT = "textChars"
|
||||
CHARS_TITLE = "titleChars"
|
||||
PARAGRAPHS = "paragraphCount"
|
||||
TITLES = "titleCount"
|
||||
WCHARS_ALL = "allWordChars"
|
||||
WCHARS_TEXT = "textWordChars"
|
||||
WCHARS_TITLE = "titleWordChars"
|
||||
WORDS_ALL = "allWords"
|
||||
WORDS_TEXT = "textWords"
|
||||
WORDS_TITLE = "titleWords"
|
||||
|
||||
# Note: The order here affects the order of menu entries
|
||||
ALL_FIELDS = [
|
||||
WORDS_ALL, WORDS_TEXT, WORDS_TITLE,
|
||||
CHARS_ALL, CHARS_TEXT, CHARS_TITLE,
|
||||
WCHARS_ALL, WCHARS_TEXT, WCHARS_TITLE,
|
||||
PARAGRAPHS, TITLES,
|
||||
]
|
||||
|
||||
|
||||
class nwLabels:
|
||||
|
||||
CLASS_NAME = {
|
||||
@@ -253,6 +281,20 @@ class nwLabels:
|
||||
nwKeyWords.STORY_KEY: QT_TRANSLATE_NOOP("Constant", "Story"),
|
||||
nwKeyWords.MENTION_KEY: QT_TRANSLATE_NOOP("Constant", "Mentions"),
|
||||
}
|
||||
KEY_SHORTCUT = {
|
||||
nwKeyWords.TAG_KEY: "Ctrl+K, G",
|
||||
nwKeyWords.POV_KEY: "Ctrl+K, V",
|
||||
nwKeyWords.FOCUS_KEY: "Ctrl+K, F",
|
||||
nwKeyWords.CHAR_KEY: "Ctrl+K, C",
|
||||
nwKeyWords.PLOT_KEY: "Ctrl+K, P",
|
||||
nwKeyWords.TIME_KEY: "Ctrl+K, T",
|
||||
nwKeyWords.WORLD_KEY: "Ctrl+K, L",
|
||||
nwKeyWords.OBJECT_KEY: "Ctrl+K, O",
|
||||
nwKeyWords.ENTITY_KEY: "Ctrl+K, E",
|
||||
nwKeyWords.CUSTOM_KEY: "Ctrl+K, X",
|
||||
nwKeyWords.STORY_KEY: "Ctrl+K, N",
|
||||
nwKeyWords.MENTION_KEY: "Ctrl+K, M",
|
||||
}
|
||||
OUTLINE_COLS = {
|
||||
nwOutline.TITLE: QT_TRANSLATE_NOOP("Constant", "Title"),
|
||||
nwOutline.LEVEL: QT_TRANSLATE_NOOP("Constant", "Level"),
|
||||
@@ -274,6 +316,19 @@ class nwLabels:
|
||||
nwOutline.MENTION: KEY_NAME[nwKeyWords.MENTION_KEY],
|
||||
nwOutline.SYNOP: QT_TRANSLATE_NOOP("Constant", "Synopsis"),
|
||||
}
|
||||
STATS_NAME = {
|
||||
nwStats.CHARS_ALL: QT_TRANSLATE_NOOP("Constant", "Characters"),
|
||||
nwStats.CHARS_TEXT: QT_TRANSLATE_NOOP("Constant", "Characters in Text"),
|
||||
nwStats.CHARS_TITLE: QT_TRANSLATE_NOOP("Constant", "Characters in Headings"),
|
||||
nwStats.PARAGRAPHS: QT_TRANSLATE_NOOP("Constant", "Paragraphs"),
|
||||
nwStats.TITLES: QT_TRANSLATE_NOOP("Constant", "Headings"),
|
||||
nwStats.WCHARS_ALL: QT_TRANSLATE_NOOP("Constant", "Characters, No Spaces"),
|
||||
nwStats.WCHARS_TEXT: QT_TRANSLATE_NOOP("Constant", "Characters in Text, No Spaces"),
|
||||
nwStats.WCHARS_TITLE: QT_TRANSLATE_NOOP("Constant", "Characters in Headings, No Spaces"),
|
||||
nwStats.WORDS_ALL: QT_TRANSLATE_NOOP("Constant", "Words"),
|
||||
nwStats.WORDS_TEXT: QT_TRANSLATE_NOOP("Constant", "Words in Text"),
|
||||
nwStats.WORDS_TITLE: QT_TRANSLATE_NOOP("Constant", "Words in Headings"),
|
||||
}
|
||||
BUILD_FMT = {
|
||||
nwBuildFmt.ODT: QT_TRANSLATE_NOOP("Constant", "Open Document (.odt)"),
|
||||
nwBuildFmt.FODT: QT_TRANSLATE_NOOP("Constant", "Flat Open Document (.fodt)"),
|
||||
|
||||
@@ -36,7 +36,8 @@ from PyQt5.QtGui import QColor, QFont
|
||||
from novelwriter import CONFIG
|
||||
from novelwriter.common import checkInt, numberToRoman
|
||||
from novelwriter.constants import (
|
||||
nwHeadFmt, nwKeyWords, nwLabels, nwShortcode, nwStyles, nwUnicode, trConst
|
||||
nwHeadFmt, nwKeyWords, nwLabels, nwShortcode, nwStats, nwStyles, nwUnicode,
|
||||
trConst
|
||||
)
|
||||
from novelwriter.core.index import processComment
|
||||
from novelwriter.core.project import NWProject
|
||||
@@ -948,20 +949,20 @@ class Tokenizer(ABC):
|
||||
|
||||
def countStats(self) -> None:
|
||||
"""Count stats on the tokenized text."""
|
||||
titleCount = self._counts.get("titleCount", 0)
|
||||
paragraphCount = self._counts.get("paragraphCount", 0)
|
||||
titleCount = self._counts.get(nwStats.TITLES, 0)
|
||||
paragraphCount = self._counts.get(nwStats.PARAGRAPHS, 0)
|
||||
|
||||
allWords = self._counts.get("allWords", 0)
|
||||
textWords = self._counts.get("textWords", 0)
|
||||
titleWords = self._counts.get("titleWords", 0)
|
||||
allWords = self._counts.get(nwStats.WORDS_ALL, 0)
|
||||
textWords = self._counts.get(nwStats.WORDS_TEXT, 0)
|
||||
titleWords = self._counts.get(nwStats.WORDS_TITLE, 0)
|
||||
|
||||
allChars = self._counts.get("allChars", 0)
|
||||
textChars = self._counts.get("textChars", 0)
|
||||
titleChars = self._counts.get("titleChars", 0)
|
||||
allChars = self._counts.get(nwStats.CHARS_ALL, 0)
|
||||
textChars = self._counts.get(nwStats.CHARS_TEXT, 0)
|
||||
titleChars = self._counts.get(nwStats.CHARS_TITLE, 0)
|
||||
|
||||
allWordChars = self._counts.get("allWordChars", 0)
|
||||
textWordChars = self._counts.get("textWordChars", 0)
|
||||
titleWordChars = self._counts.get("titleWordChars", 0)
|
||||
allWordChars = self._counts.get(nwStats.WCHARS_ALL, 0)
|
||||
textWordChars = self._counts.get(nwStats.WCHARS_TEXT, 0)
|
||||
titleWordChars = self._counts.get(nwStats.WCHARS_TITLE, 0)
|
||||
|
||||
for tType, _, tText, _, _ in self._blocks:
|
||||
tText = tText.replace(nwUnicode.U_ENDASH, " ")
|
||||
@@ -1006,20 +1007,20 @@ class Tokenizer(ABC):
|
||||
allChars += len(tText)
|
||||
allWordChars += len("".join(words))
|
||||
|
||||
self._counts["titleCount"] = titleCount
|
||||
self._counts["paragraphCount"] = paragraphCount
|
||||
self._counts[nwStats.TITLES] = titleCount
|
||||
self._counts[nwStats.PARAGRAPHS] = paragraphCount
|
||||
|
||||
self._counts["allWords"] = allWords
|
||||
self._counts["textWords"] = textWords
|
||||
self._counts["titleWords"] = titleWords
|
||||
self._counts[nwStats.WORDS_ALL] = allWords
|
||||
self._counts[nwStats.WORDS_TEXT] = textWords
|
||||
self._counts[nwStats.WORDS_TITLE] = titleWords
|
||||
|
||||
self._counts["allChars"] = allChars
|
||||
self._counts["textChars"] = textChars
|
||||
self._counts["titleChars"] = titleChars
|
||||
self._counts[nwStats.CHARS_ALL] = allChars
|
||||
self._counts[nwStats.CHARS_TEXT] = textChars
|
||||
self._counts[nwStats.CHARS_TITLE] = titleChars
|
||||
|
||||
self._counts["allWordChars"] = allWordChars
|
||||
self._counts["textWordChars"] = textWordChars
|
||||
self._counts["titleWordChars"] = titleWordChars
|
||||
self._counts[nwStats.WCHARS_ALL] = allWordChars
|
||||
self._counts[nwStats.WCHARS_TEXT] = textWordChars
|
||||
self._counts[nwStats.WCHARS_TITLE] = titleWordChars
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -523,6 +523,7 @@ class TextBlockData(QTextBlockUserData):
|
||||
self._metaData.append((s, e, res.group(0), "url"))
|
||||
|
||||
self._text = text
|
||||
self._offset = offset
|
||||
|
||||
return
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ from PyQt5.QtWidgets import (
|
||||
|
||||
from novelwriter import CONFIG, SHARED
|
||||
from novelwriter.common import fuzzyTime
|
||||
from novelwriter.constants import nwLabels, nwStats, trConst
|
||||
from novelwriter.core.buildsettings import BuildCollection, BuildSettings
|
||||
from novelwriter.core.docbuild import NWBuildDocument
|
||||
from novelwriter.extensions.modified import NIconToggleButton, NIconToolButton, NToolDialog
|
||||
@@ -928,8 +929,7 @@ class _StatsWidget(QWidget):
|
||||
self.toggleButton = NIconToggleButton(self, SHARED.theme.baseIconSize, "unfold")
|
||||
self.toggleButton.toggled.connect(self._toggleView)
|
||||
|
||||
self._buildMinimal()
|
||||
self._buildMaximal()
|
||||
self._buildStatsPanel()
|
||||
|
||||
self.mainStack = QStackedWidget(self)
|
||||
self.mainStack.addWidget(self.minWidget)
|
||||
@@ -949,23 +949,23 @@ class _StatsWidget(QWidget):
|
||||
def updateStats(self, data: dict[str, int]) -> None:
|
||||
"""Update the stats values from a Tokenizer stats dict."""
|
||||
# Minimal
|
||||
self.minWordCount.setText("{0:n}".format(data.get("allWords", 0)))
|
||||
self.minCharCount.setText("{0:n}".format(data.get("allChars", 0)))
|
||||
self.minWordCount.setText("{0:n}".format(data.get(nwStats.WORDS_ALL, 0)))
|
||||
self.minCharCount.setText("{0:n}".format(data.get(nwStats.CHARS_ALL, 0)))
|
||||
|
||||
# Maximal
|
||||
self.maxTotalWords.setText("{0:n}".format(data.get("allWords", 0)))
|
||||
self.maxHeadWords.setText("{0:n}".format(data.get("titleWords", 0)))
|
||||
self.maxTextWords.setText("{0:n}".format(data.get("textWords", 0)))
|
||||
self.maxTitleCount.setText("{0:n}".format(data.get("titleCount", 0)))
|
||||
self.maxParCount.setText("{0:n}".format(data.get("paragraphCount", 0)))
|
||||
self.maxTotalWords.setText("{0:n}".format(data.get(nwStats.WORDS_ALL, 0)))
|
||||
self.maxHeadWords.setText("{0:n}".format(data.get(nwStats.WORDS_TITLE, 0)))
|
||||
self.maxTextWords.setText("{0:n}".format(data.get(nwStats.WORDS_TITLE, 0)))
|
||||
self.maxTitleCount.setText("{0:n}".format(data.get(nwStats.TITLES, 0)))
|
||||
self.maxParCount.setText("{0:n}".format(data.get(nwStats.PARAGRAPHS, 0)))
|
||||
|
||||
self.maxTotalChars.setText("{0:n}".format(data.get("allChars", 0)))
|
||||
self.maxHeaderChars.setText("{0:n}".format(data.get("titleChars", 0)))
|
||||
self.maxTextChars.setText("{0:n}".format(data.get("textChars", 0)))
|
||||
self.maxTotalChars.setText("{0:n}".format(data.get(nwStats.CHARS_ALL, 0)))
|
||||
self.maxHeaderChars.setText("{0:n}".format(data.get(nwStats.CHARS_TITLE, 0)))
|
||||
self.maxTextChars.setText("{0:n}".format(data.get(nwStats.CHARS_TEXT, 0)))
|
||||
|
||||
self.maxTotalWordChars.setText("{0:n}".format(data.get("allWordChars", 0)))
|
||||
self.maxHeadWordChars.setText("{0:n}".format(data.get("titleWordChars", 0)))
|
||||
self.maxTextWordChars.setText("{0:n}".format(data.get("textWordChars", 0)))
|
||||
self.maxTotalWordChars.setText("{0:n}".format(data.get(nwStats.WCHARS_ALL, 0)))
|
||||
self.maxHeadWordChars.setText("{0:n}".format(data.get(nwStats.WCHARS_TITLE, 0)))
|
||||
self.maxTextWordChars.setText("{0:n}".format(data.get(nwStats.WCHARS_TEXT, 0)))
|
||||
|
||||
return
|
||||
|
||||
@@ -994,37 +994,29 @@ class _StatsWidget(QWidget):
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
def _buildMinimal(self) -> None:
|
||||
def _buildStatsPanel(self) -> None:
|
||||
"""Build the minimal stats page."""
|
||||
mPx = CONFIG.pxInt(8)
|
||||
|
||||
self.lblWordCount = QLabel(self.tr("Words"), self)
|
||||
self.minWordCount = QLabel(self)
|
||||
|
||||
self.lblCharCount = QLabel(self.tr("Characters"), self)
|
||||
self.minCharCount = QLabel(self)
|
||||
|
||||
# Assemble
|
||||
self.minLayout = QHBoxLayout()
|
||||
self.minLayout.addWidget(self.lblWordCount)
|
||||
self.minLayout.addWidget(self.minWordCount)
|
||||
self.minLayout.addSpacing(mPx)
|
||||
self.minLayout.addWidget(self.lblCharCount)
|
||||
self.minLayout.addWidget(self.minCharCount)
|
||||
self.minLayout.addStretch(1)
|
||||
self.minLayout.setSpacing(mPx)
|
||||
self.minLayout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.minWidget.setLayout(self.minLayout)
|
||||
|
||||
return
|
||||
|
||||
def _buildMaximal(self) -> None:
|
||||
"""Build the maximal stats page."""
|
||||
hPx = CONFIG.pxInt(12)
|
||||
vPx = CONFIG.pxInt(4)
|
||||
|
||||
# Left Column
|
||||
trAllChars = trConst(nwLabels.STATS_NAME[nwStats.CHARS_ALL])
|
||||
trTextChars = trConst(nwLabels.STATS_NAME[nwStats.CHARS_TEXT])
|
||||
trTitleChars = trConst(nwLabels.STATS_NAME[nwStats.CHARS_TITLE])
|
||||
trParagraphCount = trConst(nwLabels.STATS_NAME[nwStats.PARAGRAPHS])
|
||||
trTitleCount = trConst(nwLabels.STATS_NAME[nwStats.TITLES])
|
||||
trAllWordChars = trConst(nwLabels.STATS_NAME[nwStats.WCHARS_ALL])
|
||||
trTextWordChars = trConst(nwLabels.STATS_NAME[nwStats.WCHARS_TEXT])
|
||||
trTitleWordChars = trConst(nwLabels.STATS_NAME[nwStats.WCHARS_TITLE])
|
||||
trAllWords = trConst(nwLabels.STATS_NAME[nwStats.WORDS_ALL])
|
||||
trTextWords = trConst(nwLabels.STATS_NAME[nwStats.WORDS_TEXT])
|
||||
trTitleWords = trConst(nwLabels.STATS_NAME[nwStats.WORDS_TITLE])
|
||||
|
||||
# Minimal Form
|
||||
self.minWordCount = QLabel(self)
|
||||
self.minCharCount = QLabel(self)
|
||||
|
||||
# Maximal Form, Left Column
|
||||
self.maxTotalWords = QLabel(self)
|
||||
self.maxHeadWords = QLabel(self)
|
||||
self.maxTextWords = QLabel(self)
|
||||
@@ -1038,20 +1030,19 @@ class _StatsWidget(QWidget):
|
||||
self.maxParCount.setAlignment(QtAlignRight)
|
||||
|
||||
self.leftForm = QFormLayout()
|
||||
self.leftForm.addRow(self.tr("Words"), self.maxTotalWords)
|
||||
self.leftForm.addRow(self.tr("Words in Headings"), self.maxHeadWords)
|
||||
self.leftForm.addRow(self.tr("Words in Text"), self.maxTextWords)
|
||||
self.leftForm.addRow(trAllWords, self.maxTotalWords)
|
||||
self.leftForm.addRow(trTitleWords, self.maxHeadWords)
|
||||
self.leftForm.addRow(trTextWords, self.maxTextWords)
|
||||
self.leftForm.addRow("", QLabel(self))
|
||||
self.leftForm.addRow(self.tr("Headings"), self.maxTitleCount)
|
||||
self.leftForm.addRow(self.tr("Paragraphs"), self.maxParCount)
|
||||
self.leftForm.addRow(trTitleCount, self.maxTitleCount)
|
||||
self.leftForm.addRow(trParagraphCount, self.maxParCount)
|
||||
self.leftForm.setHorizontalSpacing(hPx)
|
||||
self.leftForm.setVerticalSpacing(vPx)
|
||||
|
||||
# Right Column
|
||||
# Maximal Form, Right Column
|
||||
self.maxTotalChars = QLabel(self)
|
||||
self.maxHeaderChars = QLabel(self)
|
||||
self.maxTextChars = QLabel(self)
|
||||
|
||||
self.maxTotalWordChars = QLabel(self)
|
||||
self.maxHeadWordChars = QLabel(self)
|
||||
self.maxTextWordChars = QLabel(self)
|
||||
@@ -1059,22 +1050,31 @@ class _StatsWidget(QWidget):
|
||||
self.maxTotalChars.setAlignment(QtAlignRight)
|
||||
self.maxHeaderChars.setAlignment(QtAlignRight)
|
||||
self.maxTextChars.setAlignment(QtAlignRight)
|
||||
|
||||
self.maxTotalWordChars.setAlignment(QtAlignRight)
|
||||
self.maxHeadWordChars.setAlignment(QtAlignRight)
|
||||
self.maxTextWordChars.setAlignment(QtAlignRight)
|
||||
|
||||
self.rightForm = QFormLayout()
|
||||
self.rightForm.addRow(self.tr("Characters"), self.maxTotalChars)
|
||||
self.rightForm.addRow(self.tr("Characters in Headings"), self.maxHeaderChars)
|
||||
self.rightForm.addRow(self.tr("Characters in Text"), self.maxTextChars)
|
||||
self.rightForm.addRow(self.tr("Characters, No Spaces"), self.maxTotalWordChars)
|
||||
self.rightForm.addRow(self.tr("Characters in Headings, No Spaces"), self.maxHeadWordChars)
|
||||
self.rightForm.addRow(self.tr("Characters in Text, No Spaces"), self.maxTextWordChars)
|
||||
self.rightForm.addRow(trAllChars, self.maxTotalChars)
|
||||
self.rightForm.addRow(trTitleChars, self.maxHeaderChars)
|
||||
self.rightForm.addRow(trTextChars, self.maxTextChars)
|
||||
self.rightForm.addRow(trAllWordChars, self.maxTotalWordChars)
|
||||
self.rightForm.addRow(trTitleWordChars, self.maxHeadWordChars)
|
||||
self.rightForm.addRow(trTextWordChars, self.maxTextWordChars)
|
||||
self.rightForm.setHorizontalSpacing(hPx)
|
||||
self.rightForm.setVerticalSpacing(vPx)
|
||||
|
||||
# Assemble
|
||||
self.minLayout = QHBoxLayout()
|
||||
self.minLayout.addWidget(QLabel(trAllWords, self))
|
||||
self.minLayout.addWidget(self.minWordCount)
|
||||
self.minLayout.addSpacing(mPx)
|
||||
self.minLayout.addWidget(QLabel(trAllChars, self))
|
||||
self.minLayout.addWidget(self.minCharCount)
|
||||
self.minLayout.addStretch(1)
|
||||
self.minLayout.setSpacing(mPx)
|
||||
self.minLayout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.maxLayout = QHBoxLayout()
|
||||
self.maxLayout.addLayout(self.leftForm)
|
||||
self.maxLayout.addLayout(self.rightForm)
|
||||
@@ -1082,6 +1082,7 @@ class _StatsWidget(QWidget):
|
||||
self.maxLayout.setSpacing(CONFIG.pxInt(32))
|
||||
self.maxLayout.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.minWidget.setLayout(self.minLayout)
|
||||
self.maxWidget.setLayout(self.maxLayout)
|
||||
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user