export: support custom background, style

This commit is contained in:
Le Tan 2018-02-23 19:54:07 +08:00
parent ad81e655a5
commit 60635fe5e7
18 changed files with 248 additions and 57 deletions

View File

@ -25,6 +25,8 @@ extern VNote *g_vnote;
QString VExportDialog::s_lastOutputFolder;
ExportFormat VExportDialog::s_lastExportFormat = ExportFormat::Markdown;
#define LOGERR(x) do { QString msg = (x); \
VUtils::addErrMsg(p_errMsg, msg); \
appendLogLine(msg); \
@ -79,6 +81,18 @@ void VExportDialog::setupUI()
m_rendererCB->setToolTip(tr("Choose converter to render Markdown"));
m_rendererCB->setSizeAdjustPolicy(QComboBox::AdjustToContents);
// Markdown rendering background.
m_renderBgCB = VUtils::getComboBox();
m_renderBgCB->setToolTip(tr("Choose rendering background color for Markdown"));
// Markdown rendering style.
m_renderStyleCB = VUtils::getComboBox();
m_renderStyleCB->setToolTip(tr("Choose rendering style for Markdown"));
// Markdown rendering code block style.
m_renderCodeBlockStyleCB = VUtils::getComboBox();
m_renderCodeBlockStyleCB->setToolTip(tr("Choose rendering code block style for Markdown"));
// Output directory.
m_outputEdit = new VLineEdit(s_lastOutputFolder);
connect(m_outputEdit, &QLineEdit::textChanged,
@ -128,6 +142,9 @@ void VExportDialog::setupUI()
basicLayout->addRow(tr("Notes to export:"), m_srcCB);
basicLayout->addRow(tr("Target format:"), m_formatCB);
basicLayout->addRow(tr("Markdown renderer:"), m_rendererCB);
basicLayout->addRow(tr("Markdown rendering background:"), m_renderBgCB);
basicLayout->addRow(tr("Markdown rendering style:"), m_renderStyleCB);
basicLayout->addRow(tr("Markdown rendering code block style:"), m_renderCodeBlockStyleCB);
basicLayout->addRow(tr("Output directory:"), outputLayout);
m_basicBox->setLayout(basicLayout);
@ -209,6 +226,7 @@ void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
m_formatCB->addItem(tr("Markdown"), (int)ExportFormat::Markdown);
m_formatCB->addItem(tr("HTML"), (int)ExportFormat::HTML);
m_formatCB->addItem(tr("PDF"), (int)ExportFormat::PDF);
m_formatCB->setCurrentIndex(m_formatCB->findData((int)s_lastExportFormat));
// Markdown renderer.
m_rendererCB->addItem(tr("Hoedown"), MarkdownConverterType::Hoedown);
@ -216,6 +234,34 @@ void VExportDialog::initUIFields(MarkdownConverterType p_renderer)
m_rendererCB->addItem(tr("Markdown-it"), MarkdownConverterType::MarkdownIt);
m_rendererCB->addItem(tr("Showdown"), MarkdownConverterType::Showdown);
m_rendererCB->setCurrentIndex(m_rendererCB->findData(p_renderer));
// Markdown rendering background.
m_renderBgCB->addItem(tr("System"), "System");
const QVector<VColor> &bgColors = g_config->getCustomColors();
for (int i = 0; i < bgColors.size(); ++i) {
m_renderBgCB->addItem(bgColors[i].m_name, bgColors[i].m_name);
}
m_renderBgCB->setCurrentIndex(
m_renderBgCB->findData(g_config->getCurRenderBackgroundColor()));
// Markdown rendering style.
QList<QString> styles = g_config->getCssStyles();
for (auto const &style : styles) {
m_renderStyleCB->addItem(style, style);
}
m_renderStyleCB->setCurrentIndex(
m_renderStyleCB->findData(g_config->getCssStyle()));
// Markdown rendering code block style.
QList<QString> cbStyles = g_config->getCodeBlockCssStyles();
for (auto const &style : cbStyles) {
m_renderCodeBlockStyleCB->addItem(style, style);
}
m_renderCodeBlockStyleCB->setCurrentIndex(
m_renderCodeBlockStyleCB->findData(g_config->getCodeBlockCssStyle()));
}
void VExportDialog::startExport()
@ -233,8 +279,13 @@ void VExportDialog::startExport()
ExportOption opt((ExportSource)m_srcCB->currentData().toInt(),
(ExportFormat)m_formatCB->currentData().toInt(),
(MarkdownConverterType)m_rendererCB->currentData().toInt(),
m_renderBgCB->currentData().toString(),
m_renderStyleCB->currentData().toString(),
m_renderCodeBlockStyleCB->currentData().toString(),
&m_pageLayout);
s_lastExportFormat = opt.m_format;
m_consoleEdit->clear();
appendLogLine(tr("Export to %1.").arg(outputFolder));

