예제 #1
0
    def _buildPreview(self):
        """Build a preview of the project in the document viewer.
        """
        # Get Settings
        justifyText = self.justifyText.isChecked()
        noStyling = self.noStyling.isChecked()
        textFont = self.textFont.text()
        textSize = self.textSize.value()
        replaceTabs = self.replaceTabs.isChecked()

        self.htmlText = []
        self.htmlStyle = []
        self.htmlSize = 0

        # Build Preview
        # =============

        makeHtml = ToHtml(self.theProject, self.theParent)
        self._doBuild(makeHtml, isPreview=True)
        if replaceTabs:
            makeHtml.replaceTabs()

        self.htmlText = makeHtml.fullHTML
        self.htmlStyle = makeHtml.getStyleSheet()
        self.htmlSize = makeHtml.getFullResultSize()
        self.buildTime = int(time())

        # Load Preview
        # ============

        self.docView.setTextFont(textFont, textSize)
        self.docView.setJustify(justifyText)
        if noStyling:
            self.docView.clearStyleSheet()
        else:
            self.docView.setStyleSheet(self.htmlStyle)

        if self.htmlSize < nwConst.MAX_BUILDSIZE:
            self.docView.setContent(self.htmlText, self.buildTime)
        else:
            self.docView.setText(
                "Failed to generate preview. The result is too big.")

        self._saveCache()

        return
예제 #2
0
파일: build.py 프로젝트: Jiaogh/novelWriter
    def _buildPreview(self):
        """Build a preview of the project in the document viewer.
        """
        # Get Settings
        fmtTitle = self.fmtTitle.text().strip()
        fmtChapter = self.fmtChapter.text().strip()
        fmtUnnumbered = self.fmtUnnumbered.text().strip()
        fmtScene = self.fmtScene.text().strip()
        fmtSection = self.fmtSection.text().strip()
        justifyText = self.justifyText.isChecked()
        noStyling = self.noStyling.isChecked()
        textFont = self.textFont.text()
        textSize = self.textSize.value()
        incSynopsis = self.includeSynopsis.isChecked()
        incComments = self.includeComments.isChecked()
        incKeywords = self.includeKeywords.isChecked()
        novelFiles = self.novelFiles.isChecked()
        noteFiles = self.noteFiles.isChecked()
        ignoreFlag = self.ignoreFlag.isChecked()
        includeBody = self.includeBody.isChecked()
        replaceTabs = self.replaceTabs.isChecked()

        makeHtml = ToHtml(self.theProject, self.theParent)
        makeHtml.setTitleFormat(fmtTitle)
        makeHtml.setChapterFormat(fmtChapter)
        makeHtml.setUnNumberedFormat(fmtUnnumbered)
        makeHtml.setSceneFormat(fmtScene, fmtScene == "")
        makeHtml.setSectionFormat(fmtSection, fmtSection == "")
        makeHtml.setBodyText(includeBody)
        makeHtml.setSynopsis(incSynopsis)
        makeHtml.setComments(incComments)
        makeHtml.setKeywords(incKeywords)
        makeHtml.setJustify(justifyText)
        makeHtml.setStyles(not noStyling)

        # Make sure the tree order is correct
        self.theParent.treeView.flushTreeOrder()

        self.buildProgress.setMaximum(len(self.theProject.projTree))
        self.buildProgress.setValue(0)

        tStart = int(time())

        self.htmlText = []
        self.htmlStyle = []
        self.nwdText = []

        htmlSize = 0

        for nItt, tItem in enumerate(self.theProject.projTree):

            noteRoot = noteFiles
            noteRoot &= tItem.itemType == nwItemType.ROOT
            noteRoot &= tItem.itemClass != nwItemClass.NOVEL
            noteRoot &= tItem.itemClass != nwItemClass.ARCHIVE

            try:
                if noteRoot:
                    # Add headers for root folders of notes
                    makeHtml.addRootHeading(tItem.itemHandle)
                    makeHtml.doConvert()
                    self.htmlText.append(makeHtml.getResult())
                    self.nwdText.append(makeHtml.getFilteredMarkdown())
                    htmlSize += makeHtml.getResultSize()

                elif self._checkInclude(tItem, noteFiles, novelFiles,
                                        ignoreFlag):
                    makeHtml.setText(tItem.itemHandle)
                    makeHtml.doAutoReplace()
                    makeHtml.tokenizeText()
                    makeHtml.doHeaders()
                    makeHtml.doConvert()
                    makeHtml.doPostProcessing()
                    self.htmlText.append(makeHtml.getResult())
                    self.nwdText.append(makeHtml.getFilteredMarkdown())
                    htmlSize += makeHtml.getResultSize()

            except Exception as e:
                logger.error("Failed to generate html of document '%s'" %
                             tItem.itemHandle)
                logger.error(str(e))
                self.docView.setText(
                    ("Failed to generate preview. "
                     "Document with title '%s' could not be parsed.") %
                    tItem.itemName)
                return False

            # Update progress bar, also for skipped items
            self.buildProgress.setValue(nItt + 1)

        if makeHtml.errData:
            self.theParent.makeAlert(
                ("There were problems when building the project:"
                 "<br>-&nbsp;%s") % "<br>-&nbsp;".join(makeHtml.errData),
                nwAlert.ERROR)

        if replaceTabs:
            htmlText = []
            eightSpace = "&nbsp;" * 8
            for aLine in self.htmlText:
                htmlText.append(aLine.replace("\t", eightSpace))
            self.htmlText = htmlText

            nwdText = []
            for aLine in self.nwdText:
                nwdText.append(aLine.replace("\t", "        "))
            self.nwdText = nwdText

        tEnd = int(time())
        logger.debug("Built project in %.3f ms" % (1000 * (tEnd - tStart)))
        self.htmlStyle = makeHtml.getStyleSheet()
        self.buildTime = tEnd

        # Load the preview document with the html data
        self.docView.setTextFont(textFont, textSize)
        self.docView.setJustify(justifyText)
        if noStyling:
            self.docView.clearStyleSheet()
        else:
            self.docView.setStyleSheet(self.htmlStyle)

        if htmlSize < nwConst.maxBuildSize:
            self.docView.setContent(self.htmlText, self.buildTime)
            self._enableQtSave(True)
        else:
            self.docView.setText(
                "Failed to generate preview. The result is too big.")
            self._enableQtSave(False)

        self._saveCache()

        return
