Move document format classes to new folder
This commit is contained in:
@@ -30,10 +30,10 @@ import pytest
|
||||
from novelwriter.core.buildsettings import BuildSettings
|
||||
from novelwriter.core.docbuild import NWBuildDocument
|
||||
from novelwriter.core.project import NWProject
|
||||
from novelwriter.core.tohtml import ToHtml
|
||||
from novelwriter.core.tomarkdown import ToMarkdown
|
||||
from novelwriter.core.toodt import ToOdt
|
||||
from novelwriter.enum import nwBuildFmt
|
||||
from novelwriter.formats.tohtml import ToHtml
|
||||
from novelwriter.formats.tomarkdown import ToMarkdown
|
||||
from novelwriter.formats.toodt import ToOdt
|
||||
|
||||
from tests.mocked import causeException, causeOSError
|
||||
from tests.tools import ODT_IGNORE, C, buildTestProject, cmpFiles
|
||||
@@ -146,7 +146,7 @@ def testCoreDocBuild_OpenDocument(monkeypatch, mockGUI, prjLipsum, fncPath, tstP
|
||||
# ==================
|
||||
|
||||
with monkeypatch.context() as mp:
|
||||
mp.setattr("novelwriter.core.toodt.ToOdt.doConvert", causeException)
|
||||
mp.setattr("novelwriter.formats.toodt.ToOdt.doConvert", causeException)
|
||||
assert len(docBuild) == 21
|
||||
|
||||
count = 0
|
||||
|
||||
@@ -1,737 +0,0 @@
|
||||
"""
|
||||
novelWriter – ToHtml Class Tester
|
||||
=================================
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2018–2024, Veronica Berglyd Olsen
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
|
||||
import pytest
|
||||
|
||||
from novelwriter import CONFIG
|
||||
from novelwriter.core.project import NWProject
|
||||
from novelwriter.core.tohtml import ToHtml
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_ConvertHeaders(mockGUI):
|
||||
"""Test header formats in the ToHtml class."""
|
||||
project = NWProject()
|
||||
html = ToHtml(project)
|
||||
|
||||
# Novel Files Headers
|
||||
# ===================
|
||||
|
||||
html._isNovel = True
|
||||
html._isFirst = True
|
||||
|
||||
# Header 1
|
||||
html._text = "# Partition\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 class='title' style='text-align: center;'>Partition</h1>\n"
|
||||
)
|
||||
|
||||
# Header 2
|
||||
html._text = "## Chapter Title\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 style='page-break-before: always;'>Chapter Title</h1>\n"
|
||||
)
|
||||
|
||||
# Header 3
|
||||
html._text = "### Scene Title\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == "<h2>Scene Title</h2>\n"
|
||||
|
||||
# Header 4
|
||||
html._text = "#### Section Title\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == "<h3>Section Title</h3>\n"
|
||||
|
||||
# Title
|
||||
html._text = "#! Title\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 class='title' style='text-align: center; page-break-before: always;'>Title</h1>\n"
|
||||
)
|
||||
|
||||
# Unnumbered
|
||||
html._text = "##! Prologue\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == "<h1 style='page-break-before: always;'>Prologue</h1>\n"
|
||||
|
||||
# Note Files Headers
|
||||
# ==================
|
||||
|
||||
html._isNovel = False
|
||||
html._isFirst = True
|
||||
html._handle = "0000000000000"
|
||||
html.setLinkHeadings(True)
|
||||
|
||||
# Header 1
|
||||
html._text = "# Heading One\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == "<h1><a name='0000000000000:T0001'></a>Heading One</h1>\n"
|
||||
|
||||
# Header 2
|
||||
html._text = "## Heading Two\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == "<h2><a name='0000000000000:T0001'></a>Heading Two</h2>\n"
|
||||
|
||||
# Header 3
|
||||
html._text = "### Heading Three\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == "<h3><a name='0000000000000:T0001'></a>Heading Three</h3>\n"
|
||||
|
||||
# Header 4
|
||||
html._text = "#### Heading Four\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == "<h4><a name='0000000000000:T0001'></a>Heading Four</h4>\n"
|
||||
|
||||
# Title
|
||||
html._text = "#! Heading One\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 class='title' style='text-align: center; page-break-before: always;'>"
|
||||
"<a name='0000000000000:T0001'></a>Heading One</h1>\n"
|
||||
)
|
||||
|
||||
# Unnumbered
|
||||
html._text = "##! Heading Two\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == "<h2><a name='0000000000000:T0001'></a>Heading Two</h2>\n"
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_ConvertParagraphs(mockGUI):
|
||||
"""Test paragraph formats in the ToHtml class."""
|
||||
project = NWProject()
|
||||
html = ToHtml(project)
|
||||
|
||||
html._isNovel = True
|
||||
html._isFirst = True
|
||||
|
||||
# Paragraphs
|
||||
# ==========
|
||||
|
||||
# Text
|
||||
html._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Some <strong>nested bold and <em>italic</em> and "
|
||||
"<del>strikethrough</del> text</strong> here</p>\n"
|
||||
)
|
||||
|
||||
# Shortcodes
|
||||
html._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"
|
||||
)
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Some <strong>bold</strong>, <em>italic</em>, <del>strike</del>, "
|
||||
"<span style='text-decoration: underline;'>underline</span>, <mark>mark</mark>, "
|
||||
"super<sup>script</sup>, sub<sub>script</sub> here</p>\n"
|
||||
)
|
||||
|
||||
# Text w/Hard Break
|
||||
html._text = "Line one\nLine two\nLine three\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Line one<br>Line two<br>Line three</p>\n"
|
||||
)
|
||||
|
||||
# Synopsis, Short
|
||||
html._text = "%synopsis: The synopsis ...\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == ""
|
||||
|
||||
html.setSynopsis(True)
|
||||
html._text = "%synopsis: The synopsis ...\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p class='synopsis'><strong>Synopsis:</strong> The synopsis ...</p>\n"
|
||||
)
|
||||
|
||||
html.setSynopsis(True)
|
||||
html._text = "%short: A short description ...\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p class='synopsis'><strong>Short Description:</strong> A short description ...</p>\n"
|
||||
)
|
||||
|
||||
# Comment
|
||||
html._text = "% A comment ...\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == ""
|
||||
|
||||
html.setComments(True)
|
||||
html._text = "% A comment ...\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p class='comment'><strong>Comment:</strong> A comment ...</p>\n"
|
||||
)
|
||||
|
||||
# Keywords
|
||||
html._text = "@char: Bod, Jane\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == ""
|
||||
|
||||
html.setKeywords(True)
|
||||
html._text = "@char: Bod, Jane\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p class='meta meta-char'><span class='keyword'>Characters:</span> "
|
||||
"<a class='tag' href='#tag_Bod'>Bod</a>, "
|
||||
"<a class='tag' href='#tag_Jane'>Jane</a></p>\n"
|
||||
)
|
||||
|
||||
# Tags
|
||||
html._text = "@tag: Bod\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p class='meta meta-tag'><span class='keyword'>Tag:</span> "
|
||||
"<a class='tag' name='tag_Bod'>Bod</a></p>\n"
|
||||
)
|
||||
|
||||
html._text = "@tag: Bod | Nobody Owens\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p class='meta meta-tag'><span class='keyword'>Tag:</span> "
|
||||
"<a class='tag' name='tag_Bod'>Bod</a> | <span class='optional'>Nobody Owens</a></p>\n"
|
||||
)
|
||||
|
||||
# Multiple Keywords
|
||||
html._isFirst = False
|
||||
html.setKeywords(True)
|
||||
html._text = "## Chapter\n\n@pov: Bod\n@plot: Main\n@location: Europe\n\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 style='page-break-before: always;'>Chapter</h1>\n"
|
||||
"<p class='meta meta-pov' style='margin-bottom: 0;'>"
|
||||
"<span class='keyword'>Point of View:</span> "
|
||||
"<a class='tag' href='#tag_Bod'>Bod</a></p>\n"
|
||||
"<p class='meta meta-plot' style='margin-bottom: 0; margin-top: 0;'>"
|
||||
"<span class='keyword'>Plot:</span> "
|
||||
"<a class='tag' href='#tag_Main'>Main</a></p>\n"
|
||||
"<p class='meta meta-location' style='margin-top: 0;'>"
|
||||
"<span class='keyword'>Locations:</span> "
|
||||
"<a class='tag' href='#tag_Europe'>Europe</a></p>\n"
|
||||
)
|
||||
|
||||
# Dialogue
|
||||
html.setDialogueHighlight(True)
|
||||
html._text = "## Chapter\n\nThis text \u201chas dialogue\u201d in it.\n\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 style='page-break-before: always;'>Chapter</h1>\n"
|
||||
"<p>This text <span class='dialog'>\u201chas dialogue\u201d</span> in it.</p>\n"
|
||||
)
|
||||
|
||||
# Alt. Dialogue
|
||||
CONFIG.altDialogOpen = "::"
|
||||
CONFIG.altDialogClose = "::"
|
||||
html.setDialogueHighlight(True)
|
||||
html._text = "## Chapter\n\nThis text ::has alt dialogue:: in it.\n\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 style='page-break-before: always;'>Chapter</h1>\n"
|
||||
"<p>This text <span class='altdialog'>::has alt dialogue::</span> in it.</p>\n"
|
||||
)
|
||||
|
||||
# Footnotes
|
||||
# =========
|
||||
|
||||
html._text = (
|
||||
"Text with one[footnote:fa] or two[footnote:fb] footnotes.\n\n"
|
||||
"%footnote.fa: Footnote text A.\n\n"
|
||||
)
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Text with one<sup><a href='#footnote_1'>1</a></sup> "
|
||||
"or two<sup>ERR</sup> footnotes.</p>\n"
|
||||
)
|
||||
|
||||
html.appendFootnotes()
|
||||
assert html.result == (
|
||||
"<p>Text with one<sup><a href='#footnote_1'>1</a></sup> "
|
||||
"or two<sup>ERR</sup> footnotes.</p>\n"
|
||||
"<h3>Footnotes</h3>\n"
|
||||
"<ol>\n"
|
||||
"<li id='footnote_1'><p>Footnote text A.</p></li>\n"
|
||||
"</ol>\n"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_CloseTags(mockGUI):
|
||||
"""Test automatic closing of HTML tags for shortcodes."""
|
||||
project = NWProject()
|
||||
html = ToHtml(project)
|
||||
|
||||
html._isNovel = True
|
||||
html._isFirst = True
|
||||
|
||||
# Unclosed Shortcodes
|
||||
html._text = "Text [b][i][s][u][m][sup][sub]text text text.\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Text <strong><em><del><span style='text-decoration: underline;'><mark><sup><sub>"
|
||||
"text text text.</strong></em></del></span></mark></sup></sub></p>\n"
|
||||
)
|
||||
|
||||
# Double Shortcodes
|
||||
html._text = "Text [b][i][s][u][m][sup][sub]text [b][i][s][u][m][sup][sub]text text.\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Text <strong><em><del><span style='text-decoration: underline;'><mark><sup><sub>"
|
||||
"text text text.</strong></em></del></span></mark></sup></sub></p>\n"
|
||||
)
|
||||
|
||||
# Redundant Close Shortcodes
|
||||
html._text = "Text text [/b][/i][/s][/u][/m][/sup][/sub]text text.\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Text text text text.</p>\n"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_ConvertDirect(mockGUI):
|
||||
"""Test the converter directly using the ToHtml class."""
|
||||
project = NWProject()
|
||||
html = ToHtml(project)
|
||||
|
||||
html._isNovel = True
|
||||
html._handle = "0000000000000"
|
||||
html.setLinkHeadings(True)
|
||||
|
||||
# Special Titles
|
||||
# ==============
|
||||
|
||||
# Title
|
||||
html._tokens = [
|
||||
(html.T_TITLE, 1, "A Title", [], html.A_PBB | html.A_CENTRE),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 class='title' style='text-align: center; page-break-before: always;'>"
|
||||
"<a name='0000000000000:T0001'></a>A Title</h1>\n"
|
||||
)
|
||||
|
||||
# Unnumbered
|
||||
html._tokens = [
|
||||
(html.T_HEAD2, 1, "Prologue", [], html.A_PBB),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 style='page-break-before: always;'>"
|
||||
"<a name='0000000000000:T0001'></a>Prologue</h1>\n"
|
||||
)
|
||||
|
||||
# Separators
|
||||
# ==========
|
||||
|
||||
# Separator
|
||||
html._tokens = [
|
||||
(html.T_SEP, 1, "* * *", [], html.A_CENTRE),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == "<p class='sep' style='text-align: center;'>* * *</p>\n"
|
||||
|
||||
# Skip
|
||||
html._tokens = [
|
||||
(html.T_SKIP, 1, "", [], html.A_NONE),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == "<p class='skip'> </p>\n"
|
||||
|
||||
# Alignment
|
||||
# =========
|
||||
|
||||
html.setLinkHeadings(False)
|
||||
|
||||
# Align Left
|
||||
html.setStyles(False)
|
||||
html._tokens = [
|
||||
(html.T_HEAD1, 1, "A Title", [], html.A_LEFT),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 class='title'>A Title</h1>\n"
|
||||
)
|
||||
|
||||
html.setStyles(True)
|
||||
|
||||
# Align Left
|
||||
html._tokens = [
|
||||
(html.T_HEAD1, 1, "A Title", [], html.A_LEFT),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 class='title' style='text-align: left;'>A Title</h1>\n"
|
||||
)
|
||||
|
||||
# Align Right
|
||||
html._tokens = [
|
||||
(html.T_HEAD1, 1, "A Title", [], html.A_RIGHT),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 class='title' style='text-align: right;'>A Title</h1>\n"
|
||||
)
|
||||
|
||||
# Align Centre
|
||||
html._tokens = [
|
||||
(html.T_HEAD1, 1, "A Title", [], html.A_CENTRE),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 class='title' style='text-align: center;'>A Title</h1>\n"
|
||||
)
|
||||
|
||||
# Align Justify
|
||||
html._tokens = [
|
||||
(html.T_HEAD1, 1, "A Title", [], html.A_JUSTIFY),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 class='title' style='text-align: justify;'>A Title</h1>\n"
|
||||
)
|
||||
|
||||
# Page Break
|
||||
# ==========
|
||||
|
||||
# Page Break Always
|
||||
html._tokens = [
|
||||
(html.T_HEAD1, 1, "A Title", [], html.A_PBB | html.A_PBA),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 class='title' "
|
||||
"style='page-break-before: always; page-break-after: always;'>A Title</h1>\n"
|
||||
)
|
||||
|
||||
# Indent
|
||||
# ======
|
||||
|
||||
# Indent Left
|
||||
html._tokens = [
|
||||
(html.T_TEXT, 1, "Some text ...", [], html.A_IND_L),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p style='margin-left: 4.00em;'>Some text ...</p>\n"
|
||||
)
|
||||
|
||||
# Indent Right
|
||||
html._tokens = [
|
||||
(html.T_TEXT, 1, "Some text ...", [], html.A_IND_R),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p style='margin-right: 4.00em;'>Some text ...</p>\n"
|
||||
)
|
||||
|
||||
# Text Indent
|
||||
html._tokens = [
|
||||
(html.T_TEXT, 1, "Some text ...", [], html.A_IND_T),
|
||||
]
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p style='text-indent: 1.40em;'>Some text ...</p>\n"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_SpecialCases(mockGUI):
|
||||
"""Test some special cases that have caused errors in the past."""
|
||||
project = NWProject()
|
||||
html = ToHtml(project)
|
||||
html._isNovel = True
|
||||
|
||||
# Greater/Lesser than symbols
|
||||
# ===========================
|
||||
|
||||
html._text = "Text with > and < with some **bold text** in it.\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Text with > and < with some <strong>bold text</strong> in it.</p>\n"
|
||||
)
|
||||
|
||||
html._text = "Text with some <**bold text**> in it.\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Text with some <<strong>bold text</strong>> in it.</p>\n"
|
||||
)
|
||||
|
||||
html._text = "Let's > be > _difficult **shall** > we_?\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Let's > be > <em>difficult <strong>shall</strong> > we</em>?</p>\n"
|
||||
)
|
||||
|
||||
html._text = "Test > text _<**bold**>_ and more.\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Test > text <em><<strong>bold</strong>></em> and more.</p>\n"
|
||||
)
|
||||
|
||||
# Test for issue #950
|
||||
# ===================
|
||||
# See: https://github.com/vkbo/novelWriter/issues/950
|
||||
|
||||
html.setComments(True)
|
||||
html._text = "% Test > text _<**bold**>_ and more.\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p class='comment'>"
|
||||
"<strong>Comment:</strong> Test > text <em><<strong>bold</strong>></em> and more."
|
||||
"</p>\n"
|
||||
)
|
||||
|
||||
html._isFirst = False
|
||||
html._text = "## Heading <1>\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<h1 style='page-break-before: always;'>Heading <1></h1>\n"
|
||||
)
|
||||
|
||||
# Test for issue #1412
|
||||
# ====================
|
||||
# See: https://github.com/vkbo/novelWriter/issues/1412
|
||||
|
||||
html._text = "Test text \\**_bold_** and more.\n"
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Test text **<em>bold</em>** and more.</p>\n"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_Save(mockGUI, fncPath):
|
||||
"""Test the save method of the ToHtml class."""
|
||||
project = NWProject()
|
||||
html = ToHtml(project)
|
||||
html._isNovel = True
|
||||
|
||||
# Build Project
|
||||
# =============
|
||||
|
||||
docText = [
|
||||
"# My Novel\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 = [(
|
||||
"<h1 class='title' style='text-align: center;'>My Novel</h1>\n"
|
||||
"<p><strong>By Jane Doh</strong></p>\n"
|
||||
), (
|
||||
"<h1 style='page-break-before: always;'>Chapter 1</h1>\n"
|
||||
"<p>The text of chapter one.</p>\n"
|
||||
), (
|
||||
"<h2>Scene 1</h2>\n"
|
||||
"<p>The text of scene one.</p>\n"
|
||||
), (
|
||||
"<h3>A Section</h3>\n"
|
||||
"<p>More text in scene one.</p>\n"
|
||||
), (
|
||||
"<h1 style='page-break-before: always;'>Chapter 2</h1>\n"
|
||||
"<p>The text of chapter two.</p>\n"
|
||||
), (
|
||||
"<h2>Scene 2</h2>\n"
|
||||
"<p>The text of scene two.</p>\n"
|
||||
), (
|
||||
"<h3>A Section</h3>\n"
|
||||
"<p>\tMore text in scene two.</p>\n"
|
||||
)]
|
||||
|
||||
for i in range(len(docText)):
|
||||
html._text = docText[i]
|
||||
html.doPreProcessing()
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == resText[i]
|
||||
|
||||
assert html.fullHTML == resText
|
||||
|
||||
html.replaceTabs(nSpaces=2, spaceChar=" ")
|
||||
resText[6] = "<h3>A Section</h3>\n<p> More text in scene two.</p>\n"
|
||||
|
||||
# Check Files
|
||||
# ===========
|
||||
|
||||
# HTML
|
||||
hStyle = html.getStyleSheet()
|
||||
htmlDoc = (
|
||||
"<!DOCTYPE html>\n"
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
"<meta charset='utf-8'>\n"
|
||||
"<title></title>\n"
|
||||
"</head>\n"
|
||||
"<style>\n"
|
||||
"{htmlStyle:s}\n"
|
||||
"</style>\n"
|
||||
"<body>\n"
|
||||
"<article>\n"
|
||||
"{bodyText:s}\n"
|
||||
"</article>\n"
|
||||
"</body>\n"
|
||||
"</html>\n"
|
||||
).format(
|
||||
htmlStyle="\n".join(hStyle),
|
||||
bodyText="".join(resText).rstrip()
|
||||
)
|
||||
|
||||
saveFile = fncPath / "outFile.htm"
|
||||
html.saveHtml5(saveFile)
|
||||
assert saveFile.read_text(encoding="utf-8") == htmlDoc
|
||||
|
||||
# JSON + HTML
|
||||
saveFile = fncPath / "outFile.json"
|
||||
html.saveHtmlJson(saveFile)
|
||||
data = json.loads(saveFile.read_text(encoding="utf-8"))
|
||||
assert data["meta"]["projectName"] == ""
|
||||
assert data["meta"]["novelAuthor"] == ""
|
||||
assert data["meta"]["buildTime"] > 0
|
||||
assert data["meta"]["buildTimeStr"] != ""
|
||||
assert data["text"]["css"] == hStyle
|
||||
assert len(data["text"]["html"]) == len(resText)
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_Methods(mockGUI):
|
||||
"""Test all the other methods of the ToHtml class."""
|
||||
project = NWProject()
|
||||
html = ToHtml(project)
|
||||
html.setKeepMarkdown(True)
|
||||
|
||||
# Auto-Replace, keep Unicode
|
||||
docText = "Text with <brackets> & short–dash, long—dash …\n"
|
||||
html._text = docText
|
||||
html.setReplaceUnicode(False)
|
||||
html.doPreProcessing()
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Text with <brackets> & short–dash, long—dash …</p>\n"
|
||||
)
|
||||
|
||||
# Auto-Replace, replace Unicode
|
||||
docText = "Text with <brackets> & short–dash, long—dash …\n"
|
||||
html._text = docText
|
||||
html.setReplaceUnicode(True)
|
||||
html.doPreProcessing()
|
||||
html.tokenizeText()
|
||||
html.doConvert()
|
||||
assert html.result == (
|
||||
"<p>Text with <brackets> & short–dash, long—dash …</p>\n"
|
||||
)
|
||||
|
||||
# Result Size
|
||||
assert html.getFullResultSize() == 147
|
||||
|
||||
# CSS
|
||||
# ===
|
||||
|
||||
assert len(html.getStyleSheet()) > 1
|
||||
assert "p {text-align: left;" in " ".join(html.getStyleSheet())
|
||||
assert "p {text-align: justify;" not in " ".join(html.getStyleSheet())
|
||||
|
||||
html.setJustify(True)
|
||||
assert "p {text-align: left;" not in " ".join(html.getStyleSheet())
|
||||
assert "p {text-align: justify;" in " ".join(html.getStyleSheet())
|
||||
|
||||
html.setStyles(False)
|
||||
assert html.getStyleSheet() == []
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToHtml_Format(mockGUI):
|
||||
"""Test all the formatters for the ToHtml class."""
|
||||
project = NWProject()
|
||||
html = ToHtml(project)
|
||||
|
||||
# Export Mode
|
||||
# ===========
|
||||
|
||||
assert html._formatSynopsis("synopsis text", True) == (
|
||||
"<p class='synopsis'><strong>Synopsis:</strong> synopsis text</p>\n"
|
||||
)
|
||||
assert html._formatSynopsis("short text", False) == (
|
||||
"<p class='synopsis'><strong>Short Description:</strong> short text</p>\n"
|
||||
)
|
||||
assert html._formatComments("comment text") == (
|
||||
"<p class='comment'><strong>Comment:</strong> comment text</p>\n"
|
||||
)
|
||||
|
||||
assert html._formatKeywords("") == ("", "")
|
||||
assert html._formatKeywords("tag: Jane") == (
|
||||
"tag", "<span class='keyword'>Tag:</span> <a class='tag' name='tag_Jane'>Jane</a>"
|
||||
)
|
||||
assert html._formatKeywords("char: Bod, Jane") == (
|
||||
"char",
|
||||
"<span class='keyword'>Characters:</span> "
|
||||
"<a class='tag' href='#tag_Bod'>Bod</a>, "
|
||||
"<a class='tag' href='#tag_Jane'>Jane</a>"
|
||||
)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,309 +0,0 @@
|
||||
"""
|
||||
novelWriter – ToMd Class Tester
|
||||
===============================
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2018–2024, Veronica Berglyd Olsen
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from novelwriter.core.project import NWProject
|
||||
from novelwriter.core.tomarkdown import ToMarkdown
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToMarkdown_ConvertHeaders(mockGUI):
|
||||
"""Test header formats in the ToMarkdown class."""
|
||||
project = NWProject()
|
||||
toMD = ToMarkdown(project)
|
||||
|
||||
toMD._isNovel = True
|
||||
toMD._isFirst = True
|
||||
|
||||
# Header 1
|
||||
toMD._text = "# Partition\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "# Partition\n\n"
|
||||
|
||||
# Header 2
|
||||
toMD._text = "## Chapter Title\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "## Chapter Title\n\n"
|
||||
|
||||
# Header 3
|
||||
toMD._text = "### Scene Title\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "### Scene Title\n\n"
|
||||
|
||||
# Header 4
|
||||
toMD._text = "#### Section Title\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "#### Section Title\n\n"
|
||||
|
||||
# Title
|
||||
toMD._text = "#! Title\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "# Title\n\n"
|
||||
|
||||
# Unnumbered
|
||||
toMD._text = "##! Prologue\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "## Prologue\n\n"
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToMarkdown_ConvertParagraphs(mockGUI):
|
||||
"""Test paragraph formats in the ToMarkdown class."""
|
||||
project = NWProject()
|
||||
toMD = ToMarkdown(project)
|
||||
|
||||
toMD._isNovel = True
|
||||
toMD._isFirst = True
|
||||
|
||||
# Text for Extended Markdown
|
||||
toMD.setExtendedMarkdown(True)
|
||||
toMD._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == (
|
||||
"Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n\n"
|
||||
)
|
||||
|
||||
# Text for Standard Markdown
|
||||
toMD.setExtendedMarkdown(False)
|
||||
toMD._text = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == (
|
||||
"Some **nested bold and _italic_ and strikethrough text** here\n\n"
|
||||
)
|
||||
|
||||
# Shortcodes for Extended Markdown
|
||||
toMD.setExtendedMarkdown(True)
|
||||
toMD._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"
|
||||
)
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == (
|
||||
"Some **bold**, _italic_, ~~strike~~, underline, ==mark==, "
|
||||
"super^script^, sub~script~ here\n\n"
|
||||
)
|
||||
|
||||
# Shortcodes for Standard Markdown
|
||||
toMD.setExtendedMarkdown(False)
|
||||
toMD._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"
|
||||
)
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == (
|
||||
"Some **bold**, _italic_, strike, underline, mark, superscript, subscript here\n\n"
|
||||
)
|
||||
|
||||
# Text w/Hard Break
|
||||
toMD._text = "Line one\nLine two\nLine three\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "Line one \nLine two \nLine three\n\n"
|
||||
|
||||
# Text wo/Hard Break
|
||||
toMD._text = "Line one\nLine two\nLine three\n"
|
||||
toMD.setKeepLineBreaks(False)
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "Line one Line two Line three\n\n"
|
||||
|
||||
# Synopsis, Short
|
||||
toMD._text = "%synopsis: The synopsis ...\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == ""
|
||||
|
||||
toMD.setSynopsis(True)
|
||||
toMD._text = "%synopsis: The synopsis ...\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "**Synopsis:** The synopsis ...\n\n"
|
||||
|
||||
toMD.setSynopsis(True)
|
||||
toMD._text = "%short: A description ...\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "**Short Description:** A description ...\n\n"
|
||||
|
||||
# Comment
|
||||
toMD._text = "% A comment ...\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == ""
|
||||
|
||||
toMD.setComments(True)
|
||||
toMD._text = "% A comment ...\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "**Comment:** A comment ...\n\n"
|
||||
|
||||
# Keywords
|
||||
toMD._text = "@char: Bod, Jane\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == ""
|
||||
|
||||
toMD.setKeywords(True)
|
||||
toMD._text = "@char: Bod, Jane\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "**Characters:** Bod, Jane\n\n"
|
||||
|
||||
# Multiple Keywords
|
||||
toMD.setKeywords(True)
|
||||
toMD._text = "## Chapter\n\n@pov: Bod\n@plot: Main\n@location: Europe\n\n"
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == (
|
||||
"## Chapter\n\n"
|
||||
"**Point of View:** Bod \n"
|
||||
"**Plot:** Main \n"
|
||||
"**Locations:** Europe\n\n"
|
||||
)
|
||||
|
||||
# Footnotes
|
||||
toMD._text = (
|
||||
"Text with one[footnote:fa] or two[footnote:fb] footnotes.\n\n"
|
||||
"%footnote.fa: Footnote text A.\n\n"
|
||||
)
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "Text with one[1] or two[ERR] footnotes.\n\n"
|
||||
|
||||
toMD.appendFootnotes()
|
||||
assert toMD.result == (
|
||||
"Text with one[1] or two[ERR] footnotes.\n\n"
|
||||
"### Footnotes\n\n"
|
||||
"1. Footnote text A.\n\n"
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToMarkdown_ConvertDirect(mockGUI):
|
||||
"""Test the converter directly using the ToMarkdown class."""
|
||||
project = NWProject()
|
||||
toMD = ToMarkdown(project)
|
||||
|
||||
toMD._isNovel = True
|
||||
toMD.setExtendedMarkdown(False)
|
||||
|
||||
# Special Titles
|
||||
# ==============
|
||||
|
||||
# Title
|
||||
toMD._tokens = [
|
||||
(toMD.T_TITLE, 1, "A Title", [], toMD.A_PBB | toMD.A_CENTRE),
|
||||
]
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "# A Title\n\n"
|
||||
|
||||
# Separators
|
||||
# ==========
|
||||
|
||||
# Separator
|
||||
toMD._tokens = [
|
||||
(toMD.T_SEP, 1, "* * *", [], toMD.A_CENTRE),
|
||||
]
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "* * *\n\n"
|
||||
|
||||
# Skip
|
||||
toMD._tokens = [
|
||||
(toMD.T_SKIP, 1, "", [], toMD.A_NONE),
|
||||
]
|
||||
toMD.doConvert()
|
||||
assert toMD.result == "\n\n"
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToMarkdown_Save(mockGUI, fncPath):
|
||||
"""Test the save method of the ToMarkdown class."""
|
||||
project = NWProject()
|
||||
toMD = ToMarkdown(project)
|
||||
toMD.setKeepMarkdown(True)
|
||||
toMD._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**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)):
|
||||
toMD._text = docText[i]
|
||||
toMD.doPreProcessing()
|
||||
toMD.tokenizeText()
|
||||
toMD.doConvert()
|
||||
assert toMD.result == resText[i]
|
||||
|
||||
assert toMD.fullMD == resText
|
||||
assert toMD.getFullResultSize() == len("".join(resText))
|
||||
|
||||
toMD.replaceTabs(nSpaces=4, spaceChar=" ")
|
||||
resText[6] = "#### A Section\n\n More text in scene two.\n\n"
|
||||
assert toMD.allMarkdown == resText
|
||||
|
||||
# Check File
|
||||
# ==========
|
||||
|
||||
saveFile = fncPath / "outFile.md"
|
||||
toMD.saveMarkdown(saveFile)
|
||||
assert saveFile.read_text(encoding="utf-8") == "".join(resText)
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToMarkdown_Format(mockGUI):
|
||||
"""Test all the formatters for the ToMarkdown class."""
|
||||
project = NWProject()
|
||||
toMD = ToMarkdown(project)
|
||||
|
||||
assert toMD._formatKeywords("", toMD.A_NONE) == ""
|
||||
assert toMD._formatKeywords("tag: Jane", toMD.A_NONE) == "**Tag:** Jane\n\n"
|
||||
assert toMD._formatKeywords("tag: Jane, John", toMD.A_NONE) == "**Tag:** Jane, John\n\n"
|
||||
assert toMD._formatKeywords("tag: Jane", toMD.A_Z_BTMMRG) == "**Tag:** Jane \n"
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,612 +0,0 @@
|
||||
"""
|
||||
novelWriter – ToQTextDocument Class Tester
|
||||
==========================================
|
||||
|
||||
This file is a part of novelWriter
|
||||
Copyright 2018–2024, Veronica Berglyd Olsen
|
||||
|
||||
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 <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import pytest
|
||||
|
||||
from PyQt5.QtGui import QColor, QTextBlock, QTextCharFormat, QTextCursor
|
||||
|
||||
from novelwriter import CONFIG
|
||||
from novelwriter.constants import nwUnicode
|
||||
from novelwriter.core.project import NWProject
|
||||
from novelwriter.core.toqdoc import TextDocumentTheme, ToQTextDocument
|
||||
from novelwriter.types import (
|
||||
QtAlignAbsolute, QtAlignCenter, QtAlignJustify, QtAlignLeft, QtAlignRight,
|
||||
QtPageBreakAfter, QtTransparent, QtVAlignNormal, QtVAlignSub, QtVAlignSuper
|
||||
)
|
||||
|
||||
THEME = TextDocumentTheme()
|
||||
THEME.text = QColor(0, 0, 0)
|
||||
THEME.highlight = QColor(255, 255, 166)
|
||||
THEME.head = QColor(66, 113, 174)
|
||||
THEME.comment = QColor(100, 100, 100)
|
||||
THEME.note = QColor(129, 55, 9)
|
||||
THEME.code = QColor(66, 113, 174)
|
||||
THEME.modifier = QColor(129, 55, 9)
|
||||
THEME.keyword = QColor(245, 135, 31)
|
||||
THEME.tag = QColor(66, 113, 174)
|
||||
THEME.optional = QColor(66, 113, 174)
|
||||
THEME.dialog = QColor(113, 140, 0)
|
||||
THEME.altdialog = QColor(234, 183, 0)
|
||||
|
||||
|
||||
def charFmtInBlock(block: QTextBlock, pos: int) -> QTextCharFormat:
|
||||
"""Get the character format at a given place in a block."""
|
||||
cursor = QTextCursor(block)
|
||||
cursor.setPosition(block.position() + pos)
|
||||
return cursor.charFormat()
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToQTextDocument_ConvertHeaders(mockGUI):
|
||||
"""Test header formats in the ToQTextDocument class."""
|
||||
project = NWProject()
|
||||
qdoc = ToQTextDocument(project)
|
||||
qdoc.initDocument(CONFIG.textFont, THEME)
|
||||
|
||||
qdoc._isNovel = True
|
||||
qdoc._isFirst = True
|
||||
qdoc._text = (
|
||||
"#! Title\n"
|
||||
"# Partition\n"
|
||||
"## Chapter\n"
|
||||
"### Scene\n"
|
||||
"#### Section\n"
|
||||
)
|
||||
qdoc.tokenizeText()
|
||||
qdoc.doConvert()
|
||||
assert qdoc.document.blockCount() == 5
|
||||
|
||||
# Title
|
||||
block = qdoc.document.findBlockByNumber(0)
|
||||
assert block.text() == "Title"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mHead[qdoc.T_TITLE][0]
|
||||
assert bFmt.bottomMargin() == qdoc._mHead[qdoc.T_TITLE][1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.fontWeight() == qdoc._bold
|
||||
assert cFmt.fontPointSize() == qdoc._sHead[qdoc.T_TITLE]
|
||||
assert cFmt.foreground().color() == THEME.text
|
||||
|
||||
# Partition
|
||||
block = qdoc.document.findBlockByNumber(1)
|
||||
assert block.text() == "Partition"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mHead[qdoc.T_HEAD1][0]
|
||||
assert bFmt.bottomMargin() == qdoc._mHead[qdoc.T_HEAD1][1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.fontWeight() == qdoc._bold
|
||||
assert cFmt.fontPointSize() == qdoc._sHead[qdoc.T_HEAD1]
|
||||
assert cFmt.foreground().color() == THEME.head
|
||||
|
||||
# Chapter
|
||||
block = qdoc.document.findBlockByNumber(2)
|
||||
assert block.text() == "Chapter"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mHead[qdoc.T_HEAD2][0]
|
||||
assert bFmt.bottomMargin() == qdoc._mHead[qdoc.T_HEAD2][1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.fontWeight() == qdoc._bold
|
||||
assert cFmt.fontPointSize() == qdoc._sHead[qdoc.T_HEAD2]
|
||||
assert cFmt.foreground().color() == THEME.head
|
||||
|
||||
# Scene
|
||||
block = qdoc.document.findBlockByNumber(3)
|
||||
assert block.text() == "Scene"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mHead[qdoc.T_HEAD3][0]
|
||||
assert bFmt.bottomMargin() == qdoc._mHead[qdoc.T_HEAD3][1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.fontWeight() == qdoc._bold
|
||||
assert cFmt.fontPointSize() == qdoc._sHead[qdoc.T_HEAD3]
|
||||
assert cFmt.foreground().color() == THEME.head
|
||||
|
||||
# Section
|
||||
block = qdoc.document.findBlockByNumber(4)
|
||||
assert block.text() == "Section"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mHead[qdoc.T_HEAD4][0]
|
||||
assert bFmt.bottomMargin() == qdoc._mHead[qdoc.T_HEAD4][1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.fontWeight() == qdoc._bold
|
||||
assert cFmt.fontPointSize() == qdoc._sHead[qdoc.T_HEAD4]
|
||||
assert cFmt.foreground().color() == THEME.head
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToQTextDocument_SeparatorSkip(mockGUI):
|
||||
"""Test separator and skip in the ToQTextDocument class."""
|
||||
project = NWProject()
|
||||
qdoc = ToQTextDocument(project)
|
||||
qdoc.initDocument(CONFIG.textFont, THEME)
|
||||
|
||||
qdoc._isNovel = True
|
||||
qdoc._isFirst = True
|
||||
qdoc._text = (
|
||||
"#! Title\n"
|
||||
"## Chapter\n"
|
||||
"### Scene 1\n"
|
||||
"Text 1\n"
|
||||
"### Scene 2\n"
|
||||
"Text 2\n"
|
||||
"#### Section\n"
|
||||
"Text 3\n"
|
||||
)
|
||||
qdoc.setSceneFormat("* * *", False)
|
||||
qdoc.setSectionFormat("", False)
|
||||
qdoc.tokenizeText()
|
||||
qdoc.doConvert()
|
||||
assert qdoc.document.blockCount() == 7
|
||||
|
||||
# 0: Title
|
||||
block = qdoc.document.findBlockByNumber(0)
|
||||
assert block.text() == "Title"
|
||||
|
||||
# 1: Chapter
|
||||
block = qdoc.document.findBlockByNumber(1)
|
||||
assert block.text() == "Chapter"
|
||||
|
||||
# Hidden: Scene 1
|
||||
|
||||
# 2: Text 1
|
||||
block = qdoc.document.findBlockByNumber(2)
|
||||
assert block.text() == "Text 1"
|
||||
|
||||
# 3: Scene 2
|
||||
block = qdoc.document.findBlockByNumber(3)
|
||||
assert block.text() == "* * *"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mSep[0]
|
||||
assert bFmt.bottomMargin() == qdoc._mSep[1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.foreground().color() == THEME.text
|
||||
|
||||
# 4: Text 2
|
||||
block = qdoc.document.findBlockByNumber(4)
|
||||
assert block.text() == "Text 2"
|
||||
|
||||
# 5: Section
|
||||
block = qdoc.document.findBlockByNumber(5)
|
||||
assert block.text() == nwUnicode.U_NBSP
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mText[0]
|
||||
assert bFmt.bottomMargin() == qdoc._mText[1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.foreground().color() == THEME.text
|
||||
|
||||
# 6: Text 3
|
||||
block = qdoc.document.findBlockByNumber(6)
|
||||
assert block.text() == "Text 3"
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToQTextDocument_NovelMeta(mockGUI):
|
||||
"""Test novel meta formats in the ToQTextDocument class."""
|
||||
project = NWProject()
|
||||
qdoc = ToQTextDocument(project)
|
||||
qdoc.initDocument(CONFIG.textFont, THEME)
|
||||
|
||||
qdoc._isNovel = True
|
||||
qdoc._isFirst = True
|
||||
qdoc.setComments(True)
|
||||
qdoc.setSynopsis(True)
|
||||
qdoc.setKeywords(True)
|
||||
qdoc._text = (
|
||||
"### Scene\n\n"
|
||||
"@pov: Jane\n"
|
||||
"@char: John, Bob\n\n"
|
||||
"%Synopsis: Stuff that happened\n\n"
|
||||
"% A regular comment\n\n"
|
||||
"Text\n\n"
|
||||
)
|
||||
qdoc.tokenizeText()
|
||||
qdoc.doConvert()
|
||||
assert qdoc.document.blockCount() == 6
|
||||
|
||||
# 0: Scene
|
||||
block = qdoc.document.findBlockByNumber(0)
|
||||
assert block.text() == "Scene"
|
||||
|
||||
# 1: Jane
|
||||
block = qdoc.document.findBlockByNumber(1)
|
||||
assert block.text() == "Point of View: Jane"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mMeta[0]
|
||||
assert bFmt.bottomMargin() == 0.0
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.foreground().color() == THEME.keyword
|
||||
cFmt = charFmtInBlock(block, 16)
|
||||
assert cFmt.foreground().color() == THEME.tag
|
||||
|
||||
# 2: John, Bob
|
||||
block = qdoc.document.findBlockByNumber(2)
|
||||
assert block.text() == "Characters: John, Bob"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == 0.0
|
||||
assert bFmt.bottomMargin() == qdoc._mMeta[1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.foreground().color() == THEME.keyword
|
||||
cFmt = charFmtInBlock(block, 13)
|
||||
assert cFmt.foreground().color() == THEME.tag
|
||||
|
||||
# 3: Synopsis
|
||||
block = qdoc.document.findBlockByNumber(3)
|
||||
assert block.text() == "Synopsis: Stuff that happened"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mText[0]
|
||||
assert bFmt.bottomMargin() == qdoc._mText[1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.foreground().color() == THEME.modifier
|
||||
cFmt = charFmtInBlock(block, 11)
|
||||
assert cFmt.foreground().color() == THEME.note
|
||||
|
||||
# 4: Comment
|
||||
block = qdoc.document.findBlockByNumber(4)
|
||||
assert block.text() == "Comment: A regular comment"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mText[0]
|
||||
assert bFmt.bottomMargin() == qdoc._mText[1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.foreground().color() == THEME.comment
|
||||
cFmt = charFmtInBlock(block, 10)
|
||||
assert cFmt.foreground().color() == THEME.comment
|
||||
|
||||
# 5: Text
|
||||
block = qdoc.document.findBlockByNumber(5)
|
||||
assert block.text() == "Text"
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToQTextDocument_NoteMeta(mockGUI):
|
||||
"""Test note meta formats in the ToQTextDocument class."""
|
||||
project = NWProject()
|
||||
qdoc = ToQTextDocument(project)
|
||||
qdoc.initDocument(CONFIG.textFont, THEME)
|
||||
|
||||
qdoc._isNovel = False
|
||||
qdoc._isFirst = True
|
||||
qdoc.setComments(True)
|
||||
qdoc.setSynopsis(True)
|
||||
qdoc.setKeywords(True)
|
||||
qdoc._text = (
|
||||
"# Jane Smith\n\n"
|
||||
"@tag: Jane | Jane Smith\n"
|
||||
"%Short: All about Jane\n\n"
|
||||
"Text\n\n"
|
||||
)
|
||||
qdoc.tokenizeText()
|
||||
qdoc.doConvert()
|
||||
assert qdoc.document.blockCount() == 4
|
||||
|
||||
# 0: Title
|
||||
block = qdoc.document.findBlockByNumber(0)
|
||||
assert block.text() == "Jane Smith"
|
||||
|
||||
# 1: Tag
|
||||
block = qdoc.document.findBlockByNumber(1)
|
||||
assert block.text() == "Tag: Jane | Jane Smith"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mMeta[0]
|
||||
assert bFmt.bottomMargin() == qdoc._mMeta[1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.foreground().color() == THEME.keyword
|
||||
cFmt = charFmtInBlock(block, 6)
|
||||
assert cFmt.foreground().color() == THEME.tag
|
||||
cFmt = charFmtInBlock(block, 11)
|
||||
assert cFmt.foreground().color() == THEME.text
|
||||
cFmt = charFmtInBlock(block, 13)
|
||||
assert cFmt.foreground().color() == THEME.optional
|
||||
|
||||
# 2: Short
|
||||
block = qdoc.document.findBlockByNumber(2)
|
||||
assert block.text() == "Short Description: All about Jane"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.topMargin() == qdoc._mText[0]
|
||||
assert bFmt.bottomMargin() == qdoc._mText[1]
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.foreground().color() == THEME.modifier
|
||||
cFmt = charFmtInBlock(block, 20)
|
||||
assert cFmt.foreground().color() == THEME.note
|
||||
|
||||
# 3: Text
|
||||
block = qdoc.document.findBlockByNumber(3)
|
||||
assert block.text() == "Text"
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToQTextDocument_TextBlockFormats(mockGUI):
|
||||
"""Test text block formats in the ToQTextDocument class."""
|
||||
project = NWProject()
|
||||
qdoc = ToQTextDocument(project)
|
||||
qdoc.setFirstLineIndent(True, 2.0, False)
|
||||
qdoc.initDocument(CONFIG.textFont, THEME)
|
||||
|
||||
qdoc._isNovel = True
|
||||
qdoc._isFirst = True
|
||||
|
||||
# Alignment & Indent
|
||||
# ==================
|
||||
qdoc.document.clear()
|
||||
|
||||
qdoc._text = (
|
||||
"### Scene\n\n"
|
||||
"Left <<\n\n"
|
||||
">> Center <<\n\n"
|
||||
">> Right\n\n"
|
||||
"> Left Indent\n\n"
|
||||
"Right Indent <\n\n"
|
||||
"> Double Indent <\n\n"
|
||||
"Text Indent\n\n"
|
||||
)
|
||||
qdoc.tokenizeText()
|
||||
qdoc.doConvert()
|
||||
assert qdoc.document.blockCount() == 8
|
||||
|
||||
# 0: Scene
|
||||
block = qdoc.document.findBlockByNumber(0)
|
||||
assert block.text() == "Scene"
|
||||
|
||||
# 1: Left
|
||||
block = qdoc.document.findBlockByNumber(1)
|
||||
assert block.text() == "Left"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.alignment() == QtAlignLeft
|
||||
|
||||
# 2: Center
|
||||
block = qdoc.document.findBlockByNumber(2)
|
||||
assert block.text() == "Center"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.alignment() == QtAlignCenter
|
||||
|
||||
# 3: Right
|
||||
block = qdoc.document.findBlockByNumber(3)
|
||||
assert block.text() == "Right"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.alignment() == QtAlignRight
|
||||
|
||||
# 4: Left Indent
|
||||
block = qdoc.document.findBlockByNumber(4)
|
||||
assert block.text() == "Left Indent"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.alignment() == QtAlignAbsolute
|
||||
assert bFmt.leftMargin() == qdoc._mIndent
|
||||
assert bFmt.rightMargin() == 0.0
|
||||
|
||||
# 5: Right Indent
|
||||
block = qdoc.document.findBlockByNumber(5)
|
||||
assert block.text() == "Right Indent"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.alignment() == QtAlignAbsolute
|
||||
assert bFmt.leftMargin() == 0.0
|
||||
assert bFmt.rightMargin() == qdoc._mIndent
|
||||
|
||||
# 6: Double Indent
|
||||
block = qdoc.document.findBlockByNumber(6)
|
||||
assert block.text() == "Double Indent"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.alignment() == QtAlignAbsolute
|
||||
assert bFmt.leftMargin() == qdoc._mIndent
|
||||
assert bFmt.rightMargin() == qdoc._mIndent
|
||||
|
||||
# 7: Text Indent
|
||||
block = qdoc.document.findBlockByNumber(7)
|
||||
assert block.text() == "Text Indent"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.alignment() == QtAlignAbsolute
|
||||
assert bFmt.textIndent() == qdoc._tIndent
|
||||
assert bFmt.leftMargin() == 0.0
|
||||
assert bFmt.rightMargin() == 0.0
|
||||
|
||||
# Unreachable
|
||||
# ===========
|
||||
# Some formatting markers are currently not reachable
|
||||
qdoc.document.clear()
|
||||
|
||||
qdoc._tokens = [
|
||||
(qdoc.T_TEXT, 1, "This is justified", [], qdoc.A_JUSTIFY),
|
||||
(qdoc.T_TEXT, 1, "This has a page break", [], qdoc.A_PBA),
|
||||
]
|
||||
qdoc.doConvert()
|
||||
assert qdoc.document.blockCount() == 2
|
||||
|
||||
# 0: Justify
|
||||
block = qdoc.document.findBlockByNumber(0)
|
||||
assert block.text() == "This is justified"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.alignment() == QtAlignJustify
|
||||
|
||||
# 1: Page Break After
|
||||
block = qdoc.document.findBlockByNumber(1)
|
||||
assert block.text() == "This has a page break"
|
||||
bFmt = block.blockFormat()
|
||||
assert bFmt.pageBreakPolicy() == QtPageBreakAfter
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToQTextDocument_TextCharFormats(mockGUI):
|
||||
"""Test text char formats in the ToQTextDocument class."""
|
||||
CONFIG.fmtDQuoteOpen = nwUnicode.U_LDQUO
|
||||
CONFIG.fmtDQuoteClose = nwUnicode.U_RDQUO
|
||||
CONFIG.altDialogOpen = "|<"
|
||||
CONFIG.altDialogClose = ">|"
|
||||
|
||||
project = NWProject()
|
||||
qdoc = ToQTextDocument(project)
|
||||
|
||||
# Convert before init
|
||||
qdoc._text = "Blabla"
|
||||
qdoc.setDialogueHighlight(True)
|
||||
qdoc.doConvert()
|
||||
qdoc.tokenizeText()
|
||||
assert qdoc.document.toPlainText() == ""
|
||||
|
||||
# Init
|
||||
qdoc.initDocument(CONFIG.textFont, THEME)
|
||||
|
||||
qdoc._isNovel = True
|
||||
qdoc._isFirst = True
|
||||
|
||||
qdoc._text = (
|
||||
"### Scene\n\n"
|
||||
"With [b]bold[/b] text\n\n"
|
||||
"With [i]italic[/i] text\n\n"
|
||||
"With [s]deleted[/s] text\n\n"
|
||||
"With [u]underlined[/u] text\n\n"
|
||||
"With [m]highlighted[/m] text\n\n"
|
||||
"With super[sup]script[/sup] text\n\n"
|
||||
"With sub[sub]script[/sub] text\n\n"
|
||||
"With \u201cdialog\u201d text\n\n"
|
||||
"With |<alternative dialog>| text\n\n"
|
||||
)
|
||||
qdoc.tokenizeText()
|
||||
qdoc.doConvert()
|
||||
assert qdoc.document.blockCount() == 10
|
||||
|
||||
# 0: Scene
|
||||
block = qdoc.document.findBlockByNumber(0)
|
||||
assert block.text() == "Scene"
|
||||
|
||||
# 1: Bold
|
||||
block = qdoc.document.findBlockByNumber(1)
|
||||
assert block.text() == "With bold text"
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.fontWeight() == qdoc._normal
|
||||
cFmt = charFmtInBlock(block, 6)
|
||||
assert cFmt.fontWeight() == qdoc._bold
|
||||
cFmt = charFmtInBlock(block, 10)
|
||||
assert cFmt.fontWeight() == qdoc._normal
|
||||
|
||||
# 2: Italic
|
||||
block = qdoc.document.findBlockByNumber(2)
|
||||
assert block.text() == "With italic text"
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.fontItalic() is False
|
||||
cFmt = charFmtInBlock(block, 6)
|
||||
assert cFmt.fontItalic() is True
|
||||
cFmt = charFmtInBlock(block, 12)
|
||||
assert cFmt.fontItalic() is False
|
||||
|
||||
# 3: Deleted
|
||||
block = qdoc.document.findBlockByNumber(3)
|
||||
assert block.text() == "With deleted text"
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.fontStrikeOut() is False
|
||||
cFmt = charFmtInBlock(block, 6)
|
||||
assert cFmt.fontStrikeOut() is True
|
||||
cFmt = charFmtInBlock(block, 13)
|
||||
assert cFmt.fontStrikeOut() is False
|
||||
|
||||
# 4: Underlined
|
||||
block = qdoc.document.findBlockByNumber(4)
|
||||
assert block.text() == "With underlined text"
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.fontUnderline() is False
|
||||
cFmt = charFmtInBlock(block, 6)
|
||||
assert cFmt.fontUnderline() is True
|
||||
cFmt = charFmtInBlock(block, 16)
|
||||
assert cFmt.fontUnderline() is False
|
||||
|
||||
# 5: Highlighted
|
||||
block = qdoc.document.findBlockByNumber(5)
|
||||
assert block.text() == "With highlighted text"
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.background() == QtTransparent
|
||||
cFmt = charFmtInBlock(block, 6)
|
||||
assert cFmt.background() == THEME.highlight
|
||||
cFmt = charFmtInBlock(block, 17)
|
||||
assert cFmt.background() == QtTransparent
|
||||
|
||||
# 6: Superscript
|
||||
block = qdoc.document.findBlockByNumber(6)
|
||||
assert block.text() == "With superscript text"
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.verticalAlignment() == QtVAlignNormal
|
||||
cFmt = charFmtInBlock(block, 11)
|
||||
assert cFmt.verticalAlignment() == QtVAlignSuper
|
||||
cFmt = charFmtInBlock(block, 17)
|
||||
assert cFmt.verticalAlignment() == QtVAlignNormal
|
||||
|
||||
# 7: Subscript
|
||||
block = qdoc.document.findBlockByNumber(7)
|
||||
assert block.text() == "With subscript text"
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.verticalAlignment() == QtVAlignNormal
|
||||
cFmt = charFmtInBlock(block, 9)
|
||||
assert cFmt.verticalAlignment() == QtVAlignSub
|
||||
cFmt = charFmtInBlock(block, 15)
|
||||
assert cFmt.verticalAlignment() == QtVAlignNormal
|
||||
|
||||
# 8: Dialogue
|
||||
block = qdoc.document.findBlockByNumber(8)
|
||||
assert block.text() == "With \u201cdialog\u201d text"
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.foreground() == THEME.text
|
||||
cFmt = charFmtInBlock(block, 6)
|
||||
assert cFmt.foreground() == THEME.dialog
|
||||
cFmt = charFmtInBlock(block, 14)
|
||||
assert cFmt.foreground() == THEME.text
|
||||
|
||||
# 9: Alt. Dialogue
|
||||
block = qdoc.document.findBlockByNumber(9)
|
||||
assert block.text() == "With |<alternative dialog>| text"
|
||||
cFmt = charFmtInBlock(block, 1)
|
||||
assert cFmt.foreground() == THEME.text
|
||||
cFmt = charFmtInBlock(block, 6)
|
||||
assert cFmt.foreground() == THEME.altdialog
|
||||
cFmt = charFmtInBlock(block, 28)
|
||||
assert cFmt.foreground() == THEME.text
|
||||
|
||||
|
||||
@pytest.mark.core
|
||||
def testCoreToQTextDocument_Footnotes(mockGUI):
|
||||
"""Test footnotes in the ToQTextDocument class."""
|
||||
project = NWProject()
|
||||
qdoc = ToQTextDocument(project)
|
||||
qdoc.initDocument(CONFIG.textFont, THEME)
|
||||
|
||||
qdoc._isNovel = True
|
||||
qdoc._isFirst = True
|
||||
|
||||
qdoc._text = (
|
||||
"### Scene\n\n"
|
||||
"Text with valid[footnote:fn1] and invalid[footnote:fn2] footnotes.\n\n"
|
||||
"%Footnote.fn1: Here's the first note.\n\n"
|
||||
)
|
||||
qdoc.tokenizeText()
|
||||
qdoc.doConvert()
|
||||
qdoc.appendFootnotes()
|
||||
assert qdoc.document.blockCount() == 4
|
||||
|
||||
# 0: Scene
|
||||
block = qdoc.document.findBlockByNumber(0)
|
||||
assert block.text() == "Scene"
|
||||
|
||||
# 1: Text
|
||||
block = qdoc.document.findBlockByNumber(1)
|
||||
assert block.text() == "Text with valid[1] and invalid[ERR] footnotes."
|
||||
|
||||
# 2: Footnotes
|
||||
block = qdoc.document.findBlockByNumber(2)
|
||||
assert block.text() == "Footnotes"
|
||||
|
||||
# 3: Footnote 1
|
||||
block = qdoc.document.findBlockByNumber(3)
|
||||
assert block.text() == "1. Here's the first note."
|
||||
Reference in New Issue
Block a user