Browse Source

export: add TOC function to built-in PDF export

Le Tan 7 years ago
parent
commit
9cc193178b

+ 13 - 16
src/dialog/vexportdialog.cpp

@@ -208,6 +208,10 @@ QWidget *VExportDialog::setupPDFAdvancedSettings()
 
     updatePageLayoutLabel();
 
+    // Enable table of contents.
+    m_tableOfContentsCB = new QCheckBox(tr("Enable Table Of Contents"));
+    m_tableOfContentsCB->setToolTip(tr("Add a table of contents to the document"));
+
     // Use wkhtmltopdf.
     m_wkhtmltopdfCB = new QCheckBox(tr("Use wkhtmltopdf"));
     m_wkhtmltopdfCB->setToolTip(tr("Use wkhtmltopdf tool to generate PDF (wkhtmltopdf needed to be installed)"));
@@ -217,7 +221,6 @@ QWidget *VExportDialog::setupPDFAdvancedSettings()
                 m_wkPathEdit->setEnabled(checked);
                 m_wkPathBrowseBtn->setEnabled(checked);
                 m_wkBackgroundCB->setEnabled(checked);
-                m_wkTableOfContentsCB->setEnabled(checked);
                 m_wkPageNumberCB->setEnabled(checked);
                 m_wkExtraArgsEdit->setEnabled(checked);
             });
@@ -257,11 +260,6 @@ QWidget *VExportDialog::setupPDFAdvancedSettings()
     m_wkBackgroundCB->setToolTip(tr("Enable background when printing"));
     m_wkBackgroundCB->setEnabled(m_wkhtmltopdfCB->isChecked());
 
-    // wkhtmltopdf enable table of contents.
-    m_wkTableOfContentsCB = new QCheckBox(tr("Enable Table Of Contents"));
-    m_wkTableOfContentsCB->setToolTip(tr("Add a table of contents to the document"));
-    m_wkTableOfContentsCB->setEnabled(m_wkhtmltopdfCB->isChecked());
-
     // wkhtmltopdf page number.
     m_wkPageNumberCB = VUtils::getComboBox();
     m_wkPageNumberCB->setToolTip(tr("Append page number as footer"));
@@ -277,6 +275,7 @@ QWidget *VExportDialog::setupPDFAdvancedSettings()
     advLayout->addWidget(new QLabel(tr("Page layout:")), 0, 0);
     advLayout->addWidget(m_layoutLabel, 0, 1);
     advLayout->addWidget(layoutBtn, 0, 2);
+    advLayout->addWidget(m_tableOfContentsCB, 0, 4, 1, 2);
 
     advLayout->addWidget(m_wkhtmltopdfCB, 1, 1, 1, 2);
     advLayout->addWidget(wkBtn, 1, 4, 1, 2);
@@ -291,14 +290,12 @@ QWidget *VExportDialog::setupPDFAdvancedSettings()
     advLayout->addWidget(new QLabel(tr("Output file name:")), 3, 3);
     advLayout->addWidget(m_wkTargetFileNameEdit, 3, 4, 1, 2);
 
-    advLayout->addWidget(m_wkBackgroundCB, 4, 1, 1, 2);
-    advLayout->addWidget(m_wkTableOfContentsCB, 4, 4, 1, 2);
-
-    advLayout->addWidget(new QLabel(tr("Page number:")), 5, 0);
-    advLayout->addWidget(m_wkPageNumberCB, 5, 1, 1, 2);
+    advLayout->addWidget(new QLabel(tr("Page number:")), 4, 0);
+    advLayout->addWidget(m_wkPageNumberCB, 4, 1, 1, 2);
+    advLayout->addWidget(m_wkBackgroundCB, 4, 4, 1, 2);
 