예제 #3
0
def testCoreToHtml_Convert(dummyGUI):
    """Test the converter of the ToHtml class.
    """
    theProject = NWProject(dummyGUI)
    dummyGUI.theIndex = NWIndex(theProject, dummyGUI)
    theHtml = ToHtml(theProject, dummyGUI)

    # Export Mode
    # ===========

    theHtml.isNovel = True

    # Header 1
    theHtml.theText = "# Title\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == "<h1 class='title'>Title</h1>\n"

    # Header 2
    theHtml.theText = "## Chapter Title\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == "<h1>Chapter Title</h1>\n"

    # Header 3
    theHtml.theText = "### Scene Title\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == "<h2>Scene Title</h2>\n"

    # Header 4
    theHtml.theText = "#### Section Title\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == "<h3>Section Title</h3>\n"

    theHtml.isNovel = False
    theHtml.setLinkHeaders(True)

    # Header 1
    theHtml.theText = "# Heading One\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == "<h1><a name='T000001'></a>Heading One</h1>\n"

    # Header 2
    theHtml.theText = "## Heading Two\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == "<h2><a name='T000001'></a>Heading Two</h2>\n"

    # Header 3
    theHtml.theText = "### Heading Three\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == "<h3><a name='T000001'></a>Heading Three</h3>\n"

    # Header 4
    theHtml.theText = "#### Heading Four\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == "<h4><a name='T000001'></a>Heading Four</h4>\n"

    # Text
    theHtml.theText = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<p>Some <strong>nested bold and <em>italic</em> and "
        "<del>strikethrough</del> text</strong> here</p>\n")

    # Text w/Hard Break
    theHtml.theText = "Line one  \nLine two  \nLine three\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<p class='break'>Line one<br/>Line two<br/>Line three</p>\n")

    # Synopsis
    theHtml.theText = "%synopsis: The synopsis ...\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == ""

    theHtml.setSynopsis(True)
    theHtml.theText = "%synopsis: The synopsis ...\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<p class='synopsis'><strong>Synopsis:</strong> The synopsis ...</p>\n"
    )

    # Comment
    theHtml.theText = "% A comment ...\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == ""

    theHtml.setComments(True)
    theHtml.theText = "% A comment ...\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<p class='comment'><strong>Comment:</strong> A comment ...</p>\n")

    # Keywords
    theHtml.theText = "@char: Bod, Jane\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == ""

    theHtml.setKeywords(True)
    theHtml.theText = "@char: Bod, Jane\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<p><span class='tags'>Characters:</span> "
        "<a href='#tag_Bod'>Bod</a>, <a href='#tag_Jane'>Jane</a></p>\n")

    # Multiple Keywords
    theHtml.setKeywords(True)
    theHtml.theText = "## Chapter\n\n@pov: Bod\n@plot: Main\n@location: Europe\n\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<h2>"
        "<a name='T000001'></a>Chapter</h2>\n"
        "<p style='margin-bottom: 0;'>"
        "<span class='tags'>Point of View:</span> <a href='#tag_Bod'>Bod</a>"
        "</p>\n"
        "<p style='margin-bottom: 0; margin-top: 0;'>"
        "<span class='tags'>Plot:</span> <a href='#tag_Main'>Main</a>"
        "</p>\n"
        "<p style='margin-top: 0;'>"
        "<span class='tags'>Locations:</span> <a href='#tag_Europe'>Europe</a>"
        "</p>\n")

    # Direct Tests
    # ============

    theHtml.isNovel = True

    # Title
    theHtml.theTokens = [
        (theHtml.T_TITLE, 1, "A Title", None,
         theHtml.A_PBB_AUT | theHtml.A_CENTRE),
        (theHtml.T_EMPTY, 1, "", None, theHtml.A_NONE),
    ]
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<h1 class='title' style='text-align: center; page-break-before: auto;'>"
        "<a name='T000001'></a>A Title</h1>\n")

    # Separator
    theHtml.theTokens = [
        (theHtml.T_SEP, 1, "* * *", None, theHtml.A_CENTRE),
        (theHtml.T_EMPTY, 1, "", None, theHtml.A_NONE),
    ]
    theHtml.doConvert()
    assert theHtml.theResult == "<p class='sep'>* * *</p>\n"

    # Skip
    theHtml.theTokens = [
        (theHtml.T_SKIP, 1, "", None, theHtml.A_NONE),
        (theHtml.T_EMPTY, 1, "", None, theHtml.A_NONE),
    ]
    theHtml.doConvert()
    assert theHtml.theResult == "<p class='skip'>&nbsp;</p>\n"

    # Styles
    # ======

    theHtml.setLinkHeaders(False)

    # Align Left
    theHtml.setStyles(False)
    theHtml.theTokens = [
        (theHtml.T_HEAD1, 1, "A Title", None, theHtml.A_LEFT),
    ]
    theHtml.doConvert()
    assert theHtml.theResult == ("<h1 class='title'>A Title</h1>\n")

    theHtml.setStyles(True)

    # Align Left
    theHtml.theTokens = [
        (theHtml.T_HEAD1, 1, "A Title", None, theHtml.A_LEFT),
    ]
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<h1 class='title' style='text-align: left;'>A Title</h1>\n")

    # Align Right
    theHtml.theTokens = [
        (theHtml.T_HEAD1, 1, "A Title", None, theHtml.A_RIGHT),
    ]
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<h1 class='title' style='text-align: right;'>A Title</h1>\n")

    # Align Centre
    theHtml.theTokens = [
        (theHtml.T_HEAD1, 1, "A Title", None, theHtml.A_CENTRE),
    ]
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<h1 class='title' style='text-align: center;'>A Title</h1>\n")

    # Align Justify
    theHtml.theTokens = [
        (theHtml.T_HEAD1, 1, "A Title", None, theHtml.A_JUSTIFY),
    ]
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<h1 class='title' style='text-align: justify;'>A Title</h1>\n")

    # Page Break Always
    theHtml.theTokens = [
        (theHtml.T_HEAD1, 1, "A Title", None, theHtml.A_PBB | theHtml.A_PBA),
    ]
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<h1 class='title' "
        "style='page-break-before: always; page-break-after: always;'>A Title</h1>\n"
    )

    # Page Break Auto
    theHtml.theTokens = [
        (theHtml.T_HEAD1, 1, "A Title", None,
         theHtml.A_PBB_AUT | theHtml.A_PBA_AUT),
    ]
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<h1 class='title' "
        "style='page-break-before: auto; page-break-after: auto;'>A Title</h1>\n"
    )

    # Preview Mode
    # ============

    theHtml.setPreview(True, True)

    # Text (HTML4)
    theHtml.theText = "Some **nested bold and _italic_ and ~~strikethrough~~ text** here\n"
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<p>Some <b>nested bold and <i>italic</i> and "
        "<span style='text-decoration: line-through;'>strikethrough</span> "
        "text</b> here</p>\n")
