Lots of pandoc formats

This commit is contained in:
Olivier Keshavjee 2016-04-15 11:58:09 +02:00
parent 26c42a56f1
commit f820e5a62b
14 changed files with 514 additions and 103 deletions

View file

@ -27,9 +27,8 @@ class basicExporter:
settings = QSettings()
settings.setValue("Exporters/{}_customPath".format(self.name), self.customPath)
@classmethod
def getFormatByName(cls, name):
for f in cls.exportTo:
def getFormatByName(self, name):
for f in self.exportTo:
if f.name == name:
return f
@ -43,13 +42,11 @@ class basicExporter:
else:
return 0
@classmethod
def version(cls):
def version(self):
return ""
@classmethod
def path(cls):
return shutil.which(cls.cmd)
def path(self):
return shutil.which(self.cmd)
def run(self, args):
if self.isValid() == 2:

View file

@ -57,8 +57,8 @@ class HTML(markdown):
t.setCurrentIndex(2)
return t
def output(self, settings):
html = MD.markdown(markdown.output(self, settings))
def output(self, settingsWidget):
html = MD.markdown(markdown.output(self, settingsWidget))
return html
def preview(self, settingsWidget, previewWidget):
@ -67,7 +67,7 @@ class HTML(markdown):
# Save settings
settingsWidget.writeSettings()
md = markdown.output(self, settings)
md = markdown.output(self, settingsWidget)
html = MD.markdown(md)
self.preparesTextEditView(previewWidget.widget(0), settings["Preview"]["PreviewFont"])

View file