-    advLayout->addWidget(new QLabel(tr("Additional options:")), 6, 0);
-    advLayout->addWidget(m_wkExtraArgsEdit, 6, 1, 1, 5);
+    advLayout->addWidget(new QLabel(tr("Additional options:")), 5, 0);
+    advLayout->addWidget(m_wkExtraArgsEdit, 5, 1, 1, 5);
 
     advLayout->setContentsMargins(0, 0, 0, 0);
 
@@ -437,6 +434,8 @@ void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
 
     m_mimeHTMLCB->setChecked(s_opt.m_htmlOpt.m_mimeHTML);
 
+    m_tableOfContentsCB->setChecked(s_opt.m_pdfOpt.m_enableTableOfContents);
+
     m_wkhtmltopdfCB->setChecked(s_opt.m_pdfOpt.m_wkhtmltopdf);
 
     // wkhtmltopdf path.
@@ -444,8 +443,6 @@ void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
 
     m_wkBackgroundCB->setChecked(s_opt.m_pdfOpt.m_wkEnableBackground);
 
-    m_wkTableOfContentsCB->setChecked(s_opt.m_pdfOpt.m_wkEnableTableOfContents);
-
     // wkhtmltopdf page number.
     m_wkPageNumberCB->addItem(tr("None"), (int)ExportPageNumber::None);
     m_wkPageNumberCB->addItem(tr("Left"), (int)ExportPageNumber::Left);
@@ -507,7 +504,7 @@ void VExportDialog::startExport()
                                          m_wkhtmltopdfCB->isChecked(),
                                          QDir::toNativeSeparators(m_wkPathEdit->text()),
                                          m_wkBackgroundCB->isChecked(),
-                                         m_wkTableOfContentsCB->isChecked(),
+                                         m_tableOfContentsCB->isChecked(),
                                          m_wkTitleEdit->text(),
                                          m_wkTargetFileNameEdit->text(),
                                          (ExportPageNumber)m_wkPageNumberCB->currentData().toInt(),

+ 5 - 5
src/dialog/vexportdialog.h

@@ -81,7 +81,7 @@ struct ExportPDFOption
         : m_layout(NULL),
           m_wkhtmltopdf(false),
           m_wkEnableBackground(true),
-          m_wkEnableTableOfContents(false),
+          m_enableTableOfContents(false),
           m_wkPageNumber(ExportPageNumber::None)
     {
     }
@@ -90,7 +90,7 @@ struct ExportPDFOption
                     bool p_wkhtmltopdf,
                     const QString &p_wkPath,
                     bool p_wkEnableBackground,
-                    bool p_wkEnableTableOfContents,
+                    bool p_enableTableOfContents,
                     const QString &p_wkTitle,
                     const QString &p_wkTargetFileName,
                     ExportPageNumber p_wkPageNumber,
@@ -99,7 +99,7 @@ struct ExportPDFOption
           m_wkhtmltopdf(p_wkhtmltopdf),
           m_wkPath(p_wkPath),
           m_wkEnableBackground(p_wkEnableBackground),
-          m_wkEnableTableOfContents(p_wkEnableTableOfContents),
+          m_enableTableOfContents(p_enableTableOfContents),
           m_wkTitle(p_wkTitle),
           m_wkTargetFileName(p_wkTargetFileName),
           m_wkPageNumber(p_wkPageNumber),
@@ -111,7 +111,7 @@ struct ExportPDFOption
     bool m_wkhtmltopdf;
     QString m_wkPath;
     bool m_wkEnableBackground;
-    bool m_wkEnableTableOfContents;
+    bool m_enableTableOfContents;;
     QString m_wkTitle;
     QString m_wkTargetFileName;
     ExportPageNumber m_wkPageNumber;
@@ -315,7 +315,7 @@ private:
 
     QCheckBox *m_wkBackgroundCB;
 
-    QCheckBox *m_wkTableOfContentsCB;
+    QCheckBox *m_tableOfContentsCB;
 
     QComboBox *m_wkPageNumberCB;
 

+ 1 - 0
src/main.cpp