예제 #4
0
def testCoreToHtml_Methods(dummyGUI):
    """Test all the other methods of the ToHtml class.
    """
    theProject = NWProject(dummyGUI)
    theHtml = ToHtml(theProject, dummyGUI)
    theHtml.setKeepMarkdown(True)

    # Auto-Replace, keep Unicode
    docText = "Text with <brackets> & short–dash, long—dash …\n"
    theHtml.theText = docText
    theHtml.setReplaceUnicode(False)
    theHtml.doPreProcessing()
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<p>Text with &lt;brackets&gt; &amp; short–dash, long—dash …</p>\n")

    # Auto-Replace, replace Unicode
    docText = "Text with <brackets> & short–dash, long—dash …\n"
    theHtml.theText = docText
    theHtml.setReplaceUnicode(True)
    theHtml.doPreProcessing()
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<p>Text with &lt;brackets&gt; &amp; short&ndash;dash, long&mdash;dash &hellip;</p>\n"
    )

    # With Preview
    theHtml.setPreview(True, True)
    theHtml.theText = docText
    theHtml.doPreProcessing()
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theMarkdown[-1] == (
        "Text with &lt;brackets&gt; &amp; short&ndash;dash, long&mdash;dash &hellip;\n\n"
    )
    theHtml.doPostProcessing()
    assert theHtml.theMarkdown[-1] == (
        "Text with &lt;brackets&gt; &amp; short&ndash;dash, long&mdash;dash &hellip;\n\n"
    )

    # Result Size
    assert theHtml.getFullResultSize() == 147

    # CSS
    # ===

    assert len(theHtml.getStyleSheet()) > 1
    assert "p {text-align: left;" in " ".join(theHtml.getStyleSheet())
    assert "p {text-align: justify;" not in " ".join(theHtml.getStyleSheet())

    theHtml.setJustify(True)
    assert "p {text-align: left;" not in " ".join(theHtml.getStyleSheet())
    assert "p {text-align: justify;" in " ".join(theHtml.getStyleSheet())

    theHtml.setStyles(False)
    assert theHtml.getStyleSheet() == []