@ -39,8 +39,7 @@ class markdown(plainText):
self.preparesTextEditViewMarkdown(previewWidget, settingsWidget.settings)
self.preparesTextEditView(previewWidget, settings["Preview"]["PreviewFont"])
r = self.concatenate(mainWindow().mdlOutline.rootItem, settings)
previewWidget.setPlainText(r)
previewWidget.setPlainText(self.output(settingsWidget))
def processTitle(self, text, level, settings):
return "{} {}\n".format(

View file

@ -39,7 +39,8 @@ class plainText(basicFormat):
w.setReadOnly(True)
return w
def output(self, settings):
def output(self, settingsWidget):
settings = settingsWidget.getSettings()
return self.concatenate(mainWindow().mdlOutline.rootItem, settings)
def getExportFilename(self, settingsWidget, varName=None, filter=None):
@ -90,10 +91,15 @@ class plainText(basicFormat):
filename = self.getExportFilename(settingsWidget)
settingsWidget.writeSettings()
content = self.output(settingsWidget)
if not content:
print("Error: content is empty. Nothing saved.")
return
if filename:
with open(filename, "w") as f:
f.write(self.output(settingsWidget.settings))
f.write(content)
def preview(self, settingsWidget, previewWidget):
settings = settingsWidget.getSettings()
@ -101,7 +107,7 @@ class plainText(basicFormat):
# Save settings
settingsWidget.writeSettings()
r = self.output(settings)
r = self.output(settingsWidget)
# Set preview font
self.preparesTextEditView(previewWidget, settings["Preview"]["PreviewFont"])

View file

@ -0,0 +1,40 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtWidgets import qApp
from manuskript.exporter.manuskript import HTML as MskHTML
from manuskript.exporter.pandoc.abstractPlainText import abstractPlainText
class HTML(abstractPlainText):
name = "HTML"
description = qApp.translate("Export", """A little known format modestly used. You know, web sites for example.""")
icon = "text-html"
exportVarName = "lastPandocHTML"
toFormat = "html"
exportFilter = "HTML files (*.html);; Any files (*)"
requires = {
"Settings": True,
"Preview": True,
}
def previewWidget(self):
return MskHTML.previewWidget(self)
def preview(self, settingsWidget, previewWidget):
settings = settingsWidget.getSettings()
# Save settings
settingsWidget.writeSettings()
src = self.src(settingsWidget)
html = self.output(settingsWidget)
self.preparesTextEditView(previewWidget.widget(0), settings["Preview"]["PreviewFont"])
self.preparesTextEditViewMarkdown(previewWidget.widget(0), settings)
previewWidget.widget(0).setPlainText(src)
self.preparesTextEditView(previewWidget.widget(1), settings["Preview"]["PreviewFont"])
previewWidget.widget(1).setPlainText(html)
previewWidget.widget(2).setHtml(html)

View file

@ -0,0 +1,42 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtCore import QUrl
from PyQt5.QtWebKit import QWebSettings
from PyQt5.QtWebKitWidgets import QWebView
from PyQt5.QtWidgets import qApp
from manuskript.exporter.manuskript import HTML as MskHTML
from manuskript.exporter.pandoc.abstractOutput import abstractOutput
class PDF(abstractOutput):
name = "PDF"
description = qApp.translate("Export", "Needs latex to be installed.")
icon = "application-pdf"
exportVarName = "lastPandocPDF"
toFormat = "pdf"
exportFilter = "PDF files (*.pdf);; Any files (*)"
requires = {
"Settings": True,
"Preview": True,
}
def output(self, settingsWidget, outputfile=None):
args = settingsWidget.runnableSettings()
args.remove("--to=pdf")
args.append("--to=latex")
src = self.src(settingsWidget)
return self.exporter.convert(src, args, outputfile)
def previewWidget(self):
web = QWebView()
web.settings().setAttribute(QWebSettings.PluginsEnabled, True)
# web.show()
return web
def preview(self, settingsWidget, previewWidget):
filename = "/tmp/msk_asdlhadl.pdf"
content = self.output(settingsWidget, outputfile=filename)
previewWidget.setUrl(QUrl("file://"+filename))

View file

@ -1,20 +1,17 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtWidgets import qApp
import subprocess
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import qApp, QMessageBox
from manuskript.exporter.basic import basicExporter, basicFormat
from manuskript.exporter.pandoc.markdown import markdown
class HTMLFormat(basicFormat):
name = "HTML"
description = qApp.translate("Export", "A little known format modestly used. You know, web sites for example.")
implemented = False
requires = {
"Settings": True,
"Preview": True,
}
icon="text-html"
from manuskript.exporter.pandoc.HTML import HTML
from manuskript.exporter.pandoc.PDF import PDF
from manuskript.exporter.pandoc.outputFormats import ePub, OpenDocument, DocX
from manuskript.exporter.pandoc.plainText import reST, markdown, latex
from manuskript.functions import mainWindow
class pandocExporter(basicExporter):
@ -24,21 +21,23 @@ class pandocExporter(basicExporter):
formats.</p>
<p>Website: <a href="http://www.pandoc.org">http://pandoc.org/</a></p>
""")
exportTo = [
HTMLFormat,
markdown,
basicFormat("ePub", "Books that don't kill trees.", icon="application-epub+zip"),
basicFormat("OpenDocument", "OpenDocument format. Used by LibreOffice for example.", icon="application-vnd.oasis.opendocument.text"),
basicFormat("PDF", "Needs latex to be installed.", icon="application-pdf"),
basicFormat("DocX", "Microsoft Office (.docx) document.", icon="application-vnd.openxmlformats-officedocument.wordprocessingml.document"),
basicFormat("reST", icon="text-plain"),
]
cmd = "pandoc"
def __init__(self):
basicExporter.__init__(self)
self.exportTo = [
markdown(self),
latex(self),
HTML(self),
ePub(self),
OpenDocument(self),
DocX(self),
PDF(self),
reST(self),
]
def version(self):
if self.isValid():
r = self.run(["-v"])
@ -46,5 +45,33 @@ class pandocExporter(basicExporter):
else:
return ""
def convert(self, src, args, outputfile=None):
args = [self.cmd] + args
if outputfile:
args.append("--output={}".format(outputfile))
qApp.setOverrideCursor(QCursor(Qt.WaitCursor))
p = subprocess.Popen(
args,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
if not type(src) == bytes:
src = src.encode("utf-8") # assumes utf-8
stdout, stderr = p.communicate(src)
qApp.restoreOverrideCursor()
if stderr:
err = stderr.decode("utf-8")
print(err)
QMessageBox.critical(mainWindow().dialog, qApp.translate("Export", "Error"), err)
return None
return stdout.decode("utf-8")

View file

@ -0,0 +1,22 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from manuskript.exporter.pandoc.abstractPlainText import abstractPlainText
class abstractOutput(abstractPlainText):
name = "SUBCLASSME"
description = "SUBCLASSME"
exportVarName = "SUBCLASSME"
toFormat = "SUBCLASSME"
icon = "SUBCLASSME"
exportFilter = "SUBCLASSME"
requires = {
"Settings": True,
"Preview": False,
}
def export(self, settingsWidget):
filename = self.getExportFilename(settingsWidget)
settingsWidget.writeSettings()
content = self.output(settingsWidget, outputfile=filename)

View file

@ -0,0 +1,262 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtGui import QTextCharFormat, QFont
from PyQt5.QtWidgets import qApp, QVBoxLayout, QCheckBox, QWidget, QHBoxLayout, QLabel, QSpinBox, QComboBox
from manuskript.exporter.manuskript.markdown import markdown, markdownSettings
from manuskript.ui.collapsibleGroupBox2 import collapsibleGroupBox2
class abstractPlainText(markdown):
name = "SUBCLASSME"
description = "SUBCLASSME"
exportVarName = "SUBCLASSME"
toFormat = "SUBCLASSME"
icon = "SUBCLASSME"
exportFilter = "SUBCLASSME"
def __init__(self, exporter):
self.exporter = exporter
def settingsWidget(self):
w = pandocSettings(self, toFormat=self.toFormat)
w.loadSettings()
return w
def src(self, settingsWidget):
return markdown.output(self, settingsWidget)
def output(self, settingsWidget, outputfile=None):
args = settingsWidget.runnableSettings()
src = self.src(settingsWidget)
return self.exporter.convert(src, args, outputfile)
def preview(self, settingsWidget, previewWidget):
settings = settingsWidget.getSettings()
# Save settings
settingsWidget.writeSettings()
# Prepares text edit
self.preparesTextEditViewMarkdown(previewWidget, settingsWidget.settings)
self.preparesTextEditView(previewWidget, settings["Preview"]["PreviewFont"])
r = self.output(settingsWidget)
previewWidget.setPlainText(r)
class pandocSetting:
def __init__(self, arg, type, format, label, widget=None, default=None, min=None, max=None, vals=None):
self.arg = arg
self.type = type
self.label = label
self.formats = format
if "html" in self.formats:
self.formats += " slidy dzslides revealjs slideous s5 html5"
self.widget = widget
self.default = default
self.min = min
self.max = max
self.vals = vals.split("|") if vals else []
def isValid(self, format):
"""Return whether the specific setting is active with the given format."""
# Empty formats means all
if self.formats is "":
return True
# "html" in "html markdown latex"
elif format in self.formats:
return True
# "markdown_strict" in "html markdown latex"
elif [f for f in self.formats.split(" ") if format in f]:
return True
return False
class pandocSettings(markdownSettings):
settingsList = {
# General
"standalone": pandocSetting("--standalone", "checkbox", "",
qApp.translate("Export", "Standalone document (not just a fragment)"),
default=True),
"TOC": pandocSetting("--toc", "checkbox", "",
qApp.translate("Export", "Include a table of contents.")),
"TOC-depth": pandocSetting("--toc-depth", "number", "",
qApp.translate("Export", "Number of sections level to include in TOC: "),
default=3, min=1, max=6),
"smart": pandocSetting("--smart", "checkbox", "",
qApp.translate("Export", "Typographically correct output")),
"normalize": pandocSetting("--normalize", "checkbox", "",
qApp.translate("Export", "Normalize the document (cleaner)")),
"base-header": pandocSetting("--base-header-level", "number", "",
qApp.translate("Export", "Specify the base level for headers: "),
default=1, min=1),
# Specific
"ref-link": pandocSetting("--reference-links", "checkbox", "markdown rst",
qApp.translate("Export", "Use reference-style links instead of inline links")),
"atx": pandocSetting("--atx-headers", "checkbox", "markdown asciidoc",
qApp.translate("Export", "Use ATX-style headers")),
"self-contained": pandocSetting("--self-contained", "checkbox", "html",
qApp.translate("Export", "Self-contained html files, with no dependencies")),
"q-tags": pandocSetting("--html-q-tags", "checkbox", "html",
qApp.translate("Export", "Use <q> tags for quotes in HTML")),
"latex-engine": pandocSetting("--latex-engine", "combo", "pdf",
qApp.translate("Export", "LaTeX engine used to produce the PDF."),
vals="pdflatex|lualatex|xelatex")
}
def __init__(self, _format, toFormat=None, parent=None):
markdownSettings.__init__(self, _format, parent)
self.format = toFormat
w = QWidget(self)
w.setLayout(QVBoxLayout())
self.grpPandocGeneral = self.collapsibleGroupBox(self.tr("General"), w)
self.addSettingsWidget("smart", self.grpPandocGeneral)
self.addSettingsWidget("normalize", self.grpPandocGeneral)
self.addSettingsWidget("base-header", self.grpPandocGeneral)
self.addSettingsWidget("standalone", self.grpPandocGeneral)
self.grpPandocTOC = self.collapsibleGroupBox(self.tr("Table of Content"), w)
self.addSettingsWidget("TOC", self.grpPandocTOC)
self.addSettingsWidget("TOC-depth", self.grpPandocTOC)
self.grpPandocSpecific = self.collapsibleGroupBox(self.tr("Custom settings for {}").format(self.format), w)
self.addSettingsWidget("ref-link", self.grpPandocSpecific)
self.addSettingsWidget("atx", self.grpPandocSpecific)
self.addSettingsWidget("self-contained", self.grpPandocSpecific)
self.addSettingsWidget("q-tags", self.grpPandocSpecific)
self.addSettingsWidget("latex-engine", self.grpPandocSpecific)
self.toolBox.insertItem(self.toolBox.count() - 1, w, "Pandoc")
self.toolBox.layout().setSpacing(0) # Not sure why this is needed, but hey...
self.getSettings()
def collapsibleGroupBox(self, title, parent):
g = collapsibleGroupBox2(title=title)
parent.layout().addWidget(g)
g.setLayout(QVBoxLayout())
return g
def addSettingsWidget(self, settingsName, parent):
if not settingsName in self.settingsList:
return
s = self.settingsList[settingsName]
if not s.isValid(self.format):
# That setting is not available for that export format
return
if "checkbox" in s.type:
s.widget = QCheckBox(s.label)
if s.default:
s.widget.setChecked(True)
parent.layout().addWidget(s.widget)
elif "number" in s.type:
l = QHBoxLayout()
label = QLabel(s.label, parent)
label.setWordWrap(True)
l.addWidget(label, 8)
s.widget = QSpinBox()
s.widget.setValue(s.default if s.default else 0)
if s.min:
s.widget.setMinimum(s.min)
if s.max:
s.widget.setMaximum(s.max)
l.addWidget(s.widget, 2)
parent.layout().addLayout(l)
elif "combo" in s.type:
l = QHBoxLayout()
label = QLabel(s.label, parent)
label.setWordWrap(True)
l.addWidget(label, 6)
s.widget = QComboBox()
s.widget.addItems(s.vals)
l.addWidget(s.widget, 2)
parent.layout().addLayout(l)
def updateFromSettings(self):
markdownSettings.updateFromSettings(self)
# s = self.settings["Preview"]
# val = s.get("MarkdownHighlighter", False)
# self.chkMarkdownHighlighter.setChecked(val)
if not "Pandoc" in self.settings:
return
for name in self.settingsList:
s = self.settingsList[name]
if s.isValid(self.format):
if s.type == "checkbox" and name in self.settings["Pandoc"]:
s.widget.setChecked(self.settings["Pandoc"][name])
elif s.type == "number" and name in self.settings["Pandoc"]:
s.widget.setValue(int(self.settings["Pandoc"][name]))
elif s.type == "combo" and name in self.settings["Pandoc"]:
s.widget.setCurrentText(self.settings["Pandoc"][name])
def getSettings(self):
self.settings = markdownSettings.getSettings(self)
# self.settings["Preview"]["MarkdownHighlighter"] = self.chkMarkdownHighlighter.isChecked()
P = self.settings.get("Pandoc", {})
for name in self.settingsList:
s = self.settingsList[name]
if s.isValid(self.format):
if s.type == "checkbox":
P[name] = s.widget.isChecked()
elif s.type == "number":
P[name] = str(s.widget.value())
elif s.type == "combo":
P[name] = s.widget.currentText()
self.settings["Pandoc"] = P
return self.settings
def runnableSettings(self):
r = ["--from=markdown",
"--to={}".format(self.format)]
for name in self.settingsList:
s = self.settingsList[name]
if s.isValid(self.format):
if s.type == "checkbox":
if s.widget.isChecked():
r.append(s.arg)
elif s.type == "number":
r.append("{}={}".format(
s.arg,
str(s.widget.value())
))
elif s.type == "combo":
r.append("{}={}".format(
s.arg,
s.widget.currentText()
))
return r

View file

@ -1,63 +0,0 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtGui import QTextCharFormat, QFont
from PyQt5.QtWidgets import QPlainTextEdit, QGroupBox, qApp, QVBoxLayout, QCheckBox
from manuskript.exporter.manuskript.markdown import markdown as manuskriptMarkdown
from manuskript.exporter.manuskript.markdown import markdownSettings as manuskriptMarkdownSettings
from manuskript.functions import mainWindow
from manuskript.ui.editors.MMDHighlighter import MMDHighlighter
from manuskript.ui.exporters.manuskript.plainTextSettings import exporterSettings
class markdown(manuskriptMarkdown):
name = "Markdown"
description = qApp.translate("Export", """Export to markdown, using pandoc. Allows more formatting options
than the basic manuskript exporter.""")
exportVarName = "lastPandocMarkdown"
def settingsWidget(self):
w = markdownSettings(self)
w.loadSettings()
return w
def preview(self, settingsWidget, previewWidget):
settings = settingsWidget.getSettings()
# Save settings
settingsWidget.writeSettings()
# Prepares text edit
self.preparesTextEditViewMarkdown(previewWidget, settingsWidget.settings)
self.preparesTextEditView(previewWidget, settings["Preview"]["PreviewFont"])
r = self.concatenate(mainWindow().mdlOutline.rootItem, settings)
previewWidget.setPlainText(r)
class markdownSettings(manuskriptMarkdownSettings):
def __init__(self, _format, parent=None):
manuskriptMarkdownSettings.__init__(self, _format, parent)
# # Adds markdown syntax highlighter setting
# w = self.toolBox.widget(self.toolBox.count() - 1)
# self.grpMarkdown = QGroupBox(self.tr("Markdown"))
# self.grpMarkdown.setLayout(QVBoxLayout())
# self.chkMarkdownHighlighter = QCheckBox(qApp.translate("Export", "Preview with highlighter."))
# self.grpMarkdown.layout().addWidget(self.chkMarkdownHighlighter)
#
# w.layout().insertWidget(w.layout().count() - 1, self.grpMarkdown)
def updateFromSettings(self):
manuskriptMarkdownSettings.updateFromSettings(self)
# s = self.settings["Preview"]
# val = s.get("MarkdownHighlighter", False)
# self.chkMarkdownHighlighter.setChecked(val)
def getSettings(self):
self.settings = manuskriptMarkdownSettings.getSettings(self)
# self.settings["Preview"]["MarkdownHighlighter"] = self.chkMarkdownHighlighter.isChecked()
return self.settings

View file

@ -0,0 +1,36 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtWidgets import qApp
from manuskript.exporter.pandoc.abstractOutput import abstractOutput
class ePub(abstractOutput):
name = "ePub"
description = qApp.translate("Export", """Books that don't kill trees.""")
icon = "application-epub+zip"
exportVarName = "lastPandocePub"
toFormat = "epub"
exportFilter = "ePub files (*.epub);; Any files (*)"
class OpenDocument(abstractOutput):
name = "OpenDocument"
description = qApp.translate("Export", "OpenDocument format. Used by LibreOffice for example.")
exportVarName = "lastPandocODT"
toFormat = "odt"
icon = "application-vnd.oasis.opendocument.text"
exportFilter = "OpenDocument files (*.odt);; Any files (*)"
class DocX(abstractOutput):
name = "DocX"
description = qApp.translate("Export", "Microsoft Office (.docx) document.")
exportVarName = "lastPandocDocX"
toFormat = "docx"
icon = "application-vnd.openxmlformats-officedocument.wordprocessingml.document"
exportFilter = "DocX files (*.docx);; Any files (*)"

View file

@ -0,0 +1,38 @@
#!/usr/bin/env python
# --!-- coding: utf8 --!--
from PyQt5.QtWidgets import qApp
from manuskript.exporter.pandoc.abstractPlainText import abstractPlainText
class markdown(abstractPlainText):
name = "Markdown"
description = qApp.translate("Export", """Export to markdown, using pandoc. Allows more formatting options
than the basic manuskript exporter.""")
icon = "text-x-markdown"
exportVarName = "lastPandocMarkdown"
toFormat = "markdown"
exportFilter = "Markdown files (*.md);; Any files (*)"
class reST(abstractPlainText):
name = "reST"
description = qApp.translate("Export", """reStructuredText is a lightweight markup language...""")
exportVarName = "lastPandocreST"
toFormat = "rst"
icon = "text-plain"
exportFilter = "reST files (*.rst);; Any files (*)"
class latex(abstractPlainText):
name = "LaTeX"
description = qApp.translate("Export", """LaTeX is a word processor and document markup language used to create
beautiful documents.""")
exportVarName = "lastPandocLatex"
toFormat = "latex"
icon = "text-x-tex"
exportFilter = "Tex files (*.tex);; Any files (*)"

View file

@ -7,7 +7,7 @@ from manuskript.functions import lightBlue
class collapsibleGroupBox2(QWidget):
def __init__(self, parent=None):
def __init__(self, parent=None, title=None):
QWidget.__init__(self, parent)
self.frame = QFrame(self)
self.button = QPushButton("Toggle", self)
@ -17,6 +17,8 @@ class collapsibleGroupBox2(QWidget):
self.vPolicy = None
# self.button.setStyleSheet("background-color: lightBlue;")
self.setCustomColors()
if title:
self.setTitle(title)
def resizeEvent(self, event):
if not self.switched:

View file

@ -34,6 +34,9 @@ class exporterDialog(QWidget, Ui_exporter):
self.btnPreview.clicked.connect(self.preview)
self.btnExport.clicked.connect(self.export)
# FIXME: Debug: working on pandoc's markdown
self.cmbExporters.setCurrentIndex(7)
def populateExportList(self):
# Populates list