View File

@ -42,10 +42,16 @@ struct ExportOption
ExportOption(ExportSource p_source,
ExportFormat p_format,
MarkdownConverterType p_renderer,
const QString &p_renderBg,
const QString &p_renderStyle,
const QString &p_renderCodeBlockStyle,
QPageLayout *p_layout)
: m_source(p_source),
m_format(p_format),
m_renderer(p_renderer),
m_renderBg(p_renderBg),
m_renderStyle(p_renderStyle),
m_renderCodeBlockStyle(p_renderCodeBlockStyle),
m_layout(p_layout)
{
}
@ -53,6 +59,12 @@ struct ExportOption
ExportSource m_source;
ExportFormat m_format;
MarkdownConverterType m_renderer;
// Background name.
QString m_renderBg;
QString m_renderStyle;
QString m_renderCodeBlockStyle;
QPageLayout *m_layout;
};
@ -132,6 +144,12 @@ private:
QComboBox *m_rendererCB;
QComboBox *m_renderBgCB;
QComboBox *m_renderStyleCB;
QComboBox *m_renderCodeBlockStyleCB;
VLineEdit *m_outputEdit;
QPushButton *m_browseBtn;
@ -175,6 +193,9 @@ private:
// Last output folder path.
static QString s_lastOutputFolder;
// Last export format.
static ExportFormat s_lastExportFormat;
};
#endif // VEXPORTDIALOG_H

View File

@ -150,7 +150,7 @@ ToolsDock=T
; Close current note
CloseNote=X
; Show shortcuts help document
ShortcutsHelp=?
ShortcutsHelp=Shift+?
; Flush the log file
FlushLogFile=";"
; Show opened files list
@ -234,7 +234,9 @@ Move current tab one split window right.
Evaluate current cursor word or selected text as magic words.
- `S`
Apply a snippet in edit mode.
- `?`
- `O`
Export notes.
- `Shift+?`
Display shortcuts documentation.
## Navigation Mode

View File

@ -151,7 +151,7 @@ ToolsDock=T
; Close current note
CloseNote=X
; Show shortcuts help document
ShortcutsHelp=?
ShortcutsHelp=Shift+?
; Flush the log file
FlushLogFile=";"
; Show opened files list
@ -235,7 +235,9 @@ RemoveSplit=R
编辑模式中,将当前光标所在词或者所选文本进行幻词解析。
- `S`
在编辑模式中应用片段。
- `?`
- `O`
导出笔记。
- `Shift+?`
显示本快捷键说明。
## 展览模式

View File

