Merge release 2.6 into main

This commit is contained in:
Veronica Berglyd Olsen
2025-01-26 20:50:58 +01:00
69 changed files with 2442 additions and 1751 deletions
+86 -16
View File
@@ -38,8 +38,8 @@ from tests.tools import DOCX_IGNORE, cmpFiles, xmlToText
@pytest.mark.core
def testFmtToDocX_HeadingStyles(mockGUI):
"""Test formatting of headings."""
def testFmtToDocX_NovelHeadingStyles(mockGUI):
"""Test formatting of novel headings."""
project = NWProject()
doc = ToDocX(project)
doc._isNovel = True
@@ -58,8 +58,8 @@ def testFmtToDocX_HeadingStyles(mockGUI):
'<w:r><w:rPr /><w:t>Hello World</w:t></w:r></w:p></w:body>'
)
# Heading Level 1
# ===============
# Partition
# =========
doc._text = "# Hello World"
# Plain
@@ -68,7 +68,7 @@ def testFmtToDocX_HeadingStyles(mockGUI):
doc.doConvert()
doc._pars[-1].toXml(xTest)
assert xmlToText(xTest) == (
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading1" /><w:jc w:val="center" /></w:pPr>'
'<w:body><w:p><w:pPr><w:pStyle w:val="Title" /><w:jc w:val="center" /></w:pPr>'
'<w:r><w:br w:type="page" /></w:r>'
'<w:r><w:rPr /><w:t>Hello World</w:t></w:r></w:p></w:body>'
)
@@ -80,13 +80,13 @@ def testFmtToDocX_HeadingStyles(mockGUI):
doc.doConvert()
doc._pars[-1].toXml(xTest)
assert xmlToText(xTest) == (
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading1" /><w:jc w:val="center" /></w:pPr>'
'<w:body><w:p><w:pPr><w:pStyle w:val="Title" /><w:jc w:val="center" /></w:pPr>'
'<w:r><w:br w:type="page" /></w:r>'
'<w:r><w:rPr /><w:t>Part</w:t><w:br /><w:t>Hello World</w:t></w:r></w:p></w:body>'
)
# Heading Level 2
# ===============
# Chapter
# =======
doc._text = "## Hello World"
# Plain
@@ -95,7 +95,7 @@ def testFmtToDocX_HeadingStyles(mockGUI):
doc.doConvert()
doc._pars[-1].toXml(xTest)
assert xmlToText(xTest) == (
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading2" /></w:pPr>'
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading1" /></w:pPr>'
'<w:r><w:br w:type="page" /></w:r>'
'<w:r><w:rPr /><w:t>Hello World</w:t></w:r></w:p></w:body>'
)
@@ -107,13 +107,13 @@ def testFmtToDocX_HeadingStyles(mockGUI):
doc.doConvert()
doc._pars[-1].toXml(xTest)
assert xmlToText(xTest) == (
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading2" /></w:pPr>'
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading1" /></w:pPr>'
'<w:r><w:br w:type="page" /></w:r>'
'<w:r><w:rPr /><w:t>Chapter 2</w:t><w:br /><w:t>Hello World</w:t></w:r></w:p></w:body>'
)
# Heading Level 3
# ===============
# Scene
# =====
doc._text = "### Hello World"
# Plain
@@ -122,7 +122,7 @@ def testFmtToDocX_HeadingStyles(mockGUI):
doc.doConvert()
doc._pars[-1].toXml(xTest)
assert xmlToText(xTest) == (
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading3" /></w:pPr><w:r><w:rPr />'
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading2" /></w:pPr><w:r><w:rPr />'
'<w:t>Hello World</w:t></w:r></w:p></w:body>'
)
@@ -133,14 +133,84 @@ def testFmtToDocX_HeadingStyles(mockGUI):
doc.doConvert()
doc._pars[-1].toXml(xTest)
assert xmlToText(xTest) == (
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading3" /></w:pPr>'
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading2" /></w:pPr>'
'<w:r><w:rPr /><w:t>Scene 2</w:t><w:br /><w:t>Hello World</w:t></w:r></w:p></w:body>'
)
# Heading Level 4
# ===============
# Section
# =======
doc._text = "#### Hello World"
xTest = ET.Element(_wTag("body"))
doc.tokenizeText()
doc.doConvert()
doc._pars[-1].toXml(xTest)
assert xmlToText(xTest) == (
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading3" /></w:pPr><w:r><w:rPr />'
'<w:t>Hello World</w:t></w:r></w:p></w:body>'
)
@pytest.mark.core
def testFmtToDocX_NotesHeadingStyles(mockGUI):
"""Test formatting of notes headings."""
project = NWProject()
doc = ToDocX(project)
doc._isNovel = False
doc.initDocument()
# Title
# =====
xTest = ET.Element(_wTag("body"))
doc._text = "#! Hello World"
doc.tokenizeText()
doc.doConvert()
doc._pars[-1].toXml(xTest)
assert xmlToText(xTest) == (
'<w:body><w:p><w:pPr><w:pStyle w:val="Title" /><w:jc w:val="center" /></w:pPr>'
'<w:r><w:rPr /><w:t>Hello World</w:t></w:r></w:p></w:body>'
)
# Heading 1
# =========
doc._text = "# Hello World"
xTest = ET.Element(_wTag("body"))
doc.tokenizeText()
doc.doConvert()
doc._pars[-1].toXml(xTest)
assert xmlToText(xTest) == (
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading1" /></w:pPr><w:r><w:rPr />'
'<w:t>Hello World</w:t></w:r></w:p></w:body>'
)
# Heading 2
# =========
doc._text = "## Hello World"
xTest = ET.Element(_wTag("body"))
doc.tokenizeText()
doc.doConvert()
doc._pars[-1].toXml(xTest)
assert xmlToText(xTest) == (
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading2" /></w:pPr><w:r><w:rPr />'
'<w:t>Hello World</w:t></w:r></w:p></w:body>'
)
# Heading 3
# =========
doc._text = "### Hello World"
xTest = ET.Element(_wTag("body"))
doc.tokenizeText()
doc.doConvert()
doc._pars[-1].toXml(xTest)
assert xmlToText(xTest) == (
'<w:body><w:p><w:pPr><w:pStyle w:val="Heading3" /></w:pPr><w:r><w:rPr />'
'<w:t>Hello World</w:t></w:r></w:p></w:body>'
)
# Heading 4
# =========
doc._text = "#### Hello World"
xTest = ET.Element(_wTag("body"))
doc.tokenizeText()
doc.doConvert()
+7 -9
View File
@@ -410,7 +410,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
# Unnumbered
html._blocks = [
(BlockTyp.HEAD2, tMeta, "Prologue", [], BlockFmt.PBB),
(BlockTyp.HEAD1, tMeta, "Prologue", [], BlockFmt.PBB),
]
html.doConvert()
assert html._pages[-1] == (
@@ -443,7 +443,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
# Align Left
html.setStyles(False)
html._blocks = [
(BlockTyp.HEAD1, tMeta, "A Title", [], BlockFmt.LEFT),
(BlockTyp.PART, tMeta, "A Title", [], BlockFmt.LEFT),
]
html.doConvert()
assert html._pages[-1] == (
@@ -454,7 +454,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
# Align Left
html._blocks = [
(BlockTyp.HEAD1, tMeta, "A Title", [], BlockFmt.LEFT),
(BlockTyp.PART, tMeta, "A Title", [], BlockFmt.LEFT),
]
html.doConvert()
assert html._pages[-1] == (
@@ -463,7 +463,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
# Align Right
html._blocks = [
(BlockTyp.HEAD1, tMeta, "A Title", [], BlockFmt.RIGHT),
(BlockTyp.PART, tMeta, "A Title", [], BlockFmt.RIGHT),
]
html.doConvert()
assert html._pages[-1] == (
@@ -472,7 +472,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
# Align Centre
html._blocks = [
(BlockTyp.HEAD1, tMeta, "A Title", [], BlockFmt.CENTRE),
(BlockTyp.PART, tMeta, "A Title", [], BlockFmt.CENTRE),
]
html.doConvert()
assert html._pages[-1] == (
@@ -481,7 +481,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
# Align Justify
html._blocks = [
(BlockTyp.HEAD1, tMeta, "A Title", [], BlockFmt.JUSTIFY),
(BlockTyp.PART, tMeta, "A Title", [], BlockFmt.JUSTIFY),
]
html.doConvert()
assert html._pages[-1] == (
@@ -493,7 +493,7 @@ def testFmtToHtml_ConvertDirect(mockGUI):
# Page Break Always
html._blocks = [
(BlockTyp.HEAD1, tMeta, "A Title", [], BlockFmt.PBB | BlockFmt.PBA),
(BlockTyp.PART, tMeta, "A Title", [], BlockFmt.PBB | BlockFmt.PBA),
]
html.doConvert()
assert html._pages[-1] == (
@@ -677,9 +677,7 @@ def testFmtToHtml_Save(mockGUI, fncPath):
"</style>\n"
"</head>\n"
"<body>\n"
"<article>\n"
"{bodyText:s}\n"
"</article>\n"
"</body>\n"
"</html>\n"
).format(
+103 -89
View File
@@ -291,7 +291,7 @@ def testFmtToken_HeaderFormat(mockGUI):
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "Novel Title", [], BlockFmt.CENTRE),
(BlockTyp.PART, TM1, "Novel Title", [], BlockFmt.CENTRE),
]
# Note File
@@ -313,7 +313,7 @@ def testFmtToken_HeaderFormat(mockGUI):
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD2, TM1, "Chapter One", [], BlockFmt.PBB),
(BlockTyp.HEAD1, TM1, "Chapter One", [], BlockFmt.PBB),
]
# Note File
@@ -334,7 +334,7 @@ def testFmtToken_HeaderFormat(mockGUI):
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD3, TM1, "Scene One", [], BlockFmt.NONE),
(BlockTyp.HEAD2, TM1, "Scene One", [], BlockFmt.NONE),
]
# Note File
@@ -355,7 +355,7 @@ def testFmtToken_HeaderFormat(mockGUI):
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD4, TM1, "A Section", [], BlockFmt.NONE),
(BlockTyp.HEAD3, TM1, "A Section", [], BlockFmt.NONE),
]
# Note File
@@ -399,7 +399,7 @@ def testFmtToken_HeaderFormat(mockGUI):
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD2, TM1, "Prologue", [], BlockFmt.PBB),
(BlockTyp.HEAD1, TM1, "Prologue", [], BlockFmt.PBB),
]
# Note File
@@ -1361,8 +1361,8 @@ def testFmtToken_SpecialFormat(mockGUI):
# ========
correctResp = [
(BlockTyp.HEAD1, TM1, "Title One", [], BlockFmt.CENTRE),
(BlockTyp.HEAD1, TM2, "Title Two", [], BlockFmt.CENTRE | BlockFmt.PBB),
(BlockTyp.PART, TM1, "Title One", [], BlockFmt.CENTRE),
(BlockTyp.PART, TM2, "Title Two", [], BlockFmt.CENTRE | BlockFmt.PBB),
]
# Command wo/Space
@@ -1405,9 +1405,9 @@ def testFmtToken_SpecialFormat(mockGUI):
)
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
(BlockTyp.PART, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
]
# Multiple Empty Paragraphs
@@ -1421,9 +1421,9 @@ def testFmtToken_SpecialFormat(mockGUI):
)
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
(BlockTyp.PART, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
]
# Three Skips
@@ -1434,11 +1434,11 @@ def testFmtToken_SpecialFormat(mockGUI):
)
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
(BlockTyp.PART, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
]
# Malformed Command, Case 1
@@ -1449,8 +1449,8 @@ def testFmtToken_SpecialFormat(mockGUI):
)
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
(BlockTyp.PART, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
]
# Malformed Command, Case 2
@@ -1461,8 +1461,8 @@ def testFmtToken_SpecialFormat(mockGUI):
)
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
(BlockTyp.PART, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
]
# Malformed Command, Case 3
@@ -1473,8 +1473,8 @@ def testFmtToken_SpecialFormat(mockGUI):
)
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
(BlockTyp.PART, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
]
# Empty Paragraph and Page Break
@@ -1489,9 +1489,9 @@ def testFmtToken_SpecialFormat(mockGUI):
)
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.SKIP, "", "", [], BlockFmt.PBB),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
(BlockTyp.PART, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.SKIP, "", "", [], BlockFmt.PBB),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
]
# Multiple Skip
@@ -1503,11 +1503,11 @@ def testFmtToken_SpecialFormat(mockGUI):
)
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.SKIP, "", "", [], BlockFmt.PBB),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
(BlockTyp.PART, TM1, "Title One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.SKIP, "", "", [], BlockFmt.PBB),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.SKIP, "", "", [], BlockFmt.NONE),
(BlockTyp.TEXT, "", "Some text to go here ...", [], BlockFmt.NONE),
]
@@ -1619,7 +1619,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
tokens.setPartitionFormat(f"T: {nwHeadFmt.TITLE}")
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "T: Part One", [], BlockFmt.CENTRE),
(BlockTyp.PART, TM1, "T: Part One", [], BlockFmt.CENTRE),
]
# H1: Title, Not First Page
@@ -1628,7 +1628,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
tokens.setPartitionFormat(f"T: {nwHeadFmt.TITLE}")
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD1, TM1, "T: Part One", [], BlockFmt.PBB | BlockFmt.CENTRE),
(BlockTyp.PART, TM1, "T: Part One", [], BlockFmt.PBB | BlockFmt.CENTRE),
]
# Chapters
@@ -1639,7 +1639,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
tokens.setChapterFormat(f"C: {nwHeadFmt.TITLE}")
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD2, TM1, "C: Chapter One", [], BlockFmt.PBB),
(BlockTyp.HEAD1, TM1, "C: Chapter One", [], BlockFmt.PBB),
]
# H2: Unnumbered Chapter
@@ -1647,7 +1647,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
tokens.setUnNumberedFormat(f"U: {nwHeadFmt.TITLE}")
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD2, TM1, "U: Prologue", [], BlockFmt.PBB),
(BlockTyp.HEAD1, TM1, "U: Prologue", [], BlockFmt.PBB),
]
# H2: Chapter Word Number
@@ -1656,7 +1656,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
tokens._hFormatter._chCount = 0
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD2, TM1, "Chapter One", [], BlockFmt.PBB),
(BlockTyp.HEAD1, TM1, "Chapter One", [], BlockFmt.PBB),
]
# H2: Chapter Roman Number Upper Case
@@ -1664,7 +1664,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
tokens.setChapterFormat(f"Chapter {nwHeadFmt.CH_ROMU}")
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD2, TM1, "Chapter II", [], BlockFmt.PBB),
(BlockTyp.HEAD1, TM1, "Chapter II", [], BlockFmt.PBB),
]
# H2: Chapter Roman Number Lower Case
@@ -1672,7 +1672,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
tokens.setChapterFormat(f"Chapter {nwHeadFmt.CH_ROML}")
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD2, TM1, "Chapter iii", [], BlockFmt.PBB),
(BlockTyp.HEAD1, TM1, "Chapter iii", [], BlockFmt.PBB),
]
# Scenes
@@ -1683,7 +1683,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
tokens.setSceneFormat(f"S: {nwHeadFmt.TITLE}", False)
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD3, TM1, "S: Scene One", [], BlockFmt.NONE),
(BlockTyp.HEAD2, TM1, "S: Scene One", [], BlockFmt.NONE),
]
# H3: Scene Hidden wo/Format
@@ -1731,7 +1731,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
tokens._hFormatter._scChCount = 0
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD3, TM1, "Scene 1", [], BlockFmt.NONE),
(BlockTyp.HEAD2, TM1, "Scene 1", [], BlockFmt.NONE),
]
# H3: Scene w/Chapter Number
@@ -1741,7 +1741,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
tokens._hFormatter._scChCount = 1
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD3, TM1, "Scene 3.2", [], BlockFmt.NONE),
(BlockTyp.HEAD2, TM1, "Scene 3.2", [], BlockFmt.NONE),
]
# Sections
@@ -1766,7 +1766,7 @@ def testFmtToken_ProcessHeaders(mockGUI):
tokens.setSectionFormat(f"X: {nwHeadFmt.TITLE}", False)
tokens.tokenizeText()
assert tokens._blocks == [
(BlockTyp.HEAD4, TM1, "X: A Section", [], BlockFmt.NONE),
(BlockTyp.HEAD3, TM1, "X: A Section", [], BlockFmt.NONE),
]
# H4: Section Separator
@@ -2143,11 +2143,13 @@ def testFmtToken_SceneSeparators(mockGUI):
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == (
"# T: Title One\n\n"
"T: Title One\n"
"============\n\n"
"Text\n\n"
"~\n\n"
"Text\n\n"
"# T: Title Two\n\n"
"T: Title Two\n"
"============\n\n"
"Text\n\n"
"* * *\n\n"
"Text\n\n"
@@ -2159,15 +2161,17 @@ def testFmtToken_SceneSeparators(mockGUI):
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == (
"# T: Title One\n\n"
"### S: Scene One\n\n"
"T: Title One\n"
"============\n\n"
"## S: Scene One\n\n"
"Text\n\n"
"### S: Scene Two\n\n"
"## S: Scene Two\n\n"
"Text\n\n"
"# T: Title Two\n\n"
"### S: Scene Three\n\n"
"T: Title Two\n"
"============\n\n"
"## S: Scene Three\n\n"
"Text\n\n"
"### H: Scene Four\n\n"
"## H: Scene Four\n\n"
"Text\n\n"
)
@@ -2197,12 +2201,13 @@ def testFmtToken_SceneSeparators(mockGUI):
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == (
"# T: Title One\n\n"
"## C: Chapter One\n\n"
"T: Title One\n"
"============\n\n"
"# C: Chapter One\n\n"
"Text\n\n"
"* * *\n\n"
"Text\n\n"
"## C: Chapter Two\n\n"
"# C: Chapter Two\n\n"
"Text\n\n"
"* * *\n\n"
"Text\n\n"
@@ -2214,16 +2219,17 @@ def testFmtToken_SceneSeparators(mockGUI):
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == (
"# T: Title One\n\n"
"## C: Chapter One\n\n"
"### S: Scene One\n\n"
"T: Title One\n"
"============\n\n"
"# C: Chapter One\n\n"
"## S: Scene One\n\n"
"Text\n\n"
"### S: Scene Two\n\n"
"## S: Scene Two\n\n"
"Text\n\n"
"## C: Chapter Two\n\n"
"### S: Scene Three\n\n"
"# C: Chapter Two\n\n"
"## S: Scene Three\n\n"
"Text\n\n"
"### H: Scene Four\n\n"
"## H: Scene Four\n\n"
"Text\n\n"
)
@@ -2287,6 +2293,7 @@ def testFmtToken_HeaderVisibility(mockGUI):
# Novel Files
# ===========
# Headers are promoted one level
md._isNovel = True
@@ -2301,20 +2308,22 @@ def testFmtToken_HeaderVisibility(mockGUI):
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == (
"# Novel\n\n"
"# Title One\n\n"
"## Prologue\n\n"
"Novel\n"
"=====\n\n"
"Title One\n"
"=========\n\n"
"# Prologue\n\n"
"Text\n\n"
"## Chapter One\n\n"
"### Scene One\n\n"
"# Chapter One\n\n"
"## Scene One\n\n"
"Text\n\n"
"### Scene Two\n\n"
"#### Section Two\n\n"
"## Scene Two\n\n"
"### Section Two\n\n"
"Text\n\n"
"## Chapter Two\n\n"
"### Scene Three\n\n"
"# Chapter Two\n\n"
"## Scene Three\n\n"
"Text\n\n"
"### Scene Four\n\n"
"## Scene Four\n\n"
"Text\n\n"
)
@@ -2329,7 +2338,8 @@ def testFmtToken_HeaderVisibility(mockGUI):
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == (
"# Novel\n\n"
"Novel\n"
"=====\n\n"
"Text\n\n"
"Text\n\n"
"Text\n\n"
@@ -2339,6 +2349,7 @@ def testFmtToken_HeaderVisibility(mockGUI):
# Note Files
# ==========
# Headers are exported as-is
md._isNovel = False
@@ -2353,7 +2364,8 @@ def testFmtToken_HeaderVisibility(mockGUI):
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == (
"# Novel\n\n"
"Novel\n"
"=====\n\n"
"# Title One\n\n"
"## Prologue\n\n"
"Text\n\n"
@@ -2427,31 +2439,33 @@ def testFmtToken_CounterHandling(mockGUI):
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == (
"# Novel One\n\n"
"## U: Prologue\n\n"
"Novel One\n"
"=========\n\n"
"# U: Prologue\n\n"
"Text\n\n"
"## C 1: Chapter One\n\n"
"### S 1.1 (1): Scene One\n\n"
"# C 1: Chapter One\n\n"
"## S 1.1 (1): Scene One\n\n"
"Text\n\n"
"### S 1.2 (2): Scene Two\n\n"
"## S 1.2 (2): Scene Two\n\n"
"Text\n\n"
"## C 2: Chapter Two\n\n"
"### S 2.1 (3): Scene Three\n\n"
"# C 2: Chapter Two\n\n"
"## S 2.1 (3): Scene Three\n\n"
"Text\n\n"
"### H 2.2 (4): Scene Four\n\n"
"## H 2.2 (4): Scene Four\n\n"
"Text\n\n"
"# Novel Two\n\n"
"## U: Prologue\n\n"
"Novel Two\n"
"=========\n\n"
"# U: Prologue\n\n"
"Text\n\n"
"## C 1: Chapter One\n\n"
"### S 1.1 (1): Scene One\n\n"
"# C 1: Chapter One\n\n"
"## S 1.1 (1): Scene One\n\n"
"Text\n\n"
"### S 1.2 (2): Scene Two\n\n"
"## S 1.2 (2): Scene Two\n\n"
"Text\n\n"
"## C 2: Chapter Two\n\n"
"### S 2.1 (3): Scene Three\n\n"
"# C 2: Chapter Two\n\n"
"## S 2.1 (3): Scene Three\n\n"
"Text\n\n"
"### H 2.2 (4): Scene Four\n\n"
"## H 2.2 (4): Scene Four\n\n"
"Text\n\n"
)
+16 -16
View File
@@ -42,39 +42,39 @@ def testFmtToMarkdown_ConvertHeaders(mockGUI):
md.setPartitionFormat(f"Part{nwHeadFmt.BR}{nwHeadFmt.TITLE}")
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == "# Part - Title\n\n"
assert md._pages[-1] == "Part - Title\n============\n\n"
# Header 2
md._text = "## Title\n"
md.setChapterFormat(f"Chapter {nwHeadFmt.CH_NUM}{nwHeadFmt.BR}{nwHeadFmt.TITLE}")
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == "## Chapter 1 - Title\n\n"
assert md._pages[-1] == "# Chapter 1 - Title\n\n"
# Header 3
md._text = "### Title\n"
md.setSceneFormat(f"Scene {nwHeadFmt.SC_ABS}{nwHeadFmt.BR}{nwHeadFmt.TITLE}")
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == "### Scene 1 - Title\n\n"
assert md._pages[-1] == "## Scene 1 - Title\n\n"
# Header 4
md._text = "#### Section Title\n"
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == "#### Section Title\n\n"
assert md._pages[-1] == "### Section Title\n\n"
# Title
md._text = "#! Title\n"
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == "# Title\n\n"
assert md._pages[-1] == "Title\n=====\n\n"
# Unnumbered
md._text = "##! Prologue\n"
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == "## Prologue\n\n"
assert md._pages[-1] == "# Prologue\n\n"
@pytest.mark.core
@@ -190,7 +190,7 @@ def testFmtToMarkdown_ConvertParagraphs(mockGUI):
md.tokenizeText()
md.doConvert()
assert md._pages[-1] == (
"## Chapter\n\n"
"# Chapter\n\n"
"**Point of View:** Bod \n"
"**Plot:** Main \n"
"**Locations:** Europe\n\n"
@@ -230,7 +230,7 @@ def testFmtToMarkdown_ConvertDirect(mockGUI):
(BlockTyp.TITLE, "", "A Title", [], BlockFmt.PBB | BlockFmt.CENTRE),
]
md.doConvert()
assert md._pages[-1] == "# A Title\n\n"
assert md._pages[-1] == "A Title\n=======\n\n"
# Separators
# ==========
@@ -270,13 +270,13 @@ def testFmtToMarkdown_Save(mockGUI, fncPath):
"#### A Section\n\n\tMore text in scene two.\n",
]
resText = [
"# My Novel\n\n**By Jane Doh**\n\n",
"## Chapter 1\n\nThe text of chapter one.\n\n",
"### Scene 1\n\nThe text of scene one.\n\n",
"#### A Section\n\nMore text in scene one.\n\n",
"## Chapter 2\n\nThe text of chapter two.\n\n",
"### Scene 2\n\nThe text of scene two.\n\n",
"#### A Section\n\n\tMore text in scene two.\n\n",
"My Novel\n========\n\n**By Jane Doh**\n\n",
"# Chapter 1\n\nThe text of chapter one.\n\n",
"## Scene 1\n\nThe text of scene one.\n\n",
"### A Section\n\nMore text in scene one.\n\n",
"# Chapter 2\n\nThe text of chapter two.\n\n",
"## Scene 2\n\nThe text of scene two.\n\n",
"### A Section\n\n\tMore text in scene two.\n\n",
]
for i in range(len(docText)):
@@ -289,7 +289,7 @@ def testFmtToMarkdown_Save(mockGUI, fncPath):
assert md.getFullResultSize() == len("".join(resText))
md.replaceTabs(nSpaces=4, spaceChar=" ")
resText[6] = "#### A Section\n\n More text in scene two.\n\n"
resText[6] = "### A Section\n\n More text in scene two.\n\n"
assert md._pages == resText
# Check File
+142 -68
View File
@@ -295,70 +295,12 @@ def testFmtToOdt_DialogueFormatting(mockGUI):
@pytest.mark.core
def testFmtToOdt_ConvertHeaders(mockGUI):
"""Test the converter of the ToOdt class."""
def testFmtToOdt_ConvertNovelHeadings(mockGUI):
"""Test the novel heading converter of the ToOdt class."""
project = NWProject()
odt = ToOdt(project, isFlat=True)
odt._isNovel = True
# Header 1
odt._text = "# Title\n"
odt.setPartitionFormat(f"Part{nwHeadFmt.BR}{nwHeadFmt.TITLE}")
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="P1" text:outline-level="1">Part'
'<text:line-break />Title</text:h>'
'</office:text>'
)
# Header 2
odt._text = "## Title\n"
odt.setChapterFormat(f"Chapter {nwHeadFmt.CH_NUM}{nwHeadFmt.BR}{nwHeadFmt.TITLE}")
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="P2" text:outline-level="2">Chapter 1'
'<text:line-break />Title</text:h>'
'</office:text>'
)
# Header 3
odt._text = "### Title\n"
odt.setSceneFormat(f"Scene {nwHeadFmt.SC_ABS}{nwHeadFmt.BR}{nwHeadFmt.TITLE}")
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_3" text:outline-level="3">Scene 1'
'<text:line-break />Title</text:h>'
'</office:text>'
)
# Header 4
odt._text = "#### Title\n"
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_4" text:outline-level="4">Title</text:h>'
'</office:text>'
)
# Title
odt._isFirst = True
odt._text = "#! Title\n"
@@ -373,7 +315,36 @@ def testFmtToOdt_ConvertHeaders(mockGUI):
'</office:text>'
)
# Unnumbered chapter
# Partition
odt._text = "# Title\n"
odt.setPartitionFormat(f"Part{nwHeadFmt.BR}{nwHeadFmt.TITLE}")
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:p text:style-name="P1">Part<text:line-break />Title</text:p>'
'</office:text>'
)
# Chapter
odt._text = "## Title\n"
odt.setChapterFormat(f"Chapter {nwHeadFmt.CH_NUM}{nwHeadFmt.BR}{nwHeadFmt.TITLE}")
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="P2" text:outline-level="1">Chapter 1'
'<text:line-break />Title</text:h>'
'</office:text>'
)
# Unnumbered Chapter
odt._text = "##! Prologue\n"
odt.tokenizeText()
odt.initDocument()
@@ -382,7 +353,110 @@ def testFmtToOdt_ConvertHeaders(mockGUI):
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="P2" text:outline-level="2">Prologue</text:h>'
'<text:h text:style-name="P2" text:outline-level="1">Prologue</text:h>'
'</office:text>'
)
# Scene
odt._text = "### Title\n"
odt.setSceneFormat(f"Scene {nwHeadFmt.SC_ABS}{nwHeadFmt.BR}{nwHeadFmt.TITLE}")
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_2" text:outline-level="2">Scene 1'
'<text:line-break />Title</text:h>'
'</office:text>'
)
# Alt. Scene
odt._text = "###! Title\n"
odt.setHardSceneFormat(f"Scene {nwHeadFmt.SC_ABS}{nwHeadFmt.BR}{nwHeadFmt.TITLE}")
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_2" text:outline-level="2">Scene 2'
'<text:line-break />Title</text:h>'
'</office:text>'
)
# Section
odt._text = "#### Title\n"
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_3" text:outline-level="3">Title</text:h>'
'</office:text>'
)
@pytest.mark.core
def testFmtToOdt_ConvertNotesHeadings(mockGUI):
"""Test the notes headings converter of the ToOdt class."""
project = NWProject()
odt = ToOdt(project, isFlat=True)
odt._isNovel = False
# Header 1
odt._text = "# Title\n"
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_1" text:outline-level="1">Title</text:h>'
'</office:text>'
)
# Header 2
odt._text = "## Title\n"
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_2" text:outline-level="2">Title</text:h>'
'</office:text>'
)
# Header 3
odt._text = "### Title\n"
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_3" text:outline-level="3">Title</text:h>'
'</office:text>'
)
# Header 4
odt._text = "#### Title\n"
odt.tokenizeText()
odt.initDocument()
odt.doConvert()
odt.closeDocument()
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_4" text:outline-level="4">Title</text:h>'
'</office:text>'
)
@@ -522,7 +596,7 @@ def testFmtToOdt_ConvertParagraphs(mockGUI):
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_3" text:outline-level="3">Scene</text:h>'
'<text:h text:style-name="Heading_20_2" text:outline-level="2">Scene</text:h>'
'<text:p text:style-name="Text_20_body">Hello World</text:p>'
'<text:p text:style-name="Text_20_body">Hello <text:s />World</text:p>'
'<text:p text:style-name="Text_20_body">Hello <text:s text:c="2" />World</text:p>'
@@ -547,7 +621,7 @@ def testFmtToOdt_ConvertParagraphs(mockGUI):
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_3" text:outline-level="3">Scene</text:h>'
'<text:h text:style-name="Heading_20_2" text:outline-level="2">Scene</text:h>'
'<text:p text:style-name="Text_20_Meta"><text:span text:style-name="T10">'
'Point of View:</text:span> <text:span text:style-name="T11">Jane</text:span></text:p>'
'<text:p text:style-name="Text_20_Meta"><text:span text:style-name="T12">'
@@ -617,7 +691,7 @@ def testFmtToOdt_ConvertParagraphs(mockGUI):
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_3" text:outline-level="3">Scene</text:h>'
'<text:h text:style-name="Heading_20_2" text:outline-level="2">Scene</text:h>'
'<text:p text:style-name="P1"><text:span text:style-name="T10">'
'Point of View:</text:span> <text:span text:style-name="T11">Jane</text:span></text:p>'
'<text:p text:style-name="P2"><text:span text:style-name="T10">'
@@ -655,7 +729,7 @@ def testFmtToOdt_ConvertParagraphs(mockGUI):
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="Heading_20_3" text:outline-level="3">Scene</text:h>'
'<text:h text:style-name="Heading_20_2" text:outline-level="2">Scene</text:h>'
'<text:p text:style-name="P7">Regular paragraph</text:p>'
'<text:p text:style-name="Text_20_body">with<text:line-break />break</text:p>'
'<text:p text:style-name="Text_20_body">Left Align</text:p>'
@@ -677,9 +751,9 @@ def testFmtToOdt_ConvertParagraphs(mockGUI):
assert odt.errData == []
assert xmlToText(odt._xText) == (
'<office:text>'
'<text:h text:style-name="P8" text:outline-level="2">Chapter One</text:h>'
'<text:h text:style-name="P8" text:outline-level="1">Chapter One</text:h>'
'<text:p text:style-name="Text_20_body">Text</text:p>'
'<text:h text:style-name="P8" text:outline-level="2">Chapter Two</text:h>'
'<text:h text:style-name="P8" text:outline-level="1">Chapter Two</text:h>'
'<text:p text:style-name="Text_20_body">Text</text:p>'
'</office:text>'
)
+17 -17
View File
@@ -79,6 +79,17 @@ def testFmtToQTextDocument_ConvertHeaders(mockGUI):
block = doc.document.findBlockByNumber(1)
assert block.text() == "Partition"
bFmt = block.blockFormat()
assert bFmt.topMargin() == doc._mHead[BlockTyp.PART][0]
assert bFmt.bottomMargin() == doc._mHead[BlockTyp.PART][1]
cFmt = charFmtInBlock(block, 1)
assert cFmt.fontWeight() == QFont.Weight.Bold
assert cFmt.fontPointSize() == doc._sHead[BlockTyp.PART]
assert cFmt.foreground().color() == THEME.head
# Chapter
block = doc.document.findBlockByNumber(2)
assert block.text() == "Chapter"
bFmt = block.blockFormat()
assert bFmt.topMargin() == doc._mHead[BlockTyp.HEAD1][0]
assert bFmt.bottomMargin() == doc._mHead[BlockTyp.HEAD1][1]
cFmt = charFmtInBlock(block, 1)
@@ -86,9 +97,9 @@ def testFmtToQTextDocument_ConvertHeaders(mockGUI):
assert cFmt.fontPointSize() == doc._sHead[BlockTyp.HEAD1]
assert cFmt.foreground().color() == THEME.head
# Chapter
block = doc.document.findBlockByNumber(2)
assert block.text() == "Chapter"
# Scene
block = doc.document.findBlockByNumber(3)
assert block.text() == "Scene"
bFmt = block.blockFormat()
assert bFmt.topMargin() == doc._mHead[BlockTyp.HEAD2][0]
assert bFmt.bottomMargin() == doc._mHead[BlockTyp.HEAD2][1]
@@ -97,9 +108,9 @@ def testFmtToQTextDocument_ConvertHeaders(mockGUI):
assert cFmt.fontPointSize() == doc._sHead[BlockTyp.HEAD2]
assert cFmt.foreground().color() == THEME.head
# Scene
block = doc.document.findBlockByNumber(3)
assert block.text() == "Scene"
# Section
block = doc.document.findBlockByNumber(4)
assert block.text() == "Section"
bFmt = block.blockFormat()
assert bFmt.topMargin() == doc._mHead[BlockTyp.HEAD3][0]
assert bFmt.bottomMargin() == doc._mHead[BlockTyp.HEAD3][1]
@@ -108,17 +119,6 @@ def testFmtToQTextDocument_ConvertHeaders(mockGUI):
assert cFmt.fontPointSize() == doc._sHead[BlockTyp.HEAD3]
assert cFmt.foreground().color() == THEME.head
# Section
block = doc.document.findBlockByNumber(4)
assert block.text() == "Section"
bFmt = block.blockFormat()
assert bFmt.topMargin() == doc._mHead[BlockTyp.HEAD4][0]
assert bFmt.bottomMargin() == doc._mHead[BlockTyp.HEAD4][1]
cFmt = charFmtInBlock(block, 1)
assert cFmt.fontWeight() == QFont.Weight.Bold
assert cFmt.fontPointSize() == doc._sHead[BlockTyp.HEAD4]
assert cFmt.foreground().color() == THEME.head
@pytest.mark.core
def testFmtToQTextDocument_SeparatorSkip(mockGUI):