예제 #5
0
def testCoreToHtml_Complex(dummyGUI, fncDir):
    """Test the ave method of the ToHtml class.
    """
    theProject = NWProject(dummyGUI)
    theHtml = ToHtml(theProject, dummyGUI)

    # 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>My Novel</h1>\n<p><strong>By Jane Doh</strong></p>\n",
        "<h2>Chapter 1</h2>\n<p>The text of chapter one.</p>\n",
        "<h3>Scene 1</h3>\n<p>The text of scene one.</p>\n",
        "<h4>A Section</h4>\n<p>More text in scene one.</p>\n",
        "<h2>Chapter 2</h2>\n<p>The text of chapter two.</p>\n",
        "<h3>Scene 2</h3>\n<p>The text of scene two.</p>\n",
        "<h4>A Section</h4>\n<p>\tMore text in scene two.</p>\n",
    ]

    for i in range(len(docText)):
        theHtml.theText = docText[i]
        theHtml.doPreProcessing()
        theHtml.tokenizeText()
        theHtml.doConvert()
        assert theHtml.theResult == resText[i]

    assert theHtml.fullHTML == resText

    theHtml.replaceTabs(nSpaces=2, spaceChar="&nbsp;")
    resText[
        6] = "<h4>A Section</h4>\n<p>&nbsp;&nbsp;More text in scene two.</p>\n"

    # Check File
    # ==========

    theStyle = theHtml.getStyleSheet()
    theStyle.append("article {width: 800px; margin: 40px auto;}")
    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(theStyle),
                                   bodyText="".join(resText).rstrip())

    saveFile = os.path.join(fncDir, "outFile.htm")
    theHtml.saveHTML5(saveFile)
    assert readFile(saveFile) == htmlDoc
