diff --git a/src/resources/themes/v_moonlight/v_moonlight.css b/src/resources/themes/v_moonlight/v_moonlight.css index b41bbf43..b47a373d 100644 --- a/src/resources/themes/v_moonlight/v_moonlight.css +++ b/src/resources/themes/v_moonlight/v_moonlight.css @@ -5,6 +5,7 @@ body { line-height: 1; padding: 15px; background: #282C34; + font-size: 16px; } h1, h2, h3, h4, h5, h6 { @@ -96,6 +97,8 @@ pre code { color: #98C379; background-color: #2C313A; line-height: 1.5; + font-family: Consolas, Monaco, Monospace, Courier; + white-space: pre; } code.mathjax-code { diff --git a/src/resources/themes/v_pure/v_pure.css b/src/resources/themes/v_pure/v_pure.css index a564db42..e7cb065b 100644 --- a/src/resources/themes/v_pure/v_pure.css +++ b/src/resources/themes/v_pure/v_pure.css @@ -5,6 +5,7 @@ body { line-height: 1; padding: 15px; background: #F5F5F5; + font-size: 16px; } h1, h2, h3, h4, h5, h6 { @@ -96,6 +97,8 @@ pre code { color: #222222; background-color: #E0E0E0; line-height: 1.5; + font-family: Consolas, Monaco, Monospace, Courier; + white-space: pre; } /* Should reference the style of P. */ diff --git a/src/resources/themes/v_white/v_white.css b/src/resources/themes/v_white/v_white.css index 39957db1..857b3f48 100644 --- a/src/resources/themes/v_white/v_white.css +++ b/src/resources/themes/v_white/v_white.css @@ -4,6 +4,7 @@ body { color: #222222; line-height: 1; padding: 15px; + font-size: 16px; } h1, h2, h3, h4, h5, h6 { @@ -95,6 +96,8 @@ pre code { color: #222222; background-color: #E0E0E0; line-height: 1.5; + font-family: Consolas, Monaco, Monospace, Courier; + white-space: pre; } code.mathjax-code { diff --git a/src/resources/vnote.ini b/src/resources/vnote.ini index d4efceac..8c483771 100644 --- a/src/resources/vnote.ini +++ b/src/resources/vnote.ini @@ -220,20 +220,23 @@ styles_to_inline_when_copied=all$border:color:display:font-family:font-size:font ; Define targets the copied content will be pasted into ; target_name$action1:action2:action3,targeet_name2$action2:action3 ; Available actions: -; s - add surrounding tags +; s - add surrounding tags +; e - add surrounding tags ; b(tag1|tag2) - remove background color of all tags except tag1 and tag2 ; c(tag1|tag2) - translate colors using palette defined mapping except tag1 and tag2 ; i - fix local relative ; m(tag1|tag2) - remove margin/margin-left/margin-right/padding/padding-left/padding-right of all tags except tag1 and tag2 ; r - raw html with all styles removed ; a - transform to -; x(tag1|tag2) - remove styles specified in [styles_to_inline_when_copied] of all tags except tag1 and tag2 +; x(tag1|tag2) - remove styles specified in [styles_to_remove_when_copied] of all tags except tag1 and tag2 ; p - replace the background color of
 with that of its child 
 ; n - replace the \n in 
 with 
; g - replace local relative/absolute tag with a warning label ; d - add to which is not inside
 ; f - replace " with ' in font-family style
-copy_targets="Without Background"$s:b(mark):c:i:x,OneNote$s:b(mark):c:i:m:a:x,"Microsoft Word"$s:p:b(mark|pre):c(pre):i:m:a:x,"WeChat Public Account"$s:p:b(mark|pre):c(pre):g:m:x:n:f,"Web Editor"$s:p:b(mark|pre):c(pre):m:x:n,"Raw HTML"$r:x
+; h - replace  tag with 
+; j - fix XHTML tag like  and 
+copy_targets="Without Background"$s:b(mark):c:i:x,Evernote$e:p:b(mark|pre):c(pre):g:m:a:x:n:j,OneNote$e:b(mark):c:i:m:a:x,"Microsoft Word"$s:p:b(mark|pre):c(pre):i:m:a:x,"WeChat Public Account"$s:p:b(mark|pre):c(pre):g:m:x:n:f,"Web Editor"$s:p:b(mark|pre):c(pre):m:x:n,"Raw HTML"$r:x [shortcuts] ; Define shortcuts here, with each item in the form "operation=keysequence". diff --git a/src/utils/vwebutils.cpp b/src/utils/vwebutils.cpp index 60399573..4b000284 100644 --- a/src/utils/vwebutils.cpp +++ b/src/utils/vwebutils.cpp @@ -1,6 +1,5 @@ #include "vwebutils.h" -#include #include #include #include @@ -26,6 +25,8 @@ void VWebUtils::init() m_styleTagReg = QRegExp("<([^>\\s]+)([^>]*\\s)style=\"([^\">]+)\"([^>]*)>"); + m_imgTagReg = QRegExp("]*>"); + initCopyTargets(g_config->getCopyTargets()); } @@ -115,11 +116,10 @@ bool VWebUtils::fixImageSrc(const QUrl &p_baseUrl, QString &p_html) pos = idx + reg.matchedLength(); if (!fixedStr.isEmpty() && urlStr != fixedStr) { qDebug() << "fix img url" << urlStr << fixedStr; - // Insert one more space to avoid fix the url twice. pos = pos + fixedStr.size() + 1 - urlStr.size(); p_html.replace(idx, reg.matchedLength(), - QString("")) { + p_html = "" + p_html + ""; + altered = true; + } + + break; + case 'b': altered = removeBackgroundColor(p_html, p_action.m_args); break; @@ -229,6 +242,14 @@ bool VWebUtils::alterHtmlByTargetAction(const QUrl &p_baseUrl, QString &p_html, altered = replaceQuoteInFontFamily(p_html); break; + case 'h': + altered = replaceHeadingWithSpan(p_html); + break; + + case 'j': + altered = fixXHtmlTags(p_html); + break; + default: break; } @@ -626,6 +647,7 @@ bool VWebUtils::replaceNewLineWithBR(QString &p_html) bool altered = false; int pos = 0; + const QString brTag("
"); while (pos < p_html.size()) { int tagIdx = p_html.indexOf(m_tagReg, pos); @@ -648,10 +670,9 @@ bool VWebUtils::replaceNewLineWithBR(QString &p_html) break; } - QString br("
"); - p_html.replace(idx, 1, br); - pos = idx + br.size() - 1; - preEnd = preEnd + br.size() - 1; + p_html.replace(idx, 1, brTag); + pos = idx + brTag.size() - 1; + preEnd = preEnd + brTag.size() - 1; altered = true; } @@ -666,28 +687,28 @@ bool VWebUtils::replaceLocalImgWithWarningLabel(QString &p_html) { bool altered = false; - QRegExp reg("]*>"); - QString label = QString("%1") .arg(QObject::tr("Insert_Image_HERE")); int pos = 0; while (pos < p_html.size()) { - int idx = p_html.indexOf(reg, pos); + int idx = p_html.indexOf(m_imgTagReg, pos); if (idx == -1) { break; } - QString urlStr = reg.cap(1); + QString urlStr = m_imgTagReg.cap(1); QUrl imgUrl(urlStr); if (imgUrl.scheme() == "https" || imgUrl.scheme() == "http") { - pos = idx + reg.matchedLength(); + pos = idx + m_imgTagReg.matchedLength(); continue; } - p_html.replace(idx, reg.matchedLength(), label); + p_html.replace(idx, m_imgTagReg.matchedLength(), label); pos = idx + label.size(); + + altered = true; } return altered; @@ -785,3 +806,93 @@ bool VWebUtils::replaceQuoteInFontFamily(QString &p_html) return altered; } + +static bool isHeadingTag(const QString &p_tagName) +{ + QString tag = p_tagName.toLower(); + if (!tag.startsWith('h') || tag.size() != 2) { + return false; + } + + return tag == "h1" + || tag == "h2" + || tag == "h3" + || tag == "h4" + || tag == "h5" + || tag == "h6"; +} + +bool VWebUtils::replaceHeadingWithSpan(QString &p_html) +{ + bool altered = false; + int pos = 0; + QString spanTag("span"); + + while (pos < p_html.size()) { + int tagIdx = p_html.indexOf(m_tagReg, pos); + if (tagIdx == -1) { + break; + } + + QString tagName = m_tagReg.cap(1); + if (!isHeadingTag(tagName)) { + pos = tagIdx + m_tagReg.matchedLength(); + continue; + } + + p_html.replace(tagIdx + 1, 2, spanTag); + + pos = tagIdx + m_tagReg.matchedLength() + spanTag.size() - 2; + + pos = skipToTagEnd(p_html, pos, tagName); + + Q_ASSERT(pos != -1); + + Q_ASSERT(p_html.mid(pos - 3, 2) == tagName); + + p_html.replace(pos - 3, 2, spanTag); + + pos = pos + spanTag.size() - 2; + + altered = true; + } + + return altered; +} + +bool VWebUtils::fixXHtmlTags(QString &p_html) +{ + bool altered = false; + + // . + int pos = 0; + const QString legalTag("/>"); + while (pos < p_html.size()) { + int idx = p_html.indexOf(m_imgTagReg, pos); + if (idx == -1) { + break; + } + + pos = idx + m_imgTagReg.matchedLength(); + + Q_ASSERT(p_html[pos - 1] == '>'); + + if (p_html.mid(pos - 2, 2) == legalTag) { + continue; + } + + p_html.replace(pos - 1, 1, legalTag); + pos = pos + legalTag.size() - 1; + + altered = true; + } + + //
. + int size = p_html.size(); + p_html.replace("
", "
"); + if (!altered && size != p_html.size()) { + altered = true; + } + + return altered; +} diff --git a/src/utils/vwebutils.h b/src/utils/vwebutils.h index 8288020f..2bc5ea72 100644 --- a/src/utils/vwebutils.h +++ b/src/utils/vwebutils.h @@ -103,6 +103,12 @@ private: // Replace " in font-family with '. bool replaceQuoteInFontFamily(QString &p_html); + // Replace headings with span. + bool replaceHeadingWithSpan(QString &p_html); + + // Fix tags as XHTML like and
. + bool fixXHtmlTags(QString &p_html); + QVector m_copyTargets; // Custom styles to remove when copied. @@ -124,5 +130,10 @@ private: // 3. Text inside 'style=""'; // 4. Text after 'style=""' and before '>'; QRegExp m_styleTagReg; + + // tag. + // Captured texts: + // 1. Src string without "; + QRegExp m_imgTagReg; }; #endif // VWEBUTILS_H