add copy target Evernote

This commit is contained in:
Le Tan 2018-02-23 19:53:44 +08:00
parent 956a8ab1d0
commit 4a4e4ed377
6 changed files with 150 additions and 16 deletions

View File

@ -5,6 +5,7 @@ body {
line-height: 1; line-height: 1;
padding: 15px; padding: 15px;
background: #282C34; background: #282C34;
font-size: 16px;
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@ -96,6 +97,8 @@ pre code {
color: #98C379; color: #98C379;
background-color: #2C313A; background-color: #2C313A;
line-height: 1.5; line-height: 1.5;
font-family: Consolas, Monaco, Monospace, Courier;
white-space: pre;
} }
code.mathjax-code { code.mathjax-code {

View File

@ -5,6 +5,7 @@ body {
line-height: 1; line-height: 1;
padding: 15px; padding: 15px;
background: #F5F5F5; background: #F5F5F5;
font-size: 16px;
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@ -96,6 +97,8 @@ pre code {
color: #222222; color: #222222;
background-color: #E0E0E0; background-color: #E0E0E0;
line-height: 1.5; line-height: 1.5;
font-family: Consolas, Monaco, Monospace, Courier;
white-space: pre;
} }
/* Should reference the style of P. */ /* Should reference the style of P. */

View File

@ -4,6 +4,7 @@ body {
color: #222222; color: #222222;
line-height: 1; line-height: 1;
padding: 15px; padding: 15px;
font-size: 16px;
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
@ -95,6 +96,8 @@ pre code {
color: #222222; color: #222222;
background-color: #E0E0E0; background-color: #E0E0E0;
line-height: 1.5; line-height: 1.5;
font-family: Consolas, Monaco, Monospace, Courier;
white-space: pre;
} }
code.mathjax-code { code.mathjax-code {

View File

@ -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 ; Define targets the copied content will be pasted into
; target_name$action1:action2:action3,targeet_name2$action2:action3 ; target_name$action1:action2:action3,targeet_name2$action2:action3
; Available actions: ; Available actions:
; s - add surrounding tags <html><body> ; s - add surrounding tags <html><body> </body></html>
; e - add surrounding tags <html><body><!--StartFragment--> <!--EndFragment--></body></html>
; b(tag1|tag2) - remove background color of all tags except tag1 and tag2 ; 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 ; c(tag1|tag2) - translate colors using palette defined mapping except tag1 and tag2
; i - fix local relative <img src> ; i - fix local relative <img src>
; m(tag1|tag2) - remove margin/margin-left/margin-right/padding/padding-left/padding-right of all tags except tag1 and tag2 ; 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 ; r - raw html with all styles removed
; a - transform <mark> to <span> ; a - transform <mark> to <span>
; 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 <pre> with that of its child <code> ; p - replace the background color of <pre> with that of its child <code>
; n - replace the \n in <pre> with <br> ; n - replace the \n in <pre> with <br>
; g - replace local relative/absolute <img> tag with a warning label ; g - replace local relative/absolute <img> tag with a warning label
; d - add <span> to <code> which is not inside <pre> ; d - add <span> to <code> which is not inside <pre>
; f - replace &quot; with ' in font-family style ; f - replace &quot; 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 <hi> tag with <span>
; j - fix XHTML tag like <img> and <br>
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] [shortcuts]
; Define shortcuts here, with each item in the form "operation=keysequence". ; Define shortcuts here, with each item in the form "operation=keysequence".

View File

@ -1,6 +1,5 @@
#include "vwebutils.h" #include "vwebutils.h"
#include <QRegExp>
#include <QFileInfo> #include <QFileInfo>
#include <QObject> #include <QObject>
#include <QDebug> #include <QDebug>
@ -26,6 +25,8 @@ void VWebUtils::init()
m_styleTagReg = QRegExp("<([^>\\s]+)([^>]*\\s)style=\"([^\">]+)\"([^>]*)>"); m_styleTagReg = QRegExp("<([^>\\s]+)([^>]*\\s)style=\"([^\">]+)\"([^>]*)>");
m_imgTagReg = QRegExp("<img src=\"([^\"]+)\"[^>]*>");
initCopyTargets(g_config->getCopyTargets()); initCopyTargets(g_config->getCopyTargets());
} }
@ -115,11 +116,10 @@ bool VWebUtils::fixImageSrc(const QUrl &p_baseUrl, QString &p_html)
pos = idx + reg.matchedLength(); pos = idx + reg.matchedLength();
if (!fixedStr.isEmpty() && urlStr != fixedStr) { if (!fixedStr.isEmpty() && urlStr != fixedStr) {
qDebug() << "fix img url" << 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(); pos = pos + fixedStr.size() + 1 - urlStr.size();
p_html.replace(idx, p_html.replace(idx,
reg.matchedLength(), reg.matchedLength(),
QString("<img src=\"%1\"").arg(fixedStr)); QString("<img src=\"%1\"").arg(fixedStr));
changed = true; changed = true;
} }
} }
@ -151,6 +151,11 @@ bool VWebUtils::alterHtmlAsTarget(const QUrl &p_baseUrl, QString &p_html, const
} }
} }
if (altered) {
qDebug() << "==html==";
qDebug() << p_html;
}
return altered; return altered;
} }
@ -181,6 +186,14 @@ bool VWebUtils::alterHtmlByTargetAction(const QUrl &p_baseUrl, QString &p_html,
break; break;
case 'e':
if (!p_html.startsWith("<html>")) {
p_html = "<html><body><!--StartFragment-->" + p_html + "<!--EndFragment--></body></html>";
altered = true;
}
break;
case 'b': case 'b':
altered = removeBackgroundColor(p_html, p_action.m_args); altered = removeBackgroundColor(p_html, p_action.m_args);
break; break;
@ -229,6 +242,14 @@ bool VWebUtils::alterHtmlByTargetAction(const QUrl &p_baseUrl, QString &p_html,
altered = replaceQuoteInFontFamily(p_html); altered = replaceQuoteInFontFamily(p_html);
break; break;
case 'h':
altered = replaceHeadingWithSpan(p_html);
break;
case 'j':
altered = fixXHtmlTags(p_html);
break;
default: default:
break; break;
} }
@ -626,6 +647,7 @@ bool VWebUtils::replaceNewLineWithBR(QString &p_html)
bool altered = false; bool altered = false;
int pos = 0; int pos = 0;
const QString brTag("<br/>");
while (pos < p_html.size()) { while (pos < p_html.size()) {
int tagIdx = p_html.indexOf(m_tagReg, pos); int tagIdx = p_html.indexOf(m_tagReg, pos);
@ -648,10 +670,9 @@ bool VWebUtils::replaceNewLineWithBR(QString &p_html)
break; break;
} }
QString br("<br>"); p_html.replace(idx, 1, brTag);
p_html.replace(idx, 1, br); pos = idx + brTag.size() - 1;
pos = idx + br.size() - 1; preEnd = preEnd + brTag.size() - 1;
preEnd = preEnd + br.size() - 1;
altered = true; altered = true;
} }
@ -666,28 +687,28 @@ bool VWebUtils::replaceLocalImgWithWarningLabel(QString &p_html)
{ {
bool altered = false; bool altered = false;
QRegExp reg("<img src=\"([^\"]+)\"[^>]*>");
QString label = QString("<span style=\"font-weight: bold; color: #FFFFFF; background-color: #EE0000;\">%1</span>") QString label = QString("<span style=\"font-weight: bold; color: #FFFFFF; background-color: #EE0000;\">%1</span>")
.arg(QObject::tr("Insert_Image_HERE")); .arg(QObject::tr("Insert_Image_HERE"));
int pos = 0; int pos = 0;
while (pos < p_html.size()) { while (pos < p_html.size()) {
int idx = p_html.indexOf(reg, pos); int idx = p_html.indexOf(m_imgTagReg, pos);
if (idx == -1) { if (idx == -1) {
break; break;
} }
QString urlStr = reg.cap(1); QString urlStr = m_imgTagReg.cap(1);
QUrl imgUrl(urlStr); QUrl imgUrl(urlStr);
if (imgUrl.scheme() == "https" || imgUrl.scheme() == "http") { if (imgUrl.scheme() == "https" || imgUrl.scheme() == "http") {
pos = idx + reg.matchedLength(); pos = idx + m_imgTagReg.matchedLength();
continue; continue;
} }
p_html.replace(idx, reg.matchedLength(), label); p_html.replace(idx, m_imgTagReg.matchedLength(), label);
pos = idx + label.size(); pos = idx + label.size();
altered = true;
} }
return altered; return altered;
@ -785,3 +806,93 @@ bool VWebUtils::replaceQuoteInFontFamily(QString &p_html)
return altered; 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;
// <img>.
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;
}
// <br>.
int size = p_html.size();
p_html.replace("<br>", "<br/>");
if (!altered && size != p_html.size()) {
altered = true;
}
return altered;
}

View File

@ -103,6 +103,12 @@ private:
// Replace &quot; in font-family with '. // Replace &quot; in font-family with '.
bool replaceQuoteInFontFamily(QString &p_html); bool replaceQuoteInFontFamily(QString &p_html);
// Replace headings with span.
bool replaceHeadingWithSpan(QString &p_html);
// Fix tags as XHTML like <img> and <br>.
bool fixXHtmlTags(QString &p_html);
QVector<CopyTarget> m_copyTargets; QVector<CopyTarget> m_copyTargets;
// Custom styles to remove when copied. // Custom styles to remove when copied.
@ -124,5 +130,10 @@ private:
// 3. Text inside 'style=""'; // 3. Text inside 'style=""';
// 4. Text after 'style=""' and before '>'; // 4. Text after 'style=""' and before '>';
QRegExp m_styleTagReg; QRegExp m_styleTagReg;
// <Img> tag.
// Captured texts:
// 1. Src string without ";
QRegExp m_imgTagReg;
}; };
#endif // VWEBUTILS_H #endif // VWEBUTILS_H