예제 #6
0
def testCoreToHtml_Format(dummyGUI):
    """Test all the formatters for the ToHtml class.
    """
    theProject = NWProject(dummyGUI)
    dummyGUI.theIndex = NWIndex(theProject, dummyGUI)
    theHtml = ToHtml(theProject, dummyGUI)

    # Export Mode
    # ===========

    assert theHtml._formatSynopsis("synopsis text") == (
        "<p class='synopsis'><strong>Synopsis:</strong> synopsis text</p>\n")
    assert theHtml._formatComments("comment text") == (
        "<p class='comment'><strong>Comment:</strong> comment text</p>\n")

    assert theHtml._formatKeywords("") == ""
    assert theHtml._formatKeywords("tag: Jane") == (
        "<span class='tags'>Tag:</span> <a name='tag_Jane'>Jane</a>")
    assert theHtml._formatKeywords("char: Bod, Jane") == (
        "<span class='tags'>Characters:</span> "
        "<a href='#tag_Bod'>Bod</a>, "
        "<a href='#tag_Jane'>Jane</a>")

    # Preview Mode
    # ============

    theHtml.setPreview(True, True)

    assert theHtml._formatSynopsis("synopsis text") == (
        "<p class='comment'><span class='synopsis'>Synopsis:</span> synopsis text</p>\n"
    )
    assert theHtml._formatComments("comment text") == (
        "<p class='comment'>comment text</p>\n")

    assert theHtml._formatKeywords("") == ""
    assert theHtml._formatKeywords("tag: Jane") == (
        "<span class='tags'>Tag:</span> <a name='tag_Jane'>Jane</a>")
    assert theHtml._formatKeywords("char: Bod, Jane") == (
        "<span class='tags'>Characters:</span> "
        "<a href='#char=Bod'>Bod</a>, "
        "<a href='#char=Jane'>Jane</a>")
예제 #7
0
def testCoreToHtml_Methods(dummyGUI):
    """Test all the other methods of the ToHtml class.
    """
    theProject = NWProject(dummyGUI)
    theHtml = ToHtml(theProject, dummyGUI)

    # Auto-Replace
    docText = "Text with <brackets> & short–dash, long—dash …\n"
    theHtml.theText = docText
    theHtml.doAutoReplace()
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theResult == (
        "<p>Text with &lt;brackets&gt; &amp; short&ndash;dash, long&mdash;dash &hellip;</p>\n"
    )

    # Revert on MD
    assert theHtml.theMarkdown == (
        "Text with &lt;brackets&gt; &amp; short&ndash;dash, long&mdash;dash &hellip;\n\n"
    )
    theHtml.doPostProcessing()
    assert theHtml.theMarkdown == docText + "\n"

    # With Preview, No Revert
    theHtml.setPreview(True, True)
    theHtml.theText = docText
    theHtml.doAutoReplace()
    theHtml.tokenizeText()
    theHtml.doConvert()
    assert theHtml.theMarkdown == (
        "Text with &lt;brackets&gt; &amp; short&ndash;dash, long&mdash;dash &hellip;\n\n"
    )
    theHtml.doPostProcessing()
    assert theHtml.theMarkdown == (
        "Text with &lt;brackets&gt; &amp; short&ndash;dash, long&mdash;dash &hellip;\n\n"
    )

    # CSS
    # ===

    assert len(theHtml.getStyleSheet()) > 1
    assert "p {text-align: left;}" in theHtml.getStyleSheet()
    assert "p {text-align: justify;}" not in theHtml.getStyleSheet()

    theHtml.setJustify(True)
    assert "p {text-align: left;}" not in theHtml.getStyleSheet()
    assert "p {text-align: justify;}" in theHtml.getStyleSheet()

    theHtml.setStyles(False)
    assert theHtml.getStyleSheet() == []
