mirror of
https://gitee.com/vnotex/vnote.git
synced 2025-07-05 13:59:52 +08:00
export: support HTML format
This commit is contained in:
parent
60635fe5e7
commit
1fe7567d79
@ -289,7 +289,8 @@ void VExportDialog::startExport()
|
||||
m_consoleEdit->clear();
|
||||
appendLogLine(tr("Export to %1.").arg(outputFolder));
|
||||
|
||||
if (opt.m_format == ExportFormat::PDF) {
|
||||
if (opt.m_format == ExportFormat::PDF
|
||||
|| opt.m_format == ExportFormat::HTML) {
|
||||
m_exporter->prepareExport(opt);
|
||||
}
|
||||
|
||||
@ -406,6 +407,10 @@ int VExportDialog::doExport(VFile *p_file,
|
||||
ret = doExportPDF(p_file, p_opt, p_outputFolder, p_errMsg);
|
||||
break;
|
||||
|
||||
case (int)ExportFormat::HTML:
|
||||
ret = doExportHTML(p_file, p_opt, p_outputFolder, p_errMsg);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -628,6 +633,40 @@ int VExportDialog::doExportPDF(VFile *p_file,
|
||||
}
|
||||
}
|
||||
|
||||
int VExportDialog::doExportHTML(VFile *p_file,
|
||||
const ExportOption &p_opt,
|
||||
const QString &p_outputFolder,
|
||||
QString *p_errMsg)
|
||||
{
|
||||
Q_UNUSED(p_opt);
|
||||
|
||||
QString srcFilePath(p_file->fetchPath());
|
||||
|
||||
if (p_file->getDocType() != DocType::Markdown) {
|
||||
LOGERR(tr("Skip exporting non-Markdown file %1 as HTML.").arg(srcFilePath));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!VUtils::makePath(p_outputFolder)) {
|
||||
LOGERR(tr("Fail to create directory %1.").arg(p_outputFolder));
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get output file.
|
||||
QString suffix = ".html";
|
||||
QString name = VUtils::getFileNameWithSequence(p_outputFolder,
|
||||
QFileInfo(p_file->getName()).completeBaseName() + suffix);
|
||||
QString outputPath = QDir(p_outputFolder).filePath(name);
|
||||
|
||||
if (m_exporter->exportHTML(p_file, p_opt, outputPath, p_errMsg)) {
|
||||
appendLogLine(tr("Note %1 exported to %2.").arg(srcFilePath).arg(outputPath));
|
||||
return 1;
|
||||
} else {
|
||||
appendLogLine(tr("Fail to export note %1.").arg(srcFilePath));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool VExportDialog::checkUserAction()
|
||||
{
|
||||
if (m_askedToStop) {
|
||||
|
@ -133,6 +133,11 @@ private:
|
||||
const QString &p_outputFolder,
|
||||
QString *p_errMsg = NULL);
|
||||
|
||||
int doExportHTML(VFile *p_file,
|
||||
const ExportOption &p_opt,
|
||||
const QString &p_outputFolder,
|
||||
QString *p_errMsg = NULL);
|
||||
|
||||
// Return false if we could not continue.
|
||||
bool checkUserAction();
|
||||
|
||||
|
14
src/resources/export_template.html
Normal file
14
src/resources/export_template.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<meta charset="utf-8">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
/* BACKGROUND_PLACE_HOLDER */
|
||||
</style>
|
||||
|
||||
<!-- HEAD_PLACE_HOLDER -->
|
||||
</head>
|
||||
<body>
|
||||
<!-- BODY_PLACE_HOLDER -->
|
||||
</body>
|
||||
</html>
|
@ -127,7 +127,7 @@ var updateText = function(text) {
|
||||
var highlightText = function(text, id, timeStamp) {
|
||||
var html = mdit.render(text);
|
||||
content.highlightTextCB(html, id, timeStamp);
|
||||
}
|
||||
};
|
||||
|
||||
var textToHtml = function(text) {
|
||||
var html = mdit.render(text);
|
||||
@ -139,4 +139,4 @@ var textToHtml = function(text) {
|
||||
container.innerHTML = "";
|
||||
|
||||
content.textToHtmlCB(text, html);
|
||||
}
|
||||
};
|
||||
|
@ -3,7 +3,7 @@
|
||||
<meta charset="utf-8">
|
||||
<head>
|
||||
<style type="text/css">
|
||||
<!-- BACKGROUND_PLACE_HOLDER -->
|
||||
/* BACKGROUND_PLACE_HOLDER */
|
||||
</style>
|
||||
|
||||
<style type="text/css">
|
||||
|
@ -40,6 +40,26 @@ if (typeof VEnableImageCaption == 'undefined') {
|
||||
VEnableImageCaption = false;
|
||||
}
|
||||
|
||||
var headContent = function() {
|
||||
var styles = "<style type=\"text/css\">\n";
|
||||
|
||||
for (var i = 0; i < document.styleSheets.length; ++i) {
|
||||
var styleSheet = document.styleSheets[i];
|
||||
if (styleSheet.cssRules) {
|
||||
for (var j = 0; j < styleSheet.cssRules.length; ++j) {
|
||||
styles = styles + styleSheet.cssRules[j].cssText + "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var styles = styles + "</style>";
|
||||
return styles;
|
||||
};
|
||||
|
||||
var htmlContent = function() {
|
||||
content.htmlContentCB(headContent(), placeholder.innerHTML);
|
||||
};
|
||||
|
||||
new QWebChannel(qt.webChannelTransport,
|
||||
function(channel) {
|
||||
content = channel.objects.content;
|
||||
@ -62,6 +82,10 @@ new QWebChannel(qt.webChannelTransport,
|
||||
content.requestTextToHtml.connect(textToHtml);
|
||||
content.noticeReadyToTextToHtml();
|
||||
}
|
||||
|
||||
if (typeof htmlContent == "function") {
|
||||
content.requestHtmlContent.connect(htmlContent);
|
||||
}
|
||||
});
|
||||
|
||||
var VHighlightedAnchorClass = 'highlighted-anchor';
|
||||
@ -447,7 +471,7 @@ var renderMermaidOne = function(code) {
|
||||
mermaidIdx++;
|
||||
try {
|
||||
// Do not increment mermaidIdx here.
|
||||
var graph = mermaidAPI.render('mermaid-diagram-' + mermaidIdx, code.innerText, function(){});
|
||||
var graph = mermaidAPI.render('mermaid-diagram-' + mermaidIdx, code.textContent, function(){});
|
||||
} catch (err) {
|
||||
content.setLog("err: " + err);
|
||||
return false;
|
||||
@ -493,7 +517,7 @@ var renderFlowchartOne = function(code) {
|
||||
// Flowchart code block.
|
||||
flowchartIdx++;
|
||||
try {
|
||||
var graph = flowchart.parse(code.innerText);
|
||||
var graph = flowchart.parse(code.textContent);
|
||||
} catch (err) {
|
||||
content.setLog("err: " + err);
|
||||
return false;
|
||||
@ -525,7 +549,7 @@ var renderFlowchartOne = function(code) {
|
||||
|
||||
var isImageBlock = function(img) {
|
||||
var pn = img.parentNode;
|
||||
return (pn.children.length == 1) && (pn.innerText == '');
|
||||
return (pn.children.length == 1) && (pn.textContent == '');
|
||||
};
|
||||
|
||||
var isImageWithBr = function(img) {
|
||||
@ -617,7 +641,7 @@ var insertImageCaption = function() {
|
||||
// Add caption.
|
||||
var captionDiv = document.createElement('div');
|
||||
captionDiv.classList.add(VImageCaptionClass);
|
||||
captionDiv.innerText = img.alt;
|
||||
captionDiv.textContent = img.alt;
|
||||
img.insertAdjacentElement('afterend', captionDiv);
|
||||
}
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ enable_wildcard_in_simple_search=true
|
||||
|
||||
[web]
|
||||
; Location and configuration for Mathjax
|
||||
mathjax_javascript=https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_CHTML
|
||||
mathjax_javascript=https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/MathJax.js?config=TeX-MML-AM_HTMLorMML
|
||||
|
||||
; Styles to be removed when copied
|
||||
; style1,style2,style3
|
||||
|
@ -690,6 +690,11 @@ QString VUtils::generateHtmlTemplate(const QString &p_template,
|
||||
return htmlTemplate;
|
||||
}
|
||||
|
||||
QString VUtils::generateExportHtmlTemplate(const QString &p_renderBg)
|
||||
{
|
||||
return VNote::generateExportHtmlTemplate(g_config->getRenderBackgroundColor(p_renderBg));
|
||||
}
|
||||
|
||||
QString VUtils::getFileNameWithSequence(const QString &p_directory,
|
||||
const QString &p_baseFileName,
|
||||
bool p_completeBaseName)
|
||||
|
@ -174,6 +174,9 @@ public:
|
||||
const QString &p_renderCodeBlockStyle,
|
||||
bool p_isPDF);
|
||||
|
||||
// @p_renderBg is the background name.
|
||||
static QString generateExportHtmlTemplate(const QString &p_renderBg);
|
||||
|
||||
static QString generateSimpleHtmlTemplate(const QString &p_body);
|
||||
|
||||
// Get an available file name in @p_directory with base @p_baseFileName.
|
||||
|
@ -37,6 +37,7 @@ namespace HtmlHolder
|
||||
static const QString c_JSHolder = "JS_PLACE_HOLDER";
|
||||
static const QString c_extraHolder = "<!-- EXTRA_PLACE_HOLDER -->";
|
||||
static const QString c_bodyHolder = "<!-- BODY_PLACE_HOLDER -->";
|
||||
static const QString c_headHolder = "<!-- HEAD_PLACE_HOLDER -->";
|
||||
}
|
||||
|
||||
// Directory Config file items.
|
||||
|
@ -82,6 +82,11 @@ void VDocument::textToHtmlAsync(const QString &p_text)
|
||||
emit requestTextToHtml(p_text);
|
||||
}
|
||||
|
||||
void VDocument::getHtmlContentAsync()
|
||||
{
|
||||
emit requestHtmlContent();
|
||||
}
|
||||
|
||||
void VDocument::textToHtmlCB(const QString &p_text, const QString &p_html)
|
||||
{
|
||||
emit textToHtmlFinished(p_text, p_html);
|
||||
@ -108,3 +113,8 @@ void VDocument::finishLogics()
|
||||
qDebug() << "Web side finished logics";
|
||||
emit logicsFinished();
|
||||
}
|
||||
|
||||
void VDocument::htmlContentCB(const QString &p_head, const QString &p_body)
|
||||
{
|
||||
emit htmlContentFinished(p_head, p_body);
|
||||
}
|
||||
|
@ -38,6 +38,9 @@ public:
|
||||
|
||||
bool isReadyToTextToHtml() const;
|
||||
|
||||
// Request to get the HTML content.
|
||||
void getHtmlContentAsync();
|
||||
|
||||
public slots:
|
||||
// Will be called in the HTML side
|
||||
|
||||
@ -67,6 +70,8 @@ public slots:
|
||||
// But the page may not finish loading, such as images.
|
||||
void finishLogics();
|
||||
|
||||
void htmlContentCB(const QString &p_head, const QString &p_body);
|
||||
|
||||
signals:
|
||||
void textChanged(const QString &text);
|
||||
|
||||
@ -95,6 +100,11 @@ signals:
|
||||
|
||||
void textToHtmlFinished(const QString &p_text, const QString &p_html);
|
||||
|
||||
void requestHtmlContent();
|
||||
|
||||
void htmlContentFinished(const QString &p_headContent,
|
||||
const QString &p_bodyContent);
|
||||
|
||||
private:
|
||||
QString m_toc;
|
||||
QString m_header;
|
||||
|
@ -29,6 +29,9 @@ void VExporter::prepareExport(const ExportOption &p_opt)
|
||||
p_opt.m_renderStyle,
|
||||
p_opt.m_renderCodeBlockStyle,
|
||||
p_opt.m_format == ExportFormat::PDF);
|
||||
|
||||
m_exportHtmlTemplate = VUtils::generateExportHtmlTemplate(p_opt.m_renderBg);
|
||||
|
||||
m_pageLayout = *(p_opt.m_layout);
|
||||
}
|
||||
|
||||
@ -36,6 +39,117 @@ bool VExporter::exportPDF(VFile *p_file,
|
||||
const ExportOption &p_opt,
|
||||
const QString &p_outputFile,
|
||||
QString *p_errMsg)
|
||||
{
|
||||
return exportViaWebView(p_file, p_opt, p_outputFile, p_errMsg);
|
||||
}
|
||||
|
||||
bool VExporter::exportHTML(VFile *p_file,
|
||||
const ExportOption &p_opt,
|
||||
const QString &p_outputFile,
|
||||
QString *p_errMsg)
|
||||
{
|
||||
return exportViaWebView(p_file, p_opt, p_outputFile, p_errMsg);
|
||||
}
|
||||
|
||||
void VExporter::initWebViewer(VFile *p_file, const ExportOption &p_opt)
|
||||
{
|
||||
Q_ASSERT(!m_webViewer);
|
||||
|
||||
m_webViewer = new VWebView(p_file, static_cast<QWidget *>(parent()));
|
||||
m_webViewer->hide();
|
||||
|
||||
VPreviewPage *page = new VPreviewPage(m_webViewer);
|
||||
m_webViewer->setPage(page);
|
||||
|
||||
connect(page, &VPreviewPage::loadFinished,
|
||||
this, &VExporter::handleLoadFinished);
|
||||
|
||||
m_webDocument = new VDocument(p_file, m_webViewer);
|
||||
connect(m_webDocument, &VDocument::logicsFinished,
|
||||
this, &VExporter::handleLogicsFinished);
|
||||
|
||||
QWebChannel *channel = new QWebChannel(m_webViewer);
|
||||
channel->registerObject(QStringLiteral("content"), m_webDocument);
|
||||
page->setWebChannel(channel);
|
||||
|
||||
// Need to generate HTML using Hoedown.
|
||||
if (p_opt.m_renderer == MarkdownConverterType::Hoedown) {
|
||||
VMarkdownConverter mdConverter;
|
||||
QString toc;
|
||||
QString html = mdConverter.generateHtml(p_file->getContent(),
|
||||
g_config->getMarkdownExtensions(),
|
||||
toc);
|
||||
m_webDocument->setHtml(html);
|
||||
}
|
||||
|
||||
m_webViewer->setHtml(m_htmlTemplate, p_file->getBaseUrl());
|
||||
}
|
||||
|
||||
void VExporter::handleLogicsFinished()
|
||||
{
|
||||
Q_ASSERT(!(m_noteState & NoteState::WebLogicsReady));
|
||||
m_noteState = NoteState(m_noteState | NoteState::WebLogicsReady);
|
||||
}
|
||||
|
||||
void VExporter::handleLoadFinished(bool p_ok)
|
||||
{
|
||||
Q_ASSERT(!(m_noteState & NoteState::WebLoadFinished));
|
||||
m_noteState = NoteState(m_noteState | NoteState::WebLoadFinished);
|
||||
|
||||
if (!p_ok) {
|
||||
m_noteState = NoteState(m_noteState | NoteState::Failed);
|
||||
}
|
||||
}
|
||||
|
||||
void VExporter::clearWebViewer()
|
||||
{
|
||||
// m_webDocument will be freeed by QObject.
|
||||
delete m_webViewer;
|
||||
m_webViewer = NULL;
|
||||
m_webDocument = NULL;
|
||||
}
|
||||
|
||||
bool VExporter::exportToPDF(VWebView *p_webViewer,
|
||||
const QString &p_filePath,
|
||||
const QPageLayout &p_layout)
|
||||
{
|
||||
int pdfPrinted = 0;
|
||||
p_webViewer->page()->printToPdf([&, this](const QByteArray &p_result) {
|
||||
if (p_result.isEmpty() || this->m_state == ExportState::Cancelled) {
|
||||
pdfPrinted = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
V_ASSERT(!p_filePath.isEmpty());
|
||||
|
||||
QFile file(p_filePath);
|
||||
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
pdfPrinted = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
file.write(p_result.data(), p_result.size());
|
||||
file.close();
|
||||
|
||||
pdfPrinted = 1;
|
||||
}, p_layout);
|
||||
|
||||
while (pdfPrinted == 0) {
|
||||
VUtils::sleepWait(100);
|
||||
|
||||
if (m_state == ExportState::Cancelled) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return pdfPrinted == 1;
|
||||
}
|
||||
|
||||
bool VExporter::exportViaWebView(VFile *p_file,
|
||||
const ExportOption &p_opt,
|
||||
const QString &p_outputFile,
|
||||
QString *p_errMsg)
|
||||
{
|
||||
Q_UNUSED(p_errMsg);
|
||||
|
||||
@ -74,9 +188,24 @@ bool VExporter::exportPDF(VFile *p_file,
|
||||
}
|
||||
|
||||
{
|
||||
bool exportRet = exportToPDF(m_webViewer,
|
||||
|
||||
bool exportRet = false;
|
||||
switch (p_opt.m_format) {
|
||||
case ExportFormat::PDF:
|
||||
exportRet = exportToPDF(m_webViewer,
|
||||
p_outputFile,
|
||||
m_pageLayout);
|
||||
break;
|
||||
|
||||
case ExportFormat::HTML:
|
||||
exportRet = exportToHTML(m_webViewer,
|
||||
m_webDocument,
|
||||
p_outputFile);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
clearNoteState();
|
||||
|
||||
@ -89,6 +218,7 @@ bool VExporter::exportPDF(VFile *p_file,
|
||||
} else {
|
||||
m_state = ExportState::Failed;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exit:
|
||||
@ -103,91 +233,42 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void VExporter::initWebViewer(VFile *p_file, const ExportOption &p_opt)
|
||||
bool VExporter::exportToHTML(VWebView *p_webViewer,
|
||||
VDocument *p_webDocument,
|
||||
const QString &p_filePath)
|
||||
{
|
||||
Q_ASSERT(!m_webViewer);
|
||||
Q_UNUSED(p_webViewer);
|
||||
int htmlExported = 0;
|
||||
|
||||
m_webViewer = new VWebView(p_file, static_cast<QWidget *>(parent()));
|
||||
m_webViewer->hide();
|
||||
|
||||
VPreviewPage *page = new VPreviewPage(m_webViewer);
|
||||
m_webViewer->setPage(page);
|
||||
|
||||
connect(page, &VPreviewPage::loadFinished,
|
||||
this, &VExporter::handleLoadFinished);
|
||||
|
||||
VDocument *document = new VDocument(p_file, m_webViewer);
|
||||
connect(document, &VDocument::logicsFinished,
|
||||
this, &VExporter::handleLogicsFinished);
|
||||
|
||||
QWebChannel *channel = new QWebChannel(m_webViewer);
|
||||
channel->registerObject(QStringLiteral("content"), document);
|
||||
page->setWebChannel(channel);
|
||||
|
||||
// Need to generate HTML using Hoedown.
|
||||
if (p_opt.m_renderer == MarkdownConverterType::Hoedown) {
|
||||
VMarkdownConverter mdConverter;
|
||||
QString toc;
|
||||
QString html = mdConverter.generateHtml(p_file->getContent(),
|
||||
g_config->getMarkdownExtensions(),
|
||||
toc);
|
||||
document->setHtml(html);
|
||||
}
|
||||
|
||||
m_webViewer->setHtml(m_htmlTemplate, p_file->getBaseUrl());
|
||||
}
|
||||
|
||||
void VExporter::handleLogicsFinished()
|
||||
{
|
||||
Q_ASSERT(!(m_noteState & NoteState::WebLogicsReady));
|
||||
m_noteState = NoteState(m_noteState | NoteState::WebLogicsReady);
|
||||
}
|
||||
|
||||
void VExporter::handleLoadFinished(bool p_ok)
|
||||
{
|
||||
Q_ASSERT(!(m_noteState & NoteState::WebLoadFinished));
|
||||
m_noteState = NoteState(m_noteState | NoteState::WebLoadFinished);
|
||||
|
||||
if (!p_ok) {
|
||||
m_noteState = NoteState(m_noteState | NoteState::Failed);
|
||||
}
|
||||
}
|
||||
|
||||
void VExporter::clearWebViewer()
|
||||
{
|
||||
if (m_webViewer) {
|
||||
delete m_webViewer;
|
||||
m_webViewer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool VExporter::exportToPDF(VWebView *p_webViewer,
|
||||
const QString &p_filePath,
|
||||
const QPageLayout &p_layout)
|
||||
{
|
||||
int pdfPrinted = 0;
|
||||
p_webViewer->page()->printToPdf([&, this](const QByteArray &p_result) {
|
||||
if (p_result.isEmpty() || this->m_state == ExportState::Cancelled) {
|
||||
pdfPrinted = -1;
|
||||
connect(p_webDocument, &VDocument::htmlContentFinished,
|
||||
this, [&, this](const QString &p_headContent, const QString &p_bodyContent) {
|
||||
if (p_bodyContent.isEmpty() || this->m_state == ExportState::Cancelled) {
|
||||
htmlExported = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
V_ASSERT(!p_filePath.isEmpty());
|
||||
Q_ASSERT(!p_filePath.isEmpty());
|
||||
|
||||
QFile file(p_filePath);
|
||||
|
||||
if (!file.open(QFile::WriteOnly)) {
|
||||
pdfPrinted = -1;
|
||||
htmlExported = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
file.write(p_result.data(), p_result.size());
|
||||
QString html(m_exportHtmlTemplate);
|
||||
html.replace(HtmlHolder::c_headHolder, p_headContent);
|
||||
html.replace(HtmlHolder::c_bodyHolder, p_bodyContent);
|
||||
|
||||
file.write(html.toUtf8());
|
||||
file.close();
|
||||
|
||||
pdfPrinted = 1;
|
||||
}, p_layout);
|
||||
htmlExported = 1;
|
||||
});
|
||||
|
||||
while (pdfPrinted == 0) {
|
||||
p_webDocument->getHtmlContentAsync();
|
||||
|
||||
while (htmlExported == 0) {
|
||||
VUtils::sleepWait(100);
|
||||
|
||||
if (m_state == ExportState::Cancelled) {
|
||||
@ -195,6 +276,5 @@ bool VExporter::exportToPDF(VWebView *p_webViewer,
|
||||
}
|
||||
}
|
||||
|
||||
return pdfPrinted == 1;
|
||||
return htmlExported == 1;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
class QWidget;
|
||||
class VWebView;
|
||||
class VDocument;
|
||||
|
||||
class VExporter : public QObject
|
||||
{
|
||||
@ -21,6 +22,11 @@ public:
|
||||
const QString &p_outputFile,
|
||||
QString *p_errMsg = NULL);
|
||||
|
||||
bool exportHTML(VFile *p_file,
|
||||
const ExportOption &p_opt,
|
||||
const QString &p_outputFile,
|
||||
QString *p_errMsg = NULL);
|
||||
|
||||
private slots:
|
||||
void handleLogicsFinished();
|
||||
|
||||
@ -57,17 +63,31 @@ private:
|
||||
|
||||
bool isNoteStateFailed() const;
|
||||
|
||||
bool exportViaWebView(VFile *p_file,
|
||||
const ExportOption &p_opt,
|
||||
const QString &p_outputFile,
|
||||
QString *p_errMsg = NULL);
|
||||
|
||||
bool exportToPDF(VWebView *p_webViewer,
|
||||
const QString &p_filePath,
|
||||
const QPageLayout &p_layout);
|
||||
|
||||
bool exportToHTML(VWebView *p_webViewer,
|
||||
VDocument *p_webDocument,
|
||||
const QString &p_filePath);
|
||||
|
||||
QPageLayout m_pageLayout;
|
||||
|
||||
// Will be allocated and free for each conversion.
|
||||
VWebView *m_webViewer;
|
||||
|
||||
VDocument *m_webDocument;
|
||||
|
||||
QString m_htmlTemplate;
|
||||
|
||||
// Template to hold the export HTML result.
|
||||
QString m_exportHtmlTemplate;
|
||||
|
||||
NoteState m_noteState;
|
||||
|
||||
ExportState m_state;
|
||||
|
@ -110,7 +110,7 @@ QString VNote::generateHtmlTemplate(const QString &p_renderBg,
|
||||
cssStyle += "img { max-width: 100% !important; height: auto !important; }\n";
|
||||
}
|
||||
|
||||
const QString styleHolder("<!-- BACKGROUND_PLACE_HOLDER -->");
|
||||
const QString styleHolder("/* BACKGROUND_PLACE_HOLDER */");
|
||||
const QString cssHolder("CSS_PLACE_HOLDER");
|
||||
const QString codeBlockCssHolder("HIGHLIGHTJS_CSS_PLACE_HOLDER");
|
||||
|
||||
@ -142,6 +142,32 @@ QString VNote::generateHtmlTemplate(const QString &p_renderBg,
|
||||
return templ;
|
||||
}
|
||||
|
||||
QString VNote::generateExportHtmlTemplate(const QString &p_renderBg)
|
||||
{
|
||||
const QString c_exportTemplatePath(":/resources/export_template.html");
|
||||
|
||||
QString cssStyle;
|
||||
if (!p_renderBg.isEmpty()) {
|
||||
cssStyle += "body { background-color: " + p_renderBg + " !important; }\n";
|
||||
}
|
||||
|
||||
if (g_config->getEnableImageConstraint()) {
|
||||
// Constain the image width.
|
||||
cssStyle += "img { max-width: 100% !important; height: auto !important; }\n";
|
||||
}
|
||||
|
||||
const QString styleHolder("/* BACKGROUND_PLACE_HOLDER */");
|
||||
|
||||
QString templ = VUtils::readFileFromDisk(c_exportTemplatePath);
|
||||
g_palette->fillStyle(templ);
|
||||
|
||||
if (!cssStyle.isEmpty()) {
|
||||
templ.replace(styleHolder, cssStyle);
|
||||
}
|
||||
|
||||
return templ;
|
||||
}
|
||||
|
||||
void VNote::updateTemplate()
|
||||
{
|
||||
QString renderBg = g_config->getRenderBackgroundColor(g_config->getCurRenderBackgroundColor());
|
||||
|
@ -105,6 +105,9 @@ public:
|
||||
const QString &p_codeBlockStyleUrl,
|
||||
bool p_isPDF);
|
||||
|
||||
// @p_renderBg: background color, empty to not specify given color.
|
||||
static QString generateExportHtmlTemplate(const QString &p_renderBg);
|
||||
|
||||
public slots:
|
||||
void updateTemplate();
|
||||
|
||||
|
@ -239,5 +239,6 @@
|
||||
<file>resources/icons/delete_cart_item.svg</file>
|
||||
<file>resources/icons/fullscreen.svg</file>
|
||||
<file>resources/icons/menubar.svg</file>
|
||||
<file>resources/export_template.html</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
x
Reference in New Issue
Block a user