""" novelWriter – ToMd Class Tester =============================== This file is a part of novelWriter Copyright (C) 2019 Veronica Berglyd Olsen and novelWriter contributors This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . """ # noqa from __future__ import annotations import pytest from novelwriter.constants import nwHeadFmt from novelwriter.core.project import NWProject from novelwriter.enum import nwComment from novelwriter.formats.shared import BlockFmt, BlockTyp from novelwriter.formats.tomarkdown import ToMarkdown @pytest.mark.core def testFmtToMarkdown_ConvertHeaders(mockGUI): """Test header formats in the ToMarkdown class.""" project = NWProject() md = ToMarkdown(project, False) md._isNovel = True md._isFirst = True # Header 1 md._text = "# Title\n" md.setPartitionFormat(f"Part{nwHeadFmt.BR}{nwHeadFmt.TITLE}") md.tokenizeText() md.doConvert() 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" # 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" # Header 4 md._text = "#### Section Title\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == "### Section Title\n\n" # Title md._text = "#! Title\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == "Title\n=====\n\n" # Unnumbered md._text = "##! Prologue\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == "# Prologue\n\n" @pytest.mark.core def testFmtToMarkdown_ConvertParagraphs(mockGUI): """Test paragraph formats in the ToMarkdown class.""" project = NWProject() md = ToMarkdown(project, False) md._isNovel = True md._isFirst = True # Text for Extended Markdown md._extended = True md._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == ( "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n\n" ) # Text for Standard Markdown md._extended = False md._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == ( "Some **nested bold and _italic_ and strikethrough text** here\n\n" ) # Shortcodes for Extended Markdown md._extended = True md._text = ( "Some [b]bold[/b], [i]italic[/i], [s]strike[/s], [u]underline[/u], [m]mark[/m], " "super[sup]script[/sup], sub[sub]script[/sub] here\n" ) md.tokenizeText() md.doConvert() assert md._pages[-1] == ( "Some **bold**, _italic_, ~~strike~~, underline, ==mark==, " "super^script^, sub~script~ here\n\n" ) # Shortcodes for Standard Markdown md._extended = False md._text = ( "Some [b]bold[/b], [i]italic[/i], [s]strike[/s], [u]underline[/u], [m]mark[/m], " "super[sup]script[/sup], sub[sub]script[/sub] here\n" ) md.tokenizeText() md.doConvert() assert md._pages[-1] == ( "Some **bold**, _italic_, strike, underline, mark, superscript, subscript here\n\n" ) # Text w/Hard Break md._text = "Line one\nLine two\nLine three\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == "Line one \nLine two \nLine three\n\n" # Text wo/Hard Break md._text = "Line one\nLine two\nLine three\n" md.setKeepLineBreaks(False) md.tokenizeText() md.doConvert() assert md._pages[-1] == "Line one Line two Line three\n\n" # Synopsis, Short md._text = "%synopsis: The synopsis ...\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == "" md.setCommentType(nwComment.SYNOPSIS, True) md._text = "%synopsis: The synopsis ...\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == "**Synopsis:** The synopsis ...\n\n" md.setCommentType(nwComment.SHORT, True) md._text = "%short: A description ...\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == "**Short Description:** A description ...\n\n" # Comment md._text = "% A comment ...\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == "" md.setCommentType(nwComment.PLAIN, True) md._text = "% A comment ...\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == "**Comment:** A comment ...\n\n" # Keywords md._text = "@char: Bod, Jane\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == "" md.setKeywords(True) md._text = "@char: Bod, Jane\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == "**Characters:** Bod, Jane\n\n" # Multiple Keywords md.setKeywords(True) md._text = "## Chapter\n\n@pov: Bod\n@plot: Main\n@location: Europe\n\n" md.tokenizeText() md.doConvert() assert md._pages[-1] == ( "# Chapter\n\n" "**Point of View:** Bod \n" "**Plot:** Main \n" "**Locations:** Europe\n\n" ) # Footnotes md._text = ( "Text with one[footnote:fa] or two[footnote:fb] footnotes.\n\n" "%footnote.fa: Footnote text A.\n\n" ) md.tokenizeText() md.doConvert() assert md._pages[-1] == "Text with one[1] or two[ERR] footnotes.\n\n" md.closeDocument() assert md._pages[-2] == ( "Text with one[1] or two[ERR] footnotes.\n\n" ) assert md._pages[-1] == ( "### Footnotes\n\n" "1. Footnote text A.\n\n" ) @pytest.mark.core def testFmtToMarkdown_ConvertDirect(mockGUI): """Test the converter directly using the ToMarkdown class.""" project = NWProject() md = ToMarkdown(project, False) md._isNovel = True # Special Titles # ============== # Title md._blocks = [ (BlockTyp.TITLE, "", "A Title", [], BlockFmt.PBB | BlockFmt.CENTRE), ] md.doConvert() assert md._pages[-1] == "A Title\n=======\n\n" # Separators # ========== # Separator md._blocks = [ (BlockTyp.SEP, "", "* * *", [], BlockFmt.CENTRE), ] md.doConvert() assert md._pages[-1] == "* * *\n\n" # Skip md._blocks = [ (BlockTyp.SKIP, "", "", [], BlockFmt.NONE), ] md.doConvert() assert md._pages[-1] == "\n\n" @pytest.mark.core def testFmtToMarkdown_Save(mockGUI, fncPath): """Test the save method of the ToMarkdown class.""" project = NWProject() md = ToMarkdown(project, False) md._isNovel = True # Build Project # ============= docText = [ "# My Novel\n\n**By Jane Doh**\n", "## Chapter 1\n\nThe text of chapter one.\n", "### Scene 1\n\nThe text of scene one.\n", "#### A Section\n\nMore text in scene one.\n", "## Chapter 2\n\nThe text of chapter two.\n", "### Scene 2\n\nThe text of scene two.\n", "#### A Section\n\n\tMore text in scene two.\n", ] resText = [ "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)): md._text = docText[i] md.doPreProcessing() md.tokenizeText() md.doConvert() assert md._pages == resText assert md.getFullResultSize() == len("".join(resText)) md.replaceTabs(nSpaces=4, spaceChar=" ") resText[6] = "### A Section\n\n More text in scene two.\n\n" assert md._pages == resText # Check File # ========== saveFile = fncPath / "outFile.md" md.saveDocument(saveFile) assert saveFile.read_text(encoding="utf-8") == "".join(resText)