@@ -149,6 +149,7 @@ int main(int argc, char *argv[])
     for (int i = 1; i < argc; ++i) {
         if (!qstrcmp(argv[i], "-d")) {
             g_debugLog = true;
+            break;
         }
     }
 

+ 4 - 0
src/resources/markdown-it.js

@@ -100,6 +100,10 @@ var markdownToHtml = function(markdown, needToc) {
 };
 
 var updateText = function(text) {
+    if (VAddTOC) {
+        text = "[TOC]\n\n" + text;
+    }
+
     var needToc = mdHasTocSection(text);
     var html = markdownToHtml(text, needToc);
     placeholder.innerHTML = html;

+ 11 - 1
src/resources/markdown_template.js

@@ -48,6 +48,10 @@ if (typeof VRemoveMathjaxScript == 'undefined') {
     VRemoveMathjaxScript = false;
 }
 
+if (typeof VAddTOC == 'undefined') {
+    VAddTOC = false;
+}
+
 var getUrlScheme = function(url) {
     var idx = url.indexOf(':');
     if (idx > -1) {
@@ -805,11 +809,17 @@ var handleToc = function(needToc) {
     var tocTree = tocToTree(toPerfectToc(toc, baseLevel), baseLevel);
     content.setToc(tocTree, baseLevel);
 
+    var removeToc = toc.length == 0;
+
     // Add it to html
     if (needToc) {
         var eles = document.getElementsByClassName('vnote-toc');
         for (var i = 0; i < eles.length; ++i) {
-            eles[i].innerHTML = tocTree;
+            if (removeToc) {
+                eles[i].parentNode.removeChild(eles[i]);
+            } else {
+                eles[i].innerHTML = tocTree;
+            }
         }
     }
 };

+ 4 - 0
src/resources/marked.js

@@ -49,6 +49,10 @@ var mdHasTocSection = function(markdown) {
 };
 
 var updateText = function(text) {
+    if (VAddTOC) {
+        text = "[TOC]\n\n" + text;
+    }
+
     var needToc = mdHasTocSection(text);
     var html = markdownToHtml(text, needToc);
     placeholder.innerHTML = html;

+ 4 - 0
src/resources/showdown.js

@@ -73,6 +73,10 @@ var highlightCodeBlocks = function(doc, enableMermaid, enableFlowchart, enableMa
 };
 
 var updateText = function(text) {
+    if (VAddTOC) {
+        text = "[TOC]\n\n" + text;
+    }
+
     var needToc = mdHasTocSection(text);
     var html = markdownToHtml(text, needToc);
     placeholder.innerHTML = html;

+ 16 - 3
src/utils/vutils.cpp

@@ -602,7 +602,8 @@ QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType,
                                      const QString &p_renderStyle,
                                      const QString &p_renderCodeBlockStyle,
                                      bool p_isPDF,
-                                     bool p_wkhtmltopdf)
+                                     bool p_wkhtmltopdf,
+                                     bool p_addToc)
 {
     Q_ASSERT((p_isPDF && p_wkhtmltopdf) || !p_wkhtmltopdf);
 
@@ -611,12 +612,13 @@ QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType,
                                                 g_config->getCodeBlockCssStyleUrl(p_renderCodeBlockStyle),
                                                 p_isPDF);
 
-    return generateHtmlTemplate(templ, p_conType, p_wkhtmltopdf);
+    return generateHtmlTemplate(templ, p_conType, p_wkhtmltopdf, p_addToc);
 }
 
 QString VUtils::generateHtmlTemplate(const QString &p_template,
                                      MarkdownConverterType p_conType,
-                                     bool p_wkhtmltopdf)
+                                     bool p_wkhtmltopdf,
+                                     bool p_addToc)
 {
     QString jsFile, extraFile;
     switch (p_conType) {
@@ -715,6 +717,17 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
         extraFile += "<script>var VEnableFlashAnchor = true;</script>\n";
     }
 
+    if (p_addToc) {
+        extraFile += "<script>var VAddTOC = true;</script>\n";
+        extraFile += "<style type=\"text/css\">\n"
+                     "    @media print {\n"
+                     "        .vnote-toc {\n"
+                     "            page-break-after: always;\n"
+                     "         }\n"
+                     "    }\n"
+                     "</style>";
+    }
+
     extraFile += "<script>var VStylesToInline = '" + g_config->getStylesToInlineWhenCopied() + "';</script>\n";
 
     QString htmlTemplate(p_template);

+ 4 - 2
src/utils/vutils.h

@@ -177,7 +177,8 @@ public:
                                         const QString &p_renderStyle,
                                         const QString &p_renderCodeBlockStyle,
                                         bool p_isPDF,
-                                        bool p_wkhtmltopdf = false);
+                                        bool p_wkhtmltopdf = false,
+                                        bool p_addToc = false);
 
     // @p_renderBg is the background name.
     static QString generateExportHtmlTemplate(const QString &p_renderBg, bool p_includeMathJax);
