From 13e6199af2ecda6069b2b8ec7c297f53c5366a2b Mon Sep 17 00:00:00 2001 From: Veronica Berglyd Olsen <1619840+vkbo@users.noreply.github.com> Date: Sat, 25 Jan 2025 14:58:06 +0100 Subject: [PATCH] Separate ordinary headers and novel headers in the Tokenizer --- novelwriter/formats/shared.py | 26 ++-- novelwriter/formats/tokenizer.py | 39 +++--- novelwriter/formats/tomarkdown.py | 10 +- tests/test_formats/test_fmt_tokenizer.py | 156 +++++++++++----------- tests/test_formats/test_fmt_tomarkdown.py | 24 ++-- 5 files changed, 129 insertions(+), 126 deletions(-) diff --git a/novelwriter/formats/shared.py b/novelwriter/formats/shared.py index b1c0f288..12c65020 100644 --- a/novelwriter/formats/shared.py +++ b/novelwriter/formats/shared.py @@ -104,17 +104,21 @@ class BlockTyp(IntEnum): EMPTY = 1 # Empty line (new paragraph) TITLE = 2 # Title - HEAD1 = 3 # Heading 1 - HEAD2 = 4 # Heading 2 - HEAD3 = 5 # Heading 3 - HEAD4 = 6 # Heading 4 - TEXT = 7 # Text line - SEP = 8 # Scene separator - SKIP = 9 # Paragraph break - SUMMARY = 10 # Synopsis/short comment - NOTE = 11 # Note - COMMENT = 12 # Comment - KEYWORD = 13 # Tag/reference keywords + PART = 3 # Partition + CHAPTER = 4 # Chapter + SCENE = 5 # Scene + SECTION = 6 # Section + HEAD1 = 7 # Heading 1 + HEAD2 = 8 # Heading 2 + HEAD3 = 9 # Heading 3 + HEAD4 = 10 # Heading 4 + TEXT = 11 # Text line + SEP = 12 # Scene separator + SKIP = 13 # Paragraph break + SUMMARY = 14 # Synopsis/short comment + NOTE = 15 # Note + COMMENT = 16 # Comment + KEYWORD = 17 # Tag/reference keywords class BlockFmt(Flag): diff --git a/novelwriter/formats/tokenizer.py b/novelwriter/formats/tokenizer.py index 70d1de0c..19839096 100644 --- a/novelwriter/formats/tokenizer.py +++ b/novelwriter/formats/tokenizer.py @@ -68,11 +68,20 @@ COMMENT_STYLE = { nwComment.COMMENT: ComStyle(), nwComment.STORY: ComStyle("", "modifier", "note"), } -HEADINGS = [BlockTyp.TITLE, BlockTyp.HEAD1, BlockTyp.HEAD2, BlockTyp.HEAD3, BlockTyp.HEAD4] -SKIP_INDENT = [ - BlockTyp.TITLE, BlockTyp.HEAD1, BlockTyp.HEAD2, BlockTyp.HEAD2, BlockTyp.HEAD3, - BlockTyp.HEAD4, BlockTyp.SEP, BlockTyp.SKIP, +OUTLINE_CODE = { + BlockTyp.TITLE: "TT", + BlockTyp.PART: "PT", + BlockTyp.CHAPTER: "CH", + BlockTyp.SCENE: "SC", + BlockTyp.HEAD1: "H1", + BlockTyp.HEAD2: "H2", + BlockTyp.HEAD3: "H3", +} +HEADINGS = [ + BlockTyp.TITLE, BlockTyp.PART, BlockTyp.CHAPTER, BlockTyp.SCENE, BlockTyp.SECTION, + BlockTyp.HEAD1, BlockTyp.HEAD2, BlockTyp.HEAD3, BlockTyp.HEAD4, ] +SKIP_INDENT = HEADINGS + [BlockTyp.SEP, BlockTyp.SKIP] B_EMPTY: T_Block = (BlockTyp.EMPTY, "", "", [], BlockFmt.NONE) @@ -654,6 +663,7 @@ class Tokenizer(ABC): if not (isPlain or isNovel and sHide): tStyle |= self._titleStyle if isNovel: + tType = BlockTyp.PART if isPlain else BlockTyp.TITLE if sHide: tText = "" tType = BlockTyp.EMPTY @@ -687,6 +697,7 @@ class Tokenizer(ABC): sHide = self._hideChapter if isPlain else self._hideUnNum tFormat = self._fmtChapter if isPlain else self._fmtUnNum if isNovel: + tType = BlockTyp.CHAPTER if isPlain: self._hFormatter.incChapter() if sHide: @@ -721,6 +732,7 @@ class Tokenizer(ABC): sHide = self._hideScene if isPlain else self._hideHScene tFormat = self._fmtScene if isPlain else self._fmtHScene if isNovel: + tType = BlockTyp.SCENE self._hFormatter.incScene() if sHide: tText = "" @@ -752,6 +764,7 @@ class Tokenizer(ABC): tText = aLine[5:].strip() tType = BlockTyp.HEAD4 if isNovel: + tType = BlockTyp.SECTION if self._hideSection: tText = "" tType = BlockTyp.EMPTY @@ -923,22 +936,10 @@ class Tokenizer(ABC): def buildOutline(self) -> None: """Build an outline of the text up to level 3 headings.""" - isNovel = self._isNovel for tType, tKey, tText, _, _ in self._blocks: - if tType == BlockTyp.TITLE: - prefix = "TT" - elif tType == BlockTyp.HEAD1: - prefix = "PT" if isNovel else "H1" - elif tType == BlockTyp.HEAD2: - prefix = "CH" if isNovel else "H2" - elif tType == BlockTyp.HEAD3: - prefix = "SC" if isNovel else "H3" - else: - continue - - text = tText.replace(nwHeadFmt.BR, " ").replace("&", "&") - self._outline[tKey] = f"{prefix}|{text}" - + if prefix := OUTLINE_CODE.get(tType): + text = tText.replace(nwHeadFmt.BR, " ").replace("&", "&") + self._outline[tKey] = f"{prefix}|{text}" return def countStats(self) -> None: diff --git a/novelwriter/formats/tomarkdown.py b/novelwriter/formats/tomarkdown.py index 85622025..0fe28fc6 100644 --- a/novelwriter/formats/tomarkdown.py +++ b/novelwriter/formats/tomarkdown.py @@ -113,19 +113,15 @@ class ToMarkdown(Tokenizer): tTemp = self._formatText(tText, tFormat, mTags).replace("\n", " \n") lines.append(f"{tTemp}\n\n") - elif tType == BlockTyp.TITLE: + elif tType in (BlockTyp.TITLE, BlockTyp.HEAD1, BlockTyp.PART, BlockTyp.CHAPTER): tHead = tText.replace("\n", " - ") lines.append(f"# {tHead}\n\n") - elif tType == BlockTyp.HEAD1: - tHead = tText.replace("\n", " - ") - lines.append(f"# {tHead}\n\n") - - elif tType == BlockTyp.HEAD2: + elif tType in (BlockTyp.HEAD2, BlockTyp.SCENE): tHead = tText.replace("\n", " - ") lines.append(f"## {tHead}\n\n") - elif tType == BlockTyp.HEAD3: + elif tType in (BlockTyp.HEAD3, BlockTyp.SECTION): tHead = tText.replace("\n", " - ") lines.append(f"### {tHead}\n\n") diff --git a/tests/test_formats/test_fmt_tokenizer.py b/tests/test_formats/test_fmt_tokenizer.py index 706bcdd6..585ae734 100644 --- a/tests/test_formats/test_fmt_tokenizer.py +++ b/tests/test_formats/test_fmt_tokenizer.py @@ -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.CHAPTER, 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.SCENE, 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.SECTION, 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.CHAPTER, 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.CHAPTER, 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.CHAPTER, 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.CHAPTER, 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.CHAPTER, 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.CHAPTER, 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.SCENE, 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.SCENE, 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.SCENE, 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.SECTION, TM1, "X: A Section", [], BlockFmt.NONE), ] # H4: Section Separator @@ -2160,14 +2160,14 @@ def testFmtToken_SceneSeparators(mockGUI): md.doConvert() assert md._pages[-1] == ( "# T: Title One\n\n" - "### S: Scene One\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" + "## S: Scene Three\n\n" "Text\n\n" - "### H: Scene Four\n\n" + "## H: Scene Four\n\n" "Text\n\n" ) @@ -2198,11 +2198,11 @@ def testFmtToken_SceneSeparators(mockGUI): md.doConvert() assert md._pages[-1] == ( "# T: Title One\n\n" - "## C: Chapter One\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" @@ -2215,15 +2215,15 @@ def testFmtToken_SceneSeparators(mockGUI): md.doConvert() assert md._pages[-1] == ( "# T: Title One\n\n" - "## C: Chapter One\n\n" - "### S: Scene One\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 +2287,7 @@ def testFmtToken_HeaderVisibility(mockGUI): # Novel Files # =========== + # Headers are promoted one level md._isNovel = True @@ -2303,18 +2304,18 @@ def testFmtToken_HeaderVisibility(mockGUI): assert md._pages[-1] == ( "# Novel\n\n" "# Title One\n\n" - "## Prologue\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" ) @@ -2339,6 +2340,7 @@ def testFmtToken_HeaderVisibility(mockGUI): # Note Files # ========== + # Headers are exported as-is md._isNovel = False @@ -2428,30 +2430,30 @@ def testFmtToken_CounterHandling(mockGUI): md.doConvert() assert md._pages[-1] == ( "# Novel One\n\n" - "## U: Prologue\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" + "# 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" ) diff --git a/tests/test_formats/test_fmt_tomarkdown.py b/tests/test_formats/test_fmt_tomarkdown.py index b5655e2e..1637f295 100644 --- a/tests/test_formats/test_fmt_tomarkdown.py +++ b/tests/test_formats/test_fmt_tomarkdown.py @@ -49,20 +49,20 @@ def testFmtToMarkdown_ConvertHeaders(mockGUI): 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" @@ -74,7 +74,7 @@ def testFmtToMarkdown_ConvertHeaders(mockGUI): 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" @@ -271,12 +271,12 @@ def testFmtToMarkdown_Save(mockGUI, fncPath): ] 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", + "# 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