export: fix wkhtmltopdf

- MathJax works fine;
- Mermaid does not work;
- Flowchart.js works fine;
This commit is contained in:
Le Tan 2018-03-02 22:37:22 +08:00
parent ada0b40d80
commit 635ac0a10b
7 changed files with 107 additions and 23 deletions

View File

@ -120,7 +120,7 @@ void VExportDialog::setupUI()
m_consoleEdit = new QPlainTextEdit(); m_consoleEdit = new QPlainTextEdit();
m_consoleEdit->setReadOnly(true); m_consoleEdit->setReadOnly(true);
m_consoleEdit->setLineWrapMode(QPlainTextEdit::NoWrap); m_consoleEdit->setLineWrapMode(QPlainTextEdit::WidgetWidth);
m_consoleEdit->setProperty("LineEdit", true); m_consoleEdit->setProperty("LineEdit", true);
m_consoleEdit->setPlaceholderText(tr("Output logs will be shown here")); m_consoleEdit->setPlaceholderText(tr("Output logs will be shown here"));
@ -148,6 +148,15 @@ void VExportDialog::setupUI()
QDesktopServices::openUrl(url); QDesktopServices::openUrl(url);
}); });
// Progress bar.
m_proBar = new QProgressBar();
m_proBar->setRange(0, 0);
m_proBar->hide();
QHBoxLayout *btnLayout = new QHBoxLayout();
btnLayout->addWidget(m_proBar);
btnLayout->addWidget(m_btnBox);
QFormLayout *basicLayout = new QFormLayout(); QFormLayout *basicLayout = new QFormLayout();
basicLayout->addRow(tr("Notes to export:"), m_srcCB); basicLayout->addRow(tr("Notes to export:"), m_srcCB);
basicLayout->addRow(tr("Target format:"), m_formatCB); basicLayout->addRow(tr("Target format:"), m_formatCB);
@ -175,7 +184,7 @@ void VExportDialog::setupUI()
mainLayout->addWidget(m_basicBox); mainLayout->addWidget(m_basicBox);
mainLayout->addWidget(m_settingBox); mainLayout->addWidget(m_settingBox);
mainLayout->addWidget(m_consoleEdit); mainLayout->addWidget(m_consoleEdit);
mainLayout->addWidget(m_btnBox); mainLayout->addLayout(btnLayout);
setLayout(mainLayout); setLayout(mainLayout);
@ -258,8 +267,8 @@ QWidget *VExportDialog::setupPDFAdvancedSettings()
// wkhtmltopdf extra argumnets. // wkhtmltopdf extra argumnets.
m_wkExtraArgsEdit = new VLineEdit(); m_wkExtraArgsEdit = new VLineEdit();
m_wkExtraArgsEdit->setToolTip(tr("Additional arguments passed to wkhtmltopdf")); m_wkExtraArgsEdit->setToolTip(tr("Additional global options passed to wkhtmltopdf"));
m_wkExtraArgsEdit->setPlaceholderText(tr("Use \" to enclose arguments containing space")); m_wkExtraArgsEdit->setPlaceholderText(tr("Use \" to enclose options containing spaces"));
m_wkExtraArgsEdit->setEnabled(m_wkhtmltopdfCB->isChecked()); m_wkExtraArgsEdit->setEnabled(m_wkhtmltopdfCB->isChecked());
QGridLayout *advLayout = new QGridLayout(); QGridLayout *advLayout = new QGridLayout();
@ -286,7 +295,7 @@ QWidget *VExportDialog::setupPDFAdvancedSettings()
advLayout->addWidget(new QLabel(tr("Page number:")), 5, 0); advLayout->addWidget(new QLabel(tr("Page number:")), 5, 0);
advLayout->addWidget(m_wkPageNumberCB, 5, 1, 1, 2); advLayout->addWidget(m_wkPageNumberCB, 5, 1, 1, 2);
advLayout->addWidget(new QLabel(tr("Additional global options:")), 6, 0); advLayout->addWidget(new QLabel(tr("Additional options:")), 6, 0);
advLayout->addWidget(m_wkExtraArgsEdit, 6, 1, 1, 5); advLayout->addWidget(m_wkExtraArgsEdit, 6, 1, 1, 5);
advLayout->setContentsMargins(0, 0, 0, 0); advLayout->setContentsMargins(0, 0, 0, 0);
@ -478,6 +487,7 @@ void VExportDialog::startExport()
} }
m_exportBtn->setEnabled(false); m_exportBtn->setEnabled(false);
m_proBar->show();
m_askedToStop = false; m_askedToStop = false;
m_inExport = true; m_inExport = true;
@ -523,6 +533,7 @@ void VExportDialog::startExport()
if (!checkWkhtmltopdfExecutable(s_opt.m_pdfOpt.m_wkPath)) { if (!checkWkhtmltopdfExecutable(s_opt.m_pdfOpt.m_wkPath)) {
m_inExport = false; m_inExport = false;
m_exportBtn->setEnabled(true); m_exportBtn->setEnabled(true);
m_proBar->hide();
return; return;
} }
} }
@ -616,6 +627,7 @@ exit:
m_inExport = false; m_inExport = false;
m_exportBtn->setEnabled(true); m_exportBtn->setEnabled(true);
m_proBar->hide();
} }
QString VExportDialog::getOutputDirectory() const QString VExportDialog::getOutputDirectory() const
@ -686,7 +698,8 @@ void VExportDialog::handleInputChanged()
void VExportDialog::appendLogLine(const QString &p_text) void VExportDialog::appendLogLine(const QString &p_text)
{ {
m_consoleEdit->appendPlainText(p_text); m_consoleEdit->appendPlainText(">>> " + p_text);
m_consoleEdit->ensureCursorVisible();
QCoreApplication::sendPostedEvents(); QCoreApplication::sendPostedEvents();
} }

