From 70cfc56afa89199ff256d5323490ab46a7649447 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Mon, 28 Oct 2019 17:11:14 +0100
Subject: [PATCH 1/4] Some cleanup of the export GUI
---
nw/gui/export.py | 52 +++++++++++++++++++++---------------------------
1 file changed, 23 insertions(+), 29 deletions(-)
diff --git a/nw/gui/export.py b/nw/gui/export.py
index 1477f174..f7108c2d 100644
--- a/nw/gui/export.py
+++ b/nw/gui/export.py
@@ -217,21 +217,19 @@ class GuiExport(QDialog):
class GuiExportMain(QWidget):
- FMT_NWD = 1 # novelWriter markdown
- FMT_TXT = 2 # Plain text file
- FMT_MD = 3 # Markdown file
- FMT_HTML = 4 # HTML file
- FMT_EBOOK = 5 # E-book friendly HTML
- FMT_ODT = 6 # Open document
- FMT_TEX = 7 # LaTeX file
- FMT_EXT = {
- FMT_NWD : ".nwd",
- FMT_TXT : ".txt",
- FMT_MD : ".md",
- FMT_HTML : ".htm",
- FMT_EBOOK : ".htm",
- FMT_ODT : ".odt",
- FMT_TEX : ".tex",
+ FMT_NWD = 1 # novelWriter markdown
+ FMT_TXT = 2 # Plain text file
+ FMT_MD = 3 # Markdown file
+ FMT_HTML = 4 # HTML file
+ FMT_TEX = 5 # LaTeX file
+ FMT_PDOC = 6 # Pass to pandoc
+ FMT_EXT = {
+ FMT_NWD : ".nwd",
+ FMT_TXT : ".txt",
+ FMT_MD : ".md",
+ FMT_HTML : ".htm",
+ FMT_TEX : ".tex",
+ FMT_PDOC : ".htm",
}
FMT_HELP = {
FMT_NWD : (
@@ -250,18 +248,14 @@ class GuiExportMain(QWidget):
"Exports a plain html5 file. "
"Comments are wrapped in blocks with a yellow background colour."
),
- FMT_EBOOK : (
- "Exports an html5 file that can be converted to eBook with Calibre. "
- "Comments are not exported in this format."
- ),
- FMT_ODT : (
- "Exports an open document file that can be read by office applications. "
- "Comments are exported as grey text."
- ),
FMT_TEX : (
"Exports a LaTeX file that can be compiled to PDF using for instance PDFLaTeX. "
"Comments are exported as LaTeX comments."
),
+ FMT_PDOC : (
+ "Exports first to html5. The file is then passed on to Pandoc for a second stage. "
+ "Use the Pandoc tab for settings up the conversion."
+ ),
}
def __init__(self, theParent, theProject, optState):
@@ -367,13 +361,15 @@ class GuiExportMain(QWidget):
self.outputFormat.addItem("Plain Text (.txt)", self.FMT_TXT)
self.outputFormat.addItem("Markdown (.md)", self.FMT_MD)
self.outputFormat.addItem("HTML5 (.htm)", self.FMT_HTML)
- # self.outputFormat.addItem("HTML5 for eBook (.htm)", self.FMT_EBOOK)
- # self.outputFormat.addItem("Open Document (.odt)", self.FMT_ODT)
self.outputFormat.addItem("LaTeX for PDF (.tex)", self.FMT_TEX)
+ self.outputFormat.addItem("Pandoc via HTML5 (.htm)", self.FMT_PDOC)
self.outputFormat.currentIndexChanged.connect(self._updateFormat)
optIdx = self.outputFormat.findData(self.optState.getSetting("eFormat"))
- if optIdx != -1:
+ if optIdx == -1:
+ self.outputFormat.setCurrentIndex(1)
+ self._updateFormat(1)
+ else:
self.outputFormat.setCurrentIndex(optIdx)
self._updateFormat(optIdx)
@@ -438,13 +434,11 @@ class GuiExportMain(QWidget):
"Text files (*.txt)",
"Markdown files (*.md)",
"HTML files (*.htm *.html)",
- # "Open document files (*.odt)",
"LaTeX files (*.tex)",
"All files (*.*)",
]
dlgOpt = QFileDialog.Options()
- dlgOpt |= QFileDialog.ShowDirsOnly
dlgOpt |= QFileDialog.DontUseNativeDialog
saveTo = QFileDialog.getSaveFileName(
self,"Export File",self.exportPath.text(),options=dlgOpt,filter=";;".join(extFilter)
@@ -459,7 +453,7 @@ class GuiExportMain(QWidget):
def _checkFileExtension(self):
saveTo = self.exportPath.text()
fileBits = path.splitext(saveTo)
- if self.currFormat > 0:
+ if self.currFormat > 0 and fileBits[0].strip() != "":
saveTo = fileBits[0]+self.FMT_EXT[self.currFormat]
self.exportPath.setText(saveTo)
return
From 0bb5a374147f6067f52b623e0c1fea6d407dec79 Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Mon, 28 Oct 2019 19:51:00 +0100
Subject: [PATCH 2/4] Added some basic pandoc export options
---
nw/gui/export.py | 214 +++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 197 insertions(+), 17 deletions(-)
diff --git a/nw/gui/export.py b/nw/gui/export.py
index f7108c2d..0fe39447 100644
--- a/nw/gui/export.py
+++ b/nw/gui/export.py
@@ -20,7 +20,7 @@ from PyQt5.QtCore import Qt, QSize
from PyQt5.QtSvg import QSvgWidget
from PyQt5.QtWidgets import (
QDialog, QHBoxLayout, QVBoxLayout, QWidget, QTabWidget, QGridLayout, QGroupBox, QCheckBox,
- QLabel, QComboBox, QLineEdit, QPushButton, QFileDialog, QProgressBar, QSpinBox
+ QLabel, QComboBox, QLineEdit, QPushButton, QFileDialog, QProgressBar, QSpinBox, QMessageBox
)
from nw.project.document import NWDoc
@@ -60,9 +60,11 @@ class GuiExport(QDialog):
self.theProject.countStatus()
self.tabMain = GuiExportMain(self.theParent, self.theProject, self.optState)
+ self.tabPandoc = GuiExportPandoc(self.theParent, self.theProject, self.optState)
self.tabWidget = QTabWidget()
- self.tabWidget.addTab(self.tabMain, "Settings")
+ self.tabWidget.addTab(self.tabMain, "Settings")
+ self.tabWidget.addTab(self.tabPandoc, "Pandoc")
self.outerBox.addWidget(self.svgGradient, 0, Qt.AlignTop)
self.outerBox.addLayout(self.innerBox)
@@ -113,7 +115,12 @@ class GuiExport(QDialog):
seFormat = self.tabMain.sectionFormat.text()
saveTo = self.tabMain.exportPath.text()
+ pFormat = self.tabPandoc.outputFormat.currentData()
+ tFormat = GuiExportPandoc.FMT_VIA[pFormat]
+
nItems = len(self.theProject.treeOrder)
+ if eFormat == GuiExportMain.FMT_PDOC:
+ nItems += int(0.2*nItems)
self.exportProgress.setMinimum(0)
self.exportProgress.setMaximum(nItems)
self.exportProgress.setValue(0)
@@ -133,6 +140,11 @@ class GuiExport(QDialog):
outFile = LaTeXFile(self.theProject, self.theParent)
elif eFormat == GuiExportMain.FMT_NWD:
outFile = ConcatFile(self.theProject, self.theParent)
+ elif eFormat == GuiExportMain.FMT_PDOC:
+ if tFormat == "html":
+ outFile = HtmlFile(self.theProject, self.theParent)
+ elif tFormat == "markdown":
+ outFile = MarkdownFile(self.theProject, self.theParent)
if outFile is None:
return False
@@ -180,12 +192,79 @@ class GuiExport(QDialog):
"Make sure the python package 'latexcodec' is installed and working."
), nwAlert.WARN)
- return
+ if eFormat != GuiExportMain.FMT_PDOC:
+ return True
+
+ # If we've reached this point, we're also running Pandoc
+
+ if self._callPandoc(tFormat, pFormat):
+ self.exportProgress.setValue(nItems)
+ self.exportStatus.setText("Pandoc conversion complete")
+ logger.verbose("Pandoc conversion complete")
+ else:
+ self.exportProgress.setValue(nItems)
+ self.exportStatus.setText("Pandoc conversion failed")
+ logger.verbose("Pandoc conversion failed")
+ return False
+
+ return True
+
+ def _callPandoc(self, inFmt, outFmt):
+
+ pFmt = {
+ GuiExportPandoc.FMT_ODT : "odt",
+ GuiExportPandoc.FMT_DOCX : "docx",
+ GuiExportPandoc.FMT_EPUB2 : "epub2",
+ GuiExportPandoc.FMT_EPUB3 : "epub3",
+ GuiExportPandoc.FMT_ZIM : "zimwiki",
+ }
+
+ try:
+ import pypandoc
+ except:
+ self.theParent.makeAlert((
+ "Could not load the 'pypandoc' package. "
+ "Make sure it is installed, and try again."
+ ), nwAlert.ERROR)
+ return False
+
+ inFile = self.tabMain.exportPath.text()
+ outFile = path.splitext(inFile)[0]+GuiExportPandoc.FMT_EXT[outFmt]
+ fileName = path.basename(outFile)
+
+ if path.isfile(outFile) and self.mainConf.showGUI:
+ msgBox = QMessageBox()
+ msgRes = msgBox.question(
+ self.theParent, "Overwrite",
+ ("File '%s' already exists.
Do you want to overwrite it?" % fileName)
+ )
+ if msgRes != QMessageBox.Yes:
+ return False
+
+ try:
+ pypandoc.convert_file(
+ source_file = inFile,
+ format = inFmt,
+ outputfile = outFile,
+ to = pFmt[outFmt],
+ extra_args = (),
+ encoding = "utf-8",
+ filters = None
+ )
+ except Exception as e:
+ self.theParent.makeAlert(
+ ["Failed to convert file using pypandoc + Pandoc.",
+ str(e)], nwAlert.ERROR
+ )
+ return False
+
+ return True
def _doClose(self):
logger.verbose("GuiExport close button clicked")
+ # General Settings
wNovel = self.tabMain.expNovel.isChecked()
wNotes = self.tabMain.expNotes.isChecked()
eFormat = self.tabMain.outputFormat.currentData()
@@ -208,6 +287,11 @@ class GuiExport(QDialog):
self.optState.setSetting("seFormat", seFormat)
self.optState.setSetting("saveTo", saveTo)
+ # Pandoc Settings
+ pFormat = self.tabPandoc.outputFormat.currentData()
+
+ self.optState.setSetting("pFormat", pFormat)
+
self.optState.saveSettings()
self.close()
@@ -229,32 +313,31 @@ class GuiExportMain(QWidget):
FMT_MD : ".md",
FMT_HTML : ".htm",
FMT_TEX : ".tex",
- FMT_PDOC : ".htm",
+ FMT_PDOC : ".tmp",
}
FMT_HELP = {
FMT_NWD : (
- "Exports a document using the novelWriter markdown format. "
- "The files selected by the filters are appended as-is, including comments and other settings."
+ "Exports a document using the novelWriter markdown format. The files selected by the "
+ "filters are appended as-is, including comments and other settings."
),
FMT_TXT : (
- "Exports a plain text file. "
- "All formatting is stripped and comments are in square brackets."
+ "Exports a plain text file. All formatting is stripped and comments are in square "
+ "brackets."
),
FMT_MD : (
- "Exports a standard markdown file. "
- "Comments are converted to preformatted text blocks."
+ "Exports a standard markdown file. Comments are converted to preformatted text blocks."
),
FMT_HTML : (
- "Exports a plain html5 file. "
- "Comments are wrapped in blocks with a yellow background colour."
+ "Exports a plain html5 file. Comments are wrapped in blocks with a yellow background "
+ "colour."
),
FMT_TEX : (
"Exports a LaTeX file that can be compiled to PDF using for instance PDFLaTeX. "
"Comments are exported as LaTeX comments."
),
FMT_PDOC : (
- "Exports first to html5. The file is then passed on to Pandoc for a second stage. "
- "Use the Pandoc tab for settings up the conversion."
+ "Exports first to markdown or html5. The file is then passed on to Pandoc for a second "
+ "stage. Use the Pandoc tab for settings up the conversion."
),
}
@@ -362,7 +445,7 @@ class GuiExportMain(QWidget):
self.outputFormat.addItem("Markdown (.md)", self.FMT_MD)
self.outputFormat.addItem("HTML5 (.htm)", self.FMT_HTML)
self.outputFormat.addItem("LaTeX for PDF (.tex)", self.FMT_TEX)
- self.outputFormat.addItem("Pandoc via HTML5 (.htm)", self.FMT_PDOC)
+ self.outputFormat.addItem("Pandoc via Markdown or HTML", self.FMT_PDOC)
self.outputFormat.currentIndexChanged.connect(self._updateFormat)
optIdx = self.outputFormat.findData(self.optState.getSetting("eFormat"))
@@ -379,7 +462,7 @@ class GuiExportMain(QWidget):
self.guiOutputForm.setColumnStretch(2, 1)
# Additional Settings
- self.addSettings = QGroupBox("Additional Settings", self)
+ self.addSettings = QGroupBox("Additional Settings (Format Dependent)", self)
self.addSettingsForm = QGridLayout(self)
self.addSettings.setLayout(self.addSettingsForm)
@@ -460,6 +543,102 @@ class GuiExportMain(QWidget):
# END Class GuiExportMain
+class GuiExportPandoc(QWidget):
+
+ FMT_ODT = 1
+ FMT_DOCX = 2
+ FMT_EPUB2 = 4
+ FMT_EPUB3 = 5
+ FMT_ZIM = 6
+ FMT_EXT = {
+ FMT_ODT : ".odt",
+ FMT_DOCX : ".docx",
+ FMT_EPUB2 : ".epub",
+ FMT_EPUB3 : ".epub",
+ FMT_ZIM : ".txt",
+ }
+ FMT_VIA = {
+ FMT_ODT : "html",
+ FMT_DOCX : "html",
+ FMT_EPUB2 : "markdown",
+ FMT_EPUB3 : "markdown",
+ FMT_ZIM : "markdown",
+ }
+
+ def __init__(self, theParent, theProject, optState):
+ QWidget.__init__(self, theParent)
+
+ self.theParent = theParent
+ self.theProject = theProject
+ self.outerBox = QGridLayout()
+ self.optState = optState
+
+ try:
+ import pypandoc
+ self.hasPyPan = True
+ except:
+ self.hasPyPan = False
+
+ # Information
+ self.guiInfo = QGroupBox("Information", self)
+ self.guiInfoBox = QVBoxLayout(self)
+ self.guiInfo.setLayout(self.guiInfoBox)
+
+ self.infoHelp = QLabel("")
+ self.infoHelp.setWordWrap(True)
+ self.infoHelp.setMinimumHeight(55)
+ self.infoHelp.setAlignment(Qt.AlignTop)
+
+ self.guiInfoBox.addWidget(self.infoHelp)
+
+ if self.hasPyPan:
+ self.infoHelp.setText((
+ "Additional export to other document formats than in the Settings tab is provided "
+ "by Pandoc. the project is first exported to Markdown or HTML, depending on final "
+ "format, and then processed by Pandoc into the desired format."
+ ))
+ else:
+ self.infoHelp.setText((
+ "The Python package 'pypandoc' is not installed or isn't working. This package is "
+ "required for interfacing with Pandoc. Please install it before proceeding."
+ ))
+
+ # Output Format
+ self.guiOutput = QGroupBox("Pandoc Format", self)
+ self.guiOutputForm = QGridLayout(self)
+ self.guiOutput.setLayout(self.guiOutputForm)
+
+ self.outputFormat = QComboBox(self)
+ self.outputFormat.addItem("Open Office Document (.odt)", self.FMT_ODT)
+ self.outputFormat.addItem("Word Document (.docx)", self.FMT_DOCX)
+ self.outputFormat.addItem("ePUB eBook v2 (.epub2)", self.FMT_EPUB2)
+ self.outputFormat.addItem("ePUB eBook v3 (.epub3)", self.FMT_EPUB3)
+ self.outputFormat.addItem("Zim Wiki (.txt)", self.FMT_ZIM)
+ # self.outputFormat.currentIndexChanged.connect(self._updateFormat)
+
+ optIdx = self.outputFormat.findData(self.optState.getSetting("pFormat"))
+ if optIdx == -1:
+ self.outputFormat.setCurrentIndex(1)
+ else:
+ self.outputFormat.setCurrentIndex(optIdx)
+
+ self.guiOutputForm.addWidget(QLabel("Format"), 0, 0)
+ self.guiOutputForm.addWidget(self.outputFormat, 0, 1)
+ self.guiOutputForm.setColumnStretch(2, 1)
+
+ # Assemble
+ self.outerBox.addWidget(self.guiInfo, 0, 0)
+ self.outerBox.addWidget(self.guiOutput, 1, 0)
+ self.outerBox.setRowStretch(2, 1)
+ # self.outerBox.setColumnStretch(0, 1)
+ # self.outerBox.setColumnStretch(1, 1)
+ # self.outerBox.setColumnStretch(2, 1)
+ self.setLayout(self.outerBox)
+
+ return
+
+# END Class GuiExportPandoc
+
class ExportLastState(OptLastState):
def __init__(self, theProject, theFile):
@@ -468,6 +647,7 @@ class ExportLastState(OptLastState):
"wNovel" : True,
"wNotes" : False,
"eFormat" : 1,
+ "pFormat" : 1,
"fixWidth" : 80,
"wComments" : False,
"chFormat" : "Chapter %numword%",
@@ -478,7 +658,7 @@ class ExportLastState(OptLastState):
}
self.stringOpt = ("chFormat","unFormat","scFormat","seFormat","saveTo")
self.boolOpt = ("wNovel","wNotes","wComments")
- self.intOpt = ("eFormat","fixWidth")
+ self.intOpt = ("eFormat","pFormat","fixWidth")
return
# END Class ExportLastState
From f1e8f2e321c28f1507c2af4cd7b072859dbdb32d Mon Sep 17 00:00:00 2001
From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com>
Date: Mon, 28 Oct 2019 20:36:38 +0100
Subject: [PATCH 3/4] Added some more options to the export GUI and the ability
to skip scene and section titles
---
nw/convert/file/latex.py | 1 +
nw/convert/file/text.py | 14 +++----
nw/convert/text/tohtml.py | 9 +++--
nw/convert/text/tolatex.py | 6 ++-
nw/convert/text/tomarkdown.py | 5 ++-
nw/convert/text/totext.py | 5 ++-
nw/convert/tokenizer.py | 71 ++++++++++++++++++++---------------
nw/gui/export.py | 50 ++++++++++++++++++------
8 files changed, 106 insertions(+), 55 deletions(-)
diff --git a/nw/convert/file/latex.py b/nw/convert/file/latex.py
index 962731e6..a61d3a68 100644
--- a/nw/convert/file/latex.py
+++ b/nw/convert/file/latex.py
@@ -37,6 +37,7 @@ class LaTeXFile(TextFile):
self.outFile = open(filePath,mode="wt+",encoding="utf8")
self.outFile.write("\\documentclass[12pt]{report}\n")
self.outFile.write("\\usepackage[utf8]{inputenc}\n")
+ self.outFile.write("\\usepackage[T1]{fontenc}\n")
self.outFile.write("\n")
self.outFile.write("\\begin{document}\n")
except Exception as e:
diff --git a/nw/convert/file/text.py b/nw/convert/file/text.py
index e62e5729..9c490b3d 100644
--- a/nw/convert/file/text.py
+++ b/nw/convert/file/text.py
@@ -39,7 +39,7 @@ class TextFile():
self.makeAlert = self.theParent.makeAlert
self.setComments(False)
- self.setMeta(False)
+ self.setKeywords(False)
self.setWordWrap(80)
return
@@ -60,8 +60,8 @@ class TextFile():
self.theConv.setComments(doComments)
return
- def setMeta(self, doMeta):
- self.theConv.setCommands(doMeta)
+ def setKeywords(self, doKeywords):
+ self.theConv.setKeywords(doKeywords)
return
def setWordWrap(self, wordWrap):
@@ -83,12 +83,12 @@ class TextFile():
self.theConv.setUnNumberedFormat(fmtUnNum)
return
- def setSceneFormat(self, fmtScene):
- self.theConv.setSceneFormat(fmtScene)
+ def setSceneFormat(self, fmtScene, hideScene):
+ self.theConv.setSceneFormat(fmtScene, hideScene)
return
- def setSectionFormat(self, fmtSection):
- self.theConv.setSectionFormat(fmtSection)
+ def setSectionFormat(self, fmtSection, hideSection):
+ self.theConv.setSectionFormat(fmtSection, hideSection)
return
##
diff --git a/nw/convert/text/tohtml.py b/nw/convert/text/tohtml.py
index 1a28f90c..67757574 100644
--- a/nw/convert/text/tohtml.py
+++ b/nw/convert/text/tohtml.py
@@ -83,7 +83,10 @@ class ToHtml(Tokenizer):
self.theResult += "
%s
\n" % (hStyle,tText) + + elif tType == self.T_SKIP: + self.theResult += "\n" elif tType == self.T_TEXT: tTemp = tText @@ -94,8 +97,8 @@ class ToHtml(Tokenizer): elif tType == self.T_COMMENT and self.doComments: self.theResult += "
%s\n" % tText + elif tType == self.T_KEYWORD and self.doKeywords: + self.theResult += "
@%s\n" % tText # print(self.theResult) diff --git a/nw/convert/text/tolatex.py b/nw/convert/text/tolatex.py index cb7d25f5..bd4e559e 100644 --- a/nw/convert/text/tolatex.py +++ b/nw/convert/text/tolatex.py @@ -90,6 +90,10 @@ class ToLaTeX(Tokenizer): self.theResult += "%s\n" % self._escapeUnicode(tText) self.theResult += endText + elif tType == self.T_SKIP: + self.theResult += "\\bigskip\n" + self.theResult += "\\bigskip\n\n" + elif tType == self.T_TEXT: thisPar.append(self._escapeUnicode(tText)) @@ -99,7 +103,7 @@ class ToLaTeX(Tokenizer): elif tType == self.T_COMMENT and self.doComments: self.theResult += "%s\n\n" % tText - elif tType == self.T_COMMAND and self.doCommands: + elif tType == self.T_KEYWORD and self.doKeywords: self.theResult += "%% @%s\n\n" % tText return diff --git a/nw/convert/text/tomarkdown.py b/nw/convert/text/tomarkdown.py index 50db3d9c..bd422836 100644 --- a/nw/convert/text/tomarkdown.py +++ b/nw/convert/text/tomarkdown.py @@ -98,13 +98,16 @@ class ToMarkdown(Tokenizer): elif tType == self.T_SEP: self.theResult += "%s\n\n" % tText + elif tType == self.T_SKIP: + self.theResult += "\n\n\n\n" + elif tType == self.T_TEXT: thisPar.append(tText) elif tType == self.T_COMMENT and self.doComments: self.theResult += "%s\n\n" % tText - elif tType == self.T_COMMAND and self.doCommands: + elif tType == self.T_KEYWORD and self.doKeywords: self.theResult += "%s\n\n" % tText return diff --git a/nw/convert/text/totext.py b/nw/convert/text/totext.py index abb42e7c..e685e5be 100644 --- a/nw/convert/text/totext.py +++ b/nw/convert/text/totext.py @@ -105,13 +105,16 @@ class ToText(Tokenizer): tText = self._centreText(tText,self.wordWrap) self.theResult += "%s\n\n" % tText + elif tType == self.T_SEP: + self.theResult += "\n\n\n\n" + elif tType == self.T_TEXT: thisPar.append(tText) elif tType == self.T_COMMENT and self.doComments: self.theResult += "%s\n\n" % tText - elif tType == self.T_COMMAND and self.doCommands: + elif tType == self.T_KEYWORD and self.doKeywords: self.theResult += "%s\n\n" % tText return diff --git a/nw/convert/tokenizer.py b/nw/convert/tokenizer.py index 78aa5754..1e70ff27 100644 --- a/nw/convert/tokenizer.py +++ b/nw/convert/tokenizer.py @@ -35,14 +35,15 @@ class Tokenizer(): T_EMPTY = 1 # Empty line (new paragraph) T_COMMENT = 2 # Comment line - T_COMMAND = 3 # Command line + T_KEYWORD = 3 # Command line T_HEAD1 = 4 # Header 1 (title) T_HEAD2 = 5 # Header 2 (chapter) T_HEAD3 = 6 # Header 3 (scene) T_HEAD4 = 7 # Header 4 T_TEXT = 8 # Text line T_SEP = 9 # Scene separator - T_PBREAK = 10 # Page break + T_SKIP = 10 # Scene separator + T_PBREAK = 11 # Page break A_LEFT = 1 # Left aligned A_RIGHT = 2 # Right aligned @@ -51,30 +52,31 @@ class Tokenizer(): def __init__(self, theProject, theParent): - self.mainConf = nw.CONFIG - self.theProject = theProject - self.theParent = theParent + self.mainConf = nw.CONFIG + self.theProject = theProject + self.theParent = theParent - self.theText = None - self.theHandle = None - self.theItem = None - self.theTokens = None - self.theResult = None + self.theText = None + self.theHandle = None + self.theItem = None + self.theTokens = None + self.theResult = None - self.wordWrap = 80 - self.doComments = False - self.doCommands = False + self.wordWrap = 80 + self.doComments = False + self.doKeywords = False - self.fmtTitle = "%title%" - self.fmtChapter = "Chapter %numword%: %title%" - self.fmtUnNum = "%title%" - self.fmtScene = "* * *" - self.fmtSection = "%title%" + self.fmtTitle = "%title%" + self.fmtChapter = "Chapter %numword%: %title%" + self.fmtUnNum = "%title%" + self.fmtScene = "* * *" + self.fmtSection = "%title%" - self.noSection = True + self.hideScene = False + self.hideSection = False - self.numChapter = 0 - self.firstScene = False + self.numChapter = 0 + self.firstScene = False return @@ -86,8 +88,8 @@ class Tokenizer(): self.doComments = doComments return - def setCommands(self, doCommands): - self.doCommands = doCommands + def setKeywords(self, doKeywords): + self.doKeywords = doKeywords return def setWordWrap(self, wordWrap): @@ -109,12 +111,14 @@ class Tokenizer(): self.fmtUnNum = fmtUnNum return - def setSceneFormat(self, fmtScene): - self.fmtScene = fmtScene + def setSceneFormat(self, fmtScene, hideScene): + self.fmtScene = fmtScene + self.hideScene = hideScene return - def setSectionFormat(self, fmtSection): - self.fmtSection = fmtSection + def setSectionFormat(self, fmtSection, hideSection): + self.fmtSection = fmtSection + self.hideSection = hideSection return ## @@ -175,7 +179,7 @@ class Tokenizer(): elif aLine[0] == "%": self.theTokens.append((self.T_COMMENT,aLine[1:].strip(),None,self.A_LEFT)) elif aLine[0] == "@": - self.theTokens.append((self.T_COMMAND,aLine[1:].strip(),None,self.A_LEFT)) + self.theTokens.append((self.T_KEYWORD,aLine[1:].strip(),None,self.A_LEFT)) elif aLine[:2] == "# ": self.theTokens.append((self.T_HEAD1,aLine[2:].strip(),None,self.A_LEFT)) elif aLine[:3] == "## ": @@ -242,8 +246,13 @@ class Tokenizer(): elif tType == self.T_HEAD3: tTemp = self._doFormatScene(tText) - if tTemp == "": + if tTemp == "" and self.hideScene: self.theTokens[n] = (self.T_EMPTY,"",None,self.A_LEFT) + elif tTemp == "" and not self.hideScene: + if self.firstScene: + self.theTokens[n] = (self.T_EMPTY,"",None,self.A_LEFT) + else: + self.theTokens[n] = (self.T_SKIP,"",None,self.A_LEFT) elif tTemp == self.fmtScene: if self.firstScene: self.theTokens[n] = (self.T_EMPTY,"",None,self.A_LEFT) @@ -255,8 +264,10 @@ class Tokenizer(): elif tType == self.T_HEAD4: tTemp = self._doFormatSection(tText) - if tTemp == "": + if tTemp == "" and self.hideSection: self.theTokens[n] = (self.T_EMPTY,"",None,self.A_LEFT) + elif tTemp == "" and not self.hideSection: + self.theTokens[n] = (self.T_SKIP,"",None,self.A_LEFT) elif tTemp == self.fmtSection: self.theTokens[n] = (self.T_SEP,tTemp,None,self.A_CENTRE) else: diff --git a/nw/gui/export.py b/nw/gui/export.py index 0fe39447..8f56a47a 100644 --- a/nw/gui/export.py +++ b/nw/gui/export.py @@ -109,11 +109,14 @@ class GuiExport(QDialog): eFormat = self.tabMain.outputFormat.currentData() fixWidth = self.tabMain.fixedWidth.value() wComments = self.tabMain.expComments.isChecked() + wKeywords = self.tabMain.expKeywords.isChecked() chFormat = self.tabMain.chapterFormat.text() unFormat = self.tabMain.unnumFormat.text() scFormat = self.tabMain.sceneFormat.text() seFormat = self.tabMain.sectionFormat.text() saveTo = self.tabMain.exportPath.text() + hScene = self.tabMain.hideScene.isChecked() + hSection = self.tabMain.hideSection.isChecked() pFormat = self.tabPandoc.outputFormat.currentData() tFormat = GuiExportPandoc.FMT_VIA[pFormat] @@ -151,13 +154,14 @@ class GuiExport(QDialog): if outFile.openFile(saveTo): outFile.setComments(wComments) + outFile.setKeywords(wKeywords) outFile.setExportNovel(wNovel) outFile.setExportNotes(wNotes) outFile.setWordWrap(fixWidth) outFile.setChapterFormat(chFormat) outFile.setUnNumberedFormat(unFormat) - outFile.setSceneFormat(scFormat) - outFile.setSectionFormat(seFormat) + outFile.setSceneFormat(scFormat, hScene) + outFile.setSectionFormat(seFormat, hSection) else: self.exportStatus.setText("Failed to open file for writing ...") return False @@ -270,22 +274,28 @@ class GuiExport(QDialog): eFormat = self.tabMain.outputFormat.currentData() fixWidth = self.tabMain.fixedWidth.value() wComments = self.tabMain.expComments.isChecked() + wKeywords = self.tabMain.expKeywords.isChecked() chFormat = self.tabMain.chapterFormat.text() unFormat = self.tabMain.unnumFormat.text() scFormat = self.tabMain.sceneFormat.text() seFormat = self.tabMain.sectionFormat.text() saveTo = self.tabMain.exportPath.text() + hScene = self.tabMain.hideScene.isChecked() + hSection = self.tabMain.hideSection.isChecked() self.optState.setSetting("wNovel", wNovel) self.optState.setSetting("wNotes", wNotes) self.optState.setSetting("eFormat", eFormat) self.optState.setSetting("fixWidth", fixWidth) self.optState.setSetting("wComments",wComments) + self.optState.setSetting("wKeywords",wKeywords) self.optState.setSetting("chFormat", chFormat) self.optState.setSetting("unFormat", unFormat) self.optState.setSetting("scFormat", scFormat) self.optState.setSetting("seFormat", seFormat) self.optState.setSetting("saveTo", saveTo) + self.optState.setSetting("hScene", hScene) + self.optState.setSetting("hSection", hSection) # Pandoc Settings pFormat = self.tabPandoc.outputFormat.currentData() @@ -356,24 +366,27 @@ class GuiExportMain(QWidget): self.guiFilesForm = QGridLayout(self) self.guiFiles.setLayout(self.guiFilesForm) - self.expNovel = QCheckBox(self) + self.expNovel = QCheckBox("Novel files",self) self.expNovel.setChecked(self.optState.getSetting("wNovel")) self.expNovel.setToolTip("Include all novel files in the exported document") - self.expNotes = QCheckBox(self) + self.expNotes = QCheckBox("Note files",self) self.expNotes.setChecked(self.optState.getSetting("wNotes")) self.expNotes.setToolTip("Include all note files in the exported document") - self.expComments = QCheckBox(self) + self.expComments = QCheckBox("Comments",self) self.expComments.setChecked(self.optState.getSetting("wComments")) self.expComments.setToolTip("Export comments from all files") - self.guiFilesForm.addWidget(QLabel("Novel files"), 0, 0) - self.guiFilesForm.addWidget(self.expNovel, 0, 1) - self.guiFilesForm.addWidget(QLabel("Note files"), 1, 0) - self.guiFilesForm.addWidget(self.expNotes, 1, 1) - self.guiFilesForm.addWidget(QLabel("Comments"), 2, 0) - self.guiFilesForm.addWidget(self.expComments, 2, 1) + self.expKeywords = QCheckBox("Keywords",self) + self.expKeywords.setChecked(self.optState.getSetting("wKeywords")) + self.expKeywords.setToolTip("Export @keywords from all files") + + self.guiFilesForm.addWidget(self.expNovel, 0, 1) + self.guiFilesForm.addWidget(self.expComments, 0, 2) + self.guiFilesForm.addWidget(self.expNotes, 1, 1) + self.guiFilesForm.addWidget(self.expKeywords, 1, 2) + self.guiFilesForm.setRowStretch(2, 1) # Chapter Settings self.guiChapters = QGroupBox("Chapter Headings", self) @@ -410,10 +423,20 @@ class GuiExportMain(QWidget): self.sectionFormat.setToolTip("Available formats: %title%") self.sectionFormat.setMinimumWidth(100) + self.hideScene = QCheckBox("Skip",self) + self.hideScene.setChecked(self.optState.getSetting("hScene")) + self.hideScene.setToolTip("Skip scene titles in export") + + self.hideSection = QCheckBox("Skip",self) + self.hideSection.setChecked(self.optState.getSetting("hSection")) + self.hideSection.setToolTip("Skip section titles in export") + self.guiScenesForm.addWidget(QLabel("Scenes"), 0, 0) self.guiScenesForm.addWidget(self.sceneFormat, 0, 1) + self.guiScenesForm.addWidget(self.hideScene, 0, 2) self.guiScenesForm.addWidget(QLabel("Sections"), 1, 0) self.guiScenesForm.addWidget(self.sectionFormat, 1, 1) + self.guiScenesForm.addWidget(self.hideSection, 1, 2) # Output Path self.exportTo = QGroupBox("Export Folder", self) @@ -650,14 +673,17 @@ class ExportLastState(OptLastState): "pFormat" : 1, "fixWidth" : 80, "wComments" : False, + "wKeywords" : False, "chFormat" : "Chapter %numword%", "unFormat" : "%title%", "scFormat" : "* * *", "seFormat" : "", "saveTo" : "", + "hScene" : False, + "hSection" : False, } self.stringOpt = ("chFormat","unFormat","scFormat","seFormat","saveTo") - self.boolOpt = ("wNovel","wNotes","wComments") + self.boolOpt = ("wNovel","wNotes","wComments","wKeywords","hScene","hSection") self.intOpt = ("eFormat","pFormat","fixWidth") return From 4b212ed192ce5d98a4ef2f21fb8da32cb9fad58e Mon Sep 17 00:00:00 2001 From: "Veronica K. B. Olsen" <1619840+vkbo@users.noreply.github.com> Date: Mon, 28 Oct 2019 20:40:17 +0100 Subject: [PATCH 4/4] Updated comment --- nw/convert/tokenizer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nw/convert/tokenizer.py b/nw/convert/tokenizer.py index 1e70ff27..1b7fdd51 100644 --- a/nw/convert/tokenizer.py +++ b/nw/convert/tokenizer.py @@ -42,7 +42,7 @@ class Tokenizer(): T_HEAD4 = 7 # Header 4 T_TEXT = 8 # Text line T_SEP = 9 # Scene separator - T_SKIP = 10 # Scene separator + T_SKIP = 10 # Paragraph break T_PBREAK = 11 # Page break A_LEFT = 1 # Left aligned