@ -88,6 +88,7 @@ code {
font-family: Consolas, Monaco, Monospace, Courier;
font-size: 16px;
color: #98C379;
word-break: break-all;
}
pre code {

View File

@ -88,6 +88,7 @@ code {
font-family: Consolas, Monaco, Monospace, Courier;
font-size: 16px;
color: #8E24AA;
word-break: break-all;
}
pre code {

View File

@ -87,6 +87,7 @@ code {
font-family: Consolas, Monaco, Monospace, Courier;
font-size: 16px;
color: #8E24AA;
word-break: break-all;
}
pre code {

View File

@ -297,7 +297,7 @@ ToolsDock=T
; Close current note
CloseNote=X
; Show shortcuts help document
ShortcutsHelp=?
ShortcutsHelp=Shift+?
; Flush the log file
FlushLogFile=";"
; Show opened files list
@ -334,6 +334,8 @@ RemoveSplit=R
MagicWord=M
; Prompt for user to apply a snippet
ApplySnippet=S
; Open export dialog
Export=O
[external_editors]
; Define external editors which could be called to edit notes

View File

@ -572,11 +572,31 @@ DocType VUtils::docTypeFromName(const QString &p_name)
QString VUtils::generateSimpleHtmlTemplate(const QString &p_body)
{
QString html = VNote::s_simpleHtmlTemplate;
QString html(VNote::s_simpleHtmlTemplate);
return html.replace(HtmlHolder::c_bodyHolder, p_body);
}
QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exportPdf)
QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType)
{
return generateHtmlTemplate(VNote::s_markdownTemplate, p_conType);
}
QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType,
const QString &p_renderBg,
const QString &p_renderStyle,
const QString &p_renderCodeBlockStyle,
bool p_isPDF)
{
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);
}
QString VUtils::generateHtmlTemplate(const QString &p_template,
MarkdownConverterType p_conType)
{
QString jsFile, extraFile;
switch (p_conType) {
@ -661,13 +681,7 @@ QString VUtils::generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exp
extraFile += "<script>var VStylesToInline = '" + g_config->getStylesToInlineWhenCopied() + "';</script>\n";
QString htmlTemplate;
if (p_exportPdf) {
htmlTemplate = VNote::s_markdownTemplatePDF;
} else {
htmlTemplate = VNote::s_markdownTemplate;
}
QString htmlTemplate(p_template);
htmlTemplate.replace(HtmlHolder::c_JSHolder, jsFile);
if (!extraFile.isEmpty()) {
htmlTemplate.replace(HtmlHolder::c_extraHolder, extraFile);

View File

@ -165,7 +165,14 @@ public:
static DocType docTypeFromName(const QString &p_name);
// Generate HTML template.
static QString generateHtmlTemplate(MarkdownConverterType p_conType, bool p_exportPdf);
static QString generateHtmlTemplate(MarkdownConverterType p_conType);
// @p_renderBg is the background name.
static QString generateHtmlTemplate(MarkdownConverterType p_conType,
const QString &p_renderBg,
const QString &p_renderStyle,
const QString &p_renderCodeBlockStyle,
bool p_isPDF);
static QString generateSimpleHtmlTemplate(const QString &p_body);
@ -338,6 +345,9 @@ private:
static bool deleteFile(const QString &p_recycleBinFolderPath,
const QString &p_path);
static QString generateHtmlTemplate(const QString &p_template,
MarkdownConverterType p_conType);
// <value, name>
static QVector<QPair<QString, QString>> s_availableLanguages;
};

View File

@ -859,8 +859,22 @@ QString VConfigManager::getCssStyleUrl() const
const_cast<VConfigManager *>(this)->m_cssStyle = VPalette::themeCssStyle(getThemeFile());
}
QString cssPath = getCssStyleUrl(m_cssStyle);
qDebug() << "use css style file" << cssPath;
return cssPath;
}
QString VConfigManager::getCssStyleUrl(const QString &p_style) const
{
Q_ASSERT(!m_themes.isEmpty());
Q_ASSERT(!m_cssStyles.isEmpty());
if (p_style.isEmpty()) {
return QString();
}
QString cssPath;
auto it = m_cssStyles.find(m_cssStyle);
auto it = m_cssStyles.find(p_style);
if (it != m_cssStyles.end()) {
cssPath = it.value();
}
@ -872,7 +886,6 @@ QString VConfigManager::getCssStyleUrl() const
cssPath = cssUrl.toString();
}
qDebug() << "use css style file" << cssPath;
return cssPath;
}
@ -887,8 +900,22 @@ QString VConfigManager::getCodeBlockCssStyleUrl() const
VPalette::themeCodeBlockCssStyle(getThemeFile());
}
QString cssPath = getCodeBlockCssStyleUrl(m_codeBlockCssStyle);
qDebug() << "use code block css style file" << cssPath;
return cssPath;
}
QString VConfigManager::getCodeBlockCssStyleUrl(const QString &p_style) const
{
Q_ASSERT(!m_themes.isEmpty());
Q_ASSERT(!m_codeBlockCssStyles.isEmpty());
if (p_style.isEmpty()) {
return QString();
}
QString cssPath;
auto it = m_codeBlockCssStyles.find(m_codeBlockCssStyle);
auto it = m_codeBlockCssStyles.find(p_style);
if (it != m_codeBlockCssStyles.end()) {
cssPath = it.value();
}
@ -900,7 +927,6 @@ QString VConfigManager::getCodeBlockCssStyleUrl() const
cssPath = cssUrl.toString();
}
qDebug() << "use code block css style file" << cssPath;
return cssPath;
}
@ -1435,3 +1461,17 @@ void VConfigManager::clearGroupOfSettings(QSettings *p_settings, const QString &
p_settings->remove("");
p_settings->endGroup();
}
QString VConfigManager::getRenderBackgroundColor(const QString &p_bgName) const
{
if (p_bgName != "System") {
for (int i = 0; i < m_customColors.size(); ++i) {
if (m_customColors[i].m_name == p_bgName) {
return m_customColors[i].m_color;
}
}
}
return QString();
}

View File