예제 #8
0
    def loadText(self, tHandle, updateHistory=True):
        """Load text into the viewer from an item handle.
        """
        tItem = self.theProject.projTree[tHandle]
        if tItem is None:
            logger.warning("Item not found")
            return False

        if tItem.itemType != nwItemType.FILE:
            return False

        logger.debug("Generating preview for item %s" % tHandle)
        qApp.setOverrideCursor(QCursor(Qt.WaitCursor))

        sPos = self.verticalScrollBar().value()
        aDoc = ToHtml(self.theProject, self.theParent)
        aDoc.setPreview(True, self.mainConf.viewComments,
                        self.mainConf.viewSynopsis)
        aDoc.setLinkHeaders(True)

        # Be extra careful here to prevent crashes when first opening a
        # project as a crash here leaves no way of recovering.
        # See issue #298
        try:
            aDoc.setText(tHandle)
            aDoc.doAutoReplace()
            aDoc.tokenizeText()
            aDoc.doConvert()
            aDoc.doPostProcessing()
        except Exception as e:
            logger.error(
                "Failed to generate preview for document with handle '%s'" %
                tHandle)
            logger.error(str(e))
            self.setText("An error occurred while generating the preview.")
            return False

        # Refresh the tab stops
        if self.mainConf.verQtValue >= 51000:
            self.setTabStopDistance(self.mainConf.getTabWidth())
        else:
            self.setTabStopWidth(self.mainConf.getTabWidth())

        # Must be before setHtml
        if updateHistory:
            self.docHistory.append(tHandle)

        self.setHtml(aDoc.theResult.replace("\t", "!!tab!!"))
        self.setDocumentTitle(tHandle)

        # Loop through the text and put back in the tabs. Tabs are removed by
        # the setHtml function, so the ToHtml class puts in a placeholder.
        while self.find("!!tab!!"):
            theCursor = self.textCursor()
            theCursor.insertText("\t")

        if self.theHandle == tHandle:
            self.verticalScrollBar().setValue(sPos)
        self.theHandle = tHandle
        self.theProject.setLastViewed(tHandle)
        self.docHeader.setTitleFromHandle(self.theHandle)
        self.updateDocMargins()

        # Make sure the main GUI knows we changed the content
        self.theParent.viewMeta.refreshReferences(tHandle)

        # Since we change the content while it may still be rendering, we mark
        # the document dirty again to make sure it's re-rendered properly.
        self.redrawText()
        qApp.restoreOverrideCursor()

        return True
