diff --git a/docs/source/export.rst b/docs/source/export.rst
index 91cfb5d6..8dd24631 100644
--- a/docs/source/export.rst
+++ b/docs/source/export.rst
@@ -14,6 +14,7 @@ This is done through a series of keyword–replace steps.
The keyword ``%title%`` will always be replaced by the text you put after the ``#`` characters in your document.
The keywords ``%ch%`` and ``%chw%`` is replaced by a number, or a number word, respectively.
+You can also use ``%chi%`` or ``%chI%`` for lower and upper case Roman numbers.
The number is incremented by one each time the build tool sees a new heading of level two in a file with layout "Chapter".
If the file has layout "Unnumbered", the counter is *not* incremented.
The latter is useful for for instance Prologue and Epilogue chapters.
diff --git a/nw/core/__init__.py b/nw/core/__init__.py
index 0107dac2..91616302 100644
--- a/nw/core/__init__.py
+++ b/nw/core/__init__.py
@@ -3,13 +3,10 @@
from nw.core.document import NWDoc
from nw.core.index import NWIndex
from nw.core.project import NWProject
-from nw.core.spellcheck import NWSpellCheck
-from nw.core.spellcheck import NWSpellEnchant
-from nw.core.spellcheck import NWSpellSimple
+from nw.core.spellcheck import NWSpellCheck, NWSpellEnchant, NWSpellSimple
from nw.core.tokenizer import Tokenizer
from nw.core.tohtml import ToHtml
-from nw.core.tools import countWords
-from nw.core.tools import numberToWord
+from nw.core.tools import countWords, numberToRoman, numberToWord
__all__ = [
"NWDoc",
@@ -21,5 +18,6 @@ __all__ = [
"Tokenizer",
"ToHtml",
"countWords",
+ "numberToRoman",
"numberToWord",
]
diff --git a/nw/core/tokenizer.py b/nw/core/tokenizer.py
index eba1ab65..cddce253 100644
--- a/nw/core/tokenizer.py
+++ b/nw/core/tokenizer.py
@@ -33,7 +33,7 @@ from operator import itemgetter
from PyQt5.QtCore import QRegularExpression
from nw.core.document import NWDoc
-from nw.core.tools import numberToWord
+from nw.core.tools import numberToWord, numberToRoman
from nw.constants import nwItemLayout, nwItemType, nwRegEx
logger = logging.getLogger(__name__)
@@ -690,6 +690,10 @@ class Tokenizer():
theTitle = theTitle.replace(r"%sca%", str(self.numAbsScene))
if r"%chw%" in theTitle:
theTitle = theTitle.replace(r"%chw%", numberToWord(self.numChapter,"en"))
+ if r"%chi%" in theTitle:
+ theTitle = theTitle.replace(r"%chi%", numberToRoman(self.numChapter, True))
+ if r"%chI%" in theTitle:
+ theTitle = theTitle.replace(r"%chI%", numberToRoman(self.numChapter, False))
return theTitle
# END Class Tokenizer
diff --git a/nw/core/tools.py b/nw/core/tools.py
index 5c352fe7..c4455ff1 100644
--- a/nw/core/tools.py
+++ b/nw/core/tools.py
@@ -34,9 +34,9 @@ from os import path, unlink, rmdir
logger = logging.getLogger(__name__)
-# =========================================================================== #
+# =============================================================================================== #
# Simple Word Counter
-# =========================================================================== #
+# =============================================================================================== #
def countWords(theText):
"""Count words in a piece of text, skipping special syntax and
@@ -84,9 +84,34 @@ def countWords(theText):
return charCount, wordCount, paraCount
-# =========================================================================== #
+# =============================================================================================== #
+# Convert an Integer to a Roman Number
+# =============================================================================================== #
+
+def numberToRoman(numVal, isLower=False):
+ """Convert an integer to a roman number.
+ """
+ if numVal < 1 or numVal > 4999:
+ return "NAN"
+
+ 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:
+ for _ in range(numVal//theDiv):
+ romNum += theSym
+ numVal -= theDiv
+ if numVal <= 0:
+ break
+
+ return romNum.lower if isLower else romNum
+
+# =============================================================================================== #
# Convert an Integer to a Word Number
-# =========================================================================== #
+# =============================================================================================== #
def numberToWord(numVal, theLanguage):
"""Wrapper for converting numbers to words for chapter headings.
diff --git a/nw/gui/build.py b/nw/gui/build.py
index dab7360e..7220639b 100644
--- a/nw/gui/build.py
+++ b/nw/gui/build.py
@@ -46,7 +46,7 @@ from PyQt5.QtWidgets import (
from nw.common import fuzzyTime
from nw.gui.custom import QSwitch
-from nw.core import ToHtml
+from nw.core import ToHtml, numberToRoman
from nw.constants import (
nwAlert, nwFiles, nwItemType, nwItemLayout, nwItemClass
)
@@ -105,6 +105,8 @@ class GuiBuildNovel(QDialog):
r"%title% for the title as set in the document
"
r"%ch% for chapter number (1, 2, 3)
"
r"%chw% for chapter number as a word (one, two)
"
+ r"%chI% for chapter number in upper case Roman
"
+ r"%chi% for chapter number in lower case Roman
"
r"%sc% for scene number within chapter
"
r"%sca% for scene number within novel"
)