Browse Source

export: fix wkhtmltopdf

- MathJax works fine;
- Mermaid does not work;
- Flowchart.js works fine;
Le Tan 7 years ago
parent
commit
635ac0a10b

+ 19 - 6
src/dialog/vexportdialog.cpp

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

+ 3 - 0
src/dialog/vexportdialog.h

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

+ 2 - 0
src/resources/export_template.html

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

+ 9 - 0
src/resources/markdown_template.js

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

+ 52 - 6
src/utils/vutils.cpp

@@ -601,18 +601,22 @@ QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType,
                                      const QString &p_renderBg,
                                      const QString &p_renderStyle,
                                      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),
                                                 g_config->getCssStyleUrl(p_renderStyle),
                                                 g_config->getCodeBlockCssStyleUrl(p_renderCodeBlockStyle),
                                                 p_isPDF);
 
-    return generateHtmlTemplate(templ, p_conType);
+    return generateHtmlTemplate(templ, p_conType, p_wkhtmltopdf);
 }
 
 QString VUtils::generateHtmlTemplate(const QString &p_template,
-                                     MarkdownConverterType p_conType)
+                                     MarkdownConverterType p_conType,
+                                     bool p_wkhtmltopdf)
 {
     QString jsFile, extraFile;
     switch (p_conType) {
@@ -674,6 +678,14 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
     }
 
     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\">"
                      "MathJax.Hub.Config({\n"
                      "                    tex2jax: {inlineMath: [['$','$'], ['\\\\(','\\\\)']],\n"
@@ -682,8 +694,12 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
                      "                    showProcessingMessages: false,\n"
                      "                    messageStyle: \"none\"});\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";
+
+        if (p_wkhtmltopdf) {
+            extraFile += "<script>var VRemoveMathjaxScript = true;</script>\n";
+        }
     }
 
     if (g_config->getEnableImageCaption()) {
@@ -710,9 +726,39 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
     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,

+ 6 - 3
src/utils/vutils.h

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

+ 16 - 8
src/vexporter.cpp

@@ -43,9 +43,11 @@ void VExporter::prepareExport(const ExportOption &p_opt)
                                                   p_opt.m_renderBg,
                                                   p_opt.m_renderStyle,
                                                   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);
 
@@ -96,8 +98,6 @@ static QStringList parseCombinedArgString(const QString &program)
 void VExporter::prepareWKArguments(const ExportPDFOption &p_opt)
 {
     m_wkArgs.clear();
-    m_wkArgs << "--quiet";
-    m_wkArgs << "--encoding" << "utf-8";
     m_wkArgs << "--page-size" << m_pageLayout.pageSize().key();
     m_wkArgs << "--orientation"
              << (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-top" << marginToStrMM(marginsMM.top());
 
-    m_wkArgs << (p_opt.m_wkEnableBackground ? "--background" : "--no-background");
-
     QString footer;
     switch (p_opt.m_wkPageNumber) {
     case ExportPageNumber::Left:
@@ -138,11 +136,20 @@ void VExporter::prepareWKArguments(const ExportPDFOption &p_opt)
         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()) {
         m_wkArgs.append(parseCombinedArgString(p_opt.m_wkExtraArgs));
     }
 
+    // TOC option.
     if (p_opt.m_wkEnableTableOfContents) {
         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);
     emit outputLog(cmd);
+    qDebug() << "wkhtmltopdf cmd:" << cmd;
     int ret = QProcess::execute(p_opt.m_wkPath, args);
-    qDebug() << "wkhtmltopdf returned" << ret << cmd;
+    qDebug() << "wkhtmltopdf returned" << ret;
     switch (ret) {
     case -2:
         VUtils::addErrMsg(p_errMsg, tr("Fail to start wkhtmltopdf (%1).").arg(cmd));