@ -117,8 +117,12 @@ public:
// Get the css style URL for web view.
QString getCssStyleUrl() const;
QString getCssStyleUrl(const QString &p_style) const;
QString getCodeBlockCssStyleUrl() const;
QString getCodeBlockCssStyleUrl(const QString &p_style) const;
const QString &getEditorStyle() const;
void setEditorStyle(const QString &p_style);
@ -172,6 +176,9 @@ public:
const QString &getCurRenderBackgroundColor() const;
void setCurRenderBackgroundColor(const QString &colorName);
// Return the color string of background @p_bgName.
QString getRenderBackgroundColor(const QString &p_bgName) const;
bool getToolsDockChecked() const;
void setToolsDockChecked(bool p_checked);

View File

@ -24,7 +24,11 @@ VExporter::VExporter(QWidget *p_parent)
void VExporter::prepareExport(const ExportOption &p_opt)
{
m_htmlTemplate = VUtils::generateHtmlTemplate(p_opt.m_renderer, true);
m_htmlTemplate = VUtils::generateHtmlTemplate(p_opt.m_renderer,
p_opt.m_renderBg,
p_opt.m_renderStyle,
p_opt.m_renderCodeBlockStyle,
p_opt.m_format == ExportFormat::PDF);
m_pageLayout = *(p_opt.m_layout);
}

View File