View File

@ -21,6 +21,7 @@ class VCart;
class VExporter; class VExporter;
class QCheckBox; class QCheckBox;
class VLineEdit; class VLineEdit;
class QProgressBar;
enum class ExportSource enum class ExportSource
@ -336,6 +337,8 @@ private:
VCart *m_cart; VCart *m_cart;
QProgressBar *m_proBar;
QPageLayout m_pageLayout; QPageLayout m_pageLayout;
// Whether we are exporting files. // Whether we are exporting files.

View File

@ -10,6 +10,8 @@
/* STYLE_PLACE_HOLDER */ /* STYLE_PLACE_HOLDER */
</style> </style>
<!-- EXTRA_PLACE_HOLDER -->
<!-- HEAD_PLACE_HOLDER --> <!-- HEAD_PLACE_HOLDER -->
</head> </head>
<body> <body>

View File

@ -44,6 +44,10 @@ if (typeof VEnableFlashAnchor == 'undefined') {
VEnableFlashAnchor = false; VEnableFlashAnchor = false;
} }
if (typeof VRemoveMathjaxScript == 'undefined') {
VRemoveMathjaxScript = false;
}
var getUrlScheme = function(url) { var getUrlScheme = function(url) {
var idx = url.indexOf(':'); var idx = url.indexOf(':');
if (idx > -1) { if (idx > -1) {
@ -1078,6 +1082,11 @@ var postProcessMathJax = function() {
var all = MathJax.Hub.getAllJax(); var all = MathJax.Hub.getAllJax();
for (var i = 0; i < all.length; ++i) { for (var i = 0; i < all.length; ++i) {
var node = all[i].SourceElement().parentNode; var node = all[i].SourceElement().parentNode;
if (VRemoveMathjaxScript) {
// Remove the SourceElement.
node.removeChild(all[i].SourceElement());
}
if (node.tagName.toLowerCase() == 'code') { if (node.tagName.toLowerCase() == 'code') {
var pre = node.parentNode; var pre = node.parentNode;
var p = document.createElement('p'); var p = document.createElement('p');

View File

@ -601,18 +601,22 @@ QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType,
const QString &p_renderBg, const QString &p_renderBg,
const QString &p_renderStyle, const QString &p_renderStyle,
const QString &p_renderCodeBlockStyle, const QString &p_renderCodeBlockStyle,
bool p_isPDF) bool p_isPDF,
bool p_wkhtmltopdf)
{ {
Q_ASSERT((p_isPDF && p_wkhtmltopdf) || !p_wkhtmltopdf);
QString templ = VNote::generateHtmlTemplate(g_config->getRenderBackgroundColor(p_renderBg), QString templ = VNote::generateHtmlTemplate(g_config->getRenderBackgroundColor(p_renderBg),
g_config->getCssStyleUrl(p_renderStyle), g_config->getCssStyleUrl(p_renderStyle),
g_config->getCodeBlockCssStyleUrl(p_renderCodeBlockStyle), g_config->getCodeBlockCssStyleUrl(p_renderCodeBlockStyle),
p_isPDF); p_isPDF);
return generateHtmlTemplate(templ, p_conType); return generateHtmlTemplate(templ, p_conType, p_wkhtmltopdf);
} }
QString VUtils::generateHtmlTemplate(const QString &p_template, QString VUtils::generateHtmlTemplate(const QString &p_template,
MarkdownConverterType p_conType) MarkdownConverterType p_conType,
bool p_wkhtmltopdf)
{ {
QString jsFile, extraFile; QString jsFile, extraFile;
switch (p_conType) { switch (p_conType) {
@ -674,6 +678,14 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
} }
if (g_config->getEnableMathjax()) { if (g_config->getEnableMathjax()) {
QString mj = g_config->getMathjaxJavascript();
if (p_wkhtmltopdf) {
// Chante MathJax to be rendered as SVG.
// If rendered as HTML, it will make the font of <code> messy.
QRegExp reg("(Mathjax\\.js\\?config=)\\S+", Qt::CaseInsensitive);
mj.replace(reg, QString("\\1%1").arg("TeX-MML-AM_SVG"));
}
extraFile += "<script type=\"text/x-mathjax-config\">" extraFile += "<script type=\"text/x-mathjax-config\">"
"MathJax.Hub.Config({\n" "MathJax.Hub.Config({\n"
" tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']],\n" " tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']],\n"
@ -682,8 +694,12 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
" showProcessingMessages: false,\n" " showProcessingMessages: false,\n"
" messageStyle: \"none\"});\n" " messageStyle: \"none\"});\n"
"</script>\n" "</script>\n"
"<script type=\"text/javascript\" async src=\"" + g_config->getMathjaxJavascript() + "\"></script>\n" + "<script type=\"text/javascript\" async src=\"" + mj + "\"></script>\n" +
"<script>var VEnableMathjax = true;</script>\n"; "<script>var VEnableMathjax = true;</script>\n";
if (p_wkhtmltopdf) {
extraFile += "<script>var VRemoveMathjaxScript = true;</script>\n";
}
} }
if (g_config->getEnableImageCaption()) { if (g_config->getEnableImageCaption()) {
@ -710,9 +726,39 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
return htmlTemplate; return htmlTemplate;
} }
QString VUtils::generateExportHtmlTemplate(const QString &p_renderBg) QString VUtils::generateExportHtmlTemplate(const QString &p_renderBg, bool p_includeMathJax)
{ {
return VNote::generateExportHtmlTemplate(g_config->getRenderBackgroundColor(p_renderBg)); QString templ = VNote::generateExportHtmlTemplate(g_config->getRenderBackgroundColor(p_renderBg));
QString extra;
if (p_includeMathJax) {
extra += "<script type=\"text/x-mathjax-config\">\n"
"MathJax.Hub.Config({\n"
"showProcessingMessages: false,\n"
"messageStyle: \"none\",\n"
"SVG: {\n"
"minScaleAdjust: 100,\n"
"styles: {\n"
"\".MathJax_SVG\": {\n"
"\"font-size\": \"2em !important\"\n"
"}\n"
"}\n"
"}\n"
"});\n"
"</script>\n";
QString mj = g_config->getMathjaxJavascript();
// Chante MathJax to be rendered as SVG.
QRegExp reg("(Mathjax\\.js\\?config=)\\S+", Qt::CaseInsensitive);
mj.replace(reg, QString("\\1%1").arg("TeX-MML-AM_SVG"));
extra += "<script type=\"text/javascript\" async src=\"" + mj + "\"></script>\n";
}
if (!extra.isEmpty()) {
templ.replace(HtmlHolder::c_extraHolder, extra);
}
return templ;
} }
QString VUtils::getFileNameWithSequence(const QString &p_directory, QString VUtils::getFileNameWithSequence(const QString &p_directory,

View File

@ -171,14 +171,16 @@ public:
static QString generateHtmlTemplate(MarkdownConverterType p_conType); static QString generateHtmlTemplate(MarkdownConverterType p_conType);
// @p_renderBg is the background name. // @p_renderBg is the background name.
// @p_wkhtmltopdf: whether this template is used for wkhtmltopdf.
static QString generateHtmlTemplate(MarkdownConverterType p_conType, static QString generateHtmlTemplate(MarkdownConverterType p_conType,
const QString &p_renderBg, const QString &p_renderBg,
const QString &p_renderStyle, const QString &p_renderStyle,
const QString &p_renderCodeBlockStyle, const QString &p_renderCodeBlockStyle,
bool p_isPDF); bool p_isPDF,
bool p_wkhtmltopdf = false);
// @p_renderBg is the background name. // @p_renderBg is the background name.
static QString generateExportHtmlTemplate(const QString &p_renderBg); static QString generateExportHtmlTemplate(const QString &p_renderBg, bool p_includeMathJax);
static QString generateSimpleHtmlTemplate(const QString &p_body); static QString generateSimpleHtmlTemplate(const QString &p_body);
@ -356,7 +358,8 @@ private:
const QString &p_path); const QString &p_path);
static QString generateHtmlTemplate(const QString &p_template, static QString generateHtmlTemplate(const QString &p_template,
MarkdownConverterType p_conType); MarkdownConverterType p_conType,
bool p_wkhtmltopdf = false);
// <value, name> // <value, name>
static QVector<QPair<QString, QString>> s_availableLanguages; static QVector<QPair<QString, QString>> s_availableLanguages;

View File

@ -43,9 +43,11 @@ void VExporter::prepareExport(const ExportOption &p_opt)
p_opt.m_renderBg, p_opt.m_renderBg,
p_opt.m_renderStyle, p_opt.m_renderStyle,
p_opt.m_renderCodeBlockStyle, p_opt.m_renderCodeBlockStyle,
isPdf); isPdf,
isPdf && p_opt.m_pdfOpt.m_wkhtmltopdf);
m_exportHtmlTemplate = VUtils::generateExportHtmlTemplate(p_opt.m_renderBg); m_exportHtmlTemplate = VUtils::generateExportHtmlTemplate(p_opt.m_renderBg,
isPdf && p_opt.m_pdfOpt.m_wkhtmltopdf);
m_pageLayout = *(p_opt.m_pdfOpt.m_layout); m_pageLayout = *(p_opt.m_pdfOpt.m_layout);
@ -96,8 +98,6 @@ static QStringList parseCombinedArgString(const QString &program)
void VExporter::prepareWKArguments(const ExportPDFOption &p_opt) void VExporter::prepareWKArguments(const ExportPDFOption &p_opt)
{ {
m_wkArgs.clear(); m_wkArgs.clear();
m_wkArgs << "--quiet";
m_wkArgs << "--encoding" << "utf-8";
m_wkArgs << "--page-size" << m_pageLayout.pageSize().key(); m_wkArgs << "--page-size" << m_pageLayout.pageSize().key();
m_wkArgs << "--orientation" m_wkArgs << "--orientation"
<< (m_pageLayout.orientation() == QPageLayout::Portrait ? "Portrait" : "Landscape"); << (m_pageLayout.orientation() == QPageLayout::Portrait ? "Portrait" : "Landscape");
@ -108,8 +108,6 @@ void VExporter::prepareWKArguments(const ExportPDFOption &p_opt)
m_wkArgs << "--margin-right" << marginToStrMM(marginsMM.right()); m_wkArgs << "--margin-right" << marginToStrMM(marginsMM.right());
m_wkArgs << "--margin-top" << marginToStrMM(marginsMM.top()); m_wkArgs << "--margin-top" << marginToStrMM(marginsMM.top());
m_wkArgs << (p_opt.m_wkEnableBackground ? "--background" : "--no-background");
QString footer; QString footer;
switch (p_opt.m_wkPageNumber) { switch (p_opt.m_wkPageNumber) {
case ExportPageNumber::Left: case ExportPageNumber::Left:
@ -138,11 +136,20 @@ void VExporter::prepareWKArguments(const ExportPDFOption &p_opt)
m_wkArgs << "--title" << p_opt.m_wkTitle; m_wkArgs << "--title" << p_opt.m_wkTitle;
} }
// Append additional arguments. m_wkArgs << "--encoding" << "utf-8";
m_wkArgs << (p_opt.m_wkEnableBackground ? "--background" : "--no-background");
// Delay for MathJax.
if (p_opt.m_wkhtmltopdf) {
m_wkArgs << "--javascript-delay" << "10000";
}
// Append additional global option.
if (!p_opt.m_wkExtraArgs.isEmpty()) { if (!p_opt.m_wkExtraArgs.isEmpty()) {
m_wkArgs.append(parseCombinedArgString(p_opt.m_wkExtraArgs)); m_wkArgs.append(parseCombinedArgString(p_opt.m_wkExtraArgs));
} }
// TOC option.
if (p_opt.m_wkEnableTableOfContents) { if (p_opt.m_wkEnableTableOfContents) {
m_wkArgs << "toc" << "--toc-text-size-shrink" << "1.0"; m_wkArgs << "toc" << "--toc-text-size-shrink" << "1.0";
} }
@ -658,8 +665,9 @@ bool VExporter::htmlsToPDFViaWK(const QList<QString> &p_htmlFiles,
QString cmd = p_opt.m_wkPath + " " + combineArgs(args); QString cmd = p_opt.m_wkPath + " " + combineArgs(args);
emit outputLog(cmd); emit outputLog(cmd);
qDebug() << "wkhtmltopdf cmd:" << cmd;
int ret = QProcess::execute(p_opt.m_wkPath, args); int ret = QProcess::execute(p_opt.m_wkPath, args);
qDebug() << "wkhtmltopdf returned" << ret << cmd; qDebug() << "wkhtmltopdf returned" << ret;
switch (ret) { switch (ret) {
case -2: case -2:
VUtils::addErrMsg(p_errMsg, tr("Fail to start wkhtmltopdf (%1).").arg(cmd)); VUtils::addErrMsg(p_errMsg, tr("Fail to start wkhtmltopdf (%1).").arg(cmd));