@@ -359,7 +360,8 @@ private:
 
     static QString generateHtmlTemplate(const QString &p_template,
                                         MarkdownConverterType p_conType,
-                                        bool p_wkhtmltopdf = false);
+                                        bool p_wkhtmltopdf = false,
+                                        bool p_addToc = false);
 
     // <value, name>
     static QVector<QPair<QString, QString>> s_availableLanguages;

+ 17 - 2
src/vexporter.cpp

@@ -41,13 +41,17 @@ void VExporter::prepareExport(const ExportOption &p_opt)
 {
     bool isPdf = p_opt.m_format == ExportFormat::PDF
                  || p_opt.m_format == ExportFormat::OnePDF;
+    bool extraToc = isPdf
+                    && !p_opt.m_pdfOpt.m_wkhtmltopdf
+                    && p_opt.m_pdfOpt.m_enableTableOfContents;
 
     m_htmlTemplate = VUtils::generateHtmlTemplate(p_opt.m_renderer,
                                                   p_opt.m_renderBg,
                                                   p_opt.m_renderStyle,
                                                   p_opt.m_renderCodeBlockStyle,
                                                   isPdf,
-                                                  isPdf && p_opt.m_pdfOpt.m_wkhtmltopdf);
+                                                  isPdf && p_opt.m_pdfOpt.m_wkhtmltopdf,
+                                                  extraToc);
 
     m_exportHtmlTemplate = VUtils::generateExportHtmlTemplate(p_opt.m_renderBg,
                                                               isPdf && p_opt.m_pdfOpt.m_wkhtmltopdf);
@@ -153,7 +157,7 @@ void VExporter::prepareWKArguments(const ExportPDFOption &p_opt)
     }
 
     // TOC option.
-    if (p_opt.m_wkEnableTableOfContents) {
+    if (p_opt.m_enableTableOfContents) {
         m_wkArgs << "toc" << "--toc-text-size-shrink" << "1.0";
     }
 }
@@ -203,6 +207,17 @@ void VExporter::initWebViewer(VFile *p_file, const ExportOption &p_opt)
         QString html = mdConverter.generateHtml(p_file->getContent(),
                                                 g_config->getMarkdownExtensions(),
                                                 toc);
+        bool isPdf = p_opt.m_format == ExportFormat::PDF
+                     || p_opt.m_format == ExportFormat::OnePDF;
+        bool extraToc = isPdf
+                        && !p_opt.m_pdfOpt.m_wkhtmltopdf
+                        && p_opt.m_pdfOpt.m_enableTableOfContents;
+        if (extraToc && !toc.isEmpty()) {
+            // Add toc to html.
+            QString div = "<div class=\"vnote-toc\">" + toc + "</div>\n";
+            html = div + html;
+        }
+
         m_webDocument->setHtml(html);
     }