예제 #9
0
    def _saveDocument(self, theFmt):
        """Save the document to various formats.
        """
        replaceTabs = self.replaceTabs.isChecked()

        fileExt = ""
        textFmt = ""

        # Settings
        # ========

        if theFmt == self.FMT_ODT:
            fileExt = "odt"
            textFmt = self.tr("Open Document")

        elif theFmt == self.FMT_FODT:
            fileExt = "fodt"
            textFmt = self.tr("Flat Open Document")

        elif theFmt == self.FMT_HTM:
            fileExt = "htm"
            textFmt = self.tr("Plain HTML")

        elif theFmt == self.FMT_NWD:
            fileExt = "nwd"
            textFmt = self.tr("novelWriter Markdown")

        elif theFmt == self.FMT_MD:
            fileExt = "md"
            textFmt = self.tr("Standard Markdown")

        elif theFmt == self.FMT_GH:
            fileExt = "md"
            textFmt = self.tr("GitHub Markdown")

        elif theFmt == self.FMT_JSON_H:
            fileExt = "json"
            textFmt = self.tr("JSON + novelWriter HTML")

        elif theFmt == self.FMT_JSON_M:
            fileExt = "json"
            textFmt = self.tr("JSON + novelWriter Markdown")

        elif theFmt == self.FMT_PDF:
            fileExt = "pdf"
            textFmt = self.tr("PDF")

        else:
            return False

        # Generate File Name
        # ==================

        if fileExt:

            cleanName = makeFileNameSafe(self.theProject.projName)
            fileName = "%s.%s" % (cleanName, fileExt)
            saveDir = self.mainConf.lastPath
            savePath = os.path.join(saveDir, fileName)
            if not os.path.isdir(saveDir):
                saveDir = self.mainConf.homePath

            savePath, _ = QFileDialog.getSaveFileName(
                self, self.tr("Save Document As"), savePath)
            if not savePath:
                return False

            self.mainConf.setLastPath(savePath)

        else:
            return False

        # Build and Write
        # ===============

        errMsg = ""
        wSuccess = False

        if theFmt == self.FMT_ODT:
            makeOdt = ToOdt(self.theProject, self.theParent, isFlat=False)
            self._doBuild(makeOdt)
            try:
                makeOdt.saveOpenDocText(savePath)
                wSuccess = True
            except Exception as e:
                errMsg = str(e)

        elif theFmt == self.FMT_FODT:
            makeOdt = ToOdt(self.theProject, self.theParent, isFlat=True)
            self._doBuild(makeOdt)
            try:
                makeOdt.saveFlatXML(savePath)
                wSuccess = True
            except Exception as e:
                errMsg = str(e)

        elif theFmt == self.FMT_HTM:
            makeHtml = ToHtml(self.theProject, self.theParent)
            self._doBuild(makeHtml)
            if replaceTabs:
                makeHtml.replaceTabs()

            try:
                makeHtml.saveHTML5(savePath)
                wSuccess = True
            except Exception as e:
                errMsg = str(e)

        elif theFmt == self.FMT_NWD:
            makeNwd = ToMarkdown(self.theProject, self.theParent)
            makeNwd.setKeepMarkdown(True)
            self._doBuild(makeNwd, doConvert=False)
            if replaceTabs:
                makeNwd.replaceTabs(spaceChar=" ")

            try:
                makeNwd.saveRawMarkdown(savePath)
                wSuccess = True
            except Exception as e:
                errMsg = str(e)

        elif theFmt in (self.FMT_MD, self.FMT_GH):
            makeMd = ToMarkdown(self.theProject, self.theParent)
            if theFmt == self.FMT_GH:
                makeMd.setGitHubMarkdown()
            else:
                makeMd.setStandardMarkdown()

            self._doBuild(makeMd)
            if replaceTabs:
                makeMd.replaceTabs(nSpaces=4, spaceChar=" ")

            try:
                makeMd.saveMarkdown(savePath)
                wSuccess = True
            except Exception as e:
                errMsg = str(e)

        elif theFmt == self.FMT_JSON_H or theFmt == self.FMT_JSON_M:
            jsonData = {
                "meta": {
                    "workingTitle": self.theProject.projName,
                    "novelTitle": self.theProject.bookTitle,
                    "authors": self.theProject.bookAuthors,
                    "buildTime": self.buildTime,
                }
            }

            if theFmt == self.FMT_JSON_H:
                makeHtml = ToHtml(self.theProject, self.theParent)
                self._doBuild(makeHtml)
                if replaceTabs:
                    makeHtml.replaceTabs()

                theBody = []
                for htmlPage in makeHtml.fullHTML:
                    theBody.append(htmlPage.rstrip("\n").split("\n"))
                jsonData["text"] = {
                    "css": self.htmlStyle,
                    "html": theBody,
                }

            elif theFmt == self.FMT_JSON_M:
                makeMd = ToHtml(self.theProject, self.theParent)
                makeMd.setKeepMarkdown(True)
                self._doBuild(makeMd, doConvert=False)
                if replaceTabs:
                    makeMd.replaceTabs(spaceChar=" ")

                theBody = []
                for nwdPage in makeMd.theMarkdown:
                    theBody.append(nwdPage.split("\n"))
                jsonData["text"] = {
                    "nwd": theBody,
                }

            try:
                with open(savePath, mode="w", encoding="utf8") as outFile:
                    outFile.write(json.dumps(jsonData, indent=2))
                    wSuccess = True
            except Exception as e:
                errMsg = str(e)

        elif theFmt == self.FMT_PDF:
            try:
                thePrinter = QPrinter()
                thePrinter.setOutputFormat(QPrinter.PdfFormat)
                thePrinter.setOrientation(QPrinter.Portrait)
                thePrinter.setDuplex(QPrinter.DuplexLongSide)
                thePrinter.setFontEmbeddingEnabled(True)
                thePrinter.setColorMode(QPrinter.Color)
                thePrinter.setOutputFileName(savePath)
                self.docView.qDocument.print(thePrinter)
                wSuccess = True

            except Exception as e:
                errMsg - str(e)

        else:
            errMsg = self.tr("Unknown format")

        # Report to user
        if wSuccess:
            self.theParent.makeAlert(
                "%s<br>%s" %
                (self.tr("{0} file successfully written to:").format(textFmt),
                 savePath), nwAlert.INFO)
        else:
            self.theParent.makeAlert(
                self.tr("Failed to write {0} file. {1}").format(
                    textFmt, errMsg), nwAlert.ERROR)

        return wSuccess