@ -186,6 +186,10 @@ void VMainWindow::registerCaptainAndNavigationTargets()
g_config->getCaptainShortcutKeySequence("FlushLogFile"),
this,
flushLogFileByCaptain);
m_captain->registerCaptainTarget(tr("Export"),
g_config->getCaptainShortcutKeySequence("Export"),
this,
exportByCaptain);
}
void VMainWindow::setupUI()
@ -774,6 +778,11 @@ void VMainWindow::initHelpMenu()
QAction *shortcutAct = new QAction(tr("&Shortcuts Help"), this);
shortcutAct->setToolTip(tr("View information about shortcut keys"));
QString keyText = VUtils::getCaptainShortcutSequenceText("ShortcutsHelp");
if (!keyText.isEmpty()) {
shortcutAct->setText(tr("&Shortcuts Help\t%1").arg(keyText));
}
connect(shortcutAct, &QAction::triggered,
this, &VMainWindow::shortcutsHelp);
@ -1002,6 +1011,10 @@ void VMainWindow::initFileMenu()
// Export as PDF.
m_exportAct = new QAction(tr("E&xport"), this);
m_exportAct->setToolTip(tr("Export notes"));
QString keyText = VUtils::getCaptainShortcutSequenceText("Export");
if (!keyText.isEmpty()) {
m_exportAct->setText(tr("E&xport\t%1").arg(keyText));
}
connect(m_exportAct, &QAction::triggered,
this, &VMainWindow::handleExportAct);
@ -1313,6 +1326,11 @@ void VMainWindow::initDockWindows()
QAction *toggleAct = toolDock->toggleViewAction();
toggleAct->setToolTip(tr("Toggle the tools dock widget"));
QString keyText = VUtils::getCaptainShortcutSequenceText("ToolsDock");
if (!keyText.isEmpty()) {
toggleAct->setText(tr("%1\t%2").arg(toggleAct->text()).arg(keyText));
}
m_viewMenu->addAction(toggleAct);
}
@ -2695,6 +2713,16 @@ bool VMainWindow::flushLogFileByCaptain(void *p_target, void *p_data)
return true;
}
bool VMainWindow::exportByCaptain(void *p_target, void *p_data)
{
Q_UNUSED(p_data);
VMainWindow *obj = static_cast<VMainWindow *>(p_target);
QTimer::singleShot(50, obj, SLOT(handleExportAct()));
return true;
}
void VMainWindow::promptNewNotebookIfEmpty()
{
if (vnote->getNotebooks().isEmpty()) {

View File

@ -286,6 +286,8 @@ private:
static bool flushLogFileByCaptain(void *p_target, void *p_data);
static bool exportByCaptain(void *p_target, void *p_data);
// End Captain mode functions.
VNote *vnote;

View File

@ -421,7 +421,7 @@ void VMdTab::setupMarkdownViewer()
page->setWebChannel(channel);
m_webViewer->setHtml(VUtils::generateHtmlTemplate(m_mdConType, false),
m_webViewer->setHtml(VUtils::generateHtmlTemplate(m_mdConType),
m_file->getBaseUrl());
m_stacks->addWidget(m_webViewer);
@ -1053,7 +1053,7 @@ void VMdTab::handleFileOrDirectoryChange(bool p_isFile, UpdateAction p_act)
{
// Reload the web view with new base URL.
m_headerFromEditMode = m_currentHeader;
m_webViewer->setHtml(VUtils::generateHtmlTemplate(m_mdConType, false),
m_webViewer->setHtml(VUtils::generateHtmlTemplate(m_mdConType),
m_file->getBaseUrl());
if (m_editor) {

View File

@ -25,8 +25,6 @@ QString VNote::s_simpleHtmlTemplate;
QString VNote::s_markdownTemplate;
QString VNote::s_markdownTemplatePDF;
QString VNote::s_sloganTemplate = "<div class=\"typewriter\"><h3>Hi Markdown, I'm VNote</h3></div>";
const QString VNote::c_hoedownJsFile = ":/resources/hoedown.js";
@ -95,26 +93,16 @@ void VNote::updateSimpletHtmlTemplate()
s_simpleHtmlTemplate.replace(cssHolder, g_config->getCssStyleUrl());
}
void VNote::updateTemplate()
QString VNote::generateHtmlTemplate(const QString &p_renderBg,
const QString &p_renderStyleUrl,
const QString &p_codeBlockStyleUrl,
bool p_isPDF)
{
const QString c_markdownTemplatePath(":/resources/markdown_template.html");
// Get background color
QString color;
const QString &curRenderBg = g_config->getCurRenderBackgroundColor();
const QVector<VColor> &customColors = g_config->getCustomColors();
if (curRenderBg != "System") {
for (int i = 0; i < customColors.size(); ++i) {
if (customColors[i].m_name == curRenderBg) {
color = customColors[i].m_color;
break;
}
}
}
QString cssStyle;
if (!color.isEmpty()) {
cssStyle += "body { background-color: " + color + " !important; }\n";
if (!p_renderBg.isEmpty()) {
cssStyle += "body { background-color: " + p_renderBg + " !important; }\n";
}
if (g_config->getEnableImageConstraint()) {
@ -126,29 +114,42 @@ void VNote::updateTemplate()
const QString cssHolder("CSS_PLACE_HOLDER");
const QString codeBlockCssHolder("HIGHLIGHTJS_CSS_PLACE_HOLDER");
s_markdownTemplate = VUtils::readFileFromDisk(c_markdownTemplatePath);
g_palette->fillStyle(s_markdownTemplate);
QString templ = VUtils::readFileFromDisk(c_markdownTemplatePath);
g_palette->fillStyle(templ);
// Must replace the code block holder first.
s_markdownTemplate.replace(codeBlockCssHolder, g_config->getCodeBlockCssStyleUrl());
s_markdownTemplate.replace(cssHolder, g_config->getCssStyleUrl());
templ.replace(codeBlockCssHolder, p_codeBlockStyleUrl);
templ.replace(cssHolder, p_renderStyleUrl);
s_markdownTemplatePDF = s_markdownTemplate;
if (p_isPDF) {
// Shoudl not display scrollbar in PDF.
cssStyle += "pre { white-space: pre-wrap !important; "
"word-break: break-all !important; }\n"
"pre code { white-space: pre-wrap !important; "
"word-break: break-all !important; }\n"
"code { word-break: break-all !important; }\n";
if (!g_config->getEnableImageConstraint()) {
// Constain the image width by force in PDF, otherwise, the PDF will
// be cut off.
cssStyle += "img { max-width: 100% !important; height: auto !important; }\n";
}
}
if (!cssStyle.isEmpty()) {
s_markdownTemplate.replace(styleHolder, cssStyle);
templ.replace(styleHolder, cssStyle);
}
// Shoudl not display scrollbar in PDF.
cssStyle += "pre { white-space: pre-wrap !important; "
"word-break: break-all !important; }\n";
if (!g_config->getEnableImageConstraint()) {
// Constain the image width by force in PDF, otherwise, the PDF will
// be cut off.
cssStyle += "img { max-width: 100% !important; height: auto !important; }\n";
}
return templ;
}
s_markdownTemplatePDF.replace(styleHolder, cssStyle);
void VNote::updateTemplate()
{
QString renderBg = g_config->getRenderBackgroundColor(g_config->getCurRenderBackgroundColor());
s_markdownTemplate = generateHtmlTemplate(renderBg,
g_config->getCssStyleUrl(),
g_config->getCodeBlockCssStyleUrl(),
false);
}
const QVector<VNotebook *> &VNote::getNotebooks() const

View File

@ -35,8 +35,6 @@ public:
static QString s_markdownTemplate;
static QString s_markdownTemplatePDF;
// Hoedown
static const QString c_hoedownJsFile;
@ -101,6 +99,12 @@ public:
void freeOrphanFiles();
// @p_renderBg: background color, empty to not specify given color.
static QString generateHtmlTemplate(const QString &p_renderBg,
const QString &p_renderStyleUrl,
const QString &p_codeBlockStyleUrl,
bool p_isPDF);
public slots:
void updateTemplate();