Add POV or Focus char field to manuscript header format
This commit is contained in:
@@ -300,16 +300,21 @@ class nwLabels:
|
||||
|
||||
class nwHeadFmt:
|
||||
|
||||
BR = "{BR}"
|
||||
TITLE = "{Title}"
|
||||
CH_NUM = "{Chapter}"
|
||||
CH_WORD = "{Chapter:Word}"
|
||||
CH_ROMU = "{Chapter:URoman}"
|
||||
CH_ROML = "{Chapter:LRoman}"
|
||||
SC_NUM = "{Scene}"
|
||||
SC_ABS = "{Scene:Abs}"
|
||||
BR = "{BR}"
|
||||
TITLE = "{Title}"
|
||||
CH_NUM = "{Chapter}"
|
||||
CH_WORD = "{Chapter:Word}"
|
||||
CH_ROMU = "{Chapter:URoman}"
|
||||
CH_ROML = "{Chapter:LRoman}"
|
||||
SC_NUM = "{Scene}"
|
||||
SC_ABS = "{Scene:Abs}"
|
||||
CHAR_POV = "{Char:POV}"
|
||||
CHAR_FOCUS = "{Char:Focus}"
|
||||
|
||||
PAGE_HEADERS = [TITLE, CH_NUM, CH_WORD, CH_ROMU, CH_ROML, SC_NUM, SC_ABS]
|
||||
PAGE_HEADERS = [
|
||||
TITLE, CH_NUM, CH_WORD, CH_ROMU, CH_ROML, SC_NUM, SC_ABS,
|
||||
CHAR_POV, CHAR_FOCUS
|
||||
]
|
||||
|
||||
# ODT Document Page Header
|
||||
ODT_PROJECT = "{Project}"
|
||||
|
||||
@@ -37,7 +37,9 @@ from PyQt5.QtCore import QCoreApplication, QRegularExpression
|
||||
|
||||
from novelwriter.enum import nwComment, nwItemLayout
|
||||
from novelwriter.common import formatTimeStamp, numberToRoman, checkInt
|
||||
from novelwriter.constants import nwHeadFmt, nwRegEx, nwShortcode, nwUnicode
|
||||
from novelwriter.constants import (
|
||||
nwHeadFmt, nwKeyWords, nwLabels, nwRegEx, nwShortcode, nwUnicode, trConst
|
||||
)
|
||||
from novelwriter.core.index import processComment
|
||||
from novelwriter.core.project import NWProject
|
||||
|
||||
@@ -112,13 +114,15 @@ class Tokenizer(ABC):
|
||||
|
||||
# Data Variables
|
||||
self._text = "" # The raw text to be tokenized
|
||||
self._nwItem = None # The NWItem associated with the handle
|
||||
self._tokens = [] # The list of the processed tokens
|
||||
self._nwItem = None # The NWItem currently being processed
|
||||
self._result = "" # The result of the last document
|
||||
|
||||
self._keepMarkdown = False # Whether to keep the markdown text
|
||||
self._allMarkdown = [] # The result novelWriter markdown of all documents
|
||||
|
||||
# Processed Tokens
|
||||
self._tokens: list[tuple[int, int, str, list[tuple[int, int]] | None, int]] = []
|
||||
|
||||
# User Settings
|
||||
self._textFont = "Serif" # Output text font
|
||||
self._textSize = 11 # Output text size
|
||||
@@ -655,6 +659,8 @@ class Tokenizer(ABC):
|
||||
if not self._isNovel:
|
||||
return False
|
||||
|
||||
self._hFormatter.setHandle(self._nwItem.itemHandle if self._nwItem else None)
|
||||
|
||||
for n, tToken in enumerate(self._tokens):
|
||||
|
||||
# In case we see text before a scene, we reset the flag
|
||||
@@ -664,7 +670,7 @@ class Tokenizer(ABC):
|
||||
elif tToken[0] == self.T_HEAD1:
|
||||
# Partition
|
||||
|
||||
tTemp = self._hFormatter.apply(self._fmtTitle, tToken[2])
|
||||
tTemp = self._hFormatter.apply(self._fmtTitle, tToken[2], tToken[1])
|
||||
self._tokens[n] = (
|
||||
tToken[0], tToken[1], tTemp, None, tToken[4]
|
||||
)
|
||||
@@ -674,10 +680,10 @@ class Tokenizer(ABC):
|
||||
|
||||
# Numbered or Unnumbered
|
||||
if tToken[0] == self.T_UNNUM:
|
||||
tTemp = self._hFormatter.apply(self._fmtUnNum, tToken[2])
|
||||
tTemp = self._hFormatter.apply(self._fmtUnNum, tToken[2], tToken[1])
|
||||
else:
|
||||
self._hFormatter.incChapter()
|
||||
tTemp = self._hFormatter.apply(self._fmtChapter, tToken[2])
|
||||
tTemp = self._hFormatter.apply(self._fmtChapter, tToken[2], tToken[1])
|
||||
|
||||
# Format the chapter header
|
||||
self._tokens[n] = (
|
||||
@@ -693,7 +699,7 @@ class Tokenizer(ABC):
|
||||
|
||||
self._hFormatter.incScene()
|
||||
|
||||
tTemp = self._hFormatter.apply(self._fmtScene, tToken[2])
|
||||
tTemp = self._hFormatter.apply(self._fmtScene, tToken[2], tToken[1])
|
||||
if tTemp == "" and self._hideScene:
|
||||
self._tokens[n] = (
|
||||
self.T_EMPTY, tToken[1], "", None, self.A_NONE
|
||||
@@ -726,7 +732,7 @@ class Tokenizer(ABC):
|
||||
elif tToken[0] == self.T_HEAD4:
|
||||
# Section
|
||||
|
||||
tTemp = self._hFormatter.apply(self._fmtSection, tToken[2])
|
||||
tTemp = self._hFormatter.apply(self._fmtSection, tToken[2], tToken[1])
|
||||
if tTemp == "" and self._hideSection:
|
||||
self._tokens[n] = (
|
||||
self.T_EMPTY, tToken[1], "", None, self.A_NONE
|
||||
@@ -817,11 +823,17 @@ class HeadingFormatter:
|
||||
|
||||
def __init__(self, project: NWProject) -> None:
|
||||
self._project = project
|
||||
self._handle = None
|
||||
self._chCount = 0
|
||||
self._scChCount = 0
|
||||
self._scAbsCount = 0
|
||||
return
|
||||
|
||||
def setHandle(self, tHandle: str | None) -> None:
|
||||
"""Set the handle currently being processed."""
|
||||
self._handle = tHandle
|
||||
return
|
||||
|
||||
def incChapter(self) -> None:
|
||||
"""Increment the chapter counter."""
|
||||
self._chCount += 1
|
||||
@@ -838,7 +850,7 @@ class HeadingFormatter:
|
||||
self._scChCount = 0
|
||||
return
|
||||
|
||||
def apply(self, hFormat: str, text: str) -> str:
|
||||
def apply(self, hFormat: str, text: str, nHead: int) -> str:
|
||||
"""Apply formatting to a specific heading."""
|
||||
hFormat = hFormat.replace(nwHeadFmt.TITLE, text)
|
||||
hFormat = hFormat.replace(nwHeadFmt.CH_NUM, str(self._chCount))
|
||||
@@ -854,6 +866,19 @@ class HeadingFormatter:
|
||||
chRom = numberToRoman(self._chCount, toLower=False)
|
||||
hFormat = hFormat.replace(nwHeadFmt.CH_ROMU, chRom)
|
||||
|
||||
if nwHeadFmt.CHAR_POV in hFormat or nwHeadFmt.CHAR_FOCUS in hFormat:
|
||||
if self._handle and nHead > 0:
|
||||
refs = self._project.index.getReferences(self._handle, f"T{nHead:04d}")
|
||||
povData = refs[nwKeyWords.POV_KEY]
|
||||
focData = refs[nwKeyWords.FOCUS_KEY]
|
||||
povText = povData[0] if povData else nwUnicode.U_ENDASH
|
||||
focText = focData[0] if focData else nwUnicode.U_ENDASH
|
||||
else:
|
||||
povText = trConst(nwLabels.KEY_NAME[nwKeyWords.POV_KEY])
|
||||
focText = trConst(nwLabels.KEY_NAME[nwKeyWords.FOCUS_KEY])
|
||||
hFormat = hFormat.replace(nwHeadFmt.CHAR_POV, povText)
|
||||
hFormat = hFormat.replace(nwHeadFmt.CHAR_FOCUS, focText)
|
||||
|
||||
return hFormat
|
||||
|
||||
# END Class HeadingFormatter
|
||||
|
||||
@@ -604,7 +604,7 @@ class _DetailsWidget(QWidget):
|
||||
for key in entries:
|
||||
sub = QTreeWidgetItem()
|
||||
sub.setText(0, build.getLabel(key))
|
||||
sub.setText(1, hFmt.apply(build.getStr(key), title))
|
||||
sub.setText(1, hFmt.apply(build.getStr(key), title, 0))
|
||||
item.addChild(sub)
|
||||
for key in ["headings.hideScene", "headings.hideSection"]:
|
||||
sub = QTreeWidgetItem()
|
||||
|
||||
@@ -722,6 +722,8 @@ class _HeadingsTab(NScrollablePage):
|
||||
self.aInsChRomL = self.menuInsert.addAction(self.tr("Chapter Number (Lower Case Roman)"))
|
||||
self.aInsScNum = self.menuInsert.addAction(self.tr("Scene Number (In Chapter)"))
|
||||
self.aInsScAbs = self.menuInsert.addAction(self.tr("Scene Number (Absolute)"))
|
||||
self.aInsCharPOV = self.menuInsert.addAction(self.tr("Point of View Character"))
|
||||
self.aInsCharFocus = self.menuInsert.addAction(self.tr("Focus Character"))
|
||||
|
||||
self.aInsTitle.triggered.connect(lambda: self._insertIntoForm(nwHeadFmt.TITLE))
|
||||
self.aInsChNum.triggered.connect(lambda: self._insertIntoForm(nwHeadFmt.CH_NUM))
|
||||
@@ -730,6 +732,8 @@ class _HeadingsTab(NScrollablePage):
|
||||
self.aInsChRomL.triggered.connect(lambda: self._insertIntoForm(nwHeadFmt.CH_ROML))
|
||||
self.aInsScNum.triggered.connect(lambda: self._insertIntoForm(nwHeadFmt.SC_NUM))
|
||||
self.aInsScAbs.triggered.connect(lambda: self._insertIntoForm(nwHeadFmt.SC_ABS))
|
||||
self.aInsCharPOV.triggered.connect(lambda: self._insertIntoForm(nwHeadFmt.CHAR_POV))
|
||||
self.aInsCharFocus.triggered.connect(lambda: self._insertIntoForm(nwHeadFmt.CHAR_FOCUS))
|
||||
|
||||
self.btnInsert = QPushButton(self.tr("Insert"))
|
||||
self.btnInsert.setMenu(self.menuInsert)
|
||||
|
||||
Reference in